[SOLVED] Spatial rotation and direction when moving on path

I am trying to create a turn based game with airplanes (something like ace patrol). I must turn each object when loading, to face the correct direction, but when i try to move models along path, they are not facing the correct direction. if the rotation is turned off, then they just move facing the direction that was set before, but when rotation is allowed, they turn in strange directions - even fliping the model at, or close to, waypoints.

Can you post a video and/or source code to see how you program your objects to move along a path?

2 Likes

How is path defined?

How are you doing this calculation?

Without any actual information, it’s really tough to answer.

With just the information given: set the object’s lookAt() to the direction of the path.

i am using motioncontrol - path is selected by mouse (the path setting is working as it should)

i am rotating the loaded models to face where i need by using setLocalRotation(Quaternion)
but then the rotation in motioncontrol also uses setRotation and i think it might be overwriting the previous rotations. now i tried to multiply the Quaternions and it almost works in some directions (wings of the airplane are not horizontal, but close to that), but some other directions are completely wrong.
…all airplanes are at the end of their path…

        Spatial actplane = mainScene.getChild(activePlane.getName());     
        motionControl = new MotionEvent(actplane,path);
        path.enableDebugShape(assetManager, rootNode);
        motionControl.setDirectionType(MotionEvent.Direction.PathAndRotation);
        
        //trying different rotations
            Quaternion fixPosition = actplane.getLocalRotation();
            Quaternion rotation = new Quaternion().fromAngleAxis(-FastMath.HALF_PI, Vector3f.UNIT_Z);
            Quaternion correctDirection = fixPosition.mult(rotation);
         //this was the first try - but the airplane was not doing what i wanted   
        //motionControl.setRotation(new Quaternion().fromAngleNormalAxis(FastMath.HALF_PI, Vector3f.UNIT_Y));
        motionControl.setRotation(correctDirection);
        motionControl.setInitialDuration(10f);
        motionControl.setSpeed(1f);
        motionControl.play();

also i tried to use lookat with different coordinates, but the airplanes did not change direction, - is there a way to set some direction as default so other rotations would start from there?

Perhaps it would be helpful to compare your code to TestMotionPath.java, which is working as expected (for me, at least).

that test was where i started.
maybe there is problem with the model itself - for example lookAt() doesn’t work for any vector i try.
i think the movement on path with rotation overwrites previous rotations (movement looks the same even when i turned all previous rotations off, that were used to show the airplane in correct position)

… i have to rotate every model, because when loading them, they are turned on side… (maybe i started using the coordinate system the wrong way…)

the closest a got to the correct movement was, when the plane was flying with wings vertical - like the default position of my models…

What vectors did you try? Were they all length 1? What does “doesn’t work” mean? Looks in a weird direction? Doesn’t turn at all?

Make the model a child of a node. Rotate the model so that “up” is what you expect it to be. Then from that point on, just use the node for following the path.

No, the vectors i was trying had one variable aĹĄ 100 or -100 and the others at 0. did not try different values.

Models are created and rotated as nodes, before placing them on map.

        airplane = new Node();
        airplane.setName("Airplane");
        Spatial airplanebody = assetManager.loadModel("Models/tempairplane/body.obj");
        airplanebody.setName("Fuselage");
        airplane.attachChild(airplanebody);
        Spatial cabin = assetManager.loadModel("Models/tempairplane/cabin.obj");
        cabin.setName("Cabin");
        airplane.attachChild(cabin);
        Spatial wings = assetManager.loadModel("Models/tempairplane/wings.obj");
        wings.setName("Wings");
        airplane.attachChild(wings);
        Spatial enginering = assetManager.loadModel("Models/tempairplane/enginering.obj");
        enginering.setName("Enginering");
        airplane.attachChild(enginering);
        Spatial stabilizators = assetManager.loadModel("Models/tempairplane/stabilizators.obj");
        stabilizators.setName("Stabilizators");
        airplane.attachChild(stabilizators);
        Spatial propeller = assetManager.loadModel("Models/tempairplane/propellerblades.obj");
        propeller.setName("Propeller");
        airplane.attachChild(propeller);
        airplane.center();
        airplane.scale(0.25f);
        airplane.rotateUpTo(new Vector3f(0,0,-10));
        airplane.lookAt(airplane.getLocalTranslation(), new Vector3f(-100,-100,0));
        Quaternion anotherturn = new Quaternion();
        anotherturn.fromAngleAxis( -FastMath.PI/2 , new Vector3f(0,1,0));        
        Quaternion fixPosition = roll90.mult(anotherturn);
        airplane.setLocalRotation(fixPosition);

this is how i am placing them:

        Node airplaneNode = new Node();
        airplaneNode.setName("Airplanes");
        for (Airplane ap: airplanes){
            Node airplane = models.airplane.clone(true);
            airplane.setName(ap.name);
            
         
            this.colorAirplane(ap, airplane);
            airplane.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
            airplane.setLocalTranslation(ap.location.x*1.5f*hexsize ,ap.location.y*sqrt, ap.location.z );
            Quaternion fixPosition = airplane.getLocalRotation();
//directions are from 0 to 5, 0 is north, 3 is south - i was trying it also with simple rotate command
            Quaternion setDirection = new Quaternion().fromAngleAxis(ap.direction*FastMath.PI/3, new Vector3f(0,-1,0));
            Quaternion correctDirection = fixPosition.mult(setDirection);
            airplane.setLocalRotation(correctDirection);            
            airplaneNode.attachChild(airplane);
        }

