/// <summary> /// Bakes all node transforms of all skinned meshes into the geometry so that each node's /// transform is Identity. (Only bones and morph targets keep their transforms.) /// </summary> /// <param name="node">The node.</param> private static void BakeTransforms(NodeContent node) { if (node is BoneContent) { return; } if (ContentHelper.IsMorphTarget(node)) { return; } if (ContentHelper.IsSkinned(node)) { // Bake all transforms in this subtree. BakeAllTransforms(node); } else { // Bake transforms of skinned meshes. foreach (NodeContent child in node.Children) { BakeTransforms(child); } } }
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); } } } } }
/// <summary> /// Bakes all node transforms in the specified subtree into the mesh geometry so that each /// node's transform is Identity. (Only bones and morph targets keep their transforms.) /// </summary> /// <param name="node">The node.</param> private static void BakeAllTransforms(NodeContent node) { if (node is BoneContent) { return; } if (ContentHelper.IsMorphTarget(node)) { return; } if (node.Transform != Matrix.Identity) { MeshHelper.TransformScene(node, node.Transform); node.Transform = Matrix.Identity; } foreach (NodeContent child in node.Children) { BakeAllTransforms(child); } }
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; Vector3F 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); }