예제 #1
0
        public void Dispose()
        {
            for (int i = 0; i < meshFrames.Count; i++)
            {
                AnimationMeshContainer mesh = (AnimationMeshContainer)meshFrames[i].MeshContainer;
                while (mesh != null)
                {
                    if ((mesh.MeshData != null) && (mesh.MeshData.Mesh != null))
                    {
                        mesh.MeshData.Mesh.Dispose();
                    }

/*					for (int j = 0; j < Textures.Length; j++)
 *                                      {
 *                                              Texture tex = Textures[j];
 *                                              if ((tex != null) && !tex.Disposed)
 *                                              {
 *                                                      tex.Dispose();
 *                                              }
 *                                      }*/

                    mesh = (AnimationMeshContainer)mesh.NextMeshContainer;
                }
            }

            rootFrame.Dispose();
            AnimationController.Dispose();

            IsDisposed = true;
        }
예제 #2
0
        public void HighlightBone(remParser parser, remMesh remMesh, int boneIdx, bool show)
        {
            List <List <remVertex> > submeshVertLists   = new List <List <remVertex> >(remMesh.numMats);
            List <List <ushort> >    submeshFaceLists   = new List <List <ushort> >(remMesh.numMats);
            List <int[]>             submeshVertIndices = new List <int[]>(remMesh.numMats);

            SplitMesh(remMesh, submeshVertLists, submeshFaceLists, submeshVertIndices);
            remSkin boneList = rem.FindSkin(remMesh.name, parser.SKIC);

            int submeshIdx = 0;

            for (AnimationMeshContainer mesh = (AnimationMeshContainer)meshFrames[0].MeshContainer;
                 mesh != null;
                 mesh = (AnimationMeshContainer)mesh.NextMeshContainer, submeshIdx++)
            {
                if (mesh.MeshData != null && mesh.MeshData.Mesh != null)
                {
                    List <remVertex> vertexList        = submeshVertLists[submeshIdx];
                    byte[][]         vertexBoneIndices = null;
                    float[][]        vertexWeights     = ConvertVertexWeights(vertexList, submeshVertIndices[submeshIdx], boneList, out vertexBoneIndices);
                    FillVertexBuffer(mesh.MeshData.Mesh, vertexList, vertexWeights, vertexBoneIndices, show ? boneIdx : -1);
                }
                if (mesh.BoneLines != null)
                {
                    for (int j = 0; j < BoneObjSize; j++)
                    {
                        mesh.BoneLines[boneIdx * BoneObjSize + j].Color = show ? Color.Crimson.ToArgb(): Color.CornflowerBlue.ToArgb();
                    }
                }
            }
        }
예제 #3
0
        /// <summary>
        /// Vraci pocet matic mezi kterzmi se interpoluje pri vykreslovani animace
        /// </summary>
        /// <returns>pocet matic</returns>
        public override int GetMatrixWorldCount()
        {
            if (meshes.Count > 0)
            {
                AnimationMeshContainer mesh = meshes[0].MeshContainer as AnimationMeshContainer;
                return(mesh.NumberPaletteEntries);
            }

            return(base.GetMatrixWorldCount());
        }
예제 #4
0
 private void DrawMeshFrame(AnimationFrame frame)
 {
     submeshNum = 0;
     for (AnimationMeshContainer meshContainer = (AnimationMeshContainer)frame.MeshContainer;
          meshContainer != null;
          meshContainer = (AnimationMeshContainer)meshContainer.NextMeshContainer, submeshNum++)
     {
         DrawMeshContainer(meshContainer, frame);
     }
 }
