}         // UseParentBoneNameIfMeshNameIsNotSet(input)

        #endregion

        #region StoreEffectMaterialsAndTechniques
        /// <summary>
        /// Stores the current selected technique and if the texture uses alpha
        /// into the mesh name for each mesh part.
        /// </summary>
        private void StoreEffectTechniqueInMeshName(
            NodeContent input, ContentProcessorContext context)
        {
            MeshContent mesh = input as MeshContent;

            if (mesh != null)
            {
                foreach (GeometryContent geom in mesh.Geometry)
                {
                    EffectMaterialContent effectMaterial = geom.Material as EffectMaterialContent;
                    if (effectMaterial != null)
                    {
                        if (effectMaterial.OpaqueData.ContainsKey("technique"))
                        {
                            // Store technique here! (OpaqueData["technique"] is an int32)
                            input.Name = input.Name + effectMaterial.OpaqueData["technique"];
                        } // if (effectMaterial.OpaqueData.ContainsKey)
                    }     // if (effectMaterial)
                }         // foreach (geom)
            }             // if (mesh)

            // Go through all childs
            foreach (NodeContent child in input.Children)
            {
                StoreEffectTechniqueInMeshName(child, context);
            }     // foreach (child)
        }         // StoreEffectTechniqueInMeshName(input, context)
Beispiel #2
0
        /// <summary>
        /// Recursively processes a node from the input data tree.
        /// </summary>
        void ProcessNode(NodeContent node)
        {
            // Meshes can contain internal hierarchy (nested tranforms, joints, bones,
            // etc), but this sample isn't going to bother storing any of that data.
            // Instead we will just bake any node transforms into the geometry, after
            // which we can reset them to identity and forget all about them.
            MeshHelper.TransformScene(node, node.Transform);

            node.Transform = Matrix.Identity;

            // Is this node in fact a mesh?
            MeshContent mesh = node as MeshContent;

            if (mesh != null)
            {
                // Reorder vertex and index data so triangles will render in
                // an order that makes efficient use of the GPU vertex cache.
                MeshHelper.OptimizeForCache(mesh);

                // Process all the geometry in the mesh.
                foreach (GeometryContent geometry in mesh.Geometry)
                {
                    ProcessGeometry(geometry);
                }
            }

            // Recurse over any child nodes.
            foreach (NodeContent child in node.Children)
            {
                ProcessNode(child);
            }
        }
        // Extracts a box shape from the given MeshContent.
        private void LoadBox(MeshContent mesh, out Pose pose, out Shape shape)
        {
            // Get transformation of the node.
            pose = GetPose(mesh);

            // The naming convention told us that the mesh describes a box. We need to extract
            // the box extents (width, height, depth). The mesh will probably have 8 vertices that
            // define the box. We use the Aabb struct to find the extents for us.

            // Create an AABB that contains the first vertex.
            Aabb aabb = new Aabb((Vector3F)mesh.Positions[0], (Vector3F)mesh.Positions[0]);

            // Extend the AABB to include the other 7 vertices.
            for (int i = 1; i < mesh.Positions.Count; i++)
            {
                aabb.Grow((Vector3F)mesh.Positions[i]);
            }

            // If the box is not centered on the node, add a translation to the pose.
            pose = pose * new Pose(aabb.Center);

            // Now, aabb has the box size.
            // We return a BoxShape with the same size. (Note: Aabb is only a helper structure it is
            // not itself derived from class Shape.)
            shape = new BoxShape(aabb.Extent);
        }
Beispiel #4
0
        public static bool NeedsSplitting(MeshContent mesh, int maxBones)
        {
            SortedDictionary <string, object> skinnedBones = new SortedDictionary <string, object>();

            foreach (GeometryContent geom in mesh.Geometry)
            {
                VertexChannel <BoneWeightCollection> weightChannel = null;
                foreach (VertexChannel channel in geom.Vertices.Channels)
                {
                    if (channel.Name == VertexChannelNames.Weights())
                    {
                        weightChannel = (VertexChannel <BoneWeightCollection>)channel;
                        break;
                    }
                }
                if (weightChannel != null)
                {
                    foreach (BoneWeightCollection weights in weightChannel)
                    {
                        foreach (BoneWeight weight in weights)
                        {
                            if (!skinnedBones.ContainsKey(weight.BoneName))
                            {
                                skinnedBones.Add(weight.BoneName, null);
                            }
                        }
                    }
                }
            }
            return(skinnedBones.Keys.Count > maxBones);
        }
