Ejemplo n.º 1
0
        private ModelMeshContent ProcessMesh(MeshContent mesh, ModelBoneContent parent, ContentProcessorContext context)
        {
            var bounds       = new BoundingSphere();
            var parts        = new List <ModelMeshPartContent>();
            var vertexBuffer = new VertexBufferContent();
            var indexBuffer  = new IndexCollection();

            var startVertex = 0;

            foreach (var geometry in mesh.Geometry)
            {
                var vertices    = geometry.Vertices;
                var vertexCount = vertices.VertexCount;
                var geomBuffer  = geometry.Vertices.CreateVertexBuffer();
                vertexBuffer.Write(vertexBuffer.VertexData.Length, 1, geomBuffer.VertexData);

                var startIndex = indexBuffer.Count;
                indexBuffer.AddRange(geometry.Indices);

                var partContent = new ModelMeshPartContent(vertexBuffer, indexBuffer, startVertex, vertexCount, startIndex, geometry.Indices.Count / 3);
                partContent.Material = geometry.Material;
                parts.Add(partContent);

                // Update mesh bounding box
                bounds = BoundingSphere.CreateMerged(bounds, BoundingSphere.CreateFromPoints(geometry.Vertices.Positions));

                // Geoms are supposed to all have the same decl, so just steal one of these
                vertexBuffer.VertexDeclaration = geomBuffer.VertexDeclaration;

                startVertex += vertexCount;
            }

            return(new ModelMeshContent(mesh.Name, mesh, parent, bounds, parts));
        }
Ejemplo n.º 2
0
        private ModelMeshContent ProcessMesh(MeshContent mesh, ModelBoneContent parent, ContentProcessorContext context)
        {
            var parts        = new List <ModelMeshPartContent>();
            var vertexBuffer = new VertexBufferContent();
            var indexBuffer  = new IndexCollection();

            if (GenerateTangentFrames)
            {
                context.Logger.LogMessage("Generating tangent frames.");
                foreach (GeometryContent geom in mesh.Geometry)
                {
                    if (!geom.Vertices.Channels.Contains(VertexChannelNames.Normal(0)))
                    {
                        MeshHelper.CalculateNormals(geom, true);
                    }

                    if (!geom.Vertices.Channels.Contains(VertexChannelNames.Tangent(0)) ||
                        !geom.Vertices.Channels.Contains(VertexChannelNames.Binormal(0)))
                    {
                        MeshHelper.CalculateTangentFrames(geom, VertexChannelNames.TextureCoordinate(0), VertexChannelNames.Tangent(0),
                                                          VertexChannelNames.Binormal(0));
                    }
                }
            }

            var startVertex = 0;

            foreach (var geometry in mesh.Geometry)
            {
                var vertices    = geometry.Vertices;
                var vertexCount = vertices.VertexCount;
                ModelMeshPartContent partContent;
                if (vertexCount == 0)
                {
                    partContent = new ModelMeshPartContent();
                }
                else
                {
                    var geomBuffer = geometry.Vertices.CreateVertexBuffer();
                    vertexBuffer.Write(vertexBuffer.VertexData.Length, 1, geomBuffer.VertexData);

                    var startIndex = indexBuffer.Count;
                    indexBuffer.AddRange(geometry.Indices);

                    partContent = new ModelMeshPartContent(vertexBuffer, indexBuffer, startVertex, vertexCount, startIndex, geometry.Indices.Count / 3);

                    // Geoms are supposed to all have the same decl, so just steal one of these
                    vertexBuffer.VertexDeclaration = geomBuffer.VertexDeclaration;

                    startVertex += vertexCount;
                }

                partContent.Material = geometry.Material;
                parts.Add(partContent);
            }

            var bounds = new BoundingSphere();

            if (mesh.Positions.Count > 0)
            {
                bounds = BoundingSphere.CreateFromPoints(mesh.Positions);
            }

            return(new ModelMeshContent(mesh.Name, mesh, parent, bounds, parts));
        }