예제 #5
0
        public void HighlightBone(odfParser parser, int meshIdx, int submeshIdx, int boneIdx)
        {
            const int boneObjSize = 16;

            odfSubmesh  submesh       = parser.MeshSection[meshIdx][submeshIdx];
            odfBoneList boneList      = odf.FindBoneList(submesh.Id, parser.EnvelopeSection);
            string      boneFrameName = null;

            if (boneIdx >= 0)
            {
                odfBone bone = boneList[boneIdx];
                boneFrameName = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name;
            }

            AnimationMeshContainer mesh = (AnimationMeshContainer)meshFrames[0].MeshContainer;

            for (int i = 0; mesh != null; i++)
            {
                if (i == submeshIdx && (mesh.MeshData != null) && (mesh.MeshData.Mesh != null))
                {
                    List <odfVertex> vertexList    = submesh.VertexList;
                    float[][]        vertexWeights = ConvertVertexWeights(vertexList, boneList);
                    FillVertexBuffer(mesh.MeshData.Mesh, vertexList, vertexWeights, boneIdx);
//					break;
                }
                if (boneIdx >= 0)
                {
                    for (int idx = 0; idx < mesh.BoneLines.Length / boneObjSize; idx++)
                    {
                        if (mesh.BoneNames[idx] == boneFrameName)
                        {
                            for (int j = 0; j < boneObjSize; j++)
                            {
                                mesh.BoneLines[idx * boneObjSize + j].Color = Color.Crimson.ToArgb();
                            }
                            break;
                        }
                    }
                }
                else
                {
                    for (int idx = 0; idx < mesh.BoneLines.Length / boneObjSize; idx++)
                    {
                        for (int j = 0; j < boneObjSize; j++)
                        {
                            mesh.BoneLines[idx * boneObjSize + j].Color = Color.CornflowerBlue.ToArgb();
                        }
                    }
                }
                mesh = (AnimationMeshContainer)mesh.NextMeshContainer;
            }
        }
예제 #6
0
            /// <summary>Create a new mesh container</summary>
            public override MeshContainer CreateMeshContainer(string name,
                                                              MeshData meshData, ExtendedMaterial[] materials,
                                                              EffectInstance[] effectInstances, GraphicsStream adjacency,
                                                              SkinInformation skinInfo)
            {
                // We only handle meshes here
                if (meshData.Mesh == null)
                {
                    throw new ArgumentException();
                }

                // We must have a vertex format mesh
                if (meshData.Mesh.VertexFormat == VertexFormats.None)
                {
                    throw new ArgumentException();
                }

                AnimationMeshContainer mesh = new AnimationMeshContainer();

                mesh.adjency = adjacency;
                mesh.Name    = name;
                int    numFaces = meshData.Mesh.NumberFaces;
                Device dev      = meshData.Mesh.Device;


                // Store the materials
                mesh.SetMaterials(materials);
                mesh.SetAdjacency(adjacency);

                Texture[] meshTextures = new Texture[materials.Length];
                mesh.MeshData = meshData;

                // If there is skinning info, save any required data
                if (skinInfo != null)
                {
                    mesh.SkinInformation = skinInfo;
                    int      numBones       = skinInfo.NumberBones;
                    Matrix[] offsetMatrices = new Matrix[numBones];

                    for (int i = 0; i < numBones; i++)
                    {
                        offsetMatrices[i] = skinInfo.GetBoneOffsetMatrix(i);
                    }

                    mesh.SetOffsetMatrices(offsetMatrices);

                    GenerateSkinnedMesh(mesh, adjacency);
                }

                return(mesh);
            }
예제 #7
0
        /// <summary>Vypocet a nastaveni world matic podle kosti</summary>
        private void DrawMeshContainer(AnimationMeshContainer mesh, AnimationFrame parent, int iAttrib)
        {
            BoneCombination[] bones = mesh.GetBones();

            for (int iPaletteEntry = 0; iPaletteEntry < mesh.NumberPaletteEntries;
                 ++iPaletteEntry)
            {
                int iMatrixIndex = bones[iAttrib].BoneId[iPaletteEntry];
                if (iMatrixIndex != -1)
                {
                    SetMatricesWorldByIndex(mesh.GetOffsetMatrices()[iMatrixIndex] *
                                            mesh.GetFrames()[iMatrixIndex].
                                            CombinedTransformationMatrix, iPaletteEntry);
                }
            }
        }
