extent = Math.max(xExtent, Math.max(yExtent, zExtent));
}
// Fetch the world translation for the root node of the cell and set
// the translation for this entity root node
Vector3f translation = sceneRoot.getWorldTranslation();
rootNode.setLocalTranslation(translation);
// Create a red arrow in the +x direction. We arrow we get back is
// pointed in the +y direction, so we rotate around the -z axis to
// orient the arrow properly.
xEntity = new Entity("Entity X");
xNode = createArrow("Arrow X", extent + LENGTH_OFFSET, THICKNESS, ColorRGBA.red);
Quaternion xRotation = new Quaternion().fromAngleAxis((float)Math.PI / 2, new Vector3f(0, 0, -1));
xNode.setLocalRotation(xRotation);
xNode.setLocalScale(new Vector3f(1.0f, LENGTH_SCALE, 1.0f));
xNode.setRenderState(zbuf);
addSubEntity(xEntity, xNode);
xListener = addDragListener(xEntity, xNode, TranslateAxis.X_AXIS);
// Create a green arrow in the +y direction. We arrow we get back is
// pointed in the +y direction.
yEntity = new Entity("Entity Y");
yNode = createArrow("Arrow Y", extent + LENGTH_OFFSET, THICKNESS, ColorRGBA.green);
yNode.setLocalScale(new Vector3f(1.0f, LENGTH_SCALE, 1.0f));
yNode.setRenderState(zbuf);
addSubEntity(yEntity, yNode);
yListener = addDragListener(yEntity, yNode, TranslateAxis.Y_AXIS);
// Create a red arrow in the +z direction. We arrow we get back is
// pointed in the +y direction, so we rotate around the +x axis to
// orient the arrow properly.
zEntity = new Entity("Entity Z");
zNode = createArrow("Arrow Z", extent + LENGTH_OFFSET, THICKNESS, ColorRGBA.blue);
Quaternion zRotation = new Quaternion().fromAngleAxis((float)Math.PI / 2, new Vector3f(1, 0, 0));
zNode.setLocalRotation(zRotation);
zNode.setRenderState(zbuf);
zNode.setLocalScale(new Vector3f(1.0f, LENGTH_SCALE, 1.0f));
addSubEntity(zEntity, zNode);
zListener = addDragListener(zEntity, zNode, TranslateAxis.Z_AXIS);
// Listen for changes to the cell's translation and apply the same
// update to the root node of the affordances. We also re-set the size
// of the affordances: this handles the case where the bounds of the
// scene graph has changed and we need to update the affordances
// accordingly.
sceneRoot.addGeometricUpdateListener(updateListener = new GeometricUpdateListener() {
public void geometricDataChanged(final Spatial spatial) {
// We need to perform this work inside a proper updater, to
// make sure we are MT thread safe
RenderUpdater u = new RenderUpdater() {
public void update(Object obj) {
Vector3f translation = spatial.getWorldTranslation();
rootNode.setLocalTranslation(translation);
setSizeInternal(currentScale);
ClientContextJME.getWorldManager().addToUpdateList(rootNode);
}
};