private /*static*/ void BuildOccluder(DROccluderNodeContent occluderNode)
        {
            var mesh = occluderNode.InputMesh;

            MergeDuplicatePositions(mesh, Numeric.EpsilonF);

            // Get all positions in mesh.
            var meshPositions = mesh.Positions.Select(p => (Vector3)p).ToList();

            // Get all triangles in mesh.
            var meshIndices = new List <int>();

            foreach (var geometry in mesh.Geometry)
            {
                var positionIndices = geometry.Vertices.PositionIndices;
                var indices         = geometry.Indices;
                for (int i = 0; i < indices.Count; i++)
                {
                    meshIndices.Add(positionIndices[indices[i]]);
                }
            }

            OptimizeForCache(meshPositions, meshIndices, mesh.Identity);

            occluderNode.Occluder = new DROccluderContent
            {
                Vertices = meshPositions,
                Indices  = meshIndices
            };
        }
        private void ValidateOccluder(DROccluderNodeContent occluderNode)
        {
            int numberOfVertices = occluderNode.Occluder.Vertices.Count;

            if (numberOfVertices > ushort.MaxValue)
            {
                string message = string.Format(
                    CultureInfo.InvariantCulture,
                    "Occluder is too complex: The occluder \"{0}\" has {1} vertices. Max allowed number of vertices is {2}.",
                    occluderNode.Name, numberOfVertices, ushort.MaxValue);
                throw new InvalidContentException(message, _input.Identity);
            }
        }
        private static DRSceneNodeContent BuildSceneGraph(NodeContent node, DRSceneNodeContent parent)
        {
            CheckForCyclicReferences(node);

            DRSceneNodeContent sceneNode;

            if (node is BoneContent)
            {
                // ----- BoneContent
                // Bones do not show up in the scene graph.
                sceneNode = null;
            }
            else if (node is MeshContent)
            {
                // ----- MeshContent
                var    mesh = (MeshContent)node;
                string morphTargetName;
                if (ContentHelper.IsMorphTarget(mesh, out morphTargetName))
                {
                    // ----- Morph Targets
                    // Morph targets are stored in the parent mesh, they do not show up in
                    // the scene graph. Children of morph targets are ignored!
                    mesh.Name = morphTargetName;
                    AddMorphTarget(parent, mesh);
                    sceneNode = null;
                }
                else if (ContentHelper.IsOccluder(mesh))
                {
                    // ----- OccluderNode
                    sceneNode = new DROccluderNodeContent {
                        InputMesh = mesh
                    };
                }
                else
                {
                    // ----- MeshNode
                    sceneNode = new DRMeshNodeContent {
                        InputMesh = mesh
                    };
                }
            }
            else
            {
                // ----- Empty/unsupported node
                sceneNode = new DRSceneNodeContent();
            }

            if (sceneNode != null)
            {
                sceneNode.Name = node.Name;
                Pose    pose;
                Vector3 scale;
                DecomposeTransform(node, out pose, out scale);
                sceneNode.PoseLocal  = pose;
                sceneNode.ScaleLocal = scale;
                if (node.Children.Count > 0)
                {
                    // Process children.
                    sceneNode.Children = new List <DRSceneNodeContent>();

                    // Recursively add children.
                    foreach (var childNode in node.Children)
                    {
                        var childSceneNode = BuildSceneGraph(childNode, sceneNode);
                        if (childSceneNode != null)
                        {
                            childSceneNode.Parent = sceneNode;
                            sceneNode.Children.Add(childSceneNode);
                        }
                    }
                }
            }

            return(sceneNode);
        }