示例#1
0
        public odfVertex Clone()
        {
            odfVertex newVert = new odfVertex();

            newVert.Position    = Position;
            newVert.Weights     = (float[])Weights.Clone();
            newVert.Normal      = Normal;
            newVert.BoneIndices = (byte[])BoneIndices.Clone();
            newVert.UV          = UV;
            return(newVert);
        }
示例#2
0
        public static List <odfVertex> ParseVertexList(BinaryReader reader, int numVertices)
        {
            List <odfVertex> vertList = new List <odfVertex>(numVertices);

            for (int vertIdx = 0; vertIdx < numVertices; vertIdx++)
            {
                odfVertex vertex = new odfVertex();
                vertex.Position    = reader.ReadVector3();
                vertex.Weights     = reader.ReadSingleArray(4);
                vertex.Normal      = reader.ReadVector3();
                vertex.BoneIndices = reader.ReadBytes(4);
                vertex.UV          = reader.ReadVector2();

                vertList.Add(vertex);
            }
            return(vertList);
        }
示例#3
0
文件: odfOps.cs 项目: kkdevs/sb3u
        public static void CopyNormalsNear(List <odfVertex> src, List <odfVertex> dest)
        {
            for (int i = 0; i < dest.Count; i++)
            {
                var       destVert    = dest[i];
                var       destPos     = destVert.Position;
                float     minDistSq   = Single.MaxValue;
                odfVertex nearestVert = null;
                foreach (odfVertex srcVert in src)
                {
                    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;
                        nearestVert = srcVert;
                    }
                }

                destVert.Normal = nearestVert.Normal;
            }
        }
