public static Node FromAssimp(Module.Import.Assimp.Context context, aiScene scene, aiNode assimp_node)
{
// Create new node object
Node node = new Node();
// Get node ID
node.id = context.id++;
// Get node name
node.name = Assimp.Convert.Name(assimp_node.mName, "node");
// Get node metadata
using (aiMetadata meta = assimp_node.mMetaData)
{
UnityComponent metadata = UnityComponent.FromAssimpMetadata(meta);
if (metadata != null)
{
node.components = new UnityComponent[] { metadata };
}
}
// Parse children recursively
using (aiNodeArray children = assimp_node.Children)
{
uint children_size = children.Size();
if (children_size > 0)
{
node.children = new Node[children_size];
for (uint i = 0; i < children_size; i++)
{
aiNode child = children.Get(i);
// ParseNode must dispose of the given node afterward
// We must use a proxy method for saving the result into the array because the index i is captured by the lambda otherwise and it's value is indefinite across multiple threads.
context.threads.ExecAndSaveToArray(node.children, (int)i, () => FromAssimp(context, scene, child));
}
}
}
// Parse meshes associated to this node
using (aiUIntArray meshes = assimp_node.Meshes)
{
uint meshes_size = meshes.Size();
if (meshes_size > 0)
{
int global_meshes_size = (int)scene.Meshes.Size();
node.meshes = new GraphicMesh[meshes_size];
for (uint j = 0; j < meshes_size; j++)
{
node.meshes[j] = new GraphicMesh();
if (j < global_meshes_size)
{
uint mesh_index = meshes.Get(j);
node.meshes[j].meshIndex = (int)mesh_index;
}
}
}
}
// Get the transform of this node
using (aiVector3D position = new aiVector3D())
{
using (aiVector3D scaling = new aiVector3D())
{
using (aiQuaternion rotation = new aiQuaternion())
{
assimp_node.mTransformation.Decompose(scaling, rotation, position);
node.position = Assimp.Convert.AssimpToUnity.Vector3(position);
node.rotation = Assimp.Convert.AssimpToUnity.Quaternion(rotation);
node.scale = Assimp.Convert.AssimpToUnity.Vector3(scaling);
}
}
}
// We must dispose of the given parameter to avoid memory leaks
assimp_node.Dispose();
context.progress.Update(ASSIMP_PROGRESS_FACTOR);
return(node);
}