OK, this is my solution, if somebody would need the same in future:
[java]
package mygame;
// =================================================================
// Motivation:
// This Code Should ilustrate pilot camera in jMonkey 3
// camera orientation is controled both by mouse and by orientation of aircraft
// is should be useful for looking around from pilot cockpit
// The same is used in Il-2 Strurmovik simulator
//
// Technical:
// mouse rotation is stored in variables mouseX, mouseY set in onAnalog
// Camera is rotated manually in simpleUpdate()
// made by ProkopHapala email: ProkopHapala@gmail.com
// ===================================================================
import com.jme3.scene.Mesh;
import com.jme3.scene.shape.Dome;
import com.jme3.material.RenderState.FaceCullMode;
import com.jme3.math.ColorRGBA;
import com.jme3.util.SkyFactory;
import com.jme3.app.SimpleApplication;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.*;
import com.jme3.material.Material;
import com.jme3.math.FastMath;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
public class game extends SimpleApplication implements AnalogListener {
public static void main(String args[]) {
game app = new game();
app.start();
}
private Node aircraft_node;
private Quaternion Qcam, qtemp;
private float mouseX, mouseY;
@Override
public void simpleInitApp() {
cam.setFrustumFar(100000.0f); // aircraft simulator needs big view distance
makeAircraft( new Vector3f(0,0,0) );
registerInput();
rootNode.attachChild(SkyFactory.createSky(assetManager, “Textures/Sky/Bright/FullskiesBlueClear03.dds”, false));
//flyCam.setEnabled(false); // flyCam should stay on, otherwise mouse is restricted to window
qtemp = new Quaternion(); Qcam = new Quaternion();
}
public void registerInput() {
inputManager.addMapping(“W”, new KeyTrigger(keyInput.KEY_W));
inputManager.addMapping(“S”, new KeyTrigger(keyInput.KEY_S));
inputManager.addMapping(“D”, new KeyTrigger(keyInput.KEY_D));
inputManager.addMapping(“A”, new KeyTrigger(keyInput.KEY_A));
inputManager.addMapping(“E”, new KeyTrigger(keyInput.KEY_E));
inputManager.addMapping(“Q”, new KeyTrigger(keyInput.KEY_Q));
inputManager.addListener(this, “W”, “S”, “D”, “A”, “E”, “Q” );
inputManager.addMapping(“mouseXt”, new MouseAxisTrigger(MouseInput.AXIS_X, true));
inputManager.addMapping(“mouseXf”, new MouseAxisTrigger(MouseInput.AXIS_X, false));
inputManager.addMapping(“mouseYt”, new MouseAxisTrigger(MouseInput.AXIS_Y, true));
inputManager.addMapping(“mouseYf”, new MouseAxisTrigger(MouseInput.AXIS_Y, false));
inputManager.addListener(this, “mouseXt”, “mouseXf”, “mouseYt”, “mouseYf” );
}
public Quaternion rotateByAxis( Quaternion q, int i, float value ){
if (i==0) { q.multLocal( qtemp.fromAngleNormalAxis( value, Vector3f.UNIT_X ) ); return q; }
if (i==1) { q.multLocal( qtemp.fromAngleNormalAxis( value, Vector3f.UNIT_Y ) ); return q; }
if (i==2) { q.multLocal( qtemp.fromAngleNormalAxis( value, Vector3f.UNIT_Z ) ); return q; }
return q;
}
public void onAnalog(String name, float value, float tpf) {
if ( aircraft_node!=null){
if ( name.equals(“W” )){ aircraft_node.setLocalRotation( rotateByAxis(aircraft_node.getLocalRotation(), 0, -0.01f )); return; }
if ( name.equals(“S” )){ aircraft_node.setLocalRotation( rotateByAxis(aircraft_node.getLocalRotation(), 0, +0.01f )); return; }
if ( name.equals(“D” )){ aircraft_node.setLocalRotation( rotateByAxis(aircraft_node.getLocalRotation(), 1, -0.01f )); return; }
if ( name.equals(“A” )){ aircraft_node.setLocalRotation( rotateByAxis(aircraft_node.getLocalRotation(), 1, +0.01f )); return; }
if ( name.equals(“E” )){ aircraft_node.setLocalRotation( rotateByAxis(aircraft_node.getLocalRotation(), 2, +0.01f )); return; }
if ( name.equals(“Q” )){ aircraft_node.setLocalRotation( rotateByAxis(aircraft_node.getLocalRotation(), 2, -0.01f )); return; }
if ( name.equals(“mouseXt” )){ mouseX+=value; return; }
if ( name.equals(“mouseXf” )){ mouseX-=value; return; }
if ( name.equals(“mouseYt” )){ mouseY+=value; return; }
if ( name.equals(“mouseYf” )){ mouseY-=value; return; }
}
}
private Geometry putShape( Geometry g, ColorRGBA color, Node node){
Material mat = new Material(assetManager, “Common/MatDefs/Misc/Unshaded.j3md”);
mat.getAdditionalRenderState().setWireframe(true);
mat.setColor(“Color”, color);
mat.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
g.setMaterial(mat);
node.attachChild(g);
return g;
}
public void makeAircraft( Vector3f where ) {
aircraft_node = new Node(“aircraft_node”);
Mesh wing_mesh = new Dome(Vector3f.ZERO, 2, 3, 1f,false);
Geometry wing_geo = putShape( new Geometry(“wing”, wing_mesh ) , ColorRGBA.Green, aircraft_node);
wing_geo.rotate( 0, -FastMath.PI/6, 0 );
wing_geo.scale(1, 0.1f, 1);
aircraft_node.setLocalTranslation( where );
rootNode.attachChild(aircraft_node);
}
@Override
public void simpleUpdate(float tpf) {
if ((cam!=null) && (aircraft_node!=null) ){
Qcam.set(aircraft_node.getLocalRotation());
Qcam.multLocal(qtemp.fromAngleNormalAxis( mouseX, Vector3f.UNIT_Y ));
Qcam.multLocal(qtemp.fromAngleNormalAxis( mouseY, Vector3f.UNIT_X ));
cam.setRotation( Qcam );
cam.setLocation( aircraft_node.getLocalTranslation().subtract( cam.getDirection().mult(0) ) );
}
}
}
[/java]
The only thing which is a bit strange:
I need to keep flyCam enabled, because if I switch it off by flyCam.setEnabled(false); the mouse start to behave differently (cursor appear and mouse triggers are invoked only if the mouse curser is over the window of the game )… this could be set probably alos somehow.