示例#4
0
文件: odfOps.cs 项目: kkdevs/sb3u
        public static void CalculateNormals(List <Tuple <List <odfFace>, List <odfVertex> > > pairList, float threshold)
        {
            if (threshold < 0)
            {
                VertexRef[][] vertRefArray = new VertexRef[pairList.Count][];
                for (int i = 0; i < pairList.Count; i++)
                {
                    List <odfVertex> vertList = pairList[i].Item2;
                    vertRefArray[i] = new VertexRef[vertList.Count];
                    for (int j = 0; j < vertList.Count; j++)
                    {
                        odfVertex vert    = vertList[j];
                        VertexRef vertRef = new VertexRef();
                        vertRef.vert       = vert;
                        vertRef.norm       = new Vector3();
                        vertRefArray[i][j] = vertRef;
                    }
                }

                for (int i = 0; i < pairList.Count; i++)
                {
                    List <odfFace> faceList = pairList[i].Item1;
                    for (int j = 0; j < faceList.Count; j++)
                    {
                        odfFace face = faceList[j];
                        Vector3 v1   = vertRefArray[i][face.VertexIndices[1]].vert.Position - vertRefArray[i][face.VertexIndices[2]].vert.Position;
                        Vector3 v2   = vertRefArray[i][face.VertexIndices[0]].vert.Position - vertRefArray[i][face.VertexIndices[2]].vert.Position;
                        Vector3 norm = Vector3.Cross(v2, v1);
                        norm.Normalize();
                        for (int k = 0; k < face.VertexIndices.Length; k++)
                        {
                            vertRefArray[i][face.VertexIndices[k]].norm += norm;
                        }
                    }
                }

                for (int i = 0; i < vertRefArray.Length; i++)
                {
                    for (int j = 0; j < vertRefArray[i].Length; j++)
                    {
                        Vector3 norm = vertRefArray[i][j].norm;
                        norm.Normalize();
                        vertRefArray[i][j].vert.Normal = norm;
                    }
                }
            }
            else
            {
                int vertCount = 0;
                for (int i = 0; i < pairList.Count; i++)
                {
                    vertCount += pairList[i].Item2.Count;
                }

                VertexRefComparerX vertRefComparerX = new VertexRefComparerX();
                List <VertexRef>   vertRefListX     = new List <VertexRef>(vertCount);
                VertexRef[][]      vertRefArray     = new VertexRef[pairList.Count][];
                for (int i = 0; i < pairList.Count; i++)
                {
                    var vertList = pairList[i].Item2;
                    vertRefArray[i] = new VertexRef[vertList.Count];
                    for (int j = 0; j < vertList.Count; j++)
                    {
                        odfVertex vert    = vertList[j];
                        VertexRef vertRef = new VertexRef();
                        vertRef.vert       = vert;
                        vertRef.norm       = new Vector3();
                        vertRefArray[i][j] = vertRef;
                        vertRefListX.Add(vertRef);
                    }
                }
                vertRefListX.Sort(vertRefComparerX);

                for (int i = 0; i < pairList.Count; i++)
                {
                    var faceList = pairList[i].Item1;
                    for (int j = 0; j < faceList.Count; j++)
                    {
                        odfFace face = faceList[j];
                        Vector3 v1   = vertRefArray[i][face.VertexIndices[1]].vert.Position - vertRefArray[i][face.VertexIndices[2]].vert.Position;
                        Vector3 v2   = vertRefArray[i][face.VertexIndices[0]].vert.Position - vertRefArray[i][face.VertexIndices[2]].vert.Position;
                        Vector3 norm = Vector3.Cross(v2, v1);
                        norm.Normalize();
                        for (int k = 0; k < face.VertexIndices.Length; k++)
                        {
                            vertRefArray[i][face.VertexIndices[k]].norm += norm;
                        }
                    }
                }

                float squaredThreshold = threshold * threshold;
                while (vertRefListX.Count > 0)
                {
                    VertexRef        vertRef  = vertRefListX[vertRefListX.Count - 1];
                    List <VertexRef> dupList  = new List <VertexRef>();
                    List <VertexRef> dupListX = GetAxisDups(vertRef, vertRefListX, 0, threshold, null);
                    foreach (VertexRef dupRef in dupListX)
                    {
                        if (((vertRef.vert.Position.Y - dupRef.vert.Position.Y) <= threshold) &&
                            ((vertRef.vert.Position.Z - dupRef.vert.Position.Z) <= threshold) &&
                            ((vertRef.vert.Position - dupRef.vert.Position).LengthSquared() <= squaredThreshold))
                        {
                            dupList.Add(dupRef);
                        }
                    }
                    vertRefListX.RemoveAt(vertRefListX.Count - 1);

                    Vector3 norm = vertRef.norm;
                    foreach (VertexRef dupRef in dupList)
                    {
                        norm += dupRef.norm;
                        vertRefListX.Remove(dupRef);
                    }
                    norm.Normalize();

                    vertRef.vert.Normal = norm;
                    foreach (VertexRef dupRef in dupList)
                    {
                        dupRef.vert.Normal = norm;
                        vertRefListX.Remove(dupRef);
                    }
                }
            }
        }
示例#5
0
文件: odfOps.cs 项目: kkdevs/sb3u
        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];
                }
            }
        }
示例#6
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);
        }
