private void BuildRenderableMeshes(Model model)
        {
            List<short> indices = new List<short>();
            List<InstancedVertexPositionNormalTextureBumpSkin> vertices = new List<InstancedVertexPositionNormalTextureBumpSkin>();
            Dictionary<int, int> indexRemap = new Dictionary<int, int>();

            // Get the model transforms for baking down vertices into object space (XNA Models are stored in mesh space).
            Matrix[] boneArray = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(boneArray);


            foreach (ModelMesh modelMesh in model.Meshes)
            {
                Debug.WriteLine("Building " + modelMesh.Name);
                Matrix meshToObject = boneArray[modelMesh.ParentBone.Index];

                for(int p=0;p<modelMesh.MeshParts.Count;p++)
                {
                    ModelMeshPart modelMeshPart = modelMesh.MeshParts[p];

                    int vertexCount = modelMeshPart.VertexBuffer.VertexCount;
                    int indexCount = modelMeshPart.IndexBuffer.IndexCount;

                    indexRemap.Clear();

                    vertices.Clear();
                    indices.Clear();

                    // Create a material for this meshpart
                    // TODO: Group data by effects 
                    DeferredSasEffect partEffect = (DeferredSasEffect)_sourceEffect.Clone();
                    partEffect.Parameters["AnimationTexture"].SetValue(_animationTexture);
                    partEffect.Parameters["BoneDelta"].SetValue(1f / _animationTexture.Width);
                    partEffect.Parameters["RowDelta"].SetValue(1f / _animationTexture.Height);
                    DeferredObjectEffect effect = (DeferredObjectEffect) modelMeshPart.Effect;
                    partEffect.Parameters["DiffuseTexture"].SetValue(effect.DiffuseMapTexture);                    

                    short[] sourceIndices = new short[modelMeshPart.PrimitiveCount*3];
                    modelMeshPart.IndexBuffer.GetData<short>(modelMeshPart.StartIndex*2,sourceIndices,0,modelMeshPart.PrimitiveCount*3);

                    InstancedVertexPositionNormalTextureBumpSkin[] sourceVertices = new InstancedVertexPositionNormalTextureBumpSkin[modelMeshPart.NumVertices];
                    modelMeshPart.VertexBuffer.GetData<InstancedVertexPositionNormalTextureBumpSkin>(modelMeshPart.VertexOffset * modelMeshPart.VertexBuffer.VertexDeclaration.VertexStride, sourceVertices, 0, modelMeshPart.NumVertices, modelMeshPart.VertexBuffer.VertexDeclaration.VertexStride);

                    for (int instance = 0; instance < _maxInstances; instance++)
                    {
                        for (int i = 0; i < sourceIndices.Length; i++)
                        {
                            indices.Add((short) ((sourceIndices[i]) + (instance * sourceVertices.Length))) ;
                        }

                        for (int i = 0; i < sourceVertices.Length; i++)
                        {
                            sourceVertices[i].TextureCoordinate2 = new Vector2(instance, 0);
                            vertices.Add(sourceVertices[i]);
                        }
                    }

                    VertexBuffer vertexBuffer = new VertexBuffer(_graphicsDevice, typeof(InstancedVertexPositionNormalTextureBumpSkin), vertices.Count, BufferUsage.None);
                    vertexBuffer.SetData<InstancedVertexPositionNormalTextureBumpSkin>(vertices.ToArray());
                    IndexBuffer indexBuffer = new IndexBuffer(_graphicsDevice, IndexElementSize.SixteenBits, indices.Count, BufferUsage.None);
                    indexBuffer.SetData<short>(indices.ToArray());

                    RenderableMesh renderableMesh = new RenderableMesh();
                    renderableMesh.Build(this, partEffect, Matrix.Identity, _boundingSphere, _boundingBox,
                        indexBuffer, vertexBuffer, 0, PrimitiveType.TriangleList, indexBuffer.IndexCount / 3, 0, vertexBuffer.VertexCount, 0, true);
                    base.Add(renderableMesh);

                }
            }
        }
