In the introduction post, we covered what Aspose.3D FOSS for .NET is and how to get started. This post goes deeper into the key features that make up the library, with code examples for each area.
All examples assume the following using directive:
using Aspose.ThreeD;
using Aspose.ThreeD.Entities;
using Aspose.ThreeD.Shading;
And the NuGet package:
dotnet add package Aspose.3D.Converter --version 1.0.0
The Scene Graph
The scene graph is the core data structure. A Scene contains a RootNode, and every Node can have child nodes and an attached Entity (such as a Mesh or Camera).
Creating and Navigating Nodes
var scene = new Scene();
// Create a hierarchy
var parent = scene.RootNode.CreateChildNode("Parent");
var child1 = parent.CreateChildNode("Child1");
var child2 = parent.CreateChildNode("Child2");
// Navigate the tree
Console.WriteLine("Root children: " + scene.RootNode.ChildNodes.Count);
Console.WriteLine("Parent children: " + parent.ChildNodes.Count);
Attaching Entities to Nodes
Entities are the visual content of the scene – meshes, cameras, and lights. Attach them using CreateChildNode:
var scene = new Scene();
// Create a box primitive and attach it to the scene
var box = new Box(2, 2, 2);
var boxNode = scene.RootNode.CreateChildNode("BoxNode", box);
// Create a sphere primitive
var sphere = new Sphere(1);
var sphereNode = scene.RootNode.CreateChildNode("SphereNode", sphere);
scene.Save("primitives.gltf");
Built-In Primitives
The .NET edition includes parametric shape classes that generate geometry without manual vertex construction:
| Primitive | Description |
|---|---|
Box | Axis-aligned box with configurable width, height, and depth |
Sphere | Parametric sphere with configurable radius |
Cylinder | Parametric cylinder with configurable top/bottom radii and height |
These primitives can be attached directly to nodes or converted to a Mesh via ToMesh():
var cylinder = new Cylinder(1, 1, 2);
var mesh = cylinder.ToMesh();
Console.WriteLine("Vertices: " + mesh.ControlPoints.Count);
Console.WriteLine("Polygons: " + mesh.PolygonCount);
Mesh Construction
If you need full control, build meshes from scratch using control points and polygon definitions:
var mesh = new Mesh();
// Add vertex positions
mesh.ControlPoints.Add(new Vector4(0, 0, 0, 1.0f));
mesh.ControlPoints.Add(new Vector4(1, 0, 0, 1.0f));
mesh.ControlPoints.Add(new Vector4(0.5f, 1, 0, 1.0f));
// Define a triangle face
mesh.CreatePolygon(0, 1, 2);
// Attach to a scene
var scene = new Scene();
scene.RootNode.CreateChildNode("triangle", mesh);
scene.Save("triangle.stl");
Control points use Vector4 with the w component set to 1.0f for standard Cartesian positions. Polygons are defined by passing control-point indices to CreatePolygon().
Transforms
Every Node has a Transform property that controls its local position, rotation, and scale:
var scene = new Scene();
var node = scene.RootNode.CreateChildNode("Moved");
node.Transform.Translation = new FVector3(5, 0, 0);
node.Transform.Scale = new FVector3(2, 2, 2);
Transform Inheritance
Transforms compose through the scene hierarchy. A child’s world-space position is the product of all ancestor transforms:
var scene = new Scene();
var parent = scene.RootNode.CreateChildNode("Parent");
parent.Transform.Translation = new FVector3(10, 0, 0);
var child = parent.CreateChildNode("Child");
child.Transform.Translation = new FVector3(5, 0, 0);
// Child's world position is (15, 0, 0)
// Access via child.GlobalTransform
GlobalTransform
The read-only GlobalTransform property on each Node provides the computed world-space transformation matrix after composing all ancestor transforms. Access the result via node.GlobalTransform.Matrix.
Materials
The library includes three material types with increasing complexity:
LambertMaterial
Classic diffuse-only material:
var material = new LambertMaterial("WoodMaterial");
material.Diffuse = new Vector4(0.6f, 0.4f, 0.2f, 1.0f);
material.Ambient = new Vector4(0.1f, 0.1f, 0.1f, 1.0f);
material.Transparency = 0.0f;
PhongMaterial
Extends Lambert with specular highlights:
var material = new PhongMaterial("ShinyMetal");
material.Specular = new Vector4(0.8f, 0.8f, 0.8f, 1.0f);
material.Shininess = 50.0f;
material.SpecularPower = 32.0f;
PbrMaterial
Physically based rendering material used by glTF 2.0:
var material = new PbrMaterial("GoldPBR");
material.BaseColor = new Vector4(1.0f, 0.8f, 0.2f, 1.0f);
material.Metallic = 0.9f;
material.Roughness = 0.1f;
material.Occlusion = 1.0f;
PBR materials support texture slots for base color, metallic/roughness, normal, emissive, and occlusion maps via string texture path properties.
Math Utilities
The library provides a set of math primitives for 3D spatial operations:
Vector Types
| Type | Components | Precision | Common Use |
|---|---|---|---|
Vector2 | X, Y | float | UV texture coordinates |
Vector3 | X, Y, Z | float | General-purpose 3-component vector |
Vector4 | X, Y, Z, W | float | Control points, normals |
FVector3 | X, Y, Z | float | Transform properties (Translation, Scale) |
FVector4 | X, Y, Z, W | float | Vertex element data |
Quaternion
Quaternions represent rotations without gimbal lock:
var rotation = new Quaternion(0, 0, 0, 1); // Identity
node.Transform.Rotation = rotation;
Matrix4
4x4 transformation matrices for composing transforms:
// Matrix operations are used internally by Transform
// and GlobalTransform for world-space computation
BoundingBox
Axis-aligned bounding boxes for spatial queries:
// BoundingBox stores Minimum and Maximum FVector3 corners
// Used for frustum culling and spatial partitioning
Vertex Elements
Meshes can carry additional per-vertex data layers beyond positions:
- VertexElementNormal – surface normals for lighting calculations.
- VertexElementUV – texture coordinates for mapping images onto geometry.
- VertexElementVertexColor – per-vertex RGBA colour data.
Each vertex element has a MappingMode (per control point, per polygon vertex, or per polygon) and a ReferenceMode (direct values or indexed values).
Animation Clips
The Scene class supports named animation clips via CreateAnimationClip() and GetAnimationClip(). In the current FOSS edition, animation clip creation and lookup are functional, but keyframe data and playback are not yet implemented.
var scene = new Scene();
var clip = scene.CreateAnimationClip("Walk");
// Retrieve by name
var found = scene.GetAnimationClip("Walk");
Console.WriteLine("Clip found: " + (found != null));
What’s Next
The next post covers working with 3D file formats in .NET – a practical, format-by-format guide to OBJ, STL, glTF, FBX, and 3MF with load/save options and batch conversion patterns.