示例#7
0
        public static odfMesh CreateMesh(WorkspaceMesh mesh, int subMeshFormat, out string[] materialNames, out int[] indices, out bool[] worldCoords, out bool[] replaceSubmeshesOption)
        {
            int numUncheckedSubmeshes = 0;

            foreach (ImportedSubmesh submesh in mesh.SubmeshList)
            {
                if (!mesh.isSubmeshEnabled(submesh))
                {
                    numUncheckedSubmeshes++;
                }
            }
            int numSubmeshes = mesh.SubmeshList.Count - numUncheckedSubmeshes;

            materialNames          = new string[numSubmeshes];
            indices                = new int[numSubmeshes];
            worldCoords            = new bool[numSubmeshes];
            replaceSubmeshesOption = new bool[numSubmeshes];

            odfMesh newMesh = new odfMesh(new ObjectName(String.Empty, null), null, numSubmeshes);

            for (int i = 0, submeshIdx = 0; i < numSubmeshes; i++, submeshIdx++)
            {
                while (!mesh.isSubmeshEnabled(mesh.SubmeshList[submeshIdx]))
                {
                    submeshIdx++;
                }

                ImportedSubmesh submesh = mesh.SubmeshList[submeshIdx];

                odfSubmesh newSubmesh = new odfSubmesh(new ObjectName(String.Empty, null), null, subMeshFormat);
                newMesh.AddChild(newSubmesh);

                newSubmesh.MaterialId     = ObjectID.INVALID;
                materialNames[i]          = submesh.Material;
                indices[i]                = submesh.Index;
                worldCoords[i]            = submesh.WorldCoords;
                replaceSubmeshesOption[i] = mesh.isSubmeshReplacingOriginal(mesh.SubmeshList[submeshIdx]);

                List <ImportedVertex> vertexList    = submesh.VertexList;
                List <odfVertex>      newVertexList = new List <odfVertex>(vertexList.Count);
                for (int j = 0; j < vertexList.Count; j++)
                {
                    ImportedVertex vert      = vertexList[j];
                    odfVertex      newVertex = new odfVertex();

                    newVertex.Normal      = vert.Normal;
                    newVertex.UV          = new Vector2(vert.UV[0], vert.UV[1]);
                    newVertex.Weights     = (float[])vert.Weights.Clone();
                    newVertex.BoneIndices = (byte[])vert.BoneIndices.Clone();
                    newVertex.Position    = vert.Position;
                    newVertexList.Add(newVertex);
                }
                newSubmesh.VertexList = newVertexList;

                List <ImportedFace> faceList    = submesh.FaceList;
                List <odfFace>      newFaceList = new List <odfFace>(faceList.Count);
                for (int j = 0; j < faceList.Count; j++)
                {
                    int[]   vertexIndices = faceList[j].VertexIndices;
                    odfFace newFace       = new odfFace();
                    newFace.VertexIndices = new ushort[3] {
                        (ushort)vertexIndices[0], (ushort)vertexIndices[1], (ushort)vertexIndices[2]
                    };
                    newFaceList.Add(newFace);
                }
                newSubmesh.FaceList = newFaceList;
            }

            return(newMesh);
        }
