Beispiel #1
0
        public void CopyBone(int boneListIdx, int boneIdx)
        {
            odfBoneList boneList = Parser.EnvelopeSection[boneListIdx];
            odfBone     bone     = boneList[boneIdx];

            boneList.AddChild(bone.Clone());
        }
Beispiel #2
0
        public static odfBoneList ParseBoneList(BinaryReader reader, int formatType)
        {
            ObjectName  name      = new ObjectName(reader.ReadBytes(64));
            ObjectID    id        = new ObjectID(reader.ReadBytes(4));
            ObjectID    frameId   = new ObjectID(reader.ReadBytes(4));
            ObjectID    meshObjId = new ObjectID(reader.ReadBytes(4));
            int         numBones  = reader.ReadInt32();
            odfBoneList boneList  = new odfBoneList(name, id, numBones);

            boneList.MeshFrameId = frameId;
            boneList.SubmeshId   = meshObjId;
            if (formatType >= 10)
            {
                boneList.AlwaysZero4 = reader.ReadBytes(4);
            }

            for (int boneIdx = 0; boneIdx < numBones; boneIdx++)
            {
                id = new ObjectID(reader.ReadBytes(4));
                odfBone bone = new odfBone(id);

                int numberIndices = reader.ReadInt32();
                bone.AlwaysZero24perIndex = reader.ReadBytes(24 * numberIndices);
                bone.VertexIndexArray     = reader.ReadInt32Array(numberIndices);
                bone.WeightArray          = reader.ReadSingleArray(numberIndices);
                bone.Matrix = reader.ReadMatrix();

                boneList.AddChild(bone);
            }
            return(boneList);
        }
Beispiel #3
0
        public void SetBoneMatrix(int boneListIdx, int boneIdx,
                                  double m11, double m12, double m13, double m14,
                                  double m21, double m22, double m23, double m24,
                                  double m31, double m32, double m33, double m34,
                                  double m41, double m42, double m43, double m44)
        {
            odfBone bone = Parser.EnvelopeSection[boneListIdx][boneIdx];
            Matrix  m    = new Matrix();

            m.M11 = (float)m11;
            m.M12 = (float)m12;
            m.M13 = (float)m13;
            m.M14 = (float)m14;

            m.M21 = (float)m21;
            m.M22 = (float)m22;
            m.M23 = (float)m23;
            m.M24 = (float)m24;

            m.M31 = (float)m31;
            m.M32 = (float)m32;
            m.M33 = (float)m33;
            m.M34 = (float)m34;

            m.M41 = (float)m41;
            m.M42 = (float)m42;
            m.M43 = (float)m43;
            m.M44 = (float)m44;

            bone.Matrix = m;
        }
Beispiel #4
0
        private float[][] ConvertVertexWeights(List <odfVertex> vertexList, odfBoneList boneList)
        {
            int numBones = boneList != null ? boneList.Count : 0;

            float[][] vertexWeights = new float[vertexList.Count][];
            for (int j = 0; j < vertexList.Count; j++)
            {
                vertexWeights[j] = new float[4];
                int weightIdx = 0;
                for (int k = 0; k < numBones; k++)
                {
                    odfBone bone = boneList[k];
                    for (int l = 0; l < bone.NumberIndices; l++)
                    {
                        if (bone.VertexIndexArray[l] == j)
                        {
                            vertexList[j].BoneIndices[weightIdx] = (byte)k;
                            if (weightIdx < 3)
                            {
                                vertexWeights[j][weightIdx++] = bone.WeightArray[l];
                            }
                            else
                            {
                                vertexWeights[j][3] = 1f - vertexWeights[j][0] - vertexWeights[j][1] - vertexWeights[j][2];
                            }
                            break;
                        }
                    }
                }
            }

            return(vertexWeights);
        }
Beispiel #5
0
        public odfBone Clone()
        {
            odfBone bone = new odfBone(new ObjectID(FrameId));

            bone.AlwaysZero24perIndex = (byte[])AlwaysZero24perIndex.Clone();
            bone.VertexIndexArray     = (int[])VertexIndexArray.Clone();
            bone.WeightArray          = (float[])WeightArray.Clone();
            bone.Matrix = Matrix;
            return(bone);
        }
Beispiel #6
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;
            }
        }
Beispiel #7
0
        public void SetBoneFrameId(int boneListIdx, int boneIdx, string frameId)
        {
            ObjectID newBoneFrameId = new ObjectID(frameId);
            odfFrame boneFrame      = odf.FindFrame(newBoneFrameId, Parser.FrameSection.RootFrame);

            if (boneFrame == null)
            {
                throw new FormatException("Frame not found");
            }

            odfBone bone = Parser.EnvelopeSection[boneListIdx][boneIdx];

            bone.FrameId = boneFrame.Id;
        }
