使用场景图

使用场景图

每个 Aspose.3D 中针对 .NET 的 3D 场景都组织为一棵树 Node 对象。. Scene.RootNode 是该树的根节点,所有几何体、材质和变换都作为子节点或后代位于其下。.


创建场景并访问根节点

Scene 会自动初始化一个名为 "RootNode":

using Aspose.ThreeD;

var scene = new Scene();
Node root = scene.RootNode; // always "RootNode"

添加子节点

Call CreateChildNode() 在任意节点上调用以添加子节点。该方法有三种常用的重载::

using Aspose.ThreeD;
using Aspose.ThreeD.Entities;

var scene = new Scene();
Node root = scene.RootNode;

// 1. Named node with no entity — useful as a pivot or transform container
Node pivot = root.CreateChildNode("pivot");

// 2. Named node with an entity
var box = new Box(2, 2, 2);
Node boxNode = root.CreateChildNode("box", box);

// 3. Named node with entity and material
var mat = new Aspose.ThreeD.Shading.PhongMaterial("red");
mat.Diffuse = new Vector4(0.8, 0.2, 0.2, 1.0);
Node decorated = pivot.CreateChildNode("red_box", box, mat);

要附加一个单独构造的节点,请使用 AddChildNode():

var 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)
    Console.WriteLine("Found: " + found.Name);

// By index
Node first = root.GetChild(0);

// Iterate all direct children
foreach (Node child in root.ChildNodes)
    Console.WriteLine(child.Name);

GetChild(string name) 仅搜索 直接子节点,,而不是整个子树。使用递归辅助函数或 Accept() 来搜索整棵树。.


遍历完整树

要进行完整的深度优先遍历,请迭代 ChildNodes 递归地::

static void Walk(Node node, int depth = 0)
{
    Console.WriteLine(new string(' ', depth * 2) + node.Name);
    foreach (var child in node.ChildNodes)
        Walk(child, depth + 1);
}

Walk(scene.RootNode);

对于提前退出的遍历,, node.Accept(NodeVisitor) 可用,并在每个后代上调用访问者,直到访问者返回 false.


使用 Group 对相关对象进行组织

Group 是一个容器实体,用于在不添加几何体的情况下逻辑组织节点。将其附加到其子节点代表逻辑单元的节点上::

using Aspose.ThreeD;
using Aspose.ThreeD.Entities;

var scene = new Scene();

// A group node for all furniture in a room
var furnitureGroup = new Group("furniture");
Node roomNode = scene.RootNode.CreateChildNode("living_room", furnitureGroup);

// Child nodes under the group node
Node sofaNode  = roomNode.CreateChildNode("sofa",         new Box(3, 1, 1));
Node tableNode = roomNode.CreateChildNode("coffee_table", new Box(2, 0.5, 1));

移动 roomNode 一起转换所有家具,因为子元素继承它的 Transform.


控制可见性和导出排除

节点可以被隐藏或在导出时排除,但不会从层次结构中移除::

Node ground = scene.RootNode.CreateChildNode("ground_plane", new Box(100, 0.1, 100));
ground.Visible = false;       // hidden in viewport / renderer

Node helperNode = scene.RootNode.CreateChildNode("debug_arrow", new Box());
helperNode.Excluded = true;   // omitted from all export operations

Visible = false 是一个显示提示。. Excluded = true 防止该节点在导出文件中出现,无论何种格式。.


将多个实体附加到同一节点

一个节点拥有一个 主要 实体(Entity 属性),但可以通过 AddEntity(). 这在不同网格部件共享单一变换时很有用::

var bodyMesh  = new Mesh("body");
var wheelMesh = new Mesh("wheel");

Node carNode = scene.RootNode.CreateChildNode("car");
carNode.AddEntity(bodyMesh);
carNode.AddEntity(wheelMesh);

// Retrieve all entities on this node
foreach (Entity ent in carNode.Entities)
    Console.WriteLine(ent.GetType().Name + ": " + ent.Name);

合并节点

Merge() 将所有子节点、实体和材质从源节点移动到目标节点。源节点将被清空::

Node lod0 = scene.RootNode.CreateChildNode("lod0");
lod0.CreateChildNode("mesh_high", new Box(1, 1, 1));

Node lod1 = scene.RootNode.CreateChildNode("lod1");
lod1.CreateChildNode("mesh_low", new Box(1, 1, 1));

// Consolidate lod0 children into lod1
lod1.Merge(lod0);
// lod1 now has both mesh_high and mesh_low; lod0 is empty

后续步骤


API 快速参考

成员描述
scene.RootNode场景树的根节点;始终存在于之后 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.ChildNodesIList<Node> 所有直接子节点的
node.Accept(visitor)深度优先遍历此节点及所有后代
node.AddEntity(entity)向节点附加额外实体
node.EntitiesIList<Entity> 此节点上所有实体的
node.Visible显示或隐藏节点
node.Excluded在导出时包含或排除该节点
node.Merge(other)将所有子节点和实体从 other 移动到此节点
new Group(name)用于逻辑分组子节点的容器实体
 中文