示例#8
0
        private void FillVertexBuffer(Mesh animationMesh, List <odfVertex> vertexList, float[][] vertexWeights, int selectedBoneIdx)
        {
            using (DataStream vertexStream = animationMesh.LockVertexBuffer(LockFlags.None))
            {
                Color4 col = new Color4(1f, 1f, 1f);
                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];
                    vertexStream.Write(position.X);
                    vertexStream.Write(position.Y);
                    vertexStream.Write(position.Z);
                    vertexStream.Write(boneWeights[0]);
                    vertexStream.Write(boneWeights[1]);
                    vertexStream.Write(boneWeights[2]);
                    vertexStream.Write(vertex.BoneIndices[0]);
                    vertexStream.Write(vertex.BoneIndices[1]);
                    vertexStream.Write(vertex.BoneIndices[2]);
                    vertexStream.Write(vertex.BoneIndices[3]);
                    vertexStream.Write(normal.X);
                    vertexStream.Write(normal.Y);
                    vertexStream.Write(normal.Z);
                    if (selectedBoneIdx >= 0)
                    {
                        col.Red = 0f; col.Green = 0f; col.Blue = 0f;
                        byte[] boneIndices = vertex.BoneIndices;
                        for (int k = 0; k < boneIndices.Length; k++)
                        {
                            if (boneIndices[k] == 0xFF)
                            {
                                continue;
                            }

                            byte boneIdx = boneIndices[k];
                            if (boneIdx == selectedBoneIdx)
                            {
/*								switch (cols)
 *                                                              {
 *                                                              case WeightsColourPreset.Greyscale:
 *                                                                      col.r = col.g = col.b = boneWeights[k];
 *                                                                      break;
 *                                                              case WeightsColourPreset.Metal:
 *                                                                      col.r = boneWeights[k] > 0.666f ? 1f : boneWeights[k] * 1.5f;
 *                                                                      col.g = boneWeights[k] * boneWeights[k] * boneWeights[k];
 *                                                                      break;
 *                                                              case WeightsColourPreset.Rainbow:*/
                                if (boneWeights[k] > 0.75f)
                                {
                                    col.Red   = 1f;
                                    col.Green = (1f - boneWeights[k]) * 2f;
                                    col.Blue  = 0f;
                                }
                                else if (boneWeights[k] > 0.5f)
                                {
                                    col.Red   = 1f;
                                    col.Green = (1f - boneWeights[k]) * 2f;
                                    col.Blue  = 0f;
                                }
                                else if (boneWeights[k] > 0.25f)
                                {
                                    col.Red   = (boneWeights[k] - 0.25f) * 4f;
                                    col.Green = 1f;
                                    col.Blue  = 0f;
                                }
                                else
                                {
                                    col.Green = boneWeights[k] * 4f;
                                    col.Blue  = 1f - boneWeights[k] * 4f;
                                }

/*									break;
 *                                                              }*/
                                break;
                            }
                        }
                    }
                    vertexStream.Write(col.ToArgb());
                    vertexStream.Write(vertex.UV[0]);
                    vertexStream.Write(vertex.UV[1]);
                }
                animationMesh.UnlockVertexBuffer();
            }
        }
示例#9
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);
        }
