SOLVED: must not forget to call addListener(listener, X) after you deleteMapping(X) then addMapping(X) again
===
That is, while inside the onAnalog() method of an AnalogListener instance,
if I delete the specified mapping “X” then try to add it again(ie. later) the addition has no effect ie. it’s not added or something
but if I don’t delete the mapping and I just add a new one ie. new key for same existing mapping then it works well,
However the add after delete works well when called within simpleInitApp() method
Is this intentional? I’d need this to my own camera class which would prevent mouse rotation inputs from being processed when some boolean is toggled, kind of what flyCam.setEnabled(false) would do except it just tests if !enabled and returns while in onAnalog() method but I figured it would be better to just remove the mappings while disabled, is this really not possible? or is it just a bug or likely I’m missing something?
The code below should demo this, run it then press Space to trigger the mapIncDelay mapping which will delete itself then add itself (while in onAnalog method) [but the add doesn’t work, remains deleted] and also it adds a new key (KEY_L) to a different mapping (which was never deleted) mapDecDelay which works(meaning add works when not preceded by a delete, all while inside onAnalog())
pre type="java"
package org.jme3.tests;
import com.jme3.app.SimpleApplication;
import com.jme3.font.BitmapText;
import com.jme3.input.FlyByCamera;
import com.jme3.input.KeyInput;
import com.jme3.input.controls.AnalogListener;
import com.jme3.input.controls.KeyTrigger;
import com.jme3.material.Material;
import com.jme3.math.ColorRGBA;
import com.jme3.math.FastMath;
import com.jme3.math.Matrix3f;
import com.jme3.math.Quaternion;
import com.jme3.math.Spline;
import com.jme3.math.Vector3f;
import com.jme3.scene.Geometry;
import com.jme3.scene.Mesh;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial.CullHint;
import com.jme3.scene.debug.Arrow;
import com.jme3.scene.debug.Grid;
import com.jme3.scene.shape.Box;
import com.jme3.scene.shape.Curve;
import com.jme3.system.AppSettings;
/**
- Sample 2 - How to use nodes as handles to manipulate objects in the scene
- graph. You can rotate, translate, and scale objects by manipulating their
- parent nodes. The Root Node is special: Only what is attached to the Root
- Node appears in the scene.
/
public class HelloNode6 extends SimpleApplication {
private static final float moveSpeed = 1f;
private static final float rotSpeed = 2f;
private static final float yawSpeed = 4f;
private static final float rollSpeed = 7f;
private static final float pitchSpeed = 11f;
private Vector3f cornerPos;
private Geometry geoCurve;
private Geometry geoBox;
private final Spline spline = new Spline();
private Node coord;
private Box box;
private final Vector3f centerOfBox = new Vector3f();
private final Quaternion qRotation = new Quaternion();
float yaw = 0f;
float roll = 0f;
float pitch = 0f;
private final String mapIncDelay = “IncDelay”;
private final String mapDecDelay = “DecDelay”;
long sleep = 0;
private float fpsNow;
private float maxSeenFps = 30;
private static final long sleepIncrement = 100;
private BitmapText helloText;
private final String mapRollRight = “rollRight”;
private final String mapRollLeft = “rollLeft”;
public static void main(String[] args) {
HelloNode6 app = new HelloNode6();
AppSettings aSet = new AppSettings(true);
aSet.setVSync(true);
app.setSettings(aSet);
app.setShowSettings(false);
app.start();
}
/
- (non-Javadoc)
-
-
@see com.jme3.app.SimpleApplication#simpleUpdate(float)
*/
@Override
public void simpleUpdate(float tpf) {
yaw = (yaw + FastMath.DEG_TO_RAD * rotSpeed * yawSpeed * tpf)
% (FastMath.PI * 2);
roll = (roll + FastMath.DEG_TO_RAD * rotSpeed * rollSpeed * tpf)
% (FastMath.PI * 2);
pitch = (pitch + FastMath.DEG_TO_RAD * rotSpeed * pitchSpeed * tpf)
% (FastMath.PI * 2);
qRotation.fromAngles(yaw, roll, pitch);
// rotating the box to these absolute angles (from its origin pos)
geoBox.setLocalRotation(qRotation);
// move box “forward” too, that is, forward relative to itself ie.
// spaceship moving forward
geoBox.move(geoBox.getLocalRotation().getRotationColumn(2)
.mult(moveSpeed * tpf));
Vector3f clonedCornerPos = cornerPos.clone();
// now applying the same transform (pos/rot/scale) to the corner as the
// box has
// clonedCornerPos =
geoBox.getLocalTransform().transformVector(clonedCornerPos,// in,
clonedCornerPos// store
);
geoBox.getLocalTransform().transformVector(box.getCenter().clone(),
centerOfBox);
// same orientation as Box
coord.setLocalTransform(geoBox.getLocalTransform());
// move coord system at center of Box
coord.setLocalTranslation(centerOfBox);
// we have the corner’s exact pos now, relative to the Node the geoBox &
// geoCurve are both in
// we add that pos to the curve
spline.addControlPoint(clonedCornerPos);// must be cloned!
// we must create new Curve object because we can’t add/update the
// spline in existing one (?!)
fpsNow = timer.getFrameRate();
if (fpsNow > maxSeenFps) {
maxSeenFps = fpsNow;
}
int subSegments = (int) Math.floor(maxSeenFps / fpsNow);
geoCurve.setMesh(new Curve(spline, subSegments));
helloText.setText("MaxSeenFps: " + (int) Math.ceil(maxSeenFps)
- (non-Javadoc)
- " / subSegs: " + subSegments);
try {
Thread.sleep(sleep);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void initGUI() {
// guiFont =
// assetManager.loadFont( “Interface/Fonts/Default.fnt” );
helloText = new BitmapText(guiFont, false);
helloText.setSize(guiFont.getCharSet().getRenderedSize());
helloText.setLocalTranslation(300, helloText.getLineHeight(), 0);
guiNode.attachChild(helloText);
}
private void initKeys() {
inputManager
.addMapping(mapIncDelay, new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.deleteMapping(mapIncDelay);
// XXX:here it works well: del then add
inputManager
.addMapping(mapIncDelay, new KeyTrigger(KeyInput.KEY_SPACE));
inputManager.addMapping(mapDecDelay, new KeyTrigger(
KeyInput.KEY_LCONTROL));
inputManager.addMapping(mapRollRight, new KeyTrigger(KeyInput.KEY_E));
inputManager.addMapping(mapRollLeft, new KeyTrigger(KeyInput.KEY_Q));
inputManager.addListener(analogListener, mapIncDelay, mapDecDelay,
mapRollRight, mapRollLeft);
inputManager.deleteMapping(“FLYCAM_Rise”);// delete prev. Q mapping
// (the lame way)
}
/**
- from {@link FlyByCamera#rotateCamera(float, Vector3f)} which is
- protected, copied it here
-
-
@param value
-
@param axis
*/
protected void rotateCamera(float value, Vector3f axis) {
Matrix3f mat = new Matrix3f();
mat.fromAngleNormalAxis(
// flyCam.rotationSpeed//can’t use it not visible
1f * 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.normalize();
cam.setAxes(q);
}
private final AnalogListener analogListener = new AnalogListener() {
@Override
public void onAnalog(String name, float value, float tpf) {
if (mapRollRight == name) {
System.out.println(mapRollRight);
rotateCamera(value, cam.getDirection());
return;
}
if (mapRollLeft == name) {
System.out.println(mapRollLeft);
rotateCamera(-value, cam.getDirection());
return;
}
if (mapIncDelay == name) {
System.out.println(“in mapIncDelay analog”);
sleep += sleepIncrement;
inputManager.deleteMapping(mapIncDelay);
// XXX:here it deletes it forever, can’t add:
inputManager.addMapping(mapIncDelay, new KeyTrigger(
KeyInput.KEY_SPACE));
// XXX: the add above has no effect
// but the following add works for decrement delay below
inputManager.addMapping(mapDecDelay, new KeyTrigger(
KeyInput.KEY_L));
}
if (mapDecDelay == name) {
if (sleep > 0) {
sleep -= sleepIncrement;
}
if (sleep < 0) {
sleep = 0;
}
}
System.out.println(“Sleep now at:” + sleep);
}
};
@Override
public void simpleInitApp() {
flyCam.setMoveSpeed(20f);
Node subNode = new Node();
subNode.setLocalTranslation(new Vector3f(2, 0.5f, 1));
subNode.rotate(1f, -2f, 4f);
// a box with non 0,0,0 center which means a position of x,y,z relative
// to it’s parent geoBox(below)
box = new Box(new Vector3f(2, 3, 4), 0.5f, 0.9f, 1.3f);
geoBox = new Geometry(“Box”, box);
geoBox.setLocalTranslation(1f, 2f, 3f);
geoBox.scale(1.3f, 1.2f, 1.1f);// always ok
geoBox.rotate(2f, -4f, 0.4f);
Material mat2 = new Material(assetManager,
“Common/MatDefs/Misc/WireColor.j3md”);
mat2.setColor(“Color”, ColorRGBA.Red);
geoBox.setMaterial(mat2);
Material curveMat = new Material(assetManager,
“Common/MatDefs/Misc/WireColor.j3md”);
curveMat.setColor(“Color”, ColorRGBA.Green);
geoCurve = new Geometry(“trails”);
geoCurve.setMaterial(curveMat);
subNode.attachChild(geoCurve);
subNode.attachChild(geoBox);
rootNode.setLocalTranslation(-1, -2, -4);
rootNode.rotate(-1f, 2f, -4f);
rootNode.attachChild(subNode);
rootNode.scale(1.5f);// this is always ok
subNode.scale(0.4f);// this is always ok too
// subNode.scale(1.3f, 0.7f, 0.4f);// XXX: bug when uncommented
// rootNode.scale(0.4f, 1.4f, 1.1f);// XXX: or/and this
// doing this here only once
cornerPos = new Vector3f();
// calculating position of corner, first getting corner as it were if
// box were at 0,0,0 and no rotation/scale
cornerPos.set(
box.getXExtent(), box.getYExtent(), box.getZExtent());
// now considering box may have a different than 0,0,0 center
cornerPos.addLocal(box.getCenter());
coord = new Node();
coord.setCullHint(CullHint.Never);
attachCoordinateAxes(Vector3f.ZERO, coord);
subNode.attachChild(coord);
// coord.setLocalTranslation( geoBox.getLocalTranslation() );//
// box.getCenter() );
initKeys();
initGUI();
attachGrid(Vector3f.ZERO, 100, ColorRGBA.Yellow);
}
private void attachCoordinateAxes(Vector3f pos, Node toNode) {
Arrow arrow = new Arrow(Vector3f.UNIT_X);
// make arrow thicker,
arrow.setLineWidth(1);
putShape(arrow, ColorRGBA.Red, toNode).setLocalTranslation(pos);
arrow = new Arrow(Vector3f.UNIT_Y);
arrow.setLineWidth(1); // make arrow thicker
putShape(arrow, ColorRGBA.Green, toNode).setLocalTranslation(pos);
arrow = new Arrow(Vector3f.UNIT_Z);
arrow.setLineWidth(1); // make arrow thicker
putShape(arrow, ColorRGBA.Blue, toNode).setLocalTranslation(pos);
}
private Geometry putShape(Mesh shape, ColorRGBA color, Node onNode) {
Geometry g = new Geometry(“coordinate axis”, shape);
Material mat = new Material(assetManager,
“Common/MatDefs/Misc/Unshaded.j3md”);
mat.getAdditionalRenderState().setWireframe(true);
mat.setColor(“Color”, color);
g.setMaterial(mat);
onNode.attachChild(g);
g.setCullHint(CullHint.Inherit);
return g;
}
private Geometry attachGrid(Vector3f pos, int size, ColorRGBA color) {
Geometry g = new Geometry(“wireframe grid”, new Grid(size, size, 1f));
Material mat = new Material(assetManager,
“Common/MatDefs/Misc/Unshaded.j3md”);
mat.getAdditionalRenderState().setWireframe(true);
mat.setColor(“Color”, color);
g.setMaterial(mat);
g.center().move(pos);
rootNode.attachChild(g);
return g;
}
}
/pre
- from {@link FlyByCamera#rotateCamera(float, Vector3f)} which is