public static Vec3[] GetMeshBonesPosn(CR2WFile cr2w)
        {
            rendRenderMeshBlob rendmeshblob = cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().First();

            int boneCount = rendmeshblob.Header.BonePositions.Count;

            Vec3[] posn = new Vec3[boneCount];
            float  x, y, z = 0;

            for (int i = 0; i < boneCount; i++)
            {
                x       = rendmeshblob.Header.BonePositions[i].X.Value;
                y       = rendmeshblob.Header.BonePositions[i].Y.Value;
                z       = rendmeshblob.Header.BonePositions[i].Z.Value;
                posn[i] = new Vec3(x, z, -y);
            }
            return(posn);
        }
        public static MeshesInfo GetMeshesinfo(CR2WFile cr2w)
        {
            rendRenderMeshBlob rendmeshblob = cr2w.Chunks.Select(_ => _.Data).OfType <rendRenderMeshBlob>().First();

            int meshC = rendmeshblob.Header.RenderChunkInfos.Count;

            UInt32[] vertCounts     = new UInt32[meshC];
            UInt32[] indCounts      = new UInt32[meshC];
            UInt32[] vertOffsets    = new UInt32[meshC];
            UInt32[] tx0Offsets     = new UInt32[meshC];
            UInt32[] normalOffsets  = new UInt32[meshC];
            UInt32[] tangentOffsets = new UInt32[meshC];
            UInt32[] colorOffsets   = new UInt32[meshC];
            UInt32[] tx1Offsets     = new UInt32[meshC];
            UInt32[] unknownOffsets = new UInt32[meshC];
            UInt32[] indicesOffsets = new UInt32[meshC];
            UInt32[] vpStrides      = new UInt32[meshC];
            UInt32[] LODLvl         = new UInt32[meshC];
            bool[]   extraExists    = new bool[meshC];

            for (int i = 0; i < meshC; i++)
            {
                vertCounts[i]     = rendmeshblob.Header.RenderChunkInfos[i].NumVertices.Value;
                indCounts[i]      = rendmeshblob.Header.RenderChunkInfos[i].NumIndices.Value;
                vertOffsets[i]    = rendmeshblob.Header.RenderChunkInfos[i].ChunkVertices.ByteOffsets[0].Value;
                unknownOffsets[i] = rendmeshblob.Header.RenderChunkInfos[i].ChunkVertices.ByteOffsets[4].Value;

                var cv = rendmeshblob.Header.RenderChunkInfos[i].ChunkVertices;
                for (int e = 0; e < cv.VertexLayout.Elements.Count; e++)
                {
                    if (cv.VertexLayout.Elements[e].Usage.EnumValueList[0] == "PS_Normal")
                    {
                        normalOffsets[i] = cv.ByteOffsets[cv.VertexLayout.Elements[e].StreamIndex.Value].Value;
                    }
                    if (cv.VertexLayout.Elements[e].Usage.EnumValueList[0] == "PS_Tangent")
                    {
                        tangentOffsets[i] = cv.ByteOffsets[cv.VertexLayout.Elements[e].StreamIndex.Value].Value;
                    }
                    if (cv.VertexLayout.Elements[e].Usage.EnumValueList[0] == "PS_Color")
                    {
                        colorOffsets[i] = cv.ByteOffsets[cv.VertexLayout.Elements[e].StreamIndex.Value].Value;
                    }
                    if (cv.VertexLayout.Elements[e].Usage.EnumValueList[0] == "PS_TexCoord")
                    {
                        if (tx0Offsets[i] == 0)
                        {
                            tx0Offsets[i] = cv.ByteOffsets[cv.VertexLayout.Elements[e].StreamIndex.Value].Value;
                        }
                        else
                        {
                            tx1Offsets[i] = cv.ByteOffsets[cv.VertexLayout.Elements[e].StreamIndex.Value].Value;
                        }
                    }
                }

                if (rendmeshblob.Header.RenderChunkInfos[i].ChunkIndices.TeOffset == null)
                {
                    indicesOffsets[i] = rendmeshblob.Header.IndexBufferOffset.Value;
                }
                else
                {
                    indicesOffsets[i] = rendmeshblob.Header.IndexBufferOffset.Value + rendmeshblob.Header.RenderChunkInfos[i].ChunkIndices.TeOffset.Value;
                }
                vpStrides[i] = rendmeshblob.Header.RenderChunkInfos[i].ChunkVertices.VertexLayout.SlotStrides[0].Value;
                LODLvl[i]    = rendmeshblob.Header.RenderChunkInfos[i].LodMask.Value;
            }
            Vector4 qSc = rendmeshblob.Header.QuantizationScale;
            Vector4 qTr = rendmeshblob.Header.QuantizationOffset;

            Vec4 qScale = new Vec4(qSc.X.Value, qSc.Y.Value, qSc.Z.Value, qSc.W.Value);
            Vec4 qTrans = new Vec4(qTr.X.Value, qTr.Y.Value, qTr.Z.Value, qTr.W.Value);

            // getting number of weights for the meshes
            UInt32[] weightcounts = new UInt32[meshC];
            int      count        = 0;
            UInt32   counter      = 0;
            string   checker      = string.Empty;

            for (int i = 0; i < meshC; i++)
            {
                count   = rendmeshblob.Header.RenderChunkInfos[i].ChunkVertices.VertexLayout.Elements.Count;
                counter = 0;
                for (int e = 0; e < count; e++)
                {
                    checker = rendmeshblob.Header.RenderChunkInfos[i].ChunkVertices.VertexLayout.Elements[e].Usage.EnumValueList[0];
                    if (checker == "PS_SkinIndices")
                    {
                        counter++;
                    }
                }
                weightcounts[i] = counter * 4;
            }

            for (int i = 0; i < meshC; i++)
            {
                extraExists[i] = false;
                count          = rendmeshblob.Header.RenderChunkInfos[i].ChunkVertices.VertexLayout.Elements.Count;

                for (int e = 0; e < count; e++)
                {
                    checker = rendmeshblob.Header.RenderChunkInfos[i].ChunkVertices.VertexLayout.Elements[e].Usage.EnumValueList[0];
                    if (checker == "PS_ExtraData")
                    {
                        if (rendmeshblob.Header.RenderChunkInfos[i].ChunkVertices.VertexLayout.Elements[e].StreamIndex.Value == 0)
                        {
                            extraExists[i] = true;
                        }
                    }
                }
            }

            List <Appearance> appearances = new List <Appearance>();

            for (int i = 0; i < cr2w.Chunks.Count; i++)
            {
                if (cr2w.Chunks[i].REDType == "meshMeshAppearance")
                {
                    Appearance appearance = new Appearance();
                    appearance.Name = (cr2w.Chunks[i].Data as meshMeshAppearance).Name.Value;
                    if (appearance.Name == string.Empty)
                    {
                        appearance.Name = "DEFAULT";
                    }
                    int mtCount = (cr2w.Chunks[i].Data as meshMeshAppearance).ChunkMaterials.Count;
                    appearance.MaterialNames = new string[mtCount];
                    for (int e = 0; e < mtCount; e++)
                    {
                        appearance.MaterialNames[e] = (cr2w.Chunks[i].Data as meshMeshAppearance).ChunkMaterials[e].Value;
                    }
                    appearances.Add(appearance);
                }
            }
            MeshesInfo meshesInfo = new MeshesInfo()
            {
                vertCounts        = vertCounts,
                indCounts         = indCounts,
                vertOffsets       = vertOffsets,
                tx0Offsets        = tx0Offsets,
                normalOffsets     = normalOffsets,
                tangentOffsets    = tangentOffsets,
                colorOffsets      = colorOffsets,
                tx1Offsets        = tx1Offsets,
                unknownOffsets    = unknownOffsets,
                indicesOffsets    = indicesOffsets,
                vpStrides         = vpStrides,
                weightcounts      = weightcounts,
                extraExists       = extraExists,
                LODLvl            = LODLvl,
                qScale            = qScale,
                qTrans            = qTrans,
                meshC             = meshC,
                appearances       = appearances,
                vertBufferSize    = rendmeshblob.Header.VertexBufferSize.Value,
                indexBufferOffset = rendmeshblob.Header.IndexBufferOffset.Value,
                indexBufferSize   = rendmeshblob.Header.IndexBufferSize.Value
            };

            return(meshesInfo);
        }