Example #2
0
        private void BuildRenderableMeshes(Model model)
        {
            List <short> indices = new List <short>();
            List <InstancedVertexPositionNormalTextureBumpSkin> vertices = new List <InstancedVertexPositionNormalTextureBumpSkin>();
            Dictionary <int, int> indexRemap = new Dictionary <int, int>();

            // Get the model transforms for baking down vertices into object space (XNA Models are stored in mesh space).
            Matrix[] boneArray = new Matrix[model.Bones.Count];
            model.CopyAbsoluteBoneTransformsTo(boneArray);


            foreach (ModelMesh modelMesh in model.Meshes)
            {
                Debug.WriteLine("Building " + modelMesh.Name);
                Matrix meshToObject = boneArray[modelMesh.ParentBone.Index];

                for (int p = 0; p < modelMesh.MeshParts.Count; p++)
                {
                    ModelMeshPart modelMeshPart = modelMesh.MeshParts[p];

                    int vertexCount = modelMeshPart.VertexBuffer.VertexCount;
                    int indexCount  = modelMeshPart.IndexBuffer.IndexCount;

                    indexRemap.Clear();

                    vertices.Clear();
                    indices.Clear();

                    // Create a material for this meshpart
                    // TODO: Group data by effects
                    DeferredSasEffect partEffect = (DeferredSasEffect)_sourceEffect.Clone();
                    partEffect.Parameters["AnimationTexture"].SetValue(_animationTexture);
                    partEffect.Parameters["BoneDelta"].SetValue(1f / _animationTexture.Width);
                    partEffect.Parameters["RowDelta"].SetValue(1f / _animationTexture.Height);
                    DeferredObjectEffect effect = (DeferredObjectEffect)modelMeshPart.Effect;
                    partEffect.Parameters["DiffuseTexture"].SetValue(effect.DiffuseMapTexture);

                    short[] sourceIndices = new short[modelMeshPart.PrimitiveCount * 3];
                    modelMeshPart.IndexBuffer.GetData <short>(modelMeshPart.StartIndex * 2, sourceIndices, 0, modelMeshPart.PrimitiveCount * 3);

                    InstancedVertexPositionNormalTextureBumpSkin[] sourceVertices = new InstancedVertexPositionNormalTextureBumpSkin[modelMeshPart.NumVertices];
                    modelMeshPart.VertexBuffer.GetData <InstancedVertexPositionNormalTextureBumpSkin>(modelMeshPart.VertexOffset * modelMeshPart.VertexBuffer.VertexDeclaration.VertexStride, sourceVertices, 0, modelMeshPart.NumVertices, modelMeshPart.VertexBuffer.VertexDeclaration.VertexStride);

                    for (int instance = 0; instance < _maxInstances; instance++)
                    {
                        for (int i = 0; i < sourceIndices.Length; i++)
                        {
                            indices.Add((short)((sourceIndices[i]) + (instance * sourceVertices.Length)));
                        }

                        for (int i = 0; i < sourceVertices.Length; i++)
                        {
                            sourceVertices[i].TextureCoordinate2 = new Vector2(instance, 0);
                            vertices.Add(sourceVertices[i]);
                        }
                    }

                    VertexBuffer vertexBuffer = new VertexBuffer(_graphicsDevice, typeof(InstancedVertexPositionNormalTextureBumpSkin), vertices.Count, BufferUsage.None);
                    vertexBuffer.SetData <InstancedVertexPositionNormalTextureBumpSkin>(vertices.ToArray());
                    IndexBuffer indexBuffer = new IndexBuffer(_graphicsDevice, IndexElementSize.SixteenBits, indices.Count, BufferUsage.None);
                    indexBuffer.SetData <short>(indices.ToArray());

                    RenderableMesh renderableMesh = new RenderableMesh();
                    renderableMesh.Build(this, partEffect, Matrix.Identity, _boundingSphere, _boundingBox,
                                         indexBuffer, vertexBuffer, 0, PrimitiveType.TriangleList, indexBuffer.IndexCount / 3, 0, vertexBuffer.VertexCount, 0, true);
                    base.Add(renderableMesh);
                }
            }
        }