/** * <code>rotateUpTo</code> is a utility function that alters the local rotation to point the Y * axis in the direction given by newUp. * * @param newUp the up vector to use - assumed to be a unit vector. */ public void rotateUpTo(Vector3f newUp) { TempVars vars = TempVars.get(); Vector3f compVecA = vars.vect1; Quaternion q = vars.quat1; // First figure out the current up vector. Vector3f upY = compVecA.set(Vector3f.UNIT_Y); Quaternion rot = localTransform.getRotation(); rot.multLocal(upY); // get angle between vectors float angle = upY.angleBetween(newUp); // figure out rotation axis by taking cross product Vector3f rotAxis = upY.crossLocal(newUp).normalizeLocal(); // Build a rotation quat and apply current local rotation. q.fromAngleNormalAxis(angle, rotAxis); q.mult(rot, rot); vars.release(); setTransformRefresh(); }
/** * (Internal use only) Forces a refresh of the given types of data. * * @param transforms Refresh world transform based on parents' * @param bounds Refresh bounding volume data based on child nodes * @param lights Refresh light list based on parents' */ public void forceRefresh(boolean transforms, boolean bounds, boolean lights) { if (transforms) { setTransformRefresh(); } if (bounds) { setBoundRefresh(); } if (lights) { setLightListRefresh(); } }
/** * @return A clone of this Spatial, the scene graph in its entirety is cloned and can be altered * independently of the original scene graph. * <p>Note that meshes of geometries are not cloned explicitly, they are shared if static, or * specially cloned if animated. * <p>All controls will be cloned using the Control.cloneForSpatial method on the clone. * @see Mesh#cloneForAnim() */ public Spatial clone(boolean cloneMaterial) { try { Spatial clone = (Spatial) super.clone(); if (worldBound != null) { clone.worldBound = worldBound.clone(); } clone.worldLights = worldLights.clone(); clone.localLights = localLights.clone(); // Set the new owner of the light lists clone.localLights.setOwner(clone); clone.worldLights.setOwner(clone); // No need to force cloned to update. // This node already has the refresh flags // set below so it will have to update anyway. clone.worldTransform = worldTransform.clone(); clone.localTransform = localTransform.clone(); if (clone instanceof Node) { Node node = (Node) this; Node nodeClone = (Node) clone; nodeClone.children = new SafeArrayList<Spatial>(Spatial.class); for (Spatial child : node.children) { Spatial childClone = child.clone(cloneMaterial); childClone.parent = nodeClone; nodeClone.children.add(childClone); } } clone.parent = null; clone.setBoundRefresh(); clone.setTransformRefresh(); clone.setLightListRefresh(); clone.controls = new SafeArrayList<Control>(Control.class); for (int i = 0; i < controls.size(); i++) { Control newControl = controls.get(i).cloneForSpatial(clone); newControl.setSpatial(clone); clone.controls.add(newControl); } if (userData != null) { clone.userData = (HashMap<String, Savable>) userData.clone(); } return clone; } catch (CloneNotSupportedException ex) { throw new AssertionError(); } }
/** * <code>lookAt</code> is a convenience method for auto-setting the local rotation based on a * position in world space and an up vector. It computes the rotation to transform the z-axis to * point onto 'position' and the y-axis to 'up'. Unlike {@link * Quaternion#lookAt(com.jme3.math.Vector3f, com.jme3.math.Vector3f) } this method takes a world * position to look at and not a relative direction. * * <p>Note : 28/01/2013 this method has been fixed as it was not taking into account the parent * rotation. This was resulting in improper rotation when the spatial had rotated parent nodes. * This method is intended to work in world space, so no matter what parent graph the spatial has, * it will look at the given position in world space. * * @param position where to look at in terms of world coordinates * @param upVector a vector indicating the (local) up direction. (typically {0, 1, 0} in jME.) */ public void lookAt(Vector3f position, Vector3f upVector) { Vector3f worldTranslation = getWorldTranslation(); TempVars vars = TempVars.get(); Vector3f compVecA = vars.vect4; compVecA.set(position).subtractLocal(worldTranslation); getLocalRotation().lookAt(compVecA, upVector); if (getParent() != null) { Quaternion rot = vars.quat1; rot = rot.set(parent.getWorldRotation()).inverseLocal().multLocal(getLocalRotation()); rot.normalizeLocal(); setLocalRotation(rot); } vars.release(); setTransformRefresh(); }
/** * Rotates the spatial by the given rotation. * * @return The spatial on which this method is called, e.g <code>this</code>. */ public Spatial rotate(Quaternion rot) { this.localTransform.getRotation().multLocal(rot); setTransformRefresh(); return this; }
/** * Scales the spatial by the given scale vector. * * @return The spatial on which this method is called, e.g <code>this</code>. */ public Spatial scale(float x, float y, float z) { this.localTransform.getScale().multLocal(x, y, z); setTransformRefresh(); return this; }
/** * Translates the spatial by the given translation vector. * * @return The spatial on which this method is called, e.g <code>this</code>. */ public Spatial move(Vector3f offset) { this.localTransform.getTranslation().addLocal(offset); setTransformRefresh(); return this; }
/** * Translates the spatial by the given translation vector. * * @return The spatial on which this method is called, e.g <code>this</code>. */ public Spatial move(float x, float y, float z) { this.localTransform.getTranslation().addLocal(x, y, z); setTransformRefresh(); return this; }
/** <code>setLocalTransform</code> sets the local transform of this spatial. */ public void setLocalTransform(Transform t) { this.localTransform.set(t); setTransformRefresh(); }
/** <code>setLocalTranslation</code> sets the local translation of this spatial. */ public void setLocalTranslation(float x, float y, float z) { this.localTransform.setTranslation(x, y, z); setTransformRefresh(); }
/** * <code>setLocalTranslation</code> sets the local translation of this spatial. * * @param localTranslation the local translation of this spatial. */ public void setLocalTranslation(Vector3f localTranslation) { this.localTransform.setTranslation(localTranslation); setTransformRefresh(); }
/** * <code>setLocalScale</code> sets the local scale of this node. * * @param localScale the new local scale. */ public void setLocalScale(Vector3f localScale) { localTransform.setScale(localScale); setTransformRefresh(); }
/** <code>setLocalScale</code> sets the local scale of this node. */ public void setLocalScale(float x, float y, float z) { localTransform.setScale(x, y, z); setTransformRefresh(); }
/** * <code>setLocalScale</code> sets the local scale of this node. * * @param localScale the new local scale, applied to x, y and z */ public void setLocalScale(float localScale) { localTransform.setScale(localScale); setTransformRefresh(); }
/** * <code>setLocalRotation</code> sets the local rotation of this node. * * @param quaternion the new local rotation. */ public void setLocalRotation(Quaternion quaternion) { localTransform.setRotation(quaternion); setTransformRefresh(); }
/** * <code>setLocalRotation</code> sets the local rotation of this node by using a {@link Matrix3f}. * * @param rotation the new local rotation. */ public void setLocalRotation(Matrix3f rotation) { localTransform.getRotation().fromRotationMatrix(rotation); setTransformRefresh(); }