Sphere Rotates around point

Hi!

I have recently attempted to rotate my globe using nodes instead of the actual model.

Due to this, my globe now seems to orbit around a point when trying to rotate it. I have attempted to set the local translation of both the model and the node to 0,0,0 , with no such luck of solving the issue. I want my globe to rotate around its center. This globe is the only 3D object in the game.

Here is the relevant code:
globe = assetManager.loadModel(“Models/World/World_Globe.obj”);

    globeGeometry = new Geometry();
          
    globeMaterial = new Material(assetManager,"Common/MatDefs/Misc/Unshaded.j3md");
    globeMaterial.setTexture("ColorMap", assetManager.loadTexture("Models/World/Globe_Txtr.png"));
    globe.setMaterial(globeMaterial);
    globe.setLocalTranslation(0,0,0);
    
    n.attachChild(globe); //Attach it to the node
    n.scale(0.01f); //Scale the globe down     
    n.setLocalTranslation(0,0,0);
    
    cam.lookAt(new Vector3f(0,0,0), Vector3f.UNIT_X);
    cam.update();

Sounds like the model itself is not centered.

http://hub.jmonkeyengine.org/javadoc/com/jme3/scene/Spatial.html#center()

…will center it based on its bounding shape. If you stick it under a node then and rotate the node then it should rotate about its center. Or you could fix the model itself if you got it from some other editor.

Kisses pspeed

Alright, now I have a different problem.

The globe rotates great horizontally!

But it seems I want the globe to rotate from and torwards the camera as the player rotates it. However, the y and z axis only rotate torwards two places on the sphere vertically. So if I take the difference in y on the users cursor and rotate it to, say, the z axis, the globe wont tilt torwards the way the player is facing the sphere. It’ll only tilt africa.

How can I get the sphere to rotate up and down along the part where the player sees the globe?

Do you rotate based on angles? or based on quaterions? or with the nifty rotate method?

I will post all of my code here:

[java]public void bind(Nifty NIFTY, Screen SCREEN) {

    nifty=NIFTY;
    screen=SCREEN;
    
    //I initialize a lot of Main variables.
    app = Main.getApplication();
    assetManager = app.getAssetManager();
    n = new Node("Globe");
    cam = app.getCamera();
    //We add the functionality necessary to let the player rotate the globe.
    inputManager = Main.getApplication().getInputManager();
    initKeys();
    
    //We are going to create the globe. 
    //<editor-fold defaultstate="collapsed" desc="It's 'Global'">        
    //In order to do this, first, we need to transform it to fit whatever device they're using.        
    //Here we create the actual sphere, with the radius being slightly smaller than the smallest side of whatever device is being used. 
    globe = assetManager.loadModel("Models/World/World_Globe.obj");
    
    globeGeometry = new Geometry();
          
    globeMaterial = new Material(assetManager,"Common/MatDefs/Misc/Unshaded.j3md");
    globeMaterial.setTexture("ColorMap", assetManager.loadTexture("Models/World/Globe_Txtr.png"));
    globe.setMaterial(globeMaterial);
    globe.setLocalTranslation(0,1,0);
    globe.center();
            
    n.attachChild(globe); //Attach it to the node
    n.scale(0.02f); //Scale the globe down     
    n.setLocalTranslation(0,1,0);
    
    cam.lookAt(new Vector3f(0,0,0), Vector3f.UNIT_Y);
    cam.update();
    //Now we must give it some light!
    //<editor-fold defaultstate="collapsed" desc="Light">
    DirectionalLight sun2 = new DirectionalLight();
    sun2.setDirection(new Vector3f(0,1,0).normalizeLocal());
    sun2.setColor(ColorRGBA.White);
    n.addLight(sun2);
    
    DirectionalLight sun3 = new DirectionalLight();
    sun3.setDirection(new Vector3f(0,0,1).normalizeLocal());
    sun3.setColor(ColorRGBA.White);
    n.addLight(sun3);
    
    DirectionalLight sun4 = new DirectionalLight();
    sun4.setDirection(new Vector3f(1,0,0).normalizeLocal());
    sun4.setColor(ColorRGBA.White);
    n.addLight(sun4);
    
    DirectionalLight sun5 = new DirectionalLight();
    sun5.setDirection(new Vector3f(-1,0,0).normalizeLocal());
    sun5.setColor(ColorRGBA.White);
    n.addLight(sun5);
    
    DirectionalLight sun6 = new DirectionalLight();
    sun6.setDirection(new Vector3f(0,-1,0).normalizeLocal());
    sun6.setColor(ColorRGBA.White);
    n.addLight(sun6);
    
    DirectionalLight sun7 = new DirectionalLight();
    sun7.setDirection(new Vector3f(0,0,-1).normalizeLocal());
    sun7.setColor(ColorRGBA.White);
    n.addLight(sun7);
    //</editor-fold>
    
    Main.getRN().attachChild(n); //Finally, attach the node to the root node.
    
    //</editor-fold>
}
@Override
public void update(float tpf) {
    
}
//<editor-fold defaultstate="collapsed" desc="Custom Keybinding: Map named actions to inputs.">
private void initKeys() {
    // The only input we need for android, touch. The engine automatically translates touch events into mouse events for Android, if you were wondering.
    // In fact, the engine can pretty much be used the same way as it were to be used on desktop, except that resolutions are different.
    inputManager.addMapping("Rotate",  new MouseButtonTrigger(MouseInput.BUTTON_LEFT));
    
    // Add the names to the touch listener.
    inputManager.addListener(touchMoveListener, new String[]{"Rotate"});
    inputManager.addListener(touchListener, new String[]{"Rotate"});
    
}
//<editor-fold defaultstate="collapsed" desc="Press Listener">
private ActionListener touchListener = new ActionListener() {
    @Override
    public void onAction(String name, boolean keyPressed, float tpf) {
        //This method is called every time the user either presses the device or stops pressing the device.
        //We need this so we can record an initial position for the mouse.
        if(keyPressed){
            MousePreviousPosition=inputManager.getCursorPosition().clone();
            applyAnalog = true;
        } else {
            applyAnalog = false;
        }
    }
    
};
//</editor-fold>
//<editor-fold defaultstate="collapsed" desc="Rotate Listener">
private AnalogListener touchMoveListener = new AnalogListener() {
    @Override
    public void onAnalog(String name, float value, float tpf) {
        if(applyAnalog){
            //This continuously rotates the earth in the direction the user swipes. 
            //In order to do this, we must take the previous position on the mouse
            MousePosition = inputManager.getCursorPosition().clone();
            
            //Rotate along the Y axis based on how far along the x axis the mouse has moved while he's touched the screen.
            n.rotate(0f,(MousePosition.x-MousePreviousPosition.x)/100,0f);
            System.out.println(n.getLocalRotation().getY());               
            
            
            MousePreviousPosition = MousePosition;
        }
  [/java]  }
};

As you can see, this is a seperate class from the Main class. I have given it functions to which I can retrieve the application and such.

Essentially, In this I render the globe in the Bind method and in the following methods I allow the player to left click and move their mouse left and right to rotate the sphere. The actual rotation comes in the analog function.

I rotate using the Node.rotate(x,y,z) function (I think that is using Quaternions). What I am trying to do is also to add the functionality for it to be rotated vertically, which, is harder, because the axis on which it rotates would have to be along the player’s view of the globe.