Beispiel #5
0
        static void DoFindWork(NodeContent node, List <Vector3> vertices, List <int> indices, int i)
        {
            // Is this node a mesh?
            MeshContent mesh = node as MeshContent;

            if (mesh != null)
            {
                // Look up the absolute transform of the mesh.
                Matrix absoluteTransform = mesh.AbsoluteTransform;

                // Loop over all the pieces of geometry in the mesh.
                foreach (GeometryContent geometry in mesh.Geometry)
                {
                    // Loop over all the indices in this piece of geometry.
                    // Every group of three indices represents one triangle.
                    foreach (int index in geometry.Indices)
                    {
                        // Look up the position of this vertex.
                        Vector3 vertex = geometry.Vertices.Positions[index];

                        // Transform from local into world space.
                        vertex = Vector3.Transform(vertex, absoluteTransform);

                        // Store this vertex.
                        vertices.Add(vertex);
                        indices.Add(i);
                        i++;
                    }
                }
            }
            else
            {
                //throw new InvalidContentException("Mesh is null");
            }
        }
        private static void MergeDuplicatePositions(MeshContent mesh, float tolerance)
        {
            Debug.Assert(mesh != null);
            Debug.Assert(tolerance > 0);

            var positions = mesh.Positions.Select(p => (Vector3F)p).ToList();

            int[] positionRemap;
            int   numberOfDuplicates = GeometryHelper.MergeDuplicatePositions(positions, tolerance, out positionRemap);

            if (numberOfDuplicates > 0)
            {
                mesh.Positions.Clear();
                for (int i = 0; i < positions.Count; i++)
                {
                    mesh.Positions[i] = (Vector3)positions[i];
                }

                foreach (var geometry in mesh.Geometry)
                {
                    var positionIndices  = geometry.Vertices.PositionIndices;
                    int numberOfVertices = geometry.Vertices.VertexCount;
                    for (int i = 0; i < numberOfVertices; i++)
                    {
                        positionIndices[i] = positionRemap[positionIndices[i]];
                    }
                }
            }
        }