Direction vectors are always length=1… so those weren’t direction vectors. Passing a random giant vector to a method that is expecting a direction is going to give weird results.

may therefore give bizarre results as 0,0,-10 is a nonsense direction.

I can’t really speak to the loop as it seems to not be following a path anymore but doing something else.

… tried to change the lookUp to 1 lenght vector, but still no change. same with lookAt
(i thought that lookAt directs the spatial in direction of the vector that is entered… as the airplanes are at different locations, my plan was to write large number, so each would look at the same direction, to get a noticeable change, if the lookAt would work as it should)
i also have another noob question - i have jmonkey engine installed on more computers, but on each it mentions missing javadocs, so for some commands it shows explanation, when i am writing them, but other commands are missing those. that is also the reason, why i am trying random vectors and ways to turn spatials, when something doesn’t work as i want it to… so what is the easiest way do fix those missing javadocs?

If you want to use lookAt you have to add the model to the scenegraph and set the position first. And this method does take a vector with the world position you want to lookAt

after using 1 lenght vectors, both lookUp and LookAt started working (but the airplane is looking the other direction, not where i want). the flying is still not working, but i will be experimenting a little and ask for help later.

1 Like

first argument shoult be the position you want to look at, second argument is where is up for the spatial

i was experimentigh a bit with the lookat and lookup. while i can now turn the models much faster to positions i want them to be, when it comes to lookat, it still turns to the point i want it to with one of its wings, not the front of the plane. is there a way do display (and rotate) the forward direction, so it would be looking the way i want it to?

Like most of JME, lookat assumes the +Z axis is the forward direction.
If your plane model has +X as the forward direction, then +Z would be the direction of one of the wings.

1 Like

It sounds like you need to rotate the plain’s Spatial by 90 degrees when it is initiated, so that the nose will be facing forward by default.

And then once it is oriented correctly, you can attach your plane model to another Node and then you can move/rotate that node with the lookAt() method and the plane should now be facing forward.

So something like:

Spatial planeSpatial;
Node planeNode;

planeSpatial.rotate(0, FastMath.PI, 0);
planeNode.attachChild(planeSpatial);


...
...

planeNode.lookAt(targetSpotToLook, upVec);

sorry, deleting the post for now. i thought it was already working at least halfway, but i mixed the x and y coordinates…
still looking at world with wing forward…

this is now the node creation.
without rotation i see the left side of the model, propeller on left, wings vertical to ground

        airplane = new Node();
        airplane.setName("Airplane");
        Spatial airplanebody = assetManager.loadModel("Models/tempairplane/body.obj");
        airplanebody.setName("Fuselage");
        airplanebody.rotate(0, FastMath.PI, 0);
        airplane.attachChild(airplanebody);
        Spatial cabin = assetManager.loadModel("Models/tempairplane/cabin.obj");
        cabin.setName("Cabin");
        cabin.rotate(0, FastMath.PI, 0);
        airplane.attachChild(cabin);
        Spatial wings = assetManager.loadModel("Models/tempairplane/wings.obj");
        wings.setName("Wings");
        wings.rotate(0, FastMath.PI, 0);
        airplane.attachChild(wings);
        Spatial enginering = assetManager.loadModel("Models/tempairplane/enginering.obj");
        enginering.setName("Enginering");
        enginering.rotate(0, FastMath.PI, 0);
        airplane.attachChild(enginering);
        Spatial stabilizators = assetManager.loadModel("Models/tempairplane/stabilizators.obj");
        stabilizators.setName("Stabilizators");
        stabilizators.rotate(0, FastMath.PI, 0);
        airplane.attachChild(stabilizators);
        Spatial propeller = assetManager.loadModel("Models/tempairplane/propellerblades.obj");
        propeller.setName("Propeller");
        propeller.rotate(0, FastMath.PI, 0);
        airplane.attachChild(propeller);
        airplane.scale(0.25f);

after using this rotation, the airplane looks the other direction, stil vertical, but now with propeller on right.
when i use lookAt,with upVector 0,0,1, the airplane is horizontal, but to the direction i want it to look at is its left wing.

This statement doesn’t make exact sense on its own. One way of interpreting it is just wrong and the other way is right… and maybe there are other ways of interpreting it but I really doubt you are “saving it to a file” for example.

If English is your second language then much respect because it’s very good… but also code is universal at explaining what you mean.

Then somewhere between it working and not working, you misreferenced something.

This is super basic scene graph stuff that just “always works”. So there is a 100% change that the problem is your code (that we cannot see).

It is impossible for us to help without seeing code.

Put together a simple (preferably single class) test case that illustrates your issue and we’ll definitely spot the problem.

sorry, i added my model creation code to the previous post.
i also tried to rotate my model, but models in assetpack i would like to use later are rotated like my airplane, so making this work would be better than changing all the models.

I see where you setup your model. You haven’t shown us the latest code where you actually do anything with it.

HIGHLY RECOMMEND YOU FOLLOW THIS ADVICE:

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

99% of the time, you will spot your own error when you do that. The other 1% of the time, we will definitely be able to tell you your issue. Guarantee it.

1 Like