使用场景图
使用场景图
每个 Aspose.3D 中针对 Java 的 3D 场景都组织为一棵树, Node 对象。. Scene 提供一个单一根节点 — getRootNode() — 并且每个几何体、材质和变换都作为子节点或后代节点位于该根节点之下。.
创建场景并访问根节点
Scene 会自动初始化为一个名为 "RootNode":
import com.aspose.threed.Scene;
import com.aspose.threed.Node;
Scene scene = new Scene();
Node root = scene.getRootNode(); // always "RootNode"添加子节点
调用 createChildNode() 在任意节点上添加子节点。此方法有三种常用的重载::
import com.aspose.threed.*;
Scene scene = new Scene();
Node root = scene.getRootNode();
// 1. Named node with no entity — useful as a pivot or group container
Node pivot = root.createChildNode("pivot");
// 2. Named node with an entity
Mesh mesh = new Mesh("box");
mesh.getControlPoints().add(new Vector4(0, 0, 0));
mesh.getControlPoints().add(new Vector4(1, 0, 0));
mesh.getControlPoints().add(new Vector4(1, 1, 0));
mesh.getControlPoints().add(new Vector4(0, 1, 0));
mesh.createPolygon(0, 1, 2, 3);
Node meshNode = root.createChildNode("box", mesh);
// 3. Named node with entity and material
PbrMaterial mat = new PbrMaterial("red");
mat.setAlbedo(new Vector4(0.8f, 0.2f, 0.2f, 1.0f));
Node decorated = pivot.createChildNode("red_box", mesh, mat);要附加一个单独构造的节点,请使用 addChildNode():
Node detached = new Node("standalone");
root.addChildNode(detached);查询子节点
按名称或索引查找直接子节点,或遍历所有直接子节点::
// By name — returns null if no direct child has that name
Node found = root.getChild("box");
if (found != null) {
System.out.println("Found: " + found.getName());
}
// By index
Node first = root.getChild(0);
// Iterate all direct children
for (Node child : root.getChildNodes()) {
System.out.println(child.getName());
}getChild(String name) 仅搜索 直接子节点,,而不是整个子树。使用 accept() 来搜索整棵树。.
遍历完整树
node.accept(NodeVisitor) 以深度优先顺序遍历一个节点及其所有后代。访问者返回 true 以继续,或 false 以提前停止::
import com.aspose.threed.NodeVisitor;
// Print every node name in the scene
scene.getRootNode().accept(n -> {
System.out.println(n.getName());
return true; // false would stop traversal
});
// Stop after finding the first node that has an entity
final Node[] found = {null};
scene.getRootNode().accept(n -> {
if (n.getEntity() != null) {
found[0] = n;
return false; // stop walking
}
return true;
});NodeVisitor 是一个单方法接口,因此在 Java 8+ 中可以接受 lambda 表达式。.
控制可见性和导出排除
节点可以被隐藏或在导出时排除,但不会从层次结构中移除::
Node ground = root.createChildNode("ground_plane", mesh);
ground.setVisible(false); // hidden in viewport / renderer
Node helperNode = root.createChildNode("debug_arrow", mesh);
helperNode.setExcluded(true); // omitted from all export operationssetVisible(false) 是一个显示提示。. setExcluded(true) 阻止该节点在导出的文件中出现,无论文件格式如何。.
将多个实体附加到同一节点
节点具有一个 主要 实体 (getEntity() / setEntity()), 但可以通过额外的实体容纳更多实体 addEntity().。当不同的网格部件共享单一变换时,这很有用::
Mesh body = new Mesh("body");
Mesh wheel = new Mesh("wheel");
Node carNode = root.createChildNode("car");
carNode.addEntity(body);
carNode.addEntity(wheel);
// Retrieve all entities on this node
for (Entity ent : carNode.getEntities()) {
System.out.println(ent.getName());
}合并节点
merge() 将所有子节点、实体和材质从源节点移动到目标节点。源节点将被清空::
Node lod0 = root.createChildNode("lod0");
lod0.createChildNode("mesh_high", mesh);
Node lod1 = root.createChildNode("lod1");
lod1.createChildNode("mesh_low", mesh);
// Consolidate lod0 children into lod1
lod1.merge(lod0);
// lod1 now has both mesh_high and mesh_low; lod0 is empty后续步骤
API 快速参考
| 成员 | 描述 |
|---|---|
scene.getRootNode() | 场景树的根节点;在…之后始终存在 new Scene() |
node.createChildNode(name) | 创建一个没有实体的具名子节点 |
node.createChildNode(name, entity) | 创建一个带有实体的具名子节点 |
node.createChildNode(name, entity, material) | 创建一个带有实体和材质的具名子节点 |
node.addChildNode(node) | 附加一个单独构建的 Node |
node.getChild(name) | 通过名称查找直接子节点;返回 null 如果未找到 |
node.getChild(index) | 获取指定索引的直接子节点 |
node.getChildNodes() | List<Node> 所有直接子节点的 |
node.accept(visitor) | 深度优先遍历此节点及所有后代 |
node.addEntity(entity) | 将额外实体附加到节点 |
node.getEntities() | List<Entity> 此节点上所有实体的 |
node.setVisible(bool) | 显示或隐藏节点 |
node.setExcluded(bool) | 在导出时包含或排除节点 |
node.merge(other) | 将所有子项和实体从 other 到此节点 |