dragToRotate

Hello
Sorry, because my english is really bad
I have 2 simple class (modifications of simpleapplication and flybycamera).

If I click MouseInput.BUTTON_LEFT:
canRotate = true,
rotateCamera() working;
if i release MouseInput.BUTTON_LEFT:
canRotate = false,
rotateCamera() not working;

If I click KeyInput.KEY_SPACE:
canRotate = true,
rotateCamera() working only 1 moment;
if i release KeyInput.KEY_SPACE:
canRotate = false,
rotateCamera() not working;

why?

and again sorry for my english
ICQ:288577163
Skype:Alex_Farg

[java]package farg;

import com.jme3.app.Application;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.queue.RenderQueue.Bucket;
import com.jme3.scene.Geometry;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.Spatial.CullHint;
import com.jme3.scene.shape.Box;
import com.jme3.system.AppSettings;
import com.jme3.system.JmeContext.Type;
import com.jme3.util.BufferUtils;

import farg.data.AlFaFlyCamera;

public class AlFaTactics extends Application {

public static void main(String[] args) {
	AlFaTactics app = new AlFaTactics();
    app.start();
}

protected float secondCounter = 0.0f;

// создание рут и гуи нодов
protected Node rootNode = new Node("Root Node");
protected Node guiNode = new Node("Gui Node");

// создание каменры
protected AlFaFlyCamera flyCam;
// отключение запроса парамметров
protected boolean showSettings = false;

// создание класса лисенера
private class AppActionListener implements ActionListener {
    public void onAction(String name, boolean value, float tpf) {
        if (!value)
            return;

        if (name.equals("SIMPLEAPP_Exit")) {
        	stop();
        } else if (name.equals("SIMPLEAPP_CameraPos")) {
            if (cam != null){
                Vector3f loc = cam.getLocation();
                Quaternion rot = cam.getRotation();
                System.out.println("Camera Position: ("+
                        loc.x+", "+loc.y+", "+loc.z+")");
                System.out.println("Camera Rotation: "+rot);
                System.out.println("Camera Direction: "+cam.getDirection());
            }
        } else if (name.equals("SIMPLEAPP_Memory")) {
            BufferUtils.printCurrentDirectMemory(null);
        }
    }
}
// создание экземпляра лисенера
private AppActionListener actionListener = new AppActionListener();

public void addInputMapping() {
	inputManager.addMapping("SIMPLEAPP_Exit", new KeyTrigger(KeyInput.KEY_ESCAPE));
    inputManager.addListener(actionListener, "SIMPLEAPP_Exit");
}

public void start(){
    // set some default settings in-case
    // settings dialog is not shown
    if (settings == null)
        setSettings(new AppSettings(true));

    // show settings dialog
    /*
    if (showSettings){
        if (!JmeSystem.showSettingsDialog(settings))
            return;
    }
	*/
    super.start();
}

public AlFaTactics(){
    super();
}

public AlFaFlyCamera getAlFaFlyCamera() {
    return flyCam;
}

public Node getGuiNode() {
    return guiNode;
}

public Node getRootNode() {
    return rootNode;
}

public boolean isShowSettings() {
    return showSettings;
}

public void setShowSettings(boolean showSettings) {
    this.showSettings = showSettings;
}

@Override
public void initialize(){
    super.initialize();

    guiNode.setQueueBucket(Bucket.Gui);
    guiNode.setCullHint(CullHint.Never);
    viewPort.attachScene(rootNode);
    guiViewPort.attachScene(guiNode);
    
    
    if (inputManager != null){
        flyCam = new AlFaFlyCamera(cam);
        flyCam.setMoveSpeed(10f);
        flyCam.registerWithInput(inputManager);

        if (context.getType() == Type.Display)
            inputManager.addMapping("SIMPLEAPP_Exit", new KeyTrigger(KeyInput.KEY_ESCAPE));
        
        inputManager.addMapping("SIMPLEAPP_CameraPos", new KeyTrigger(KeyInput.KEY_C));
        inputManager.addMapping("SIMPLEAPP_Memory", new KeyTrigger(KeyInput.KEY_M));
        inputManager.addListener(actionListener, "SIMPLEAPP_Exit",
                                 "SIMPLEAPP_CameraPos", "SIMPLEAPP_Memory");
    }
    
    
    // addInputMapping();
    
    // call user code
    simpleInitApp();
}

@Override
public void update() {
    if (speed == 0 || paused)
        return;
    
    super.update();
    float tpf = timer.getTimePerFrame() * speed;

    secondCounter += timer.getTimePerFrame();
    int fps = (int) timer.getFrameRate();
    if (secondCounter >= 1.0f){
        // fpsText.setText("Frames per second: "+fps);
        secondCounter = 0.0f;
    }

    // update states
    stateManager.update(tpf);

    // simple update and root node
    // simpleUpdate(tpf);
    rootNode.updateLogicalState(tpf);
    guiNode.updateLogicalState(tpf);
    rootNode.updateGeometricState();
    guiNode.updateGeometricState();

    // render states
    stateManager.render(renderManager);
    renderManager.render(tpf, true);
}

public void simpleInitApp() {
	Box bx = new Box(Vector3f.ZERO, 10, 1, 1);
	Geometry gx = new Geometry("X Blue", bx);
    Material matx = new Material(assetManager,
      "Common/MatDefs/Misc/Unshaded.j3md");
    matx.setColor("Color", ColorRGBA.Blue);
    gx.setMaterial(matx);
    rootNode.attachChild(gx);
    
    Box by = new Box(Vector3f.ZERO, 1, 10, 1);
	Geometry gy = new Geometry("Y Red", by);
    Material maty = new Material(assetManager,
      "Common/MatDefs/Misc/Unshaded.j3md");
    maty.setColor("Color", ColorRGBA.Red);
    gy.setMaterial(maty);
    rootNode.attachChild(gy);
    
    Box bz = new Box(Vector3f.ZERO, 1, 1, 10);
	Geometry gz = new Geometry("Z White", bz);
    Material matz = new Material(assetManager,
      "Common/MatDefs/Misc/Unshaded.j3md");
    matz.setColor("Color", ColorRGBA.White);
    gz.setMaterial(matz);
    rootNode.attachChild(gz);
}

}
[/java]