예제 #8
0
            /// <summary>
            /// Vztvoreni skinned meshe
            /// </summary>
            /// <param name="mesh">Container s meshem</param>
            /// <param name="adjacency">adjacency</param>
            static void GenerateSkinnedMesh(AnimationMeshContainer mesh, GraphicsStream adjacency)
            {
                if (mesh.SkinInformation == null)
                {
                    throw new ArgumentException();  // There is nothing to generate
                }
                MeshFlags flags = MeshFlags.OptimizeVertexCache;

                flags |= MeshFlags.Managed;


                int numMaxFaceInfl;

                using (IndexBuffer ib = mesh.MeshData.Mesh.IndexBuffer)
                {
                    numMaxFaceInfl = mesh.SkinInformation.GetMaxFaceInfluences(ib,
                                                                               mesh.MeshData.Mesh.NumberFaces);
                }
                // 12 entry palette guarantees that any triangle (4 independent
                // influences per vertex of a tri) can be handled
                numMaxFaceInfl = (int)Math.Min(numMaxFaceInfl, 12);


                mesh.NumberPaletteEntries = 4;

                int influences = 0;

                BoneCombination[] bones = null;

                // Use ConvertToBlendedMesh to generate a drawable mesh
                MeshData data = mesh.MeshData;

                data.Mesh = mesh.SkinInformation.ConvertToIndexedBlendedMesh(data.Mesh, flags, mesh.GetAdjacencyStream(), mesh.NumberPaletteEntries, out influences, out bones);



                int use32Bit = (int)(data.Mesh.Options.Value & MeshFlags.Use32Bit);


                mesh.NumberInfluences = influences;
                mesh.SetBones(bones);

                // Get the number of attributes
                mesh.NumberAttributes = bones.Length;

                mesh.MeshData = data;
            }
예제 #9
0
        private void SetupBoneMatrices(AnimationFrame frame, AnimationFrame root)
        {
            for (AnimationMeshContainer mesh = (AnimationMeshContainer)frame.MeshContainer;
                 mesh != null;
                 mesh = (AnimationMeshContainer)mesh.NextMeshContainer)
            {
                int numBones = mesh.BoneNames.Length;
                if (numBones <= 0)
                {
                    continue;
                }

                AnimationFrame[] boneFrames = new AnimationFrame[numBones];
                for (int i = 0; i < numBones; i++)
                {
                    AnimationFrame boneFrame = (AnimationFrame)root.FindChild(mesh.BoneNames[i]);
                    boneFrames[i] = boneFrame;
                }
                mesh.BoneFrames = boneFrames;

                float boneWidth = 0.1f;
                int   boneColor = Color.CornflowerBlue.ToArgb();
                PositionBlendWeightIndexedColored[] boneLines = new PositionBlendWeightIndexedColored[numBones * BoneObjSize];
                for (byte i = 0; i < numBones; i++)
                {
                    AnimationFrame bone = boneFrames[i];

                    if (bone != null && bone.Parent != null)
                    {
                        byte parentBoneIdx = 0xFF;
                        for (byte j = 0; j < mesh.BoneNames.Length; j++)
                        {
                            if (mesh.BoneNames[j] == bone.Parent.Name)
                            {
                                parentBoneIdx = j;
                                break;
                            }
                        }
                        if (parentBoneIdx == 0xFF)
                        {
                            continue;
                        }
                        Matrix boneMatrix       = Matrix.Invert(mesh.BoneOffsets[i]);
                        Matrix boneParentMatrix = Matrix.Invert(mesh.BoneOffsets[parentBoneIdx]);

                        Vector3 bonePos       = Vector3.TransformCoordinate(new Vector3(), boneMatrix);
                        Vector3 boneParentPos = Vector3.TransformCoordinate(new Vector3(), boneParentMatrix);

                        Vector3 direction     = bonePos - boneParentPos;
                        Vector3 perpendicular = direction.Perpendicular();
                        Vector3 cross         = Vector3.Cross(direction, perpendicular);
                        perpendicular = Vector3.Normalize(perpendicular) * boneWidth;
                        cross         = Vector3.Normalize(cross) * boneWidth;

                        Vector3 bottomLeft  = -perpendicular + -cross + boneParentPos;
                        Vector3 bottomRight = -perpendicular + cross + boneParentPos;
                        Vector3 topLeft     = perpendicular + -cross + boneParentPos;
                        Vector3 topRight    = perpendicular + cross + boneParentPos;

                        boneLines[i * BoneObjSize]       = new PositionBlendWeightIndexedColored(bottomLeft, parentBoneIdx, boneColor);
                        boneLines[(i * BoneObjSize) + 1] = new PositionBlendWeightIndexedColored(bottomRight, parentBoneIdx, boneColor);
                        boneLines[(i * BoneObjSize) + 2] = new PositionBlendWeightIndexedColored(bottomRight, parentBoneIdx, boneColor);
                        boneLines[(i * BoneObjSize) + 3] = new PositionBlendWeightIndexedColored(topRight, parentBoneIdx, boneColor);
                        boneLines[(i * BoneObjSize) + 4] = new PositionBlendWeightIndexedColored(topRight, parentBoneIdx, boneColor);
                        boneLines[(i * BoneObjSize) + 5] = new PositionBlendWeightIndexedColored(topLeft, parentBoneIdx, boneColor);
                        boneLines[(i * BoneObjSize) + 6] = new PositionBlendWeightIndexedColored(topLeft, parentBoneIdx, boneColor);
                        boneLines[(i * BoneObjSize) + 7] = new PositionBlendWeightIndexedColored(bottomLeft, parentBoneIdx, boneColor);

                        boneLines[(i * BoneObjSize) + 8]  = new PositionBlendWeightIndexedColored(bottomLeft, parentBoneIdx, boneColor);
                        boneLines[(i * BoneObjSize) + 9]  = new PositionBlendWeightIndexedColored(bonePos, i, boneColor);
                        boneLines[(i * BoneObjSize) + 10] = new PositionBlendWeightIndexedColored(bottomRight, parentBoneIdx, boneColor);
                        boneLines[(i * BoneObjSize) + 11] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor);
                        boneLines[(i * BoneObjSize) + 12] = new PositionBlendWeightIndexedColored(topLeft, parentBoneIdx, boneColor);
                        boneLines[(i * BoneObjSize) + 13] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor);
                        boneLines[(i * BoneObjSize) + 14] = new PositionBlendWeightIndexedColored(topRight, parentBoneIdx, boneColor);
                        boneLines[(i * BoneObjSize) + 15] = new PositionBlendWeightIndexedColored(bonePos, i, boneColor);
                    }
                }

                mesh.BoneLines = boneLines;
            }

            if (frame.Sibling != null)
            {
                SetupBoneMatrices(frame.Sibling as AnimationFrame, root);
            }

            if (frame.FirstChild != null)
            {
                SetupBoneMatrices(frame.FirstChild as AnimationFrame, root);
            }
        }