Beispiel #8
0
 public static void MergeBoneLists(odfMesh mesh, Dictionary <ObjectID, ObjectID> submeshIDtrans, odfParser parser)
 {
     foreach (odfSubmesh submesh in mesh)
     {
         ObjectID baseSubmeshId = submeshIDtrans[submesh.Id];
         for (int i = 0; i < parser.EnvelopeSection.Count; i++)
         {
             odfBoneList boneList = parser.EnvelopeSection[i];
             if (boneList.SubmeshId == baseSubmeshId)
             {
                 Dictionary <int, int> boneDic = new Dictionary <int, int>(boneList.Count);
                 for (int j = 0; j < boneList.Count; j++)
                 {
                     odfBone bone = boneList[j];
                     boneDic.Add((int)bone.FrameId, j);
                 }
                 for (int j = i + 1; j < parser.EnvelopeSection.Count; j++)
                 {
                     odfBoneList boneList2 = parser.EnvelopeSection[j];
                     if (boneList2.SubmeshId == submesh.Id)
                     {
                         foreach (odfBone bone in boneList2)
                         {
                             int boneIdx;
                             if (boneDic.TryGetValue((int)bone.FrameId, out boneIdx))
                             {
                                 boneList.RemoveChild(boneIdx);
                                 boneList.InsertChild(boneIdx, bone);
                             }
                             else
                             {
                                 boneList.AddChild(bone);
                                 boneDic.Add((int)bone.FrameId, boneDic.Count);
                             }
                         }
                         parser.EnvelopeSection.RemoveChild(boneList2);
                     }
                 }
                 break;
             }
             else
             {
                 Report.ReportLog("wrong");
             }
         }
     }
 }
Beispiel #9
0
        void DeleteReferringBones(odfFrame frame)
        {
            for (int i = 0; i < Parser.EnvelopeSection.Count; i++)
            {
                odfBoneList boneList = Parser.EnvelopeSection[i];
                for (int j = 0; j < boneList.Count; j++)
                {
                    odfBone bone = boneList[j];
                    if (bone.FrameId == frame.Id)
                    {
                        if (RemoveBone(Parser.EnvelopeSection.IndexOf(boneList), j))
                        {
                            i--;
                        }
                        break;
                    }
                }
            }

            foreach (odfFrame child in frame)
            {
                DeleteReferringBones(child);
            }
        }
Beispiel #10
0
        public static void CopyBonesNear(List <odfVertex> src, List <odfVertex> dest, odfBoneList destBones)
        {
            Dictionary <odfBone, Tuple <List <int>, List <float> > > boneTranslation = new Dictionary <odfBone, Tuple <List <int>, List <float> > >(destBones.Count);

            for (int i = 0; i < dest.Count; i++)
            {
                var   destVert       = dest[i];
                var   destPos        = destVert.Position;
                float minDistSq      = Single.MaxValue;
                int   nearestVertIdx = -1;
                for (int j = 0; j < src.Count; j++)
                {
                    odfVertex srcVert = src[j];
                    var       srcPos  = srcVert.Position;
                    float[]   diff    = new float[] { destPos[0] - srcPos[0], destPos[1] - srcPos[1], destPos[2] - srcPos[2] };
                    float     distSq  = (diff[0] * diff[0]) + (diff[1] * diff[1]) + (diff[2] * diff[2]);
                    if (distSq < minDistSq)
                    {
                        minDistSq      = distSq;
                        nearestVertIdx = j;
                    }
                }

                int numInfluences = 0;
                foreach (odfBone srcBone in destBones)
                {
                    for (int k = 0; k < srcBone.NumberIndices; k++)
                    {
                        if (srcBone.VertexIndexArray[k] == nearestVertIdx)
                        {
                            List <int>   idxList;
                            List <float> weightList;
                            Tuple <List <int>, List <float> > destLists;
                            if (!boneTranslation.TryGetValue(srcBone, out destLists))
                            {
                                idxList    = new List <int>();
                                weightList = new List <float>();
                                destLists  = new Tuple <List <int>, List <float> >(idxList, weightList);
                                boneTranslation.Add(srcBone, destLists);
                            }
                            else
                            {
                                idxList    = destLists.Item1;
                                weightList = destLists.Item2;
                            }
                            idxList.Add(i);
                            weightList.Add(srcBone.WeightArray[k]);
                            numInfluences++;
                            break;
                        }
                    }
                    if (numInfluences == 4)
                    {
                        break;
                    }
                }
            }
            foreach (var boneListPair in boneTranslation)
            {
                odfBone srcBone   = boneListPair.Key;
                int     oldLength = srcBone.VertexIndexArray.Length;
                Tuple <List <int>, List <float> > destLists = boneListPair.Value;
                srcBone.VertexIndexArray = destLists.Item1.ToArray();
                srcBone.WeightArray      = destLists.Item2.ToArray();
                if (srcBone.VertexIndexArray.Length != oldLength)
                {
                    srcBone.AlwaysZero24perIndex = new byte[24 * srcBone.VertexIndexArray.Length];
                }
            }
        }