Beispiel #7
0
        /// <summary>
        /// Determines whether the specified mesh represents an occluder.
        /// </summary>
        /// <param name="mesh">The mesh.</param>
        /// <returns>
        /// <see langword="true"/> if the mesh represents an occluder; otherwise,
        /// <see langword="false"/>.
        /// </returns>
        internal static bool IsOccluder(MeshContent mesh)
        {
            // Acceptable occluder names are:
            //  "*OCCLUDER*"
            //  "*OCCLUSION*"
            // where * means zero or more characters.
            // Comparison is case-insensitive.
            string name = mesh.Name;

            if (name != null)
            {
                const string pattern0 = "OCCLUDER";
                const string pattern1 = "OCCLUSION";
                if (name.Length >= pattern0.Length)
                {
                    if (name.IndexOf(pattern0, StringComparison.OrdinalIgnoreCase) >= 0 ||
                        name.IndexOf(pattern1, StringComparison.OrdinalIgnoreCase) >= 0)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
        public static void CalcBoundingBox(MeshContent mesh, ModelContent owner)
        {
            Vector3 minBox = new Vector3(Single.MaxValue, Single.MaxValue, Single.MaxValue);
            Vector3 maxBox = new Vector3(-Single.MaxValue, -Single.MaxValue, -Single.MaxValue);

            foreach (Vector3 x in mesh.Positions)
            {
                minBox.X = Math.Min(minBox.X, x.X);
                minBox.Y = Math.Min(minBox.Y, x.Y);
                minBox.Z = Math.Min(minBox.Z, x.Z);

                maxBox.X = Math.Max(maxBox.X, x.X);
                maxBox.Y = Math.Max(maxBox.Y, x.Y);
                maxBox.Z = Math.Max(maxBox.Z, x.Z);
            }

            // find the ModelMeshContent of the same name and store the bbox there
            // a little funky backwoods of the xna process, methinks
            foreach (ModelMeshContent m in owner.Meshes)
            {
                if (m.Name == mesh.Name)
                {
                    UIMeshData data = new UIMeshData();
                    data.bBox.Min = minBox;
                    data.bBox.Max = maxBox;

                    m.Tag = data;
                }
            }
        }
Beispiel #9
0
        /// <summary>
        /// Stores the current selected technique and if the texture uses alpha
        /// into the mesh name for each mesh part.
        /// </summary>
        private void StoreEffectTechniqueInMeshName(
            NodeContent input, ContentProcessorContext context)
        {
            MeshContent mesh = input as MeshContent;

            if (mesh != null)
            {
                foreach (GeometryContent geom in mesh.Geometry)
                {
                    EffectMaterialContent effectMaterial =
                        geom.Material as EffectMaterialContent;
                    if (effectMaterial != null)
                    {
                        if (effectMaterial.OpaqueData.ContainsKey("technique"))
                        {
                            // Store technique here! (OpaqueData["technique"] is an
                            // int32) If we have multiple mesh parts in our mesh object,
                            // there will be multiple techniques listed at the end of
                            // our mesh name.
                            input.Name =
                                input.Name + effectMaterial.OpaqueData["technique"];
                        }
                    }
                }
            }

            // Go through all childs
            foreach (NodeContent child in input.Children)
            {
                StoreEffectTechniqueInMeshName(child, context);
            }
        }
Beispiel #10
0
        private void ScaleModel(
            NodeContent input,
            ContentProcessorContext context,
            float scaleFactor
            )
        {
            MeshContent mesh = input as MeshContent;

            if (mesh != null)
            {
                for (int i = 0; i < mesh.Positions.Count; ++i)
                {
                    Matrix  inverseTransform = Matrix.Invert(mesh.AbsoluteTransform);
                    Vector3 position         = Vector3.Transform(mesh.Positions[i], mesh.AbsoluteTransform);
                    position *= scaleFactor;
                    position  = Vector3.Transform(position, inverseTransform);

                    mesh.Positions[i] = position;
                }
            }

            // Go through all childs
            foreach (NodeContent child in input.Children)
            {
                ScaleModel(child, context, scaleFactor);
            }
        }
Beispiel #11
0
        /// <summary>
        /// The refresh model
        /// </summary>
        private void RefreshModel()
        {
            if (this.ModelMesh.InternalModel == null)
            {
                return;
            }

            this.meshContent = this.ModelMesh.MeshContent;
            this.meshes      = this.ModelMesh.MeshContent?.MeshParts?.Select(mp => (mp as SkinnedMesh)?.Clone()).ToArray();

            this.rootInverseBindPose = Matrix.Identity;

            if (this.meshContent.Skin >= 0)
            {
                this.skin = this.ModelMesh.InternalModel?.Skins[this.meshContent.Skin];

                for (int i = 0; i < this.skin.Joints.Length; i++)
                {
                    if (this.skin.RootJoint == this.skin.Joints[i].NodeId)
                    {
                        this.rootInverseBindPose = this.skin.Joints[i].InverseBindPose;
                        break;
                    }
                }

                Array.Resize(ref this.skinMatrices, this.skin.Joints.Length);
                for (int i = 0; i < this.skinMatrices.Length; i++)
                {
                    this.skinMatrices[i] = Matrix.Identity;
                }
            }

            this.shouldSkinMeshes = true;
            this.rootJointChanged = true;
        }
Beispiel #12
0
        private BoundingBox ComputeBoundingBox(NodeContent input, ref BoundingBox aabb, MeshMetadata metadata)
        {
            BoundingBox boundingBox;

            if (input is MeshContent)
            {
                MeshContent mc = (MeshContent)input;
                MeshHelper.TransformScene(mc, mc.Transform);
                mc.Transform = Matrix.Identity;

                boundingBox = BoundingBox.CreateFromPoints(mc.Positions);
                //create sub mesh information
                MeshMetadata.SubMeshMetadata subMeshMetadata = new MeshMetadata.SubMeshMetadata();
                subMeshMetadata.BoundingBox = boundingBox;
                subMeshMetadata.RenderQueue = _renderQueue;
                subMeshMetadata.CastShadows = CastShadows;
                metadata.AddSubMeshMetadata(subMeshMetadata);
                if (metadata.SubMeshesMetadata.Count > 1)
                {
                    boundingBox = BoundingBox.CreateMerged(boundingBox, aabb);
                }
            }
            else
            {
                boundingBox = aabb;
            }

            foreach (NodeContent c in input.Children)
            {
                boundingBox = BoundingBox.CreateMerged(boundingBox, ComputeBoundingBox(c, ref boundingBox, metadata));
            }
            return(boundingBox);
        }
Beispiel #13
0
        public void Initialize(RemoteFortressReader.BuildingInstance buildingInput)
        {
            if (originalBuilding != null &&
                originalBuilding.active == buildingInput.active &&
                originalBuilding.items.Count == buildingInput.items.Count &&
                originalBuilding.pos_x_min == buildingInput.pos_x_min &&
                originalBuilding.pos_y_min == buildingInput.pos_y_min)
            {
                return; //There's nothing changed.
            }
            originalBuilding = buildingInput;

            foreach (var part in parts)
            {
                part.UpdatePart(buildingInput);
            }

            DFHack.DFCoord pos = new DFHack.DFCoord(
                (buildingInput.pos_x_min + buildingInput.pos_x_max) / 2,
                (buildingInput.pos_y_min + buildingInput.pos_y_max) / 2,
                buildingInput.pos_z_max);

            if (MapDataStore.Main[pos] != null && rotationType != RotationType.BuildingDirection)
            {
                transform.localRotation = MeshContent.TranslateRotation(rotationType, MapDataStore.Main[pos]);
            }
        }
Beispiel #14
0
        private static void MakeRelativeMorphTargets(MeshContent baseMesh, List <MeshContent> morphTargets)
        {
            foreach (var morphTarget in morphTargets)
            {
                // Make positions relative to base mesh.
                // (Positions are stored in MeshContent.Positions.)
                var basePositions     = baseMesh.Positions;
                var morphPositions    = morphTarget.Positions;
                int numberOfPositions = basePositions.Count;
                for (int i = 0; i < numberOfPositions; i++)
                {
                    morphPositions[i] -= basePositions[i];
                }

                // Make normals relative to base mesh.
                // (Normals are stored as a vertex channel per submesh.)
                int numberOfSubmeshes = baseMesh.Geometry.Count;
                for (int i = 0; i < numberOfSubmeshes; i++)
                {
                    var baseGeometry    = baseMesh.Geometry[i];
                    var morphGeometry   = morphTarget.Geometry[i];
                    var baseNormals     = baseGeometry.Vertices.Channels.Get <Vector3>(VertexChannelNames.Normal());
                    var morphNormals    = morphGeometry.Vertices.Channels.Get <Vector3>(VertexChannelNames.Normal());
                    int numberOfNormals = baseNormals.Count;
                    for (int j = 0; j < numberOfNormals; j++)
                    {
                        morphNormals[j] -= baseNormals[j];
                    }
                }
            }
        }
Beispiel #15
0
 private void CalcMinMax(MeshContent a_mc)
 {
     foreach (Vector3 a_position in a_mc.Positions)
     {
         if (a_position.X < min.X)
         {
             min.X = a_position.X;
         }
         if (a_position.Y < min.Y)
         {
             min.Y = a_position.Y;
         }
         if (a_position.Z < min.Z)
         {
             min.Z = a_position.Z;
         }
         if (a_position.X > max.X)
         {
             max.X = a_position.X;
         }
         if (a_position.Y > max.Y)
         {
             max.Y = a_position.Y;
         }
         if (a_position.Z > max.Z)
         {
             max.Z = a_position.Z;
         }
     }
 }
        private void parseChildren(MeshContent meshContent)
        {
            foreach (Vector3 vector in meshContent.Positions)
            {
                if (vector.X < minX)
                {
                    minX = vector.X;
                }

                if (vector.Y < minY)
                {
                    minY = vector.Y;
                }

                if (vector.Z < minZ)
                {
                    minZ = vector.Z;
                }

                if (vector.X > maxX)
                {
                    maxX = vector.X;
                }

                if (vector.Y > maxY)
                {
                    maxY = vector.Y;
                }

                if (vector.Z > maxZ)
                {
                    maxZ = vector.Z;
                }
            }
        }
Beispiel #17
0
        public void AppendMesh(IMeshDecoder <int> srcMesh)
        {
            var dstMesh = new MeshContent();

            dstMesh.Name = srcMesh.Name;
            dstMesh.Tag  = srcMesh.Tag;

            foreach (var prim in srcMesh.Primitives)
            {
                var vdecl = MeshPrimitiveDecoder.GetVertexDeclaration(prim);

                int vbIndex = _UseVertexBuffer(vdecl);
                int ibIndex = _UseIndexBuffer();

                var geometry = CreateGeometry(vbIndex, ibIndex, prim, vdecl);
                if (geometry == null)
                {
                    continue;
                }

                dstMesh.AddMeshPart(geometry, prim.Material);
            }

            _Meshes.Add(dstMesh);
        }
        private void ProcessMeshes(NodeContent node, ContentProcessorContext context)
        {
            MeshContent mesh = node as MeshContent;

            if (mesh != null)
            {
                // Validate mesh
                if (!ValidateMesh(mesh, context))
                {
                    return;
                }

                // Process the entire mesh
                ProcessMesh(mesh, context);

                // Now process each of its geometries
                foreach (GeometryContent geometry in mesh.Geometry)
                {
                    ProcessGeometry(geometry, context);
                }
            }

            foreach (NodeContent child in node.Children)
            {
                ProcessMeshes(child, context);
            }
        }
        private string GetExternalMaterial(MeshContent mesh, GeometryContent geometry)
        {
            if (_modelDescription != null)
            {
                var meshDescription = _modelDescription.GetMeshDescription(mesh.Name);
                if (meshDescription != null)
                {
                    int index = mesh.Geometry.IndexOf(geometry);
                    if (0 <= index && index < meshDescription.Submeshes.Count)
                    {
                        return(meshDescription.Submeshes[index].Material);
                    }
                }
            }

            // Fallback:
            // The model description does not define a material file. Try to use the texture name
            // as a fallback.
            if (geometry != null && geometry.Material != null && geometry.Material.Textures.ContainsKey("Texture"))
            {
                string textureFile  = geometry.Material.Textures["Texture"].Filename;
                string materialFile = Path.ChangeExtension(textureFile, ".drmat");

                if (File.Exists(materialFile))
                {
                    return(materialFile);
                }
            }

            return(null);
        }
        /// <summary>
        /// Helper for extracting a list of all the vertex positions in a model.
        /// </summary>
        void FindVertices(NodeContent node)
        {
            // Is this node a mesh?
            MeshContent mesh = node as MeshContent;

            if (mesh != null)
            {
                // Look up the absolute transform of the mesh.
                //Matrix absoluteTransform = mesh.AbsoluteTransform;

                // Loop over all the pieces of geometry in the mesh.
                foreach (GeometryContent geometry in mesh.Geometry)
                {
                    // Loop over all the indices in this piece of geometry.
                    // Every group of three indices represents one triangle.
                    foreach (int index in geometry.Indices)
                    {
                        // Look up the position of this vertex.
                        Vector3 vertex = geometry.Vertices.Positions[index];

                        // Transform from local into world space.
                        //vertex = Vector3.Transform(vertex, absoluteTransform);

                        // Store this vertex.
                        vertices.Add(vertex);
                    }
                }
            }

            // Recursively scan over the children of this node.
            foreach (NodeContent child in node.Children)
            {
                FindVertices(child);
            }
        }
Beispiel #21
0
        MeshData ProcessMesh(MeshContent mesh, ContentProcessorContext context, string rootPath, Dictionary <string, object> processedContent, SkeletonData skeletonData, AnimationData[] animations, ref int geometryCount)
        {
            MeshHelper.TransformScene(mesh, mesh.AbsoluteTransform);

            string[] normalMapNames = new string[] { "Bump0", "Bump", "NormalMap", "Normalmap", "Normals", "BumpMap" };
            MeshHelper.OptimizeForCache(mesh);

            List <GeometryData> geometry = new List <GeometryData>();

            BoneContent skeleton = MeshHelper.FindSkeleton(mesh);
            Dictionary <string, int> boneIndices = null;

            if (skeleton != null)
            {
                boneIndices = FlattenSkeleton(skeleton);
            }

            foreach (GeometryContent geom in mesh.Geometry)
            {
                this.ProcessVertexChannels(geom, context, rootPath, boneIndices, null);
                MeshHelper.MergeDuplicateVertices(geom);

                VertexBufferContent vb;
                VertexElement[]     ve;
                geom.Vertices.CreateVertexBuffer(out vb, out ve, context.TargetPlatform);

                int[] indices = new int[geom.Indices.Count];
                geom.Indices.CopyTo(indices, 0);

                geometry.Add(new GeometryData(geometryCount++, geom.Name, ve, vb.VertexData, indices, new MaterialData(), skeletonData, animations, context.TargetPlatform == TargetPlatform.Xbox360));
            }

            return(new MeshData(mesh.Name, geometry.ToArray(), animations));
        }
Beispiel #22
0
        private List <Triangle[]> AddModelMeshTriangleArrayToList(NodeContent node, List <Triangle[]> triangleList)
        {
            foreach (NodeContent child in node.Children)
            {
                triangleList = AddModelMeshTriangleArrayToList(child, triangleList);
            }

            MeshContent mesh = node as MeshContent;

            if (mesh != null)
            {
                foreach (GeometryContent geo in mesh.Geometry)
                {
                    int             triangles     = geo.Indices.Count / 3;
                    List <Triangle> nodeTriangles = new List <Triangle>();

                    for (int currentTriangle = 0; currentTriangle < triangles; currentTriangle++)
                    {
                        int index0 = geo.Indices[currentTriangle * 3 + 0];
                        int index1 = geo.Indices[currentTriangle * 3 + 1];
                        int index2 = geo.Indices[currentTriangle * 3 + 2];

                        Vector3 v0 = geo.Vertices.Positions[index0];
                        Vector3 v1 = geo.Vertices.Positions[index1];
                        Vector3 v2 = geo.Vertices.Positions[index2];

                        Triangle newTriangle = new Triangle(v0, v1, v2);
                        nodeTriangles.Add(newTriangle);
                    }
                    triangleList.Add(nodeTriangles.ToArray());
                }
            }

            return(triangleList);
        }
Beispiel #23
0
        void findVertices(NodeContent node, bool transformEachVertex)
        {
            MeshContent mesh = (node as MeshContent);

            if (mesh != null)
            {
                Matrix absoluteTransform = mesh.AbsoluteTransform;

                foreach (GeometryContent geometry in mesh.Geometry)
                {
                    foreach (int index in geometry.Indices)
                    {
                        Vector3 vertex = geometry.Vertices.Positions[index];
                        if (transformEachVertex)
                        {
                            vertex = Vector3.Transform(vertex, absoluteTransform);
                        }

                        this.vertices.Add(vertex);
                    }
                }
            }

            foreach (NodeContent child in node.Children)
            {
                this.findVertices(child, transformEachVertex);
            }
        }
Beispiel #24
0
        private List <Vector3> FindLowestPoints(NodeContent node, List <Vector3> lowestPoints)
        {
            Vector3?    lowestPos = null;
            MeshContent mesh      = node as MeshContent;

            foreach (NodeContent child in node.Children)
            {
                lowestPoints = FindLowestPoints(child, lowestPoints);
            }

            if (mesh != null)
            {
                foreach (GeometryContent geo in mesh.Geometry)
                {
                    foreach (Vector3 vertexPos in geo.Vertices.Positions)
                    {
                        if (lowestPos == null ||
                            (vertexPos.Y < lowestPos.Value.Y))
                        {
                            lowestPos = vertexPos;
                        }
                    }
                }

                lowestPoints.Add(lowestPos.Value);
            }

            return(lowestPoints);
        }
Beispiel #25
0
        /// <summary>
        /// Makes sure this mesh contains the kind of data we know how to animate.
        /// </summary>
        static void ValidateMesh(NodeContent node, ContentProcessorContext context, string parentBoneName)
        {
            MeshContent mesh = node as MeshContent;

            if (mesh != null)
            {
                // Validate the mesh.
                if (parentBoneName != null)
                {
                    context.Logger.LogWarning(null, null,
                                              "Mesh {0} is a child of bone {1}. AnimatedModelProcessor " +
                                              "does not correctly handle meshes that are children of bones.",
                                              mesh.Name, parentBoneName);
                }
            }
            else if (node is BoneContent)
            {
                // If this is a bone, remember that we are now looking inside it.
                parentBoneName = node.Name;
            }

            // Recurse (iterating over a copy of the child collection,
            // because validating children may delete some of them).
            foreach (NodeContent child in new List <NodeContent>(node.Children))
            {
                ValidateMesh(child, context, parentBoneName);
            }
        }
Beispiel #26
0
        protected virtual void FlattenTransforms(NodeContent node, NodeContent stopper, ContentProcessorContext context)
        {
            if (node == stopper)
            {
                BakeTransformsToTop(node.Parent);
                return;
            }
            MeshContent mc = node as MeshContent;

            if (mc != null)
            {
                foreach (GeometryContent gc in mc.Geometry)
                {
                    if (VerticesAreSkinned(gc.Vertices, context))
                    {
                        BakeTransformsToTop(node);
                        break;
                    }
                }
            }
            foreach (NodeContent child in node.Children)
            {
                FlattenTransforms(child, stopper, context);
            }
        }
        /// <summary>
        /// Makes sure this mesh contains the kind of data we know how to animate
        /// </summary>
        /// <param name="node"></param>
        /// <param name="context"></param>
        /// <param name="parentBoneName"></param>
        static void ValidateMesh(NodeContent node, string parentBoneName)
        {
            MeshContent mesh = node as MeshContent;

            if (mesh != null)
            {
                // validate the mesh
                if (parentBoneName != null)
                {
                    //Debug.Log(string.Format("WARNING: Mesh {0} is a child of bone {1}. This is not supported.", mesh.Name, parentBoneName));
                }

                if (!MeshHasSkinning(mesh))
                {
                    //Debug.Log(string.Format("WARNING: Mesh {0} has no skinning information, so it has been deleted.", mesh.Name));
                    mesh.Parent.Children.Remove(mesh);
                    return;
                }
            }
            else if (node is BoneContent)
            {
                // if this is a bone, remember that we are now looking inside it
                parentBoneName = node.Name;
            }

            // Recurse
            foreach (NodeContent child in new List <NodeContent>(node.Children))
            {
                ValidateMesh(child, parentBoneName);
            }
        }
        /// <summary>
        /// Recursively processes a node from the input data tree.
        /// </summary>
        void ProcessNode(NodeContent node)
        {
            // Bake node transforms into the geometry, so we won't have
            // to bother dealing with these in the runtime drawing code.
            MeshHelper.TransformScene(node, node.Transform);

            node.Transform = Matrix.Identity;

            // Is this node in fact a mesh?
            MeshContent mesh = node as MeshContent;

            if (mesh != null)
            {
                // Reorder vertex and index data so triangles will render in
                // an order that makes efficient use of the GPU vertex cache.
                MeshHelper.OptimizeForCache(mesh);

                // Process all the geometry in the mesh.
                foreach (GeometryContent geometry in mesh.Geometry)
                {
                    ProcessGeometry(geometry);
                }
            }

            // Recurse over any child nodes.
            foreach (NodeContent child in node.Children)
            {
                ProcessNode(child);
            }
        }
Beispiel #29
0
        void ExtractVerticesAndIndices(NodeContent node)
        {
            // Is this node a mesh?
            MeshContent mesh = node as MeshContent;

            if (mesh != null)
            {
                // Look up the absolute transform of the mesh.
                Matrix absoluteTransform = mesh.AbsoluteTransform;

                // Loop over all the pieces of geometry in the mesh.
                foreach (GeometryContent geometry in mesh.Geometry)
                {
                    int baseElement = vertices.Count;
                    foreach (Vector3 v in geometry.Vertices.Positions)
                    {
                        vertices.Add(Vector3.Transform(v, absoluteTransform));
                    }
                    foreach (int i in geometry.Indices)
                    {
                        indices.Add(baseElement + i);
                    }
                }
            }

            // Recursively scan over the children of this node.
            foreach (NodeContent child in node.Children)
            {
                ExtractVerticesAndIndices(child);
            }
        }
        /// <summary>
        /// Adds for each texture the corresponding normal map to the material textures list
        /// the normal map name is generated from the texture name:
        /// [texture_name].tga => [texture_name]_normal.tga
        /// </summary>
        private void LookUpNormalMapAndAddToTextures(NodeContent node)
        {
            MeshContent mesh = node as MeshContent;

            if (mesh != null)
            {
                // for all geometry contents in the mesh
                foreach (GeometryContent geometry in mesh.Geometry)
                {
                    // does the geometry content contain a texture, and haven't we already processed it?
                    if (geometry.Material.Textures.Count > 0 &&
                        !geometry.Material.Textures.ContainsKey(NormalMapKey))
                    {
                        // extract the texture name
                        BasicMaterialContent basicMaterial = (BasicMaterialContent)geometry.Material;

                        // replace .tga with _normal.tga
                        string normalMapPath = basicMaterial.Texture.Filename.Replace(".tga", "_normal.tga");

                        // add the texture to the textures list
                        geometry.Material.Textures.Add(
                            NormalMapKey,
                            new ExternalReference <TextureContent>(normalMapPath)
                            );
                    }
                }
            }

            // recurse to all children
            foreach (NodeContent child in node.Children)
            {
                LookUpNormalMapAndAddToTextures(child);
            }
        }