}
// Fetch the world translation for the root node of the cell and set
// the translation and rotation for this entity root node
Vector3f translation = sceneRoot.getWorldTranslation();
Quaternion rotation = sceneRoot.getWorldRotation();
rootNode.setLocalTranslation(translation);
rootNode.setLocalRotation(rotation);
float[] angles = new float[3];
rotation.toAngles(angles);
// Create a tube to rotate about the X axis. The tube is drawn in the
// X-Z plane, so we must rotate 90 degrees about the +z axis so that the
// axis of rotation is about +x axis.
xEntity = new Entity("Tube X");
xNode = createTube("Tube X", outerRadius, innerRadius, THICKNESS, ColorRGBA.red);
Quaternion xQ = new Quaternion().fromAngleAxis(1.5707f, new Vector3f(0, 0, 1));
xNode.setLocalRotation(xQ);
xNode.setLocalScale(new Vector3f(currentScale, 1.0f, currentScale));
xNode.setRenderState(zbuf);
addSubEntity(xEntity, xNode);
xListener = addRotateListener(xEntity, xNode, RotateAxis.X_AXIS);
// Create a tube to rotate about the Y axis. The tube is drawn in the
// X-Z plane already.
yEntity = new Entity("Tube Y");
yNode = createTube("Tube Y", outerRadius, innerRadius, THICKNESS, ColorRGBA.green);
yNode.setLocalScale(new Vector3f(currentScale, 1.0f, currentScale));
yNode.setRenderState(zbuf);
addSubEntity(yEntity, yNode);
yListener = addRotateListener(yEntity, yNode, RotateAxis.Y_AXIS);
// Create a tube to rotate about the Z axis. The tube is drawn in the
// X-Z plane, so we must rotate 90 degrees about the +x axis so that the
// axis of rotation is about +z axis.
zEntity = new Entity("Tube Z");
zNode = createTube("Tube Z", outerRadius, innerRadius, THICKNESS, ColorRGBA.blue);
Quaternion zQ = new Quaternion().fromAngleAxis(1.5707f, new Vector3f(1, 0, 0));
zNode.setLocalRotation(zQ);
zNode.setLocalScale(new Vector3f(currentScale, 1.0f, currentScale));
zNode.setRenderState(zbuf);
addSubEntity(zEntity, zNode);
zListener = addRotateListener(zEntity, zNode, RotateAxis.Z_AXIS);
// Listen for changes to the cell's translation and apply the same
// update to the root node of the affordances
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) {
// For the rotate affordance we need to move it whenever
// the cell is moved, but also need to rotate it when
// the cell rotation changes too. We also need to
// account for any changes to the size of the cell's
// scene graph, so we reset the size here to take care
// of that.
Vector3f translation = spatial.getWorldTranslation();
rootNode.setLocalTranslation(translation);
Quaternion rotation = spatial.getLocalRotation();
rootNode.setLocalRotation(rotation);
setSizeInternal(currentScale);
ClientContextJME.getWorldManager().addToUpdateList(rootNode);
}
};