예제 #10
0
        private AnimationFrame CreateFrame(remBone frame, remParser parser, HashSet <string> extractFrames, remMesh mesh, Device device, Matrix combinedParent, List <AnimationFrame> meshFrames)
        {
            AnimationFrame animationFrame = new AnimationFrame();

            animationFrame.Name = frame.name.ToString();
            animationFrame.TransformationMatrix = frame.matrix;
            animationFrame.OriginalTransform    = animationFrame.TransformationMatrix;
            animationFrame.CombinedTransform    = combinedParent * animationFrame.TransformationMatrix;

            if (frame.name == mesh.frame)
            {
                ExtendedMaterial[] materials = new ExtendedMaterial[mesh.numMats];

                List <List <remVertex> > submeshVertLists   = new List <List <remVertex> >(mesh.numMats);
                List <List <ushort> >    submeshFaceLists   = new List <List <ushort> >(mesh.numMats);
                List <int[]>             submeshVertIndices = new List <int[]>(mesh.numMats);
                SplitMesh(mesh, submeshVertLists, submeshFaceLists, submeshVertIndices);

                remSkin       boneList        = rem.FindSkin(mesh.name, parser.SKIC);
                bool          skinned         = boneList != null;
                int           numBones        = skinned ? boneList.Count : 0;
                List <string> boneNamesList   = new List <string>(numBones);
                List <Matrix> boneOffsetsList = new List <Matrix>(numBones);
                for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                {
                    boneNamesList.Add(boneList[boneIdx].bone.ToString());
                    boneOffsetsList.Add(boneList[boneIdx].matrix);
                }
                List <string> boneFrameParentNames    = new List <string>(numBones);
                List <Matrix> boneFrameParentMatrices = new List <Matrix>(numBones);
                for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                {
                    remBone boneFrame = rem.FindFrame(boneList[boneIdx].bone, parser.BONC.rootFrame);
                    if (boneFrame == null)
                    {
                        continue;
                    }
                    remBone boneFrameParent = boneFrame.Parent;
                    if (!boneNamesList.Contains(boneFrameParent.name) && !boneFrameParentNames.Contains(boneFrameParent.name))
                    {
                        boneFrameParentNames.Add(boneFrameParent.name);
                        Matrix incompleteMeshFrameCorrection = Matrix.Invert(frame.matrix);
                        boneFrameParentMatrices.Add(incompleteMeshFrameCorrection * Matrix.Invert(boneFrame.matrix) * boneList[boneIdx].matrix);
                    }
                }
                boneNamesList.AddRange(boneFrameParentNames);
                string[] boneNames = boneNamesList.ToArray();
                boneOffsetsList.AddRange(boneFrameParentMatrices);
                Matrix[] boneOffsets = boneOffsetsList.ToArray();

                AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[submeshFaceLists.Count];
                Vector3 min = new Vector3(Single.MaxValue);
                Vector3 max = new Vector3(Single.MinValue);
                for (int i = 0; i < submeshFaceLists.Count; i++)
                {
                    List <ushort>    faceList   = submeshFaceLists[i];
                    List <remVertex> vertexList = submeshVertLists[i];

                    Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format);

                    using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None))
                    {
                        for (int j = 0; j < faceList.Count; j++)
                        {
                            indexStream.Write(faceList[j]);
                        }
                        animationMesh.UnlockIndexBuffer();
                    }

                    byte[][]  vertexBoneIndices = null;
                    float[][] vertexWeights     = ConvertVertexWeights(vertexList, submeshVertIndices[i], boneList, out vertexBoneIndices);
                    FillVertexBuffer(animationMesh, vertexList, vertexWeights, vertexBoneIndices, -1);

                    var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2];
                    for (int j = 0; j < vertexList.Count; j++)
                    {
                        remVertex vertex      = vertexList[j];
                        Vector3   position    = vertex.Position;
                        Vector3   normal      = vertex.Normal;
                        float[]   boneWeights = vertexWeights[j];

                        normalLines[j * 2]       = new PositionBlendWeightsIndexedColored(position, boneWeights, vertexBoneIndices[j], Color.Coral.ToArgb());
                        normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(position + normal, boneWeights, vertexBoneIndices[j], Color.Blue.ToArgb());

#if !DONT_MIRROR
                        position.Z *= -1f;
#endif
                        min = Vector3.Minimize(min, position);
                        max = Vector3.Maximize(max, position);
                    }

                    AnimationMeshContainer meshContainer = new AnimationMeshContainer();
                    meshContainer.Name        = animationFrame.Name;
                    meshContainer.MeshData    = new MeshData(animationMesh);
                    meshContainer.NormalLines = normalLines;
                    meshContainer.BoneNames   = boneNames;
                    meshContainer.BoneOffsets = boneOffsets;
                    meshContainers[i]         = meshContainer;

                    remMaterial mat = rem.FindMaterial(mesh.materials[i], parser.MATC);
                    if (mat != null)
                    {
                        Material material3D = new Material();
                        material3D.Ambient  = new Color4(mat.ambient);
                        material3D.Diffuse  = new Color4(mat.diffuse);
                        material3D.Emissive = new Color4(mat.emissive);
                        material3D.Specular = new Color4(mat.specular);
                        material3D.Power    = mat.specularPower;
                        int matIdx = parser.MATC.IndexOf(mat);
                        Materials[matIdx]           = material3D;
                        meshContainer.MaterialIndex = matIdx;

                        int texIdx = 0;
                        if (mat.texture != null && !TextureDic.TryGetValue(mat.texture.ToString(), out texIdx))
                        {
                            ImportedTexture importedTex = null;
                            if (!ImportedTextures.TryGetValue(mat.texture.ToString(), out importedTex))
                            {
                                importedTex = rem.ImportedTexture(mat.texture, parser.RemPath, true);
                                if (importedTex == null)
                                {
                                    Report.ReportLog("Export textures of TEXH.FPK!");
                                    continue;
                                }
                                ImportedTextures.Add(mat.texture.ToString(), importedTex);
                            }
                            Texture memTex = Texture.FromMemory(device, importedTex.Data);
                            texIdx = TextureDic.Count;
                            TextureDic.Add(mat.texture.ToString(), texIdx);
                            Textures.Add(memTex);
                        }
                        meshContainer.TextureIndex = texIdx;
                    }
                }

                for (int i = 0; i < (meshContainers.Length - 1); i++)
                {
                    meshContainers[i].NextMeshContainer = meshContainers[i + 1];
                }

                min = Vector3.TransformCoordinate(min, animationFrame.CombinedTransform);
                max = Vector3.TransformCoordinate(max, animationFrame.CombinedTransform);
                animationFrame.Bounds        = new BoundingBox(min, max);
                animationFrame.MeshContainer = meshContainers[0];
                meshFrames.Add(animationFrame);
            }

            for (int i = 0; i < frame.Count; i++)
            {
                remBone child = frame[i];
                if (extractFrames.Contains(child.name.ToString()))
                {
                    AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, mesh, device, animationFrame.CombinedTransform, meshFrames);
                    childAnimationFrame.Parent = animationFrame;
                    animationFrame.AppendChild(childAnimationFrame);
                }
            }

            numFrames++;
            return(animationFrame);
        }
