node.java
来自「java 3d game jme 工程开发源代码」· Java 代码 · 共 712 行 · 第 1/2 页
JAVA
712 行
/*
* 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.Collections;
import java.util.List;
import java.util.Stack;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.jme.bounding.BoundingVolume;
import com.jme.intersection.CollisionResults;
import com.jme.intersection.PickResults;
import com.jme.math.Ray;
import com.jme.renderer.Renderer;
import com.jme.scene.state.RenderState;
import com.jme.util.export.JMEExporter;
import com.jme.util.export.JMEImporter;
import com.jme.util.export.Savable;
/**
* <code>Node</code> defines an internal node of a scene graph. The internal
* node maintains a collection of children and handles merging said children
* into a single bound to allow for very fast culling of multiple nodes. Node
* allows for any number of children to be attached.
*
* @author Mark Powell
* @author Gregg Patton
* @author Joshua Slack
*/
public class Node extends Spatial implements Serializable, Savable {
private static final Logger logger = Logger.getLogger(Node.class.getName());
private static final long serialVersionUID = 1L;
/** This node's children. */
protected List<Spatial> children;
/**
* Default constructor.
*/
public Node() {
logger.info("Node created.");
}
/**
* Constructor instantiates a new <code>Node</code> with a default empty
* list for containing children.
*
* @param name
* the name of the scene element. This is required for
* identification and comparision purposes.
*/
public Node(String name) {
super(name);
logger.info("Node created.");
}
/**
*
* <code>getQuantity</code> returns the number of children this node
* maintains.
*
* @return the number of children this node maintains.
*/
public int getQuantity() {
if(children == null) {
return 0;
}
return children.size();
}
/**
* <code>getTriangleCount</code> returns the number of triangles contained
* in all sub-branches of this node that contain geometry.
* @return the triangle count of this branch.
*/
@Override
public int getTriangleCount() {
int count = 0;
if(children != null) {
for(int i = 0; i < children.size(); i++) {
count += children.get(i).getTriangleCount();
}
}
return count;
}
/**
* <code>getVertexCount</code> returns the number of vertices contained
* in all sub-branches of this node that contain geometry.
* @return the vertex count of this branch.
*/
@Override
public int getVertexCount() {
int count = 0;
if(children != null) {
for(int i = 0; i < children.size(); i++) {
count += children.get(i).getVertexCount();
}
}
return count;
}
/**
*
* <code>attachChild</code> attaches a child to this node. This node
* becomes the child's parent. The current number of children maintained is
* returned.
* <br>
* If the child already had a parent it is detached from that former parent.
*
* @param child
* the child to attach to this node.
* @return the number of children maintained by this node.
*/
public int attachChild(Spatial child) {
if (child != null) {
if (child.getParent() != this) {
if (child.getParent() != null) {
child.getParent().detachChild(child);
}
child.setParent(this);
if(children == null) {
children = Collections.synchronizedList(new ArrayList<Spatial>(1));
}
children.add(child);
if (logger.isLoggable(Level.INFO)) {
logger.info("Child (" + child.getName()
+ ") attached to this" + " node (" + getName()
+ ")");
}
}
}
if (children == null) return 0;
return children.size();
}
/**
*
* <code>attachChildAt</code> attaches a child to this node at an index. This node
* becomes the child's parent. The current number of children maintained is
* returned.
* <br>
* If the child already had a parent it is detached from that former parent.
*
* @param child
* the child to attach to this node.
* @return the number of children maintained by this node.
*/
public int attachChildAt(Spatial child, int index) {
if (child != null) {
if (child.getParent() != this) {
if (child.getParent() != null) {
child.getParent().detachChild(child);
}
child.setParent(this);
if(children == null) {
children = Collections.synchronizedList(new ArrayList<Spatial>(1));
}
children.add(index, child);
if (logger.isLoggable(Level.INFO)) {
logger.info("Child (" + child.getName()
+ ") attached to this" + " node (" + getName()
+ ")");
}
}
}
if (children == null) return 0;
return children.size();
}
/**
* <code>detachChild</code> removes a given child from the node's list.
* This child will no longe be maintained.
*
* @param child
* the child to remove.
* @return the index the child was at. -1 if the child was not in the list.
*/
public int detachChild(Spatial child) {
if(children == null) {
return -1;
}
if (child == null)
return -1;
if (child.getParent() == this) {
int index = children.indexOf(child);
if (index != -1) {
detachChildAt(index);
}
return index;
}
return -1;
}
/**
* <code>detachChild</code> removes a given child from the node's list.
* This child will no longe be maintained. Only the first child with a
* matching name is removed.
*
* @param childName
* the child to remove.
* @return the index the child was at. -1 if the child was not in the list.
*/
public int detachChildNamed(String childName) {
if(children == null) {
return -1;
}
if (childName == null)
return -1;
for (int x = 0, max = children.size(); x < max; x++) {
Spatial child = children.get(x);
if (childName.equals(child.getName())) {
detachChildAt( x );
return x;
}
}
return -1;
}
/**
*
* <code>detachChildAt</code> removes a child at a given index. That child
* is returned for saving purposes.
*
* @param index
* the index of the child to be removed.
* @return the child at the supplied index.
*/
public Spatial detachChildAt(int index) {
if(children == null) {
return null;
}
Spatial child = children.remove(index);
if ( child != null ) {
child.setParent( null );
logger.info("Child removed.");
}
return child;
}
/**
*
* <code>detachAllChildren</code> removes all children attached to this
* node.
*/
public void detachAllChildren() {
if(children != null) {
for ( int i = children.size() - 1; i >= 0; i-- ) {
detachChildAt( i );
}
logger.info("All children removed.");
}
}
public int getChildIndex(Spatial sp) {
if(children == null) {
return -1;
}
return children.indexOf(sp);
}
public void swapChildren(int index1, int index2) {
Spatial c2 = children.get(index2);
Spatial c1 = children.remove(index1);
children.add(index1, c2);
children.remove(index2);
children.add(index2, c1);
}
/**
*
* <code>getChild</code> returns a child at a given index.
*
* @param i
* the index to retrieve the child from.
* @return the child at a specified index.
*/
public Spatial getChild(int i) {
if(children == null) {
return null;
}
return children.get(i);
}
/**
* <code>getChild</code> returns the first child found with exactly the
* given name (case sensitive.)
*
* @param name
* the name of the child to retrieve. If null, we'll return null.
* @return the child if found, or null.
*/
public Spatial getChild(String name) {
if (name == null) return null;
for (int x = 0, cSize = getQuantity(); x < cSize; x++) {
Spatial child = children.get(x);
if (name.equals(child.getName())) {
return child;
} else if(child instanceof Node) {
Spatial out = ((Node)child).getChild(name);
if(out != null) {
return out;
}
}
}
return null;
}
/**
* determines if the provided Spatial is contained in the children list of
* this node.
*
* @param spat
* the child object to look for.
* @return true if the object is contained, false otherwise.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?