Ejemplo n.º 1
0
        private void GenerateSkinnedMesh(Device device, GMeshContainer container)
        {
            //max number of bone influences per vertex
            int maxVertexInfluence;

            BoneCombination[] combinedBones;

            var skeletalRender = (SkelletalMeshRender)Engine.RenderManager.GetRender <SkelletalMeshNode>();

            if (skeletalRender == null)
            {
                throw new InvalidOperationException("An skeletalModelRender is not defined");
            }

            int maxPaletteEntries = skeletalRender.MaxPaletteMatrices;

            int numPaletteEntries = Math.Min(maxPaletteEntries, container.SkinInfo.BoneCount);

            container.NumPaletteEntries = numPaletteEntries;
            container.Mesh = container.SkinInfo.ConvertToIndexedBlendedMesh(container.MeshData.Mesh,
                                                                            container.NumPaletteEntries,
                                                                            container.GetAdjacency(),
                                                                            out maxVertexInfluence,
                                                                            out combinedBones);
            container.BoneCombinations    = combinedBones;
            container.MaxVertexInfluences = maxVertexInfluence;
        }
Ejemplo n.º 2
0
        public MeshContainer CreateMeshContainer(string name, MeshData meshData, ExtendedMaterial[] materials, EffectInstance[] effectInstances, int[] adjacency, SkinInfo skinInfo)
        {
            var            device        = meshData.Mesh.Device;
            GMeshContainer meshContainer = new GMeshContainer();

            meshContainer.Name = name;
            SlimDX.Direct3D9.Mesh mesh = meshData.Mesh;
            if (!mesh.VertexFormat.HasFlag(VertexFormat.Normal))
            {
                meshContainer.MeshData = new MeshData(mesh.Clone(device, mesh.CreationOptions, mesh.VertexFormat | VertexFormat.Normal));
                meshContainer.MeshData.Mesh.ComputeNormals();
            }
            else
            {
                meshContainer.MeshData = new MeshData(mesh);
            }

            meshContainer.SetMaterials(materials);
            meshContainer.SetAdjacency(adjacency);

            meshContainer.SkinInfo = skinInfo;

            meshContainer.BoneOffsetsMatrix = new Matrix[skinInfo.BoneCount];
            for (int i = 0; i < skinInfo.BoneCount; i++)
            {
                meshContainer.BoneOffsetsMatrix[i] = skinInfo.GetBoneOffsetMatrix(i);
            }

            GenerateSkinnedMesh(device, meshContainer);

            return(meshContainer);
        }
