Spatial disappears when I move it

My wild guess, an NAN in rotation or position :slight_smile:

I do not believe … I do not believe that the problem can be this … in fact, I do not understand very well about the guartary rotation (x and z w).

Well, you didn’t output the rotation so we don’t know.

You will get more people to help if you find a way to include the relevant bits of code here without making us download and extract a zip. Maybe some folks will have the time but most won’t bother.

Thanks for the information … I will make the code available on the forum.

In case it’s necessary:

public void simpleInitApp() { super.flyCam.setEnabled(false); super.flyCam.setMoveSpeed(20); super.setDisplayFps(true); cam.setLocation(new Vector3f(disx, disy + 10, disz - 10)); cam.setRotation(new Quaternion(0.18495204f, -0.0086373165f, 0.0016255928f, 0.9827082f)); nod = (Node) assetManager.loadModel("Models/valet2.j3o"); spt = nod.getChild("2b02f008_obj");
    terr = new TerrainMaker(this);

    DirectionalLight sun = new DirectionalLight();
    sun.setDirection((new Vector3f(-0.5f, -0.5f, -0.5f)).normalizeLocal());
    sun.setColor(ColorRGBA.White);
    rootNode.addLight(sun);
    rootNode.attachChild(spt);
    
    
    
    
    
    
    AnimControl cont=spt.getControl(AnimControl.class);
    deb=new SkeletonDebugger("mixanorig:Hips", cont.getSkeleton());
    Material mat=new Material(
            assetManager,
            "Common/MatDefs/Misc/Unshaded.j3md"
    );
    mat.setColor("Color", ColorRGBA.Blue);
    deb.setMaterial(mat);
    
    rootNode.attachChild(deb);

    
    
    
    
    
    if (!flyCam.isEnabled()) {
        this.initTeclado();
    }
}

public void onAnimCycleDone(AnimControl cont, AnimChannel can, String annome) {
}

public void onAnimChange(AnimControl control, AnimChannel channel, String animName) {
    // sem uso
}

public void initTeclado() {
    inputManager.addMapping("x-", new KeyTrigger(KeyInput.KEY_S));
    inputManager.addMapping("x+", new KeyTrigger(KeyInput.KEY_W));
    inputManager.addMapping("z-", new KeyTrigger(KeyInput.KEY_D));
    inputManager.addMapping("z+", new KeyTrigger(KeyInput.KEY_A));
    inputManager.addMapping("tab", new KeyTrigger(KeyInput.KEY_TAB));
    inputManager.addMapping("o", new KeyTrigger(KeyInput.KEY_O));
    inputManager.addMapping("l", new KeyTrigger(KeyInput.KEY_L));
    inputManager.addMapping("i", new KeyTrigger(KeyInput.KEY_I));
    inputManager.addMapping("k", new KeyTrigger(KeyInput.KEY_K));
    
    
    inputManager.addListener(ac, "x+");
    inputManager.addListener(ac, "x-");
    inputManager.addListener(ac, "z+");
    inputManager.addListener(ac, "z-");
    inputManager.addListener(ac, "tab");
}
private final int velo = 50;
private float disx = 0;
private final float disy = 0;
private float disz = 0;

@Override
public void simpleUpdate(float tpf) {
    System.out.println("|-------------------|");
    System.out.println("locCAMERA"+cam.getLocation());
    System.out.println("rotCAMERA"+cam.getRotation());
    System.out.println("locSPATIAL"+spt.getLocalTranslation());
    System.out.println("|-------------------|");
    if (zma) {
        disx += tpf * velo;
        spt.setLocalTranslation(disx, disy, disz);
        cam.setLocation(new Vector3f(disx-10, disy + 10, disz));
        //spt.setLocalRotation(new Quaternion(0,90,0,1));
        cam.setRotation(Constants.zma);
    }
    if (zme) {
        disx -= tpf * velo;
        spt.setLocalTranslation(disx, disy, disz);
        cam.setLocation(new Vector3f(disx+10, disy + 10, disz));
        //spt.setLocalRotation(new Quaternion(0, 0, 0, 1));
        cam.setRotation(Constants.zme);
    }
    if (xma) {
        disz += tpf * velo;
        spt.setLocalTranslation(disx, disy, disz);
        spt.setLocalRotation(new Quaternion(0, 0, 0, 1));
        deb.setLocalTranslation(disx, disy+3, disz);
        cam.setFrustum(1f, 1000f, -0.6627417f, 0.6627417f, 0.41421357f, -0.41421357f);
        cam.setLocation(new Vector3f(disx + 2.4f, disy + 10, disz - 15));
    }
    if (xme) {
        disz -= tpf * velo;
        spt.setLocalTranslation(disx, disy, disz);
        spt.setLocalRotation(new Quaternion(0, 0, 180, 1));
        deb.setLocalTranslation(disx, disy+3, disz);
        cam.setFrustum(1f, 900f, -0.6627417f, 0.6627417f, 0.41421357f, -0.41421357f);
        cam.setLocation(new Vector3f(disx + 2.4f, disy + 10, disz + 15));
    }
}
boolean xma = false, xme = false, zma = false, zme = false;
private int a=2;
private int b=1;
private ActionListener ac = new ActionListener() {
    @Override
    public void onAction(String name, boolean keyPressed, float tpf) {
        if (!flyCam.isEnabled()) {
            if (name.equals("x+")) {
                xma = keyPressed;
            }
            if (name.equals("x-")) {
                xme = keyPressed;
            }
            if (name.equals("z+")) {
                zma = keyPressed;
            }
            if (name.equals("z-")) {
                zme = keyPressed;
            }
        }
        if (name.equals("tab")) {
            flyCam.setEnabled(true);
        }
    }

};

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.

:wink:

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.

http://javadoc.jmonkeyengine.org/

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!

2 Likes

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.