Ejemplo n.º 3
0
        public override ModelContent Process(SceneContent input, ContentProcessorContext context)
        {
            List <ModelMeshContent> meshes       = new List <ModelMeshContent>();
            VertexBufferContent     vertexBuffer = new VertexBufferContent(new VertexAttribute[] {
                new PositionAttribute(),
                new NormalAttribute(),
                new TextureCoordinateAttribute(),
            });

            if (Skin)
            {
                vertexBuffer.AddAttribute(new BlendWeightsAttribute());
                vertexBuffer.AddAttribute(new BlendIndicesAttribute());
            }

            BoneContent rootBone = BuildSkeleton(input.Scene.RootNode, null);

            MaterialContent[] materials = new MaterialContent[input.Scene.MaterialCount];
            for (int i = 0; i < input.Scene.MaterialCount; i++)
            {
                Dictionary <string, object> parameters = new Dictionary <string, object>();
                GetMaterialParameters(input.Scene.Materials[i], parameters, context);
                string materialFactory;
                if (!MaterialTypeFactoryReplacements.TryGetValue(i, out materialFactory))
                {
                    materialFactory = DefaultMaterialTypeFactory;
                }
                MaterialContent material = context.ContentManager.MaterialFactoryManager.GetMaterialFactory(materialFactory)(context, parameters);
                material.Name = input.Scene.Materials[i].HasName ? input.Scene.Materials[i].Name : string.Format("{0}_Material_{1}", input.Name, i);
                materials[i]  = material;
            }

            uint numVertices = 0;
            uint numIndices  = 0;

            for (int i = 0; i < input.Scene.MeshCount; i++)
            {
                Mesh mesh            = input.Scene.Meshes[i];
                uint primitiveCount  = (uint)mesh.FaceCount;
                uint baseVertex      = numVertices;
                uint baseIndex       = numIndices;
                uint partNumIndices  = (uint)mesh.FaceCount * 3;
                uint partNumVertices = (uint)mesh.VertexCount;

                numVertices += (uint)mesh.VertexCount;
                numIndices  += (uint)mesh.FaceCount * 3;

                Dictionary <uint, List <VertexWeight> > boneVertWeights = new Dictionary <uint, List <VertexWeight> >();
                if (Skin)
                {
                    ExtractBoneWeights(mesh, boneVertWeights);
                }

                for (int j = 0; j < mesh.VertexCount; j++)
                {
                    vertexBuffer[Minotaur.Graphics.VertexUsage.Position].AddValues(mesh, j);
                    vertexBuffer[Minotaur.Graphics.VertexUsage.Normal].AddValues(mesh, j);
                    vertexBuffer[Minotaur.Graphics.VertexUsage.TextureCoordinate].AddValues(mesh, j);
                    if (Skin)
                    {
                        float[] weights = new float[4];
                        byte[]  indices = new byte[4];
                        GetNormalizedBoneWeights(boneVertWeights[(uint)j], weights, indices);
                        ((BlendWeightsAttribute)vertexBuffer[Minotaur.Graphics.VertexUsage.BlendWeight]).AddValues(weights);
                        ((BlendIndicesAttribute)vertexBuffer[Minotaur.Graphics.VertexUsage.BlendIndices]).AddValues(indices);
                    }
                }

                IndexCollection indecies = new IndexCollection();
                indecies.AddRange(mesh.GetIndices().Select(k => k + (uint)baseVertex));

                ModelMeshPartContent         part           = new ModelMeshPartContent(vertexBuffer, indecies, baseVertex, partNumVertices, baseIndex, partNumIndices, primitiveCount);
                Minotaur.Core.BoundingSphere boundingSphere = Minotaur.Core.BoundingSphere.CreateFromPoints(
                    ((PositionAttribute)vertexBuffer[Minotaur.Graphics.VertexUsage.Position]).Values.Select(
                        p => new OpenTK.Vector3(p.X, p.Y, p.Z)));
                ModelMeshContent modelmesh = new ModelMeshContent(mesh.Name, GetMeshParentBone(input.Scene.RootNode, i), new[] { part }, boundingSphere);
                meshes.Add(modelmesh);

                part.Material = materials[mesh.MaterialIndex];
            }

            List <ExternalReferenceContent <BoneAnimationsContent> > animations = new List <ExternalReferenceContent <BoneAnimationsContent> >();

            foreach (Animation anim in input.Scene.Animations)
            {
                if (ExportAnimations.Count == 0 || ExportAnimations.Contains(anim.Name))
                {
                    animations.Add(context.ContentManager.BuildContent <BoneAnimationsContent>(input.Name, "ModelImporter",
                                                                                               processorName: "BoneAnimProcessor",
                                                                                               processorData: new Dictionary <string, object>()
                    {
                        { "AnimationName", anim.Name },
                        { "NamePre", string.Format("{0}_", Path.GetFileNameWithoutExtension(input.Name)) },
                    },
                                                                                               ignoreBuildItem: true
                                                                                               ));
                }
            }

            return(new ModelContent(rootBone, _bones, meshes, animations));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Construye la información de nodos del terreno
        /// </summary>
        /// <param name="vertList">Lista de vértices</param>
        /// <param name="width">Anchura del terreno</param>
        /// <param name="deep">Profundidad del terreno</param>
        /// <param name="levels">Niveles distintos de detalle</param>
        /// <returns>Devuelve la información de nodos del terreno</returns>
        public static SceneryNodeInfo Build(
            VertexMultitextured[] vertList,
            int width,
            int deep,
            int levels)
        {
            // Lista resultante de nodos
            List <SceneryTriangleNode> nodes = new List <SceneryTriangleNode>();

            // Diccionario de índices
            Dictionary <LOD, IndexCollection> indices = new Dictionary <LOD, IndexCollection>();

            IndexCollection highIndices   = new IndexCollection();
            IndexCollection mediumIndices = new IndexCollection();
            IndexCollection lowIndices    = new IndexCollection();

            // Tamaño de la cuadrícula
            int totalCellsX = width;
            int totalCellsZ = deep;

            // Número de divisiones
            int divisions  = Convert.ToInt32(Math.Pow(4, levels));
            int divisionsX = divisions / 2;
            int divisionsZ = divisions / 2;

            // Número de vértices en X y en Z
            int numVertexesX = (totalCellsX / divisionsX);
            int numVertexesZ = (totalCellsZ / divisionsZ);

            // Número total de vértices, triángulos e índices
            int totalVertices  = totalCellsX * totalCellsZ;
            int totalTriangles = (totalCellsX - 1) * (totalCellsZ - 1) * 2;
            int totalIndices   = totalTriangles * 3;

            for (int x = 0; x < divisionsX; x++)
            {
                int offsetX = x * numVertexesX;
                int cellsX  = numVertexesX;

                for (int z = 0; z < divisionsZ; z++)
                {
                    int offsetZ = z * numVertexesZ;
                    int cellsZ  = numVertexesZ;

                    // Crear índices para generar la lista de triángulos de colisión
                    int[] collisionIndices = SceneryNodeInfo.CreateCollisionIndices(
                        offsetX,
                        offsetZ,
                        cellsX,
                        cellsZ,
                        totalCellsX,
                        totalCellsZ);

                    // Crear la lista de triángulos
                    Triangle[] quadTriangles = SceneryNodeInfo.BuildPrimitiveList(vertList, collisionIndices);

                    // Crear los índices para alta resolución
                    SceneryNodeIndexInfo quadHighInfo = null;
                    Int32[] quadHighIndices           = Build(
                        LOD.High,
                        highIndices.Count,
                        offsetX,
                        offsetZ,
                        cellsX,
                        cellsZ,
                        totalCellsX,
                        totalCellsZ,
                        out quadHighInfo);

                    // Crear los índices para media resolución
                    SceneryNodeIndexInfo quadMediumInfo = null;
                    Int32[] quadMediumIndices           = Build(
                        LOD.Medium,
                        mediumIndices.Count,
                        offsetX,
                        offsetZ,
                        cellsX,
                        cellsZ,
                        totalCellsX,
                        totalCellsZ,
                        out quadMediumInfo);

                    // Crear los índices para baja resolución
                    SceneryNodeIndexInfo quadLowInfo = null;
                    Int32[] quadLowIndices           = Build(
                        LOD.Low,
                        lowIndices.Count,
                        offsetX,
                        offsetZ,
                        cellsX,
                        cellsZ,
                        totalCellsX,
                        totalCellsZ,
                        out quadLowInfo);

                    // Añadir los índices a la colección de índices para cada resolución
                    highIndices.AddRange(quadHighIndices);
                    mediumIndices.AddRange(quadMediumIndices);
                    lowIndices.AddRange(quadLowIndices);

                    Dictionary <LOD, SceneryNodeIndexInfo> info = new Dictionary <LOD, SceneryNodeIndexInfo>();
                    info.Add(LOD.High, quadHighInfo);
                    info.Add(LOD.Medium, quadMediumInfo);
                    info.Add(LOD.Low, quadLowInfo);

                    // Crear el nodo con los triángulos para la colisión, los índices de inicio y el número de triángulos para cada resolución
                    SceneryTriangleNode newQuadNode = new SceneryTriangleNode(quadTriangles, info);
                    nodes.Add(newQuadNode);
                }
            }

            // Crear el diccionario de buffers de índices para cada resolución
            indices = new Dictionary <LOD, IndexCollection>();
            indices.Add(LOD.High, highIndices);
            indices.Add(LOD.Medium, mediumIndices);
            indices.Add(LOD.Low, lowIndices);

            // Devolver la información de nodos del escenario
            return(new SceneryNodeInfo()
            {
                Nodes = nodes.ToArray(),
                Indices = indices,
            });
        }