예제 #11
0
        private void DrawMeshContainer(AnimationMeshContainer meshContainer, AnimationFrame frame)
        {
            device.SetRenderState(RenderState.ZEnable, ZBufferType.UseZBuffer);
            device.SetRenderState(RenderState.Lighting, true);

#if !DONT_MIRROR
            Cull culling = (Gui.Renderer.Culling) ? Cull.Clockwise : Cull.None;
#else
            Cull culling = (Gui.Renderer.Culling) ? Cull.Counterclockwise : Cull.None;
#endif
            device.SetRenderState(RenderState.CullMode, culling);

            FillMode fill = (Gui.Renderer.Wireframe) ? FillMode.Wireframe : FillMode.Solid;
            device.SetRenderState(RenderState.FillMode, fill);

            if (meshContainer.BoneNames.Length > 0)
            {
                device.SetRenderState(RenderState.VertexBlend, VertexBlend.Weights3);
                device.SetRenderState(RenderState.IndexedVertexBlendEnable, true);
                device.SetRenderState(RenderState.DiffuseMaterialSource, ColorSource.Material);
                device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Material);
                switch (Gui.Renderer.ShowBoneWeights)
                {
                case ShowBoneWeights.Weak:
                    device.SetRenderState(RenderState.DiffuseMaterialSource, ColorSource.Color1);
                    break;

                case ShowBoneWeights.Strong:
                    device.SetRenderState(RenderState.DiffuseMaterialSource, ColorSource.Color1);
                    device.SetRenderState(RenderState.AmbientMaterialSource, ColorSource.Color1);
                    break;

                case ShowBoneWeights.Off:
                    break;
                }

                for (int i = 0; i < meshContainer.BoneNames.Length; i++)
                {
                    if (meshContainer.BoneFrames[i] != null)
                    {
                        device.SetTransform(i, meshContainer.BoneOffsets[i] * meshContainer.BoneFrames[i].CombinedTransform);
                    }
                }
            }
            else
            {
                device.SetRenderState(RenderState.VertexBlend, VertexBlend.Disable);
#if !DONT_MIRROR
                device.SetTransform(TransformState.World, Matrix.Scaling(1.0f, 1.0f, -1.0f) * frame.CombinedTransform);
#else
                device.SetTransform(TransformState.World, frame.CombinedTransform);
#endif
            }

            try
            {
                int matIdx = meshContainer.MaterialIndex;
                device.Material = ((matIdx >= 0) && (matIdx < Materials.Length)) ? Materials[matIdx] : nullMaterial;

                int     texIdx = meshContainer.TextureIndex;
                Texture tex    = ((texIdx >= 0) && (texIdx < Textures.Count)) ? Textures[texIdx] : null;
                device.SetTexture(0, tex);

                meshContainer.MeshData.Mesh.DrawSubset(0);
            }
            catch (Exception ex)
            {
                Report.ReportLog("Drawing mesh crashed with " + ex.ToString());
            }

            if (HighlightSubmesh.Contains(submeshNum))
            {
                try
                {
                    device.SetRenderState(RenderState.ZEnable, ZBufferType.DontUseZBuffer);
                    device.SetRenderState(RenderState.FillMode, FillMode.Wireframe);
                    device.Material = highlightMaterial;
                    device.SetTexture(0, null);
                    meshContainer.MeshData.Mesh.DrawSubset(0);
                }
                catch (Exception ex)
                {
                    Report.ReportLog("Drawing highlighting crashed with " + ex.ToString());
                }
            }

            if (Gui.Renderer.ShowNormals)
            {
                try
                {
                    device.SetRenderState(RenderState.ZEnable, ZBufferType.UseZBuffer);
                    device.SetRenderState(RenderState.Lighting, false);
                    device.Material = nullMaterial;
                    device.SetTexture(0, null);
                    device.VertexFormat = PositionBlendWeightsIndexedColored.Format;
                    device.DrawUserPrimitives(PrimitiveType.LineList, meshContainer.NormalLines.Length / 2, meshContainer.NormalLines);
                }
                catch (Exception ex)
                {
                    Report.ReportLog("Drawing normals crashed with " + ex.ToString());
                }
            }

            if (Gui.Renderer.ShowBones && (meshContainer.BoneLines != null))
            {
                try
                {
                    device.SetRenderState(RenderState.ZEnable, ZBufferType.DontUseZBuffer);
                    device.SetRenderState(RenderState.VertexBlend, VertexBlend.Weights1);
                    device.SetRenderState(RenderState.IndexedVertexBlendEnable, true);
                    device.SetRenderState(RenderState.Lighting, false);
                    device.Material = nullMaterial;
                    device.SetTexture(0, null);
                    device.VertexFormat = PositionBlendWeightIndexedColored.Format;
                    device.DrawUserPrimitives(PrimitiveType.LineList, meshContainer.BoneLines.Length / 2, meshContainer.BoneLines);
                }
                catch (Exception ex)
                {
                    Report.ReportLog("Drawing bones crashed with " + ex.ToString());
                }
            }
        }
