I'm testing something with jMonkeyEngine and I'm attempting to have the camera follow a box spatial. I followed official instructions here:
http://jmonkeyengine.org/wiki/doku.php/jme3:advanced:making_the_camera_follow_a_character
When applying, what I learnt there I produced the following code:
#Override
public void simpleInitApp() {
flyCam.setEnabled(false);
//world objects
Box b = new Box(Vector3f.ZERO, 1, 1, 1);
Geometry geom = new Geometry("Box", b);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue);
geom.setMaterial(mat);
rootNode.attachChild(geom);
//Ship node
shipNode = new Node();
rootNode.attachChild(shipNode);
//Ship
Box shipBase = new Box(new Vector3f(0, -1f, 10f), 5, 0.2f, 5);
Geometry shipGeom = new Geometry("Ship Base", shipBase);
Material shipMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
shipMat.setColor("Color", ColorRGBA.Green);
shipGeom.setMaterial(shipMat);
shipNode.attachChild(shipGeom);
//Camera node
cameraNode = new CameraNode("Camera Node", cam);
cameraNode.setControlDir(ControlDirection.CameraToSpatial);
shipNode.attachChild(cameraNode);
initPhysics();
initKeys();
}
When the following code is called:
#Override
public void simpleUpdate(float tpf) {
//Update ship heading
shipHeading = shipHeading.mult(shipRotationMoment);
shipNode.setLocalRotation(shipHeading);
shipPos = shipPos.add(shipVelocity);
shipNode.setLocalTranslation(shipPos);
}
The box moves as is predicted but the camera stays where it is. The graph should be something like this:
rootNode
b (Box)
shipNode
shipBase
cameraNode
Therefore the camera should be already bound to shipNode. What am I missing?
Reading through the tutorial you provided, it seems you might have a typo. You have:
cameraNode.setControlDir(ControlDirection.CameraToSpatial);
However, the tutorial has:
//This mode means that camera copies the movements of the target:
camNode.setControlDir(ControlDirection.SpatialToCamera);
Lower down in the tutorial it defines the difference between these 2 ControlDirections. The one the tutorial provides has the camera follow the movement of the object, whereas what you have the object follows the movement of the camera.
Hope this helps.
Related
#Override
public void create()
{
batch = new SpriteBatch();
shape = new ShapeRenderer();
velocity = new Vector2(100, 0);
position = new Rectangle(0, 5, 100, 100);
font = new BitmapFont();
font.setColor(Color.BLACK);
font.getData().scale(3f);
camera = new OrthographicCamera();
confCamera();
}
#Override
public void render()
{
if(Gdx.input.isTouched())
position.x = Gdx.input.getX() - position.width/2;
position.y = (Gdx.input.getY() - position.height/2);
shape.begin(ShapeRenderer.ShapeType.Filled);
shape.setColor(Color.BLACK);
shape.rect(position.x, position.y, position.width, position.height);
shape.end();
}
It's a simple code, but I'm not undestanding Y axis, my shape moves like a mirror. If I touch on top, my shape goes to bottom. If I touch on bottom, my shape goes to top. How to fix it?
LibGDX (by default) for rendering uses coordinate system where 0 is at bottom of the screen and the more you go up Y coordinate grows.
Also, when you read input coordinates (touches, moves...) you get screen coordinates, but when you render your graphics you are using "world" coordinates. They are in 2 different coordinate system so to convert from screen to world you have to use camera.unproject() call. Should be like:
Vector3 touchPos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
camera.unproject(touchPos);
and then use touchPos.x and touchPos.y.
The similar question is asked here so you can find more answers there:
Using unProject correctly in Java Libgdx
Is there a possibility to connect two marker locations with a line? I have two location marker:
LocationMarker point1 = new LocationMarker(
20.501925,
44.792181,
new AnnotationRenderer("point1 ")
);
LocationMarker point2 = new LocationMarker(
20.502972,
44.790873,
new AnnotationRenderer("point2 ")
);
Any example? I use ArCore Location
The code below will draw a line between two points - the points are associated with anchors in Sceneform - this is adapted from the answer here https://stackoverflow.com/a/52816504/334402:
private void drawLine(AnchorNode node1, AnchorNode node2) {
//Draw a line between two AnchorNodes
Log.d(TAG,"drawLine");
Vector3 point1, point2;
point1 = node1.getWorldPosition();
point2 = node2.getWorldPosition();
//First, find the vector extending between the two points and define a look rotation
//in terms of this Vector.
final Vector3 difference = Vector3.subtract(point1, point2);
final Vector3 directionFromTopToBottom = difference.normalized();
final Quaternion rotationFromAToB =
Quaternion.lookRotation(directionFromTopToBottom, Vector3.up());
MaterialFactory.makeOpaqueWithColor(getApplicationContext(), new Color(0, 255, 244))
.thenAccept(
material -> {
/* Then, create a rectangular prism, using ShapeFactory.makeCube() and use the difference vector
to extend to the necessary length. */
Log.d(TAG,"drawLine insie .thenAccept");
ModelRenderable model = ShapeFactory.makeCube(
new Vector3(.01f, .01f, difference.length()),
Vector3.zero(), material);
/* Last, set the world rotation of the node to the rotation calculated earlier and set the world position to
the midpoint between the given points . */
Anchor lineAnchor = node2.getAnchor();
nodeForLine = new Node();
nodeForLine.setParent(node1);
nodeForLine.setRenderable(model);
nodeForLine.setWorldPosition(Vector3.add(point1, point2).scaled(.5f));
nodeForLine.setWorldRotation(rotationFromAToB);
}
);
}
Update: Full working example available here:
https://github.com/mickod/LineView
I have problem in moving camera behind the car.The camera can not adjusting itself to be directly behind the new direction of the car.
My code:
Vector3 tmpV = new Vector3();
Quaternion quatRotation = new Quaternion();
//chassis is car
chassis.transform.getTranslation(camera.position);
tmpV.set(camera.position).sub(5, 0, 5).y = 0f;
chassis.transform.getRotation(quatRotation);
camera.rotate(quatRotation);
camera.position.add(tmpV.nor().scl(-4f)).y = 4.f;
chassis.transform.getTranslation(tmpV);
camera.lookAt(tmpV);
camera.up.set(Vector3.Y);
It is currently happening when moving right:
What i needs to happen when moving right:
By using of this class from this link
that Xoppa posted in the comment:
camera.desiredLocation.set(new Vector3(0, 5, 5));
camera.transform=chassis.transform;
camera.up.set(Vector3.Y);
I'm new to 3d engines in general, and I'm getting this NullPointerException when I try to collide a Geometry and a BoundingVolume object.
Here's how I declare my objects (sorry, it's rather messy at the moment)
public void simpleInitApp() {
Quad q= new Quad(100, 100);
Dome mesh = new Dome(Vector3f.ZERO, 2, 32, 1f,false);
geom = new Geometry("Cylinder", mesh); //declared elsewhere
g3 = new Geometry("lel", q);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue);
Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat2.setColor("Color", ColorRGBA.Red);
geom.setMaterial(mat);
g3.setMaterial(mat2);
rootNode.attachChild(geom);
rootNode.attachChild(g3);
and here's my update loop
public void simpleUpdate(float tpf) {
// System.out.println("hi");
BoundingVolume b = g3.getWorldBound(); //should give boundingvolume of the quad
System.out.println(b.getVolume()); //just to test if this works
CollisionResults r2 = new CollisionResults(); //declare and initialize the collisionresults
geom.collideWith(b, r2); //collide
System.out.println(r2.size()); //this returns a value, usually between 0-2
for(CollisionResult x:r2){
System.out.println("x = "+ x.getContactPoint().getX());
/*and oddly enough, i get a NullPointerException here even though the collision appeared successful - this never prints anything either so it's not going out of bounds or anything*/
}
}
tl;dr-get a NullPointerException when I try to print off the coordinates of each CollisionResult from the intersection of a BoundingVolume and a Geometry
Neither the JMonkey Forums nor the JMonkey docs seem to be of any assistance. Would any of you be able to help? Thanks in advance.
Your models not attached to JBullet physics.
try sg like this:
BulletAppState buleltAppState;
public void simpleInitApp() {
Quad q= new Quad(100, 100);
Dome mesh = new Dome(Vector3f.ZERO, 2, 32, 1f,false);
geom = new Geometry("Cylinder", mesh); //declared elsewhere
g3 = new Geometry("lel", q);
Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat.setColor("Color", ColorRGBA.Blue);
Material mat2 = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
mat2.setColor("Color", ColorRGBA.Red);
geom.setMaterial(mat);
g3.setMaterial(mat2);
bulletAppState = new BulletAppState();
stateManager.attach(bulletAppState);
bulletAppState.getPhysicsSpace().attachChild(geom);
bulletAppState.getPhysicsSpace().attachChild(g3);
rootNode.attachChild(geom);
rootNode.attachChild(g3);
}
after that you can check collision!
I've done a little research and I believe the problem is that there isn't a single collision point between 2 2D/3D objects, there is a 2D/3D collision region. Therefore null is returned as no single point is available. This is backed up by a comment by a developer. I believe the JMonkey collision detection doesn't actually calculate the intersection region because its quite mathematically complex (although it does give the triangle involved in the collision)
If both your shapes are convex you may be interested in this post on calculating 3d polygon intersections: Finding the intersection of two 3D polygons.
So Im new to JME3 and I have a few problems understanding the BetterCharacterControl.
When I try to apply a BetterCharacterControl to a box it always "expands" from the upper part of the box instead of the center. (A picture explains that better:)
I cant find any functions to change the location it gets applied at, I already tried to create a subclass in which I changed the RigidBody to the BoxCollisionShape directly but that seems to somehow screw up the isOnGround Method. Also if I want to use slopes later it would be nice to have the capsule shape.
Box box2 = new Box(10, 15, 10);
player = new Geometry("Player", box2);
player.setLocalTranslation(new Vector3f(0, 20, 0));
Material mat = new Material(assetManager,
"Common/MatDefs/Light/Lighting.j3md");
mat.setBoolean("UseMaterialColors", true);
mat.setColor("Ambient", ColorRGBA.Blue);
mat.setColor("Diffuse", ColorRGBA.Blue);
player.setMaterial(mat);
playerC = new BetterCharacterControl(12, 30, 0);
playerC.setJumpForce(new Vector3f(0, 700, 0));
player.addControl(playerC);
rootNode.attachChild(player);
bulletAppState.getPhysicsSpace().add(playerC);
On a different note, it seems like I i have to apply a huge vector for the jump force for it to do anything (I didnt change any gravity values)
Im glad for any help
i had this same problem. The way I resolved it is not usual. I coded a class and did inherit from BetterCharacterControl overwriting getShape() method as follows:
protected CollisionShape getShape() {
//TODO: cleanup size mess..
CapsuleCollisionShape capsuleCollisionShape = new CapsuleCollisionShape(getFinalRadius(), (getFinalHeight() - (2 * getFinalRadius())));
CompoundCollisionShape compoundCollisionShape = new CompoundCollisionShape();
//Vector3f addLocation = new Vector3f(0, (getFinalHeight() / 2.0f), 0); REMOVED LINE
Vector3f addLocation = new Vector3f(0, 0, 0); //NEW LINE
compoundCollisionShape.addChildShape(capsuleCollisionShape, addLocation);
return compoundCollisionShape;
}
This works because the original code is a composite created in such a way so that the child node is offset by the value: (getFinalHeight () / 2.0f). The new line adds not realize this shift, leaving the object in the center position of the box set. However, this way of solving the problem, it can create problems when actually a composite mesh is used in the final object.