spatial.java
来自「java 3d game jme 工程开发源代码」· Java 代码 · 共 1,773 行 · 第 1/4 页
JAVA
1,773 行
/*
* Copyright (c) 2003-2009 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme.scene;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Stack;
import com.jme.bounding.BoundingVolume;
import com.jme.intersection.CollisionResults;
import com.jme.intersection.PickResults;
import com.jme.math.Matrix3f;
import com.jme.math.Matrix4f;
import com.jme.math.Quaternion;
import com.jme.math.Ray;
import com.jme.math.Vector3f;
import com.jme.renderer.Camera;
import com.jme.renderer.Renderer;
import com.jme.scene.state.RenderState;
import com.jme.system.DisplaySystem;
import com.jme.util.export.InputCapsule;
import com.jme.util.export.JMEExporter;
import com.jme.util.export.JMEImporter;
import com.jme.util.export.OutputCapsule;
import com.jme.util.export.Savable;
/**
* <code>Spatial</code> defines the base class for scene graph nodes. It
* maintains a link to a parent, it's local transforms and the world's
* transforms. All other nodes, such as <code>Node</code> and
* <code>Geometry</code> are subclasses of <code>Spatial</code>.
*
* @author Mark Powell
* @author Joshua Slack
* @version $Revision: 4091 $, $Data$
*/
public abstract class Spatial implements Serializable, Savable {
/**
* Describes how to combine textures from ancestor texturestates when an
* updateRenderState is called on a Spatial.
*
* @author Joshua Slack
*/
public enum TextureCombineMode {
/** When updating render states, turn off texturing for this spatial. */
Off,
/**
* Combine textures starting from the root node and working towards the
* given Spatial. Ignore disabled states.
*/
CombineFirst,
/**
* Combine textures starting from the given Spatial and working towards
* the root. Ignore disabled states. (Default)
*/
CombineClosest,
/**
* Similar to CombineClosest, but if a disabled state is encountered, it
* will stop combining at that point.
*/
CombineClosestEnabled,
/** Inherit mode from parent. */
Inherit,
/** Do not combine textures, just use the most recent texture state. */
Replace;
}
/**
* Describes how to combine lights from ancestor lightstates when an
* updateRenderState is called on a Spatial.
*
* @author Joshua Slack
*/
public enum LightCombineMode {
/** When updating render states, turn off lighting for this spatial. */
Off,
/**
* Combine lights starting from the root node and working towards the
* given Spatial. Ignore disabled states. Stop combining when lights ==
* MAX_LIGHTS_ALLOWED
*/
CombineFirst,
/**
* Combine lights starting from the given Spatial and working up towards
* the root. Ignore disabled states. Stop combining when lights ==
* MAX_LIGHTS_ALLOWED
*/
CombineClosest,
/**
* Similar to CombineClosest, but if a disabled state is encountered, it
* will stop combining at that point. Stop combining when lights ==
* MAX_LIGHTS_ALLOWED
*/
CombineClosestEnabled,
/** Inherit mode from parent. */
Inherit,
/** Do not combine lights, just use the most recent light state. */
Replace;
}
public enum CullHint {
/** Do whatever our parent does. If no parent, we'll default to dynamic. */
Inherit,
/**
* Do not draw if we are not at least partially within the view frustum
* of the renderer's camera.
*/
Dynamic,
/** Always cull this from view. */
Always,
/**
* Never cull this from view. Note that we will still get culled if our
* parent is culled.
*/
Never;
}
public enum NormalsMode {
/**
* Do whatever our parent does. If no parent, we'll default to
* NormalizeIfScaled.
*/
Inherit,
/** Send through the normals currently set as-is. */
UseProvided,
/**
* Tell the card to normalize any normals data we might give it for this
* Spatial.
*/
AlwaysNormalize,
/**
* If this Spatial is scaled other than 1,1,1 then tell the card to
* normalize any normals data we might give it.
*/
NormalizeIfScaled,
/**
* Do not send normal data to the card for this Spatial, even if we have
* some.
*/
Off;
}
public static final int LOCKED_NONE = 0;
public static final int LOCKED_BOUNDS = 1;
public static final int LOCKED_MESH_DATA = 2;
public static final int LOCKED_TRANSFORMS = 4;
public static final int LOCKED_SHADOWS = 8;
public static final int LOCKED_BRANCH = 16;
/**
* A flag indicating how normals should be treated by the renderer.
*/
protected NormalsMode normalsMode = NormalsMode.Inherit;
/**
* A flag indicating if scene culling should be done on this object by
* inheritance, dynamically, never, or always.
*/
protected CullHint cullHint = CullHint.Inherit;
/** Spatial's bounding volume relative to the world. */
protected BoundingVolume worldBound;
/** The render states of this spatial. */
protected RenderState[] renderStateList;
protected int renderQueueMode = Renderer.QUEUE_INHERIT;
/** Used to determine draw order for ortho mode rendering. */
protected int zOrder = 0;
/**
* Used to indicate this spatial (and any below it in the case of Node) is
* locked against certain changes.
*/
protected int lockedMode = LOCKED_NONE;
/**
* Flag signaling how lights are combined for this node. By default set to
* INHERIT.
*/
protected LightCombineMode lightCombineMode = LightCombineMode.Inherit;
/**
* Flag signaling how textures are combined for this node. By default set to
* INHERIT.
*/
protected TextureCombineMode textureCombineMode = TextureCombineMode.Inherit;
/** This spatial's name. */
protected String name;
// scale values
protected Camera.FrustumIntersect frustrumIntersects = Camera.FrustumIntersect.Intersects;
/**
* Defines if this spatial will be used in intersection operations or not.
* Default is true
*/
protected boolean isCollidable = true;
public transient float queueDistance = Float.NEGATIVE_INFINITY;
private static final long serialVersionUID = 2L;
/** Spatial's rotation relative to its parent. */
protected Quaternion localRotation;
/** Spatial's world absolute rotation. */
protected Quaternion worldRotation;
/** Spatial's translation relative to its parent. */
protected Vector3f localTranslation;
/** Spatial's world absolute translation. */
protected Vector3f worldTranslation;
/** Spatial's scale relative to its parent. */
protected Vector3f localScale;
/** Spatial's world absolute scale. */
protected Vector3f worldScale;
/** Spatial's parent, or null if it has none. */
protected transient Node parent;
/** ArrayList of controllers for this spatial. */
protected ArrayList<Controller> geometricalControllers;
private static final Vector3f compVecA = new Vector3f();
private static final Quaternion compQuat = new Quaternion();
/**
* Default Constructor.
*/
public Spatial() {
localRotation = new Quaternion();
worldRotation = new Quaternion();
localTranslation = new Vector3f();
worldTranslation = new Vector3f();
localScale = new Vector3f(1.0f, 1.0f, 1.0f);
worldScale = new Vector3f(1.0f, 1.0f, 1.0f);
}
/**
* Constructor instantiates a new <code>Spatial</code> object setting the
* rotation, translation and scale value to defaults.
*
* @param name
* the name of the scene element. This is required for
* identification and comparision purposes.
*/
public Spatial(String name) {
this();
this.name = name;
}
/**
* Adds a Controller to this Spatial's list of controllers.
*
* @param controller
* The Controller to add
* @see com.jme.scene.Controller
*/
public void addController(Controller controller) {
if (geometricalControllers == null) {
geometricalControllers = new ArrayList<Controller>(1);
}
geometricalControllers.add(controller);
}
/**
* Removes a Controller from this Spatial's list of controllers, if it
* exist.
*
* @param controller
* The Controller to remove
* @return True if the Controller was in the list to remove.
* @see com.jme.scene.Controller
*/
public boolean removeController(Controller controller) {
if (geometricalControllers == null) {
return false;
}
return geometricalControllers.remove(controller);
}
/**
* Removes a Controller from this Spatial's list of controllers by index.
*
* @param index
* The index of the controller to remove
* @return The Controller removed or null if nothing was removed.
* @see com.jme.scene.Controller
*/
public Controller removeController(int index) {
if (geometricalControllers == null) {
return null;
}
return geometricalControllers.remove(index);
}
/**
* Removes all Controllers from this Spatial's list of controllers.
*
* @see com.jme.scene.Controller
*/
public void clearControllers() {
if (geometricalControllers != null) {
geometricalControllers.clear();
}
}
/**
* Returns the controller in this list of controllers at index i.
*
* @param i
* The index to get a controller from.
* @return The controller at index i.
* @see com.jme.scene.Controller
*/
public Controller getController(int i) {
if (geometricalControllers == null) {
geometricalControllers = new ArrayList<Controller>(1);
}
return geometricalControllers.get(i);
}
/**
* Returns the ArrayList that contains this spatial's Controllers.
*
* @return This spatial's geometricalControllers.
*/
public ArrayList<Controller> getControllers() {
if (geometricalControllers == null) {
geometricalControllers = new ArrayList<Controller>(1);
}
return geometricalControllers;
}
/**
* @return the number of controllers set on this Spatial.
*/
public int getControllerCount() {
if (geometricalControllers == null) {
return 0;
}
return geometricalControllers.size();
}
/**
* <code>onDraw</code> checks the spatial with the camera to see if it
* should be culled, if not, the node's draw method is called.
* <p>
* This method is called by the renderer. Usually it should not be called
* directly.
*
* @param r
* the renderer used for display.
*/
public void onDraw(Renderer r) {
CullHint cm = getCullHint();
if (cm == Spatial.CullHint.Always) {
setLastFrustumIntersection(Camera.FrustumIntersect.Outside);
return;
} else if (cm == Spatial.CullHint.Never) {
setLastFrustumIntersection(Camera.FrustumIntersect.Intersects);
draw(r);
return;
}
Camera camera = r.getCamera();
int state = camera.getPlaneState();
// check to see if we can cull this node
frustrumIntersects = (parent != null ? parent.frustrumIntersects
: Camera.FrustumIntersect.Intersects);
if (cm == Spatial.CullHint.Dynamic
&& frustrumIntersects == Camera.FrustumIntersect.Intersects) {
frustrumIntersects = camera.contains(worldBound);
}
if (frustrumIntersects != Camera.FrustumIntersect.Outside) {
draw(r);
}
camera.setPlaneState(state);
}
/**
* <code>getWorldRotation</code> retrieves the absolute rotation of the
* Spatial.
*
* @return the Spatial's world rotation matrix.
*/
public Quaternion getWorldRotation() {
return worldRotation;
}
/**
* <code>getWorldTranslation</code> retrieves the absolute translation of
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?