I wish geometry to rotate around it's center by mouse movement.
Similar like camera rotates in sample application.
The program below should rotate the cube on mouse moves horizontally. If mouse moves left, it should rotate left, if mouse moves right, it should rotate right.
Unfortunately, it always rotate right.
package jme3test.helloworld;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jme3.app.SimpleApplication;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.MouseAxisTrigger;
import com.jme3.material.Material;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.shape.Box;
import com.jme3.math.ColorRGBA;
public class HelloJME3_3 extends SimpleApplication {
private static final Logger log = LoggerFactory.getLogger(HelloJME3_3.class);
public static void main(String[] args){
HelloJME3_3 app = new HelloJME3_3();
app.start(); // start the game
}
@Override
public void simpleInitApp() {
Box b = new Box(1, 1, 1); // create cube shape
final Geometry geom = new Geometry("Box", b); // create cube geometry from the shape
Material mat = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md"); // create a simple material
mat.setColor("Color", ColorRGBA.Blue); // set color of material to blue
geom.setMaterial(mat); // set the cube's material
rootNode.attachChild(geom); // make the cube appear in the scene
flyCam.setEnabled(false);
inputManager.addMapping("RotateX",
new MouseAxisTrigger(MouseInput.AXIS_X, false),
new MouseAxisTrigger(MouseInput.AXIS_X, true)
);
inputManager.addListener(new AnalogListener() {
@Override
public void onAnalog(String name, float value, float tpf) {
log.debug(name);
if( "RotateX".equals(name) ) {
//geom.rotate((float) (value*speed), 0, 0);
geom.rotate(0, (float) (value*speed), 0);
}
}
}, "RotateX");
}
}
The problem here is that both positive and negative axis movements generate positive values for value
. Hence your object only rotates one way.
The simplest solution to this is to bind positive and negative axis movements separately and manage them separately.
public class HelloJME_3 extends SimpleApplication {
public static void main(String[] args){
HelloJME_3 app = new HelloJME_3();
app.start(); // start the game
}
@Override
public void simpleInitApp() {
Box b = new Box(1, 1, 1); // create cube shape
final Geometry geom = new Geometry("Box", b); // create cube geometry from the shape
Material mat = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md"); // create a simple material
mat.setColor("Color", ColorRGBA.Blue); // set color of material to blue
geom.setMaterial(mat); // set the cube's material
rootNode.attachChild(geom); // make the cube appear in the scene
flyCam.setEnabled(false);
inputManager.addMapping("RotateX",
new MouseAxisTrigger(MouseInput.AXIS_X, true)
);
inputManager.addMapping("RotateX_negative",
new MouseAxisTrigger(MouseInput.AXIS_X, false)
);
inputManager.addListener(new AnalogListener() {
@Override
public void onAnalog(String name, float value, float tpf) {
if( "RotateX".equals(name) ) {
geom.rotate(0, (float) (value*speed), 0);
}else if("RotateX_negative".equals(name)){
geom.rotate(0, (float) (-value*speed), 0);
}
}
}, "RotateX", "RotateX_negative");
}
}
You mentioned that you would like to create a rotation such that when the mouse is in the centre of the screen the object is unrotated. You can achieve this using the mouses screen coordinates.
inputManager.getCursorPosition();
This of course also requires you to set the rotation rather than rotating in addition to the current rotation (this takes a Quaternion argument but we largely don't have to worry about how that works.
Quaternion quat=new Quaternion();
quat.fromAngles(0, desiredAngle, 0);
geom.setLocalRotation(quat);
Of course when the mouse is initially captured the object will suddenly move to its "correct" position for wherever the mouse now is.
public class HelloJME_3 extends SimpleApplication {
public static float PIXELSMOVED_TO_RADIANSROTATED=0.01f;
public static void main(String[] args){
HelloJME_3 app = new HelloJME_3();
app.start(); // start the game
}
@Override
public void simpleInitApp() {
Box b = new Box(1, 1, 1); // create cube shape
final Geometry geom = new Geometry("Box", b); // create cube geometry from the shape
Material mat = new Material(assetManager,
"Common/MatDefs/Misc/Unshaded.j3md"); // create a simple material
mat.setColor("Color", ColorRGBA.Blue); // set color of material to blue
geom.setMaterial(mat); // set the cube's material
rootNode.attachChild(geom); // make the cube appear in the scene
flyCam.setEnabled(false);
inputManager.addMapping("MouseMoved",
new MouseAxisTrigger(MouseInput.AXIS_X, false),
new MouseAxisTrigger(MouseInput.AXIS_X, true)
);
inputManager.addListener(new AnalogListener() {
@Override
public void onAnalog(String name, float value, float tpf) {
inputManager.getCursorPosition();
float centredX=inputManager.getCursorPosition().x-0.5f*settings.getWidth();
Quaternion quat=new Quaternion();
quat.fromAngles(0, PIXELSMOVED_TO_RADIANSROTATED*centredX, 0);
geom.setLocalRotation(quat);
}
}, "MouseMoved");
}
}