[java]package farg.data;

import com.jme3.collision.MotionAllowedListener;
import com.jme3.input.FlyByCamera;
import com.jme3.input.InputManager;
import com.jme3.input.JoyInput;
import com.jme3.input.Joystick;
import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.controls.ActionListener;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.input.controls.MouseAxisTrigger;
import com.jme3.input.controls.MouseButtonTrigger;
import com.jme3.math.FastMath;
import com.jme3.math.Matrix3f;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.Camera;

public class AlFaFlyCamera implements AnalogListener, ActionListener {
protected Camera cam;
protected Vector3f initialUpVec;
protected float rotationSpeed = 1f;
protected float moveSpeed = 3f;
protected MotionAllowedListener motionAllowed = null;
protected boolean enabled = true;
protected boolean dragToRotate = true;
protected boolean canRotate = false;
protected InputManager inputManager;

public AlFaFlyCamera(Camera cam){
    this.cam = cam;
    initialUpVec = cam.getUp().clone();
}

/**
 * Sets the up vector that should be used for the camera.
 * @param upVec
 */
public void setUpVector(Vector3f upVec) {
   initialUpVec.set(upVec);
}

public void setMotionAllowedListener(MotionAllowedListener listener){
    this.motionAllowed = listener;
}

/**
 * Sets the move speed. The speed is given in world units per second.
 * @param moveSpeed
 */
public void setMoveSpeed(float moveSpeed){
    this.moveSpeed = moveSpeed;
}

/**
 * Sets the rotation speed.
 * @param rotationSpeed
 */
public void setRotationSpeed(float rotationSpeed){
    this.rotationSpeed = rotationSpeed;
}

/**
 * @param enable If false, the camera will ignore input.
 */
public void setEnabled(boolean enable){
    if (enabled && !enable){
        if (!dragToRotate || (dragToRotate && canRotate)){
            inputManager.setCursorVisible(true);
        }
    }
    enabled = enable;
}

/**
 * @return If enabled
 * @see FlyByCamera#setEnabled(boolean)
 */
public boolean isEnabled(){
    return enabled;
}

/**
 * @return If drag to rotate feature is enabled.
 *
 * @see FlyByCamera#setDragToRotate(boolean) 
 */
public boolean isDragToRotate() {
    return dragToRotate;
}

/**
 * @param dragToRotate When true, the user must hold the mouse button
 * and drag over the screen to rotate the camera, and the cursor is
 * visible until dragged. Otherwise, the cursor is invisible at all times
 * and holding the mouse button is not needed to rotate the camera.
 * This feature is disabled by default.
 */
public void setDragToRotate(boolean dragToRotate) {
    this.dragToRotate = dragToRotate;
    inputManager.setCursorVisible(dragToRotate);
}

/**
 * Registers the FlyByCamera to receive input events from the provided
 * Dispatcher.
 * @param dispacher
 */
public void registerWithInput(InputManager inputManager){
    this.inputManager = inputManager;
    
    String[] mappings = new String[]{
        "FLYCAM_Left",
        "FLYCAM_Right",
        "FLYCAM_Up",
        "FLYCAM_Down",

        "FLYCAM_StrafeLeft",
        "FLYCAM_StrafeRight",
        "FLYCAM_Forward",
        "FLYCAM_Backward",

        "FLYCAM_ZoomIn",
        "FLYCAM_ZoomOut",
        "FLYCAM_RotateDrag",

        "FLYCAM_Rise",
        "FLYCAM_Lower"
    };

    // both mouse and button - rotation of cam
    inputManager.addMapping("FLYCAM_Left", new MouseAxisTrigger(MouseInput.AXIS_X, true),
                                           new KeyTrigger(KeyInput.KEY_LEFT));

    inputManager.addMapping("FLYCAM_Right", new MouseAxisTrigger(MouseInput.AXIS_X, false),
                                            new KeyTrigger(KeyInput.KEY_RIGHT));

    inputManager.addMapping("FLYCAM_Up", new MouseAxisTrigger(MouseInput.AXIS_Y, false),
                                         new KeyTrigger(KeyInput.KEY_UP));

    inputManager.addMapping("FLYCAM_Down", new MouseAxisTrigger(MouseInput.AXIS_Y, true),
                                           new KeyTrigger(KeyInput.KEY_DOWN));

    // mouse only - zoom in/out with wheel, and rotate drag
    inputManager.addMapping("FLYCAM_ZoomIn", new MouseAxisTrigger(MouseInput.AXIS_WHEEL, false));
    inputManager.addMapping("FLYCAM_ZoomOut", new MouseAxisTrigger(MouseInput.AXIS_WHEEL, true));
    inputManager.addMapping("FLYCAM_RotateDrag", new MouseButtonTrigger(MouseInput.BUTTON_LEFT), new KeyTrigger(KeyInput.KEY_SPACE));

    // keyboard only WASD for movement and WZ for rise/lower height
    inputManager.addMapping("FLYCAM_StrafeLeft", new KeyTrigger(KeyInput.KEY_A));
    inputManager.addMapping("FLYCAM_StrafeRight", new KeyTrigger(KeyInput.KEY_D));
    inputManager.addMapping("FLYCAM_Forward", new KeyTrigger(KeyInput.KEY_W));
    inputManager.addMapping("FLYCAM_Backward", new KeyTrigger(KeyInput.KEY_S));
    inputManager.addMapping("FLYCAM_Rise", new KeyTrigger(KeyInput.KEY_Q));
    inputManager.addMapping("FLYCAM_Lower", new KeyTrigger(KeyInput.KEY_Z));

    inputManager.addListener(this, mappings);
    inputManager.setCursorVisible(dragToRotate);
}

protected void rotateCamera(float value, Vector3f axis){
    /*
	if (dragToRotate){
        if (canRotate){

// value = -value;
}else{
return;
}
}
*/

    Matrix3f mat = new Matrix3f();
    mat.fromAngleNormalAxis(rotationSpeed * value, axis);

    Vector3f up = cam.getUp();
    Vector3f left = cam.getLeft();
    Vector3f dir = cam.getDirection();
    
    mat.mult(up, up);
    mat.mult(left, left);
    mat.mult(dir, dir);

    Quaternion q = new Quaternion();
    q.fromAxes(left, up, dir);
    q.norm();

    cam.setAxes(q);
}

protected void zoomCamera(float value){
    // derive fovY value
    float h = cam.getFrustumTop();
    float w = cam.getFrustumRight();
    float aspect = w / h;

    float near = cam.getFrustumNear();

    float fovY = FastMath.atan(h / near)
              / (FastMath.DEG_TO_RAD * .5f);
    fovY += value * 0.1f;

    h = FastMath.tan( fovY * FastMath.DEG_TO_RAD * .5f) * near;
    w = h * aspect;

    cam.setFrustumTop(h);
    cam.setFrustumBottom(-h);
    cam.setFrustumLeft(-w);
    cam.setFrustumRight(w);
}

protected void riseCamera(float value){
    Vector3f vel = new Vector3f(0, value * moveSpeed, 0);
    Vector3f pos = cam.getLocation().clone();

    if (motionAllowed != null)
        motionAllowed.checkMotionAllowed(pos, vel);
    else
        pos.addLocal(vel);

    cam.setLocation(pos);
}

protected void moveCamera(float value, boolean sideways){
    Vector3f vel = new Vector3f();
    Vector3f pos = cam.getLocation().clone();

    if (sideways){
        cam.getLeft(vel);
    }else{
        cam.getDirection(vel);
    }
    vel.multLocal(value * moveSpeed);

    if (motionAllowed != null)
        motionAllowed.checkMotionAllowed(pos, vel);
    else
        pos.addLocal(vel);

    cam.setLocation(pos);
}

public void onAnalog(String name, float value, float tpf) {
    if (!enabled)
        return;

    if (name.equals("FLYCAM_Left")){
        rotateCamera(value, initialUpVec);
    }else if (name.equals("FLYCAM_Right")){
        rotateCamera(-value, initialUpVec);
    }else if (name.equals("FLYCAM_Up")){
        rotateCamera(-value, cam.getLeft());
    }else if (name.equals("FLYCAM_Down")){
        rotateCamera(value, cam.getLeft());
    }else if (name.equals("FLYCAM_Forward")){
        moveCamera(value, false);
    }else if (name.equals("FLYCAM_Backward")){
        moveCamera(-value, false);
    }else if (name.equals("FLYCAM_StrafeLeft")){
        moveCamera(value, true);
    }else if (name.equals("FLYCAM_StrafeRight")){
        moveCamera(-value, true);
    }else if (name.equals("FLYCAM_Rise")){
        riseCamera(value);
    }else if (name.equals("FLYCAM_Lower")){
        riseCamera(-value);
    }else if (name.equals("FLYCAM_ZoomIn")){
        zoomCamera(value);
    }else if (name.equals("FLYCAM_ZoomOut")){
        zoomCamera(-value);
    }
}

public void onAction(String name, boolean value, float tpf) {
    if (!enabled)
        return;

    if (name.equals("FLYCAM_RotateDrag") && dragToRotate){
        canRotate = value;
        inputManager.setCursorVisible(!value);
        
        if (canRotate) {
        	System.out.println("true");
        } else {
        	System.out.println("false");
        }
    }
    
}

}[/java]