Spatial disappears when I move it

Why do you call this?

cam.setFrustum(1f, 1000f, -0.6627417f, 0.6627417f, 0.41421357f, -0.41421357f);

I was making the camera spin when the character moves, so that the character does not escape the camera. Searching, I noticed that it was better to use this method than setLocalRotation (). But I can test using this method.

So, you need to make your camera look at the character?
Because if yes, there’s an easier way to rotate the Camera rather to creating Quaternions:

cam.lookAt(character.getLocalTranslation(), Vector3f.UP)

Or even better, learn how to use ChaseCamera, a 3rd person camera that, as the name implies, chases a specific spatial.

thanks, i whill try.

I’d also suggest printing the position/rotation values for the model as soon as you calculate them - that way you will immediately catch Float.NaN or other suspicious values.


I found this method very interesting but in fact it is not what I plan, but I was happy to know that there is something so easy, this will open up my horizons.

1 Like

I managed to solve … I’ll do a little tutorial about it … maybe it helps those who may have the same doubt, now or in the future …

Open JME (I am using stable version 3.1) and blender (preferably with the same model that was loaded by your game, in my case the “valet2”).

In 3D-View, press “n” to open the properties tab of the selected object (Sorry if I made a mistake in the name of this tab).
Note that the location, scale, and rotation property exists. In the case let’s focus on the rotation (of course :))!

In rotation, there exists the x, y, z axis. (Assume that the z axis of the blender is the y axis of the JME), there is a space with some options (As shown in arrow 1), select the Quartenion option ).

Note that a fourth axis, the “w”, has now appeared. Now the axes of the blender corresponds to the axis of the JME (Again, the z axis of the blender is the y axis of the JME).

Now, press “7” or go View → Top, to be in the top view. Select the model and press “r”, so you can rotate the object. To get more precise, after pressing “r” type “90”, for your model to be 90 °. Now notice how the values of the axes (x, y, z, w) remained.

Now in JME, change the rotation by entering the values you got in the blender (Again, the z axis of the blender is the y axis of the JME).

And order … note that the rotation was done successfully!


If you just want to create a quaternion which represents rotation for X degrees around for example Y axis, you can get one by calling:
new Quaternion().fromAngleAxis() which accepts a rotation axis and a rotation in degrees.

Btw for more experienced people, why is fromAngleAxis() not static? Why do I have to create a throwaway quaternion just to make another one?

Cause it invokes fromAngleNormalAxis() which is not static? And it is not static because you have to create instance somewhere not touching reference Quaternion()? (I assume)

You’re not making a throwaway one though, the one you create is the one the rotation gets applied to. It’s a local method.

To OP, if you find yourself setting quaternion values directly then you are doing something wrong.

Unless you happen to be writing low-level serialization code… you’ve made a bunch of bad choices and a bunch of bad assumptions.

Have you tried instead to apply the rotation in blender before importing in JME3? (Object -> Apply -> Rotation).

Why does it return the quaternion then?
Something confusing is going on here.

No it’s pretty much as it should be. Most Vector3f and Quaternion methods return the object for easy chaining of method calls iirc, which is quite useful all the time.


fromAngles() returns “this” so that you can easily chain things.

fromAngles() is not static so that you can avoid creating a throw-away Quaternion if you already have one… and it follows the pattern already set by a hundred other methods.

because it is:

protected float x, y, z, w;


public Quaternion() {
        x = 0;
        y = 0;
        z = 0;
        w = 1;


public Quaternion fromAngleNormalAxis(float angle, Vector3f axis) {
        if (axis.x == 0 && axis.y == 0 && axis.z == 0) {
        } else {
            float halfAngle = 0.5f * angle;
            float sin = FastMath.sin(halfAngle);
            w = FastMath.cos(halfAngle);
            x = sin * axis.x;
            y = sin * axis.y;
            z = sin * axis.z;
        return this;

@oreganBR you seriously need to see this and this. Don’t touch the Quaternions. You can (and I believe you should) rotate your models as in real life: degrees or radians. I never create Quaternionx like you do in the code.