Ejemplo n.º 1
0
 public static void SetBoundingBox(xxFrame frame)
 {
     if (frame.Mesh == null)
     {
         frame.Bounds = new BoundingBox();
     }
     else
     {
         xxMesh  meshList = frame.Mesh;
         Vector3 min      = new Vector3(Single.MaxValue, Single.MaxValue, Single.MaxValue);
         Vector3 max      = new Vector3(Single.MinValue, Single.MinValue, Single.MinValue);
         for (int i = 0; i < meshList.SubmeshList.Count; i++)
         {
             List <xxVertex> vertList = meshList.SubmeshList[i].VertexList;
             for (int j = 0; j < vertList.Count; j++)
             {
                 xxVertex vert = vertList[j];
                 Vector3  pos  = vert.Position;
                 min = Vector3.Minimize(min, pos);
                 max = Vector3.Maximize(max, pos);
             }
         }
         frame.Bounds = new BoundingBox(min, max);
     }
 }
Ejemplo n.º 2
0
        public static List <xxVertex> CreateVertexListDup(List <xxSubmesh> submeshList)
        {
            List <xxVertex>      vertListDup     = new List <xxVertex>(UInt16.MaxValue);
            List <VertexCompare> vertCompareList = new List <VertexCompare>(UInt16.MaxValue);

            for (int i = 0; i < submeshList.Count; i++)
            {
                xxSubmesh       meshObj  = submeshList[i];
                List <xxVertex> vertList = meshObj.VertexList;
                for (int j = 0; j < vertList.Count; j++)
                {
                    xxVertex      vert        = vertList[j];
                    VertexCompare vertCompare = new VertexCompare(vertCompareList.Count, vert.Position, vert.Normal, vert.BoneIndices, vert.Weights3);
                    int           idx         = vertCompareList.BinarySearch(vertCompare);
                    if (idx < 0)
                    {
                        vertCompareList.Insert(~idx, vertCompare);
                        vert.Index = vertCompareList.Count;
                        vertListDup.Add(vert.Clone());
                    }
                    else
                    {
                        vert.Index = vertCompareList[idx].index;
                    }
                }
            }
            vertListDup.TrimExcess();
            return(vertListDup);
        }
Ejemplo n.º 3
0
        public xxVertex Clone()
        {
            xxVertex vertex = InitClone();

            vertex.Index       = Index;
            vertex.Position    = Position;
            vertex.Weights3    = (float[])Weights3.Clone();
            vertex.BoneIndices = (byte[])BoneIndices.Clone();
            vertex.Normal      = Normal;
            vertex.UV          = (float[])UV.Clone();
            vertex.Unknown1    = Unknown1.CloneIfNotNull();
            return(vertex);
        }
Ejemplo n.º 4
0
 private static void UpdateBoneIndices(List <xxVertex> vertList, byte[] boneMap)
 {
     for (int i = 0; i < vertList.Count; i++)
     {
         xxVertex vert        = vertList[i];
         byte[]   boneIndices = (byte[])vert.BoneIndices.Clone();
         for (int j = 0; j < boneIndices.Length; j++)
         {
             if (boneIndices[j] != 0xFF)
             {
                 boneIndices[j] = boneMap[boneIndices[j]];
             }
         }
         vert.BoneIndices = boneIndices;
     }
 }
