private void ValidateInput()
        {
            if (_input is BoneContent)
            {
                // Root node cannot be a BoneContent.
                throw new InvalidContentException("The root node of the model is a bone. - This is not supported.", _input.Identity);
            }

            var tree = TreeHelper.GetSubtree(_input, n => n.Children, true);
            int numberOfSkeletons = 0;

            // Check each node in tree.
            foreach (var node in tree)
            {
                if (node is BoneContent)
                {
                    // Each root BoneContent defines a new skeleton.
                    if (!(node.Parent is BoneContent))
                    {
                        numberOfSkeletons++;
                    }

                    if (numberOfSkeletons > 1)
                    {
                        // ----- More than one skeleton.
                        throw new InvalidContentException("Model contains more than one skeleton. Only one skeleton definition is supported per model.", _input.Identity);
                    }
                }
                else
                {
                    if (node.Parent is BoneContent)
                    {
                        // ----- Current node is a NodeContent or a MeshContent under a BoneContent.
                        _context.Logger.LogWarning(
                            null, _input.Identity,
                            "Bone \"{0}\" contains node \"{1}\" which is not a bone. Bones must only have bones as children. The node might be ignored.",
                            node.Parent.Name, node.Name);
                    }

                    var mesh = node as MeshContent;
                    if (mesh != null)
                    {
                        if (ContentHelper.IsMorphTarget(mesh))
                        {
                            ValidateMorphTarget(mesh);
                        }
                        else if (ContentHelper.IsOccluder(mesh))
                        {
                            ValidateOccluder(mesh);
                        }
                        else
                        {
                            ValidateMesh(mesh);
                        }
                    }
                }
            }
        }
        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);
        }