Beispiel #11
0
        public static odfBoneList CreateBoneList(ObjectID id, ObjectID meshFrameId, odfSubmesh submesh, List <ImportedBone> boneList, Matrix lMeshMatrixInv, odfFrame rootFrame)
        {
            if (boneList == null || boneList.Count == 0)
            {
                return(null);
            }
            Dictionary <byte, Tuple <byte, odfBone> > boneDic = new Dictionary <byte, Tuple <byte, odfBone> >(boneList.Count);

            Tuple <List <int>, List <float> >[] newBoneListComponents = new Tuple <List <int>, List <float> > [boneList.Count];
            int boneframeNotFound = 0;

            for (int i = 0; i < submesh.NumVertices; i++)
            {
                odfVertex vert = submesh.VertexList[i];
                for (int j = 0; j < vert.BoneIndices.Length; j++)
                {
                    byte boneIdx = vert.BoneIndices[j];
                    if (boneIdx == 0xFF)
                    {
                        continue;
                    }
                    Tuple <byte, odfBone> boneDesc;
                    odfBone newBone;
                    if (!boneDic.TryGetValue(boneIdx, out boneDesc))
                    {
                        odfFrame boneFrame = odf.FindFrame(boneList[boneIdx].Name, rootFrame);
                        if (boneFrame == null)
                        {
                            boneframeNotFound++;
                            continue;
                        }

                        newBone        = new odfBone(boneFrame.Id);
                        newBone.Matrix = boneList[boneIdx].Matrix;

                        boneDesc = new Tuple <byte, odfBone>((byte)boneDic.Count, newBone);
                        boneDic.Add(boneIdx, boneDesc);
                        newBoneListComponents[boneDesc.Item1] = new Tuple <List <int>, List <float> >(new List <int>(200), new List <float>(200));
                    }
                    else
                    {
                        newBone = boneDesc.Item2;
                    }
                    byte       newBoneIdx     = boneDesc.Item1;
                    List <int> newBoneIdxList = newBoneListComponents[newBoneIdx].Item1;
                    newBoneIdxList.Add(i);
                    List <float> newBoneWeightList = newBoneListComponents[newBoneIdx].Item2;
                    newBoneWeightList.Add(vert.Weights[j]);
                }
            }

            if (boneDic.Count == 0)
            {
                Report.ReportLog(submesh.ToString() + ": all bones dropped because of missing skeleton.");
                return(null);
            }
            odfBoneList newBoneList = new odfBoneList(new ObjectName(String.Empty, null), id, boneDic.Count);

            newBoneList.MeshFrameId = meshFrameId;
            newBoneList.SubmeshId   = submesh.Id;
            newBoneList.AlwaysZero4 = new byte[4];
            foreach (Tuple <byte, odfBone> boneDesc in boneDic.Values)
            {
                byte         newBoneIdx        = boneDesc.Item1;
                List <int>   newBoneIdxList    = newBoneListComponents[newBoneIdx].Item1;
                List <float> newBoneWeightList = newBoneListComponents[newBoneIdx].Item2;
                odfBone      newBone           = boneDesc.Item2;
                newBone.AlwaysZero24perIndex = new byte[24 * newBoneIdxList.Count];
                newBone.VertexIndexArray     = newBoneIdxList.ToArray();
                newBone.WeightArray          = newBoneWeightList.ToArray();

                Matrix lMatrix = Matrix.Invert(newBone.Matrix);
                newBone.Matrix = Matrix.Invert(lMatrix * lMeshMatrixInv);

                newBoneList.AddChild(newBone);
            }
            if (boneframeNotFound > 0)
            {
                Report.ReportLog(submesh.ToString() + ": " + boneframeNotFound + " bone(s) because of missing boneframe(s) dropped.");
            }

            return(newBoneList);
        }
Beispiel #12
0
        public void SetBoneSRT(int boneListIdx, int boneIdx, double sX, double sY, double sZ, double rX, double rY, double rZ, double tX, double tY, double tZ)
        {
            odfBone bone = Parser.EnvelopeSection[boneListIdx][boneIdx];

            bone.Matrix = FbxUtility.SRTToMatrix(new Vector3((float)sX, (float)sY, (float)sZ), new Vector3((float)rX, (float)rY, (float)rZ), new Vector3((float)tX, (float)tY, (float)tZ));
        }
Beispiel #13
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);
        }