Ejemplo n.º 5
0
        public static void CopyNormalsNear(List <xxVertex> src, List <xxVertex> dest)
        {
            for (int i = 0; i < dest.Count; i++)
            {
                var      destVert    = dest[i];
                var      destPos     = destVert.Position;
                float    minDistSq   = Single.MaxValue;
                xxVertex nearestVert = null;
                foreach (xxVertex 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;
            }
        }
Ejemplo n.º 6
0
        public static void CopyBonesNear(List <xxVertex> src, List <xxVertex> dest)
        {
            for (int i = 0; i < dest.Count; i++)
            {
                var      destVert    = dest[i];
                var      destPos     = destVert.Position;
                float    minDistSq   = Single.MaxValue;
                xxVertex nearestVert = null;
                foreach (xxVertex 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.BoneIndices = (byte[])nearestVert.BoneIndices.Clone();
                destVert.Weights3    = (float[])nearestVert.Weights3.Clone();
            }
        }
Ejemplo n.º 7
0
        public float SetMorphKeyframe(xxFrame meshFrame, xaMorphIndexSet idxSet, xaMorphKeyframe keyframe, bool asStart)
        {
            foreach (AnimationFrame frame in meshFrames)
            {
                if (frame.Name == meshFrame.Name)
                {
                    xxMesh xxMesh     = meshFrame.Mesh;
                    int    meshObjIdx = xa.MorphMeshObjIdx(idxSet.MeshIndices, xxMesh);
                    if (meshObjIdx < 0)
                    {
                        Report.ReportLog("no valid mesh object was found for the morph");
                        return(-1f);
                    }
                    MorphMeshContainer     morphMesh = null;
                    AnimationMeshContainer animMesh  = frame.MeshContainer as AnimationMeshContainer;
                    if (animMesh != null)
                    {
                        for (int i = 1; i < meshObjIdx; i++)
                        {
                            animMesh = (AnimationMeshContainer)animMesh.NextMeshContainer;
                            if (animMesh == null)
                            {
                                break;
                            }
                        }
                        if (animMesh == null)
                        {
                            Report.ReportLog("Bad submesh specified.");
                            return(-1f);
                        }

                        morphMesh             = new MorphMeshContainer();
                        morphMesh.FaceCount   = xxMesh.SubmeshList[meshObjIdx].FaceList.Count;
                        morphMesh.IndexBuffer = animMesh.MeshData.Mesh.IndexBuffer;

                        morphMesh.VertexCount = xxMesh.SubmeshList[meshObjIdx].VertexList.Count;
                        List <xxVertex> vertexList = xxMesh.SubmeshList[meshObjIdx].VertexList;
                        VertexBuffer    vertBuffer = CreateMorphVertexBuffer(idxSet, keyframe, vertexList);
                        morphMesh.StartBuffer = morphMesh.EndBuffer = vertBuffer;

                        int vertBufferSize = morphMesh.VertexCount * Marshal.SizeOf(typeof(TweeningMeshesVertexBufferFormat.Stream2));
                        vertBuffer = new VertexBuffer(device, vertBufferSize, Usage.WriteOnly, VertexFormat.Texture1, Pool.Managed);
                        using (DataStream vertexStream = vertBuffer.Lock(0, vertBufferSize, LockFlags.None))
                        {
                            for (int i = 0; i < vertexList.Count; i++)
                            {
                                xxVertex vertex = vertexList[i];
                                vertexStream.Write(vertex.UV[0]);
                                vertexStream.Write(vertex.UV[1]);
                            }
                            vertBuffer.Unlock();
                        }
                        morphMesh.CommonBuffer = vertBuffer;

                        morphMesh.MaterialIndex = animMesh.MaterialIndex;
                        morphMesh.TextureIndex  = animMesh.TextureIndex;

                        morphMesh.NextMeshContainer = animMesh;
                        frame.MeshContainer         = morphMesh;

                        morphMesh.TweenFactor = 0.0f;
                    }
                    else
                    {
                        morphMesh = frame.MeshContainer as MorphMeshContainer;
                        List <xxVertex> vertexList = xxMesh.SubmeshList[meshObjIdx].VertexList;
                        VertexBuffer    vertBuffer = CreateMorphVertexBuffer(idxSet, keyframe, vertexList);
                        if (asStart)
                        {
                            if (morphMesh.StartBuffer != morphMesh.EndBuffer)
                            {
                                morphMesh.StartBuffer.Dispose();
                            }
                            morphMesh.StartBuffer = vertBuffer;
                            morphMesh.TweenFactor = 0.0f;
                        }
                        else
                        {
                            if (morphMesh.StartBuffer != morphMesh.EndBuffer)
                            {
                                morphMesh.EndBuffer.Dispose();
                            }
                            morphMesh.EndBuffer   = vertBuffer;
                            morphMesh.TweenFactor = 1.0f;
                        }
                    }
                    return(morphMesh.TweenFactor);
                }
            }
            Report.ReportLog("Mesh frame " + meshFrame + " not displayed.");
            return(-1f);
        }
Ejemplo n.º 8
0
        private void FillVertexBuffer(Mesh animationMesh, List <xxVertex> vertexList, int selectedBoneIdx)
        {
            using (DataStream vertexStream = animationMesh.LockVertexBuffer(LockFlags.None))
            {
                Color4 col = new Color4(1f, 1f, 1f);
                for (int i = 0; i < vertexList.Count; i++)
                {
                    xxVertex vertex = vertexList[i];
                    vertexStream.Write(vertex.Position.X);
                    vertexStream.Write(vertex.Position.Y);
                    vertexStream.Write(vertex.Position.Z);
                    vertexStream.Write(vertex.Weights3[0]);
                    vertexStream.Write(vertex.Weights3[1]);
                    vertexStream.Write(vertex.Weights3[2]);
                    vertexStream.Write(vertex.BoneIndices[0]);
                    vertexStream.Write(vertex.BoneIndices[1]);
                    vertexStream.Write(vertex.BoneIndices[2]);
                    vertexStream.Write(vertex.BoneIndices[3]);
                    vertexStream.Write(vertex.Normal.X);
                    vertexStream.Write(vertex.Normal.Y);
                    vertexStream.Write(vertex.Normal.Z);
                    if (selectedBoneIdx >= 0)
                    {
                        col.Red = 0f; col.Green = 0f; col.Blue = 0f;
                        byte[]  boneIndices = vertex.BoneIndices;
                        float[] boneWeights = vertex.Weights4(true);
                        for (int j = 0; j < boneIndices.Length; j++)
                        {
                            if (boneIndices[j] == 0xFF)
                            {
                                continue;
                            }

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

/*									break;
 *                                                              }*/
                                break;
                            }
                        }
                    }
                    vertexStream.Write(col.ToArgb());
                    vertexStream.Write(vertex.UV[0]);
                    vertexStream.Write(vertex.UV[1]);
                }
                animationMesh.UnlockVertexBuffer();
            }
        }
Ejemplo n.º 9
0
        private AnimationFrame CreateFrame(xxFrame frame, xxParser parser, HashSet <string> extractFrames, HashSet <string> meshNames, 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;

            xxMesh mesh = frame.Mesh;

            if (meshNames.Contains(frame.Name) && (mesh != null))
            {
                List <xxBone> boneList = mesh.BoneList;

                string[] boneNames   = new string[boneList.Count];
                Matrix[] boneOffsets = new Matrix[boneList.Count];
                for (int i = 0; i < boneList.Count; i++)
                {
                    xxBone bone = boneList[i];
                    boneNames[i]   = bone.Name;
                    boneOffsets[i] = bone.Matrix;
                }

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

                    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[2]);
                            indexStream.Write(indices[1]);
                        }
                        animationMesh.UnlockIndexBuffer();
                    }

                    FillVertexBuffer(animationMesh, vertexList, -1);

                    var normalLines = new PositionBlendWeightsIndexedColored[vertexList.Count * 2];
                    for (int j = 0; j < vertexList.Count; j++)
                    {
                        xxVertex vertex = vertexList[j];

                        normalLines[j * 2]       = new PositionBlendWeightsIndexedColored(vertex.Position, vertex.Weights3, vertex.BoneIndices, Color.Yellow.ToArgb());
                        normalLines[(j * 2) + 1] = new PositionBlendWeightsIndexedColored(vertex.Position + (vertex.Normal / 16), vertex.Weights3, vertex.BoneIndices, Color.Yellow.ToArgb());

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

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

                    int matIdx = submesh.MaterialIndex;
                    if ((matIdx >= 0) && (matIdx < parser.MaterialList.Count))
                    {
                        int texIdx;
                        if (!MatTexIndices.TryGetValue(matIdx, out texIdx))
                        {
                            texIdx = -1;

                            xxMaterial mat         = parser.MaterialList[matIdx];
                            Material   materialD3D = new Material();
                            materialD3D.Ambient  = mat.Ambient;
                            materialD3D.Diffuse  = mat.Diffuse;
                            materialD3D.Emissive = mat.Emissive;
                            materialD3D.Specular = mat.Specular;
                            materialD3D.Power    = mat.Power;
                            Materials[matIdx]    = materialD3D;

                            xxMaterialTexture matTex     = mat.Textures[0];
                            string            matTexName = matTex.Name;
                            if (matTexName != String.Empty)
                            {
                                for (int j = 0; j < parser.TextureList.Count; j++)
                                {
                                    xxTexture tex = parser.TextureList[j];
                                    if (tex.Name == matTexName)
                                    {
                                        texIdx = j;
                                        if (Textures[j] == null)
                                        {
                                            ImportedTexture importedTex = xx.ImportedTexture(tex);
                                            Textures[j] = Texture.FromMemory(device, importedTex.Data);
                                        }
                                        break;
                                    }
                                }
                            }

                            MatTexIndices.Add(matIdx, texIdx);
                        }

                        meshContainer.MaterialIndex = matIdx;
                        meshContainer.TextureIndex  = texIdx;
                    }
                }

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

                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++)
            {
                xxFrame child = frame[i];
                if (extractFrames.Contains(child.Name))
                {
                    AnimationFrame childAnimationFrame = CreateFrame(child, parser, extractFrames, meshNames, device, animationFrame.CombinedTransform, meshFrames);
                    childAnimationFrame.Parent = animationFrame;
                    animationFrame.AppendChild(childAnimationFrame);
                }
            }

            numFrames++;
            return(animationFrame);
        }
Ejemplo n.º 10
0
 public static void CreateUnknown(xxVertex vertex)
 {
     vertex.Unknown1 = new byte[20];
 }
Ejemplo n.º 11
0
        public static void CalculateNormals(List <Tuple <List <xxFace>, List <xxVertex> > > pairList, float threshold)
        {
            if (threshold < 0)
            {
                VertexRef[][] vertRefArray = new VertexRef[pairList.Count][];
                for (int i = 0; i < pairList.Count; i++)
                {
                    List <xxVertex> vertList = pairList[i].Item2;
                    vertRefArray[i] = new VertexRef[vertList.Count];
                    for (int j = 0; j < vertList.Count; j++)
                    {
                        xxVertex  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 <xxFace> faceList = pairList[i].Item1;
                    for (int j = 0; j < faceList.Count; j++)
                    {
                        xxFace  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++)
                    {
                        xxVertex  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++)
                    {
                        xxFace  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);
                    }
                }
            }
        }