示例#10
0
文件: Fbx.cs 项目: kkdevs/sb3u
            private void ConvertMeshes(List <odfMesh> meshes, odfParser parser)
            {
                MeshList     = new List <ImportedMesh>(meshes.Count);
                MaterialList = new List <ImportedMaterial>(meshes.Count);
                TextureList  = new List <ImportedTexture>(parser.TextureSection != null ? parser.TextureSection.Count : 0);
                foreach (odfMesh mesh in meshes)
                {
                    ImportedMesh iMesh = new ImportedMesh();
                    MeshList.Add(iMesh);
                    iMesh.Name     = odf.FindMeshFrame(mesh.Id, parser.FrameSection.RootFrame).Name;
                    iMesh.BoneList = new List <ImportedBone>();
                    Dictionary <ObjectID, byte> boneDic = new Dictionary <ObjectID, byte>();
                    iMesh.SubmeshList = new List <ImportedSubmesh>(mesh.Count);
                    foreach (odfSubmesh submesh in mesh)
                    {
                        ImportedSubmesh iSubmesh = new ImportedSubmesh();
                        iMesh.SubmeshList.Add(iSubmesh);
                        odfMaterial mat = odf.FindMaterialInfo(submesh.MaterialId, parser.MaterialSection);
                        if (mat != null)
                        {
                            iSubmesh.Material = mat.Name;
                            ImportedMaterial iMat = ImportedHelpers.FindMaterial(iSubmesh.Material, MaterialList);
                            if (iMat == null)
                            {
                                iMat = new ImportedMaterial();
                                MaterialList.Add(iMat);
                                iMat.Name     = iSubmesh.Material;
                                iMat.Diffuse  = mat.Diffuse;
                                iMat.Ambient  = mat.Ambient;
                                iMat.Specular = mat.Specular;
                                iMat.Emissive = mat.Emissive;
                                iMat.Power    = mat.SpecularPower;

                                iMat.Textures = new string[4];
                                for (int i = 0; i < 4; i++)
                                {
                                    if (submesh.TextureIds[i] != ObjectID.INVALID)
                                    {
                                        odfTexture tex = odf.FindTextureInfo(submesh.TextureIds[i], parser.TextureSection);
                                        iMat.Textures[i] = tex.Name;
                                        if (ImportedHelpers.FindTexture(iMat.Textures[i], TextureList) == null)
                                        {
                                            try
                                            {
                                                odfTextureFile texFile = new odfTextureFile(iMat.Textures[i], Path.GetDirectoryName(parser.ODFPath) + @"\" + iMat.Textures[i]);
                                                MemoryStream   memStream;
                                                int            filesize = 0;
                                                using (BinaryReader reader = texFile.DecryptFile(ref filesize))
                                                {
                                                    memStream = new MemoryStream(reader.ReadBytes(filesize));
                                                }
                                                ImportedTexture iTex = new ImportedTexture(memStream, iMat.Textures[i]);
                                                TextureList.Add(iTex);
                                            }
                                            catch
                                            {
                                                Report.ReportLog("cant read texture " + iMat.Textures[i]);
                                            }
                                        }
                                    }
                                    else
                                    {
                                        iMat.Textures[i] = String.Empty;
                                    }
                                }
                            }
                        }

                        List <Tuple <byte, float> >[] skin = new List <Tuple <byte, float> > [submesh.NumVertices];
                        for (int i = 0; i < submesh.NumVertices; i++)
                        {
                            skin[i] = new List <Tuple <byte, float> >(4);
                        }
                        odfBoneList boneList = odf.FindBoneList(submesh.Id, parser.EnvelopeSection);
                        if (boneList != null)
                        {
                            if (iMesh.BoneList.Capacity < boneList.Count)
                            {
                                iMesh.BoneList.Capacity += boneList.Count;
                            }
                            foreach (odfBone bone in boneList)
                            {
                                byte idx;
                                if (!boneDic.TryGetValue(bone.FrameId, out idx))
                                {
                                    ImportedBone iBone = new ImportedBone();
                                    iMesh.BoneList.Add(iBone);
                                    iBone.Name   = odf.FindFrame(bone.FrameId, parser.FrameSection.RootFrame).Name;
                                    iBone.Matrix = bone.Matrix;
                                    boneDic.Add(bone.FrameId, idx = (byte)boneDic.Count);
                                }
                                for (int i = 0; i < bone.NumberIndices; i++)
                                {
                                    skin[bone.VertexIndexArray[i]].Add(new Tuple <byte, float>(idx, bone.WeightArray[i]));
                                }
                            }
                        }

                        iSubmesh.VertexList = new List <ImportedVertex>(submesh.NumVertices);
                        for (int i = 0; i < submesh.NumVertices; i++)
                        {
                            odfVertex      vert  = submesh.VertexList[i];
                            ImportedVertex iVert = new ImportedVertex();
                            iSubmesh.VertexList.Add(iVert);
                            iVert.Position    = vert.Position;
                            iVert.Normal      = vert.Normal;
                            iVert.UV          = new float[] { vert.UV[0], vert.UV[1] };
                            iVert.BoneIndices = new byte[4];
                            iVert.Weights     = new float[4];
                            for (int j = 0; j < 4; j++)
                            {
                                if (j < skin[i].Count)
                                {
                                    Tuple <byte, float> vertIdxWeight = skin[i][j];
                                    iVert.BoneIndices[j] = vertIdxWeight.Item1;
                                    iVert.Weights[j]     = vertIdxWeight.Item2;
                                }
                                else
                                {
                                    iVert.BoneIndices[j] = 0xFF;
                                }
                            }
                        }

                        iSubmesh.FaceList = new List <ImportedFace>(submesh.NumVertexIndices / 3);
                        foreach (odfFace face in submesh.FaceList)
                        {
                            ImportedFace iFace = new ImportedFace();
                            iSubmesh.FaceList.Add(iFace);
                            iFace.VertexIndices = new int[3];
                            for (int i = 0; i < 3; i++)
                            {
                                iFace.VertexIndices[i] = face.VertexIndices[i];
                            }
                        }
                    }
                }
            }