예제 #12
0
        private AnimationFrame CreateFrame(odfFrame frame, odfParser parser, HashSet <int> extractFrames, HashSet <int> meshIDs, Device device, Matrix combinedParent, List <AnimationFrame> meshFrames)
        {
            AnimationFrame animationFrame = new AnimationFrame();

            animationFrame.Name = frame.Name;
            animationFrame.TransformationMatrix = frame.Matrix;
            animationFrame.OriginalTransform    = animationFrame.TransformationMatrix;
            animationFrame.CombinedTransform    = combinedParent * animationFrame.TransformationMatrix;

            if ((int)frame.MeshId != 0 && meshIDs.Contains((int)frame.MeshId))
            {
                odfMesh            mesh      = odf.FindMeshListSome(frame.MeshId, parser.MeshSection);
                ExtendedMaterial[] materials = new ExtendedMaterial[mesh.Count];

                AnimationMeshContainer[] meshContainers = new AnimationMeshContainer[mesh.Count];
                Vector3 min = new Vector3(Single.MaxValue);
                Vector3 max = new Vector3(Single.MinValue);
                for (int i = 0; i < mesh.Count; i++)
                {
                    odfSubmesh       submesh    = mesh[i];
                    List <odfFace>   faceList   = submesh.FaceList;
                    List <odfVertex> vertexList = submesh.VertexList;

                    odfBoneList boneList    = odf.FindBoneList(submesh.Id, parser.EnvelopeSection);
                    bool        skinned     = boneList != null;
                    int         numBones    = skinned ? boneList.Count : 0;
                    string[]    boneNames   = new string[numBones];
                    Matrix[]    boneOffsets = new Matrix[numBones];
                    for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
                    {
                        odfBone bone = boneList[boneIdx];
                        boneNames[boneIdx] = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name;
                        Matrix mirrored;
                        if (!BoneMatrixDic.TryGetValue(boneNames[boneIdx], out mirrored))
                        {
#if !DONT_MIRROR
                            Vector3    translate, scale;
                            Quaternion rotate;
                            bone.Matrix.Decompose(out scale, out rotate, out translate);
                            mirrored = Matrix.Scaling(scale.X, scale.Y, -scale.Z) * Matrix.RotationQuaternion(rotate) * Matrix.Translation(translate);
#else
                            mirrored = bone.Matrix;
#endif
                            BoneMatrixDic.Add(boneNames[boneIdx], mirrored);
                        }
                        boneOffsets[boneIdx] = mirrored;
                    }

                    Mesh animationMesh = new Mesh(device, faceList.Count, vertexList.Count, MeshFlags.Managed, PositionBlendWeightsIndexedNormalTexturedColoured.Format);

                    using (DataStream indexStream = animationMesh.LockIndexBuffer(LockFlags.None))
                    {
                        for (int j = 0; j < faceList.Count; j++)
                        {
                            ushort[] indices = faceList[j].VertexIndices;
                            indexStream.Write(indices[0]);
                            indexStream.Write(indices[1]);
                            indexStream.Write(indices[2]);
                        }
                        animationMesh.UnlockIndexBuffer();
                    }

                    float[][] vertexWeights = ConvertVertexWeights(vertexList, boneList);
                    FillVertexBuffer(animationMesh, vertexList, vertexWeights, -1);

                    var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2];
                    for (int j = 0; j < vertexList.Count; j++)
                    {
                        odfVertex vertex = vertexList[j];
#if !DONT_MIRROR
                        Vector3 position = new Vector3(vertex.Position.X, vertex.Position.Y, -vertex.Position.Z);
                        Vector3 normal   = new Vector3(vertex.Normal.X, vertex.Normal.Y, -vertex.Normal.Z);
#else
                        Vector3 position = vertex.Position;
                        Vector3 normal   = vertex.Normal;
#endif
                        float[] boneWeights = vertexWeights[j];

                        normalLines[j * 2]       = new PositionBlendWeightsIndexedColored(position, boneWeights, vertex.BoneIndices, Color.Yellow.ToArgb());
                        normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(position + (normal / 11), boneWeights, vertex.BoneIndices, Color.Blue.ToArgb());

                        min = Vector3.Minimize(min, position);
                        max = Vector3.Maximize(max, position);
                    }

                    AnimationMeshContainer meshContainer = new AnimationMeshContainer();
                    meshContainer.Name        = animationFrame.Name;
                    meshContainer.MeshData    = new MeshData(animationMesh);
                    meshContainer.NormalLines = normalLines;
                    meshContainer.BoneNames   = boneNames;
                    meshContainer.BoneOffsets = boneOffsets;
                    meshContainers[i]         = meshContainer;

                    odfMaterial mat = odf.FindMaterialInfo(submesh.MaterialId, parser.MaterialSection);
                    if (mat != null)
                    {
                        Material material3D = new Material();
                        material3D.Ambient  = mat.Ambient;
                        material3D.Diffuse  = mat.Diffuse;
                        material3D.Emissive = mat.Emissive;
                        material3D.Specular = mat.Specular;
                        material3D.Power    = mat.SpecularPower;
                        int matIdx = parser.MaterialSection.IndexOf(mat);
                        Materials[matIdx]           = material3D;
                        meshContainer.MaterialIndex = matIdx;

                        int texIdx = -1;
                        if ((int)submesh.TextureIds[0] != 0 && !TextureDic.TryGetValue((int)submesh.TextureIds[0], out texIdx))
                        {
                            odfTexture tex = odf.FindTextureInfo(submesh.TextureIds[0], parser.TextureSection);
                            if (tex != null)
                            {
                                try
                                {
                                    odfTextureFile  texFile  = new odfTextureFile(null, Path.GetDirectoryName(parser.ODFPath) + Path.DirectorySeparatorChar + tex.TextureFile);
                                    int             fileSize = 0;
                                    ImportedTexture impTex   = new ImportedTexture(texFile.DecryptFile(ref fileSize).BaseStream, tex.TextureFile);
                                    Texture         memTex   = impTex.ToTexture(device);
                                    texIdx = TextureDic.Count;
                                    TextureDic.Add((int)submesh.TextureIds[0], texIdx);
                                    Textures[texIdx] = memTex;
                                }
                                catch (SlimDXException ex)
                                {
                                    Utility.ReportException(ex);
                                    Report.ReportLog("Please check " + tex.TextureFile + ". It may have an unsupported format.");
                                }
                                catch (Exception ex)
                                {
                                    Utility.ReportException(ex);
                                }
                            }
                        }
                        meshContainer.TextureIndex = texIdx;
                    }
                }

                for (int i = 0; i < (meshContainers.Length - 1); i++)
                {
                    meshContainers[i].NextMeshContainer = meshContainers[i + 1];
                }

                animationFrame.Bounds        = new BoundingBox(min, max);
                animationFrame.MeshContainer = meshContainers[0];
                meshFrames.Add(animationFrame);
            }

            for (int i = 0; i < frame.Count; i++)
            {
                odfFrame child = frame[i];
                if (extractFrames.Contains((int)child.Id))
                {
                    AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, meshIDs, device, animationFrame.CombinedTransform, meshFrames);
                    childAnimationFrame.Parent = animationFrame;
                    animationFrame.AppendChild(childAnimationFrame);
                }
            }

            numFrames++;
            return(animationFrame);
        }