spatial.java

来自「java 3d game jme 工程开发源代码」· Java 代码 · 共 1,773 行 · 第 1/4 页

JAVA
1,773
字号
     * states Stack array.
     * 
     * @param states
     *            The Stack[] to push states onto.
     */
    @SuppressWarnings("unchecked")
    public void propagateStatesFromRoot(Stack[] states) {
        // traverse to root to allow downward state propagation
        if (parent != null)
            parent.propagateStatesFromRoot(states);

        // push states onto current render state stack
        for (RenderState.StateType type : RenderState.StateType.values()) {
            if (getRenderState(type) != null)
                states[type.ordinal()].push(getRenderState(type));
        }
    }

    /**
     * <code>propagateBoundToRoot</code> passes the new world bound up the
     * tree to the root.
     */
    public void propagateBoundToRoot() {
        if (parent != null) {
            parent.updateWorldBound();
            parent.propagateBoundToRoot();
        }
    }

    /**
     * <code>calculateCollisions</code> calls findCollisions to populate the
     * CollisionResults object then processes the collision results.
     * 
     * @param scene
     *            the scene to test against.
     * @param results
     *            the results object.
     */
    public void calculateCollisions(Spatial scene, CollisionResults results) {
        findCollisions(scene, results);
        results.processCollisions();
    }

    /**
     * <code>updateBound</code> recalculates the bounding object for this
     * Spatial.
     */
    public abstract void updateModelBound();

    /**
     * <code>setModelBound</code> sets the bounding object for this Spatial.
     * 
     * @param modelBound
     *            the bounding object for this spatial.
     */
    public abstract void setModelBound(BoundingVolume modelBound);

    /**
     * checks this spatial against a second spatial, any collisions are stored
     * in the results object.
     * 
     * @param scene
     *            the scene to test against.
     * @param results
     *            the results of the collisions.
     */
    public abstract void findCollisions(Spatial scene, CollisionResults results);

    /**
     * Checks this spatial against a second spatial for collisions.
     * 
     * @param scene
     *            the scene to test against.
     * @param checkTriangles
     *            check for collisions on triangle accuracy level
     * @return true if any collision were found
     */
    public abstract boolean hasCollision(Spatial scene, boolean checkTriangles);

    public void calculatePick(Ray ray, PickResults results) {
        findPick(ray, results);
        results.processPick();
    }

    /**
     * Tests a ray against this spatial, and stores the results in the result
     * object.
     * 
     * @param toTest
     *            ray to test picking against
     * @param results
     *            the results of the picking
     */
    public abstract void findPick(Ray toTest, PickResults results);

    /**
     * Stores user define data for this Spatial.
     * 
     * @param key
     *            the key component to retrieve the data from the hash map.
     * @param data
     *            the data to store.
     */
    public void setUserData(String key, Savable data) {
        UserDataManager.getInstance().setUserData(this, key, data);
    }

    /**
     * Retrieves user data from the hashmap defined by the provided key.
     * 
     * @param key
     *            the key of the data to obtain.
     * @return the data referenced by the key. If the key is invalid, null is
     *         returned.
     */
    public Savable getUserData(String key) {
        return UserDataManager.getInstance().getUserData(this, key);
    }

    /**
     * Removes user data from the hashmap defined by the provided key.
     * 
     * @param key
     *            the key of the data to remove.
     * @return the data that has been removed, null if no data existed.
     */
    public Savable removeUserData(String key) {
        return UserDataManager.getInstance().removeUserData(this, key);
    }

    public abstract int getVertexCount();

    public abstract int getTriangleCount();

    public void write(JMEExporter ex) throws IOException {
        OutputCapsule capsule = ex.getCapsule(this);
        capsule.write(name, "name", null);
        capsule.write(isCollidable, "isCollidable", true);
        capsule.write(cullHint, "cullMode", CullHint.Inherit);

        capsule.write(renderQueueMode, "renderQueueMode",
                Renderer.QUEUE_INHERIT);
        capsule.write(zOrder, "zOrder", 0);
        capsule.write(lightCombineMode, "lightCombineMode", LightCombineMode.Inherit);
        capsule.write(textureCombineMode, "textureCombineMode",
                TextureCombineMode.Inherit);
        capsule.write(normalsMode, "normalsMode", NormalsMode.Inherit);
        capsule.write(renderStateList, "renderStateList", null);
        capsule.write(localRotation, "localRotation", new Quaternion());
        capsule.write(localTranslation, "localTranslation", Vector3f.ZERO);
        capsule.write(localScale, "localScale", Vector3f.UNIT_XYZ);

        capsule.writeStringSavableMap(UserDataManager.getInstance().getAllData(
                this), "userData", null);

        capsule.writeSavableArrayList(geometricalControllers,
                "geometricalControllers", null);
    }

    @SuppressWarnings("unchecked")
    public void read(JMEImporter im) throws IOException {
        InputCapsule capsule = im.getCapsule(this);
        name = capsule.readString("name", null);
        isCollidable = capsule.readBoolean("isCollidable", true);
        cullHint = capsule.readEnum("cullMode", CullHint.class,
                CullHint.Inherit);

        renderQueueMode = capsule.readInt("renderQueueMode",
                Renderer.QUEUE_INHERIT);
        zOrder = capsule.readInt("zOrder", 0);
        lightCombineMode = capsule.readEnum("lightCombineMode", LightCombineMode.class,
                LightCombineMode.Inherit);
        textureCombineMode = capsule.readEnum("textureCombineMode", TextureCombineMode.class,
                TextureCombineMode.Inherit);
        normalsMode = capsule.readEnum("normalsMode", NormalsMode.class,
                NormalsMode.Inherit);

        Savable[] savs = capsule.readSavableArray("renderStateList", null);
        if (savs == null)
            renderStateList = null;
        else {
            renderStateList = new RenderState[savs.length];
            for (int x = 0; x < savs.length; x++) {
                renderStateList[x] = (RenderState) savs[x];
            }
        }

        localRotation = (Quaternion) capsule.readSavable("localRotation",
                new Quaternion());
        localTranslation = (Vector3f) capsule.readSavable("localTranslation",
                Vector3f.ZERO.clone());
        localScale = (Vector3f) capsule.readSavable("localScale",
                Vector3f.UNIT_XYZ.clone());

        HashMap<String, Savable> map = (HashMap<String, Savable>) capsule
                .readStringSavableMap("userData", null);
        if (map != null) {
            UserDataManager.getInstance().setAllData(this, map);
        }

        geometricalControllers = capsule.readSavableArrayList(
                "geometricalControllers", null);

        worldRotation = new Quaternion();
        worldTranslation = new Vector3f();
        worldScale = new Vector3f(1.0f, 1.0f, 1.0f);
    }

    /**
     * Sets the name of this spatial.
     * 
     * @param name
     *            The spatial's new name.
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Returns the name of this spatial.
     * 
     * @return This spatial's name.
     */
    public String getName() {
        return name;
    }

    /**
     * Sets if this Spatial is to be used in intersection (collision and
     * picking) calculations. By default this is true.
     * 
     * @param isCollidable
     *            true if this Spatial is to be used in intersection
     *            calculations, false otherwise.
     */
    public void setIsCollidable(boolean isCollidable) {
        this.isCollidable = isCollidable;
    }

    /**
     * Defines if this Spatial is to be used in intersection (collision and
     * picking) calculations. By default this is true.
     * 
     * @return true if this Spatial is to be used in intersection calculations,
     *         false otherwise.
     */
    public boolean isCollidable() {
        return this.isCollidable;
    }

    /**
     * <code>getWorldBound</code> retrieves the world bound at this node
     * level.
     * 
     * @return the world bound at this level.
     */
    public BoundingVolume getWorldBound() {
        return worldBound;
    }

    /**
     * <code>draw</code> abstract method that handles drawing data to the
     * renderer if it is geometry and passing the call to it's children if it is
     * a node.
     * 
     * @param r
     *            the renderer used for display.
     */
    public abstract void draw(Renderer r);

    /**
     * <code>setCullHint</code> sets how scene culling should work on this
     * spatial during drawing. CullHint.Dynamic: Determine via the defined
     * Camera planes whether or not this Spatial should be culled.
     * CullHint.Always: Always throw away this object and any children during
     * draw commands. CullHint.Never: Never throw away this object (always draw
     * it) CullHint.Inherit: Look for a non-inherit parent and use its cull
     * mode. NOTE: You must set this AFTER attaching to a parent or it will be
     * reset with the parent's cullMode value.
     * 
     * @param hint
     *            one of CullHint.Dynamic, CullHint.Always, CullHint.Inherit or
     *            CullHint.Never
     */
    public void setCullHint(CullHint hint) {
        cullHint = hint;
    }

    /**
     * @return the cullmode set on this Spatial
     */
    public CullHint getLocalCullHint() {
        return cullHint;
    }

    /**
     * Calling this method tells the scenegraph that it is not necessary to
     * update bounds from this point in the scenegraph on down to the leaves.
     * This is useful for performance gains where you have scene items that do
     * not move (at all) or change shape and thus do not need constant
     * re-calculation of boundaries. When you call lock, the bounds are first
     * updated to ensure current bounds are accurate.
     * 
     * @see #unlockBounds()
     */
    public void lockBounds() {
        updateGeometricState(0, true);
        lockedMode |= LOCKED_BOUNDS;
    }

    /**
     * Calling this method tells the scenegraph that it is not necessary to
     * update Shadow volumes that may be associated with this Spatial. This is
     * useful for skipping various checks for spatial transformation when
     * deciding whether or not to recalc a shadow volume for a Spatial.
     * 
     * @see #unlockShadows()
     */
    public void lockShadows() {
        lockedMode |= LOCKED_SHADOWS;
    }

    /**
     * Calling this method tells the scenegraph that it is not necessary to
     * traverse this Spatial or any below it during the update phase. This
     * should be called *after* any other lock call to ensure they are able to
     * update any bounds or vectors they might need to update.
     * 
     * @see #unlockBranch()
     */
    public void lockBranch() {
        lockedMode |= LOCKED_BRANCH;
    }

    /**
     * Flags this spatial and those below it in the scenegraph to not
     * recalculate world transforms such as translation, rotation and scale on
     * every update. This is useful for efficiency when you have scene items
     * that stay in one place all the time as it avoids needless recalculation
     * of transforms.
     * 
     * @see #unlockTransforms()
     */
    public void lockTransforms() {
        updateWorldVectors();
        lockedMode |= LOCKED_TRANSFORMS;
    }

    /**
     * Flags this spatial and those below it that any meshes in the specified
     * scenegraph location or lower will not have changes in vertex, texcoord,
     * normal or color data. This allows optimizations by the engine such as
     * creating display lists from the data. Calling this method does not
     * provide a guarentee that data changes will not be allowed or will/won't
     * show up in the scene. It is merely a hint to the engine.
     * 
     * @param r
     *            A renderer to lock against.
     * @see #unlockMeshes(Renderer)
     */
    public void lockMeshes(Renderer r) {
        updateRenderState();
        lockedMode |= LOCKED_MESH_DATA;
    }

    /**
     * Flags this spatial and those below it that any meshes in the specified
     * scenegraph location or lower will not have changes in vertex, texcoord,
     * normal or color data. This allows optimizations by the engine such as
     * creating display lists from the data. Calling this method does not
     * provide a guarentee that data changes will not be allowed or will/won't
     * show up in the scene. It is merely a hint to the engine. Calls
     * lockMeshes(Renderer) with the current display system's renderer.
     * 
     * @see #lockMeshes(Renderer)
     */
    public void lockMeshes() {
        lockMeshes(DisplaySystem.getDisplaySystem().getRenderer());
    }

    /**
     * Convienence function for locking all aspects of a Spatial.
     * 
     * @see #lockBounds()
     * @see #lockTransforms()
     * @see #lockMeshes(Renderer)
     * @see #lockShadows()
     */
    public void lock(Renderer r) {
        lockBounds();
        lockBranch();
        lockTransforms();
        lockMeshes(r);
        lockShadows();
    }

    /**
     * Convienence function for locking all aspects of a Spatial. For lockMeshes
     * it calls:
     * <code>lockMeshes(DisplaySystem.getDisplaySystem().getRenderer());</code>
     * 
     * @see #lockBounds()
     * @see #lockTransforms()
     * @see #lockMeshes()
     * @see #lockShadows()
     */
    public void lock() {
        lockBounds();
        lockBranch();
        lockTransforms();
        lockMeshes();
        lockShadows();
    }

    /**
     * Flags this spatial and those below it to allow for bounds updating (the
     * default).
     * 
     * @see #lockBounds()
     */
    public void unlockBounds() {
        lockedMode &= ~LOCKED_BOUNDS;
    }

    /**
     * Flags this spatial and those below it to allow for shadow volume updates
     * (the default).
     * 
     * @see #lockShadows()
     */
    public void unlockShadows() {
        lockedMode &= ~LOCKED_SHADOWS;
    }

    /**
     * Flags this Spatial and any below it as being traversable during the
     * update phase.
     * 
     * @see #lockBranch()
     */
    public void unlockBranch() {
        lockedMode &= ~LOCKED_BRANCH;
    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?