Ejemplo n.º 3
0
        private SkelletalMesh GetMesh(GMeshContainer meshContainer, Bone root, VertexDescriptor vd)
        {
            SlimDX.Direct3D9.Mesh d3dMesh = meshContainer.Mesh;

            var adjacency                 = meshContainer.GetAdjacency();
            var meshMaterials             = meshContainer.GetMaterials();
            List <MeshMaterial> materials = new List <MeshMaterial>();

            for (int i = 0; i < meshMaterials.Length; i++)
            {
                var matd3d = meshMaterials[i].MaterialD3D;

                string textureFilename = meshMaterials[i].TextureFileName;
                if (textureFilename != null && !Path.IsPathRooted(textureFilename))
                {
                    textureFilename = Path.Combine(Path.GetDirectoryName(xFile), textureFilename);
                }

                materials.Add(new MeshMaterial()
                {
                    Name          = root.Name + "_material" + i,
                    Alpha         = matd3d.Diffuse.Alpha,
                    Diffuse       = matd3d.Diffuse.ToVector3(),
                    Specular      = matd3d.Specular.ToVector3(),
                    SpecularPower = Math.Max(1, matd3d.Power),
                    Reflectivity  = 0,
                    Refractitity  = 0,
                    EmissiveColor = matd3d.Emissive.ToVector3(),
                    DiffuseMap    = textureFilename
                });
            }


            SkelletalMesh mesh = new SkelletalMesh(vd);

            mesh.Adjacency = adjacency;
            SkinVertex[] vertexes = new SkinVertex[d3dMesh.VertexCount];
            Array        indices;

            if (d3dMesh.IndexBuffer.Description.Format == Format.Index16)
            {
                indices = new ushort[d3dMesh.FaceCount * 3];
            }
            else
            {
                indices = new uint[d3dMesh.FaceCount * 3];
            }

            VertexDescriptor meshVD = new VertexDescriptor(d3dMesh.GetDeclaration());
            int positionOffset      = meshVD.GetOffset(DeclarationUsage.Position, 0);
            int normalOffset        = meshVD.GetOffset(DeclarationUsage.Normal, 0);
            int texCoordOffset      = meshVD.GetOffset(DeclarationUsage.TextureCoordinate, 0);
            int blendIndicesOffset  = meshVD.GetOffset(DeclarationUsage.BlendIndices, 0);
            int blendIndicesSize    = meshVD.SizeOfElement(DeclarationUsage.BlendIndices, 0);
            int blendWeightsOffset  = meshVD.GetOffset(DeclarationUsage.BlendWeight, 0);
            int blendWeightSize     = meshVD.SizeOfElement(DeclarationUsage.BlendWeight, 0);

            byte[] buffer;
            unsafe
            {
                DataStream vertexStream = d3dMesh.LockVertexBuffer(0);
                buffer = new byte[vertexStream.Length];
                vertexStream.Read(buffer, 0, (int)vertexStream.Length);
                fixed(byte *_pter = buffer)
                {
                    fixed(SkinVertex *pVertexes = vertexes)
                    {
                        byte *pter = _pter;
                        int   j    = 0;

                        for (int i = 0; i < d3dMesh.VertexCount; i++)
                        {
                            pVertexes[i].Position = *((Vector3 *)(pter + positionOffset));

                            if (normalOffset >= 0)
                            {
                                pVertexes[i].Normal = *((Vector3 *)(pter + normalOffset));
                            }
                            if (texCoordOffset >= 0)
                            {
                                pVertexes[i].TexCoord = *((Vector2 *)(pter + texCoordOffset));
                            }
                            if (blendIndicesOffset >= 0)
                            {
                                byte *indicesPter = (pter + blendIndicesOffset);
                                uint *pDest       = (uint *)&(pVertexes[i].BlendIndices);
                                for (j = 0; j < blendIndicesSize; j++)
                                {
                                    *(((byte *)pDest) + j) = *(indicesPter + j);
                                }
                            }
                            if (blendWeightsOffset >= 0)
                            {
                                byte *   weightsPter = (pter + blendWeightsOffset);
                                Vector4 *pDest       = &(pVertexes[i].BlendWeights);

                                for (j = 0; j < blendWeightSize; j++)
                                {
                                    *(((byte *)pDest) + j) = *(weightsPter + j);
                                }
                            }

                            pter += d3dMesh.BytesPerVertex;
                        }
                    }
                }

                d3dMesh.UnlockVertexBuffer();

                DataStream indexStream = d3dMesh.LockIndexBuffer(0);
                GCHandle   handler     = GCHandle.Alloc(indices, GCHandleType.Pinned);
                IntPtr     indexPter   = Marshal.UnsafeAddrOfPinnedArrayElement(indices, 0);

                buffer = new byte[indexStream.Length];
                indexStream.Read(buffer, 0, (int)indexStream.Length);
                Marshal.Copy(buffer, 0, indexPter, buffer.Length);

                handler.Free();
                d3dMesh.UnlockIndexBuffer();
            }

            mesh.CreateVertexBuffer(vertexes);
            if (d3dMesh.IndexBuffer.Description.Format == Format.Index16)
            {
                mesh.CreateIndexBuffer((ushort[])indices);
            }
            else
            {
                mesh.CreateIndexBuffer((uint[])indices);
            }

            List <MeshLayer> layers = new List <MeshLayer>();

            if (meshContainer.BoneCombinations == null || meshContainer.BoneCombinations.Length == 0)
            {
                MeshLayer component = new MeshLayer();
                materials.Add(MeshMaterial.CreateDefaultMaterial(meshContainer.Name + "_default"));
                component.materialIndex  = 0;
                component.primitiveCount = mesh.FaceCount;
                component.startIndex     = 0;
                component.startVertex    = 0;
                component.vertexCount    = mesh.VertexCount;
                layers.Add(component);
            }
            else
            {
                for (int i = 0; i < meshContainer.BoneCombinations.Length; i++)
                {
                    BoneCombination comb = meshContainer.BoneCombinations[i];

                    MeshLayer component = new MeshLayer();
                    component.materialIndex  = comb.AttributeId;
                    component.primitiveCount = comb.FaceCount;
                    component.startIndex     = comb.FaceStart * 3;
                    component.startVertex    = comb.VertexStart;
                    component.vertexCount    = comb.VertexCount;

                    layers.Add(component);
                }
            }

            var layerArray = layers.ToArray();

            mesh.Materials = materials.ToArray();
            mesh.SetLayers(layerArray);

            var skinInfo = meshContainer.SkinInfo;

            mesh.MaxVertexInfluences = skinInfo.MaximumVertexInfluences;

            var bones = new Bone[skinInfo.BoneCount];
            var boneOffsetMatrices = new Matrix[bones.Length];

            for (int i = 0; i < bones.Length; i++)
            {
                bones[i] = root.FindChild(skinInfo.GetBoneName(i));
                boneOffsetMatrices[i] = skinInfo.GetBoneOffsetMatrix(i);
            }

            mesh.Bones = bones;
            mesh.BoneBindingMatrices = boneOffsetMatrices;

            if (meshContainer.BoneCombinations != null && meshContainer.BoneCombinations.Length > 0)
            {
                for (int layerIndex = 0; layerIndex < layerArray.Length; layerIndex++)
                {
                    mesh.SetLayerBones(layerIndex, meshContainer.BoneCombinations[layerIndex].BoneIds);
                }
            }

            mesh.LockVertexBuffer();
            int[]   vertices;
            float[] weights;
            for (int i = 0; i < mesh.bones.Length; i++)
            {
                skinInfo.GetBoneInfluence(i, out vertices, out weights);
                VertexStreamView <Vector3> positions = mesh.GetVertexViewStream <Vector3>(DeclarationUsage.Position, 0, vertices);
            }
            mesh.UnlockVertexBuffer();

            meshVD.Dispose();

            if (normalOffset < 0)
            {
                mesh.ComputeNormals();
            }
            if (texCoordOffset < 0)
            {
                mesh.ComputeTextureCoords(CoordMappingType.Spherical);
            }

            mesh.ComputeTangents();

            return(mesh);
        }