示例#1
0
        public Boolean ProcessAssetContext(H1StaticLODModel staticLODModel, H1MeshContext[] meshContexts, H1SkeletalContext skeletalContext)
        {
            if (m_Skeleton == null)
            {
                return(false);
            }

            // 1. process skeletalContext (H1SkeletalContext)
            H1SkeletalContext.JointNode rootNode    = skeletalContext.Root;
            H1ReferenceSkeleton         refSkeleton = m_Skeleton.RefSkeleton;

            #region Disabled
            // process recursively from root node
            //Dictionary<String, H1SkeletalContext.JointNode> mapNodeNameToJointNode = new Dictionary<string, H1SkeletalContext.JointNode>();
            //if (!ProcessAssetContextRecursive(rootNode, ref refSkeleton, ref mapNodeNameToJointNode))
            //    return false; // failed to process nodes from root nodes
            #endregion

            // 2. process meshContexts (H1MeshContext)
            // collect all vertices for all different mesh contexts
            Int32[] meshContextOffsetsList = new Int32[meshContexts.Count()];

            List <Vector3> positionsList = new List <Vector3>();
            List <Vector3> tangentXList  = new List <Vector3>();
            List <Vector3> tangentYList  = new List <Vector3>();
            List <Vector3> tangentZList  = new List <Vector3>();
            List <Vector2> texcoordsList = new List <Vector2>();

            Int32 currMeshContextIndex = 0;
            foreach (H1MeshContext meshContext in meshContexts)
            {
                meshContextOffsetsList[currMeshContextIndex] = positionsList.Count;

                positionsList.AddRange(meshContext.Positions);
                tangentXList.AddRange(meshContext.Tangents);
                tangentYList.AddRange(meshContext.Normals);
                tangentZList.AddRange(meshContext.BiTangents);
                texcoordsList.AddRange(meshContext.UVBuffers[0].Buffer);

                currMeshContextIndex++;
            }

            Vector3[] positions = positionsList.ToArray();
            Vector3[] tangentX  = tangentXList.ToArray();
            Vector3[] tangentY  = tangentYList.ToArray();
            Vector3[] tangentZ  = tangentZList.ToArray();
            Vector2[] texcoords = texcoordsList.ToArray();

            Int32 numPositions = positions.Count();
            if (numPositions != texcoords.Count())
            {
                return(false);
            }

            // create the list of vertex info
            List <VertexInfo> vertexInfoList = new List <VertexInfo>();
#if DEBUG
            List <Boolean> taggedVertexInfoList = new List <Boolean>();
#endif

            for (Int32 i = 0; i < numPositions; ++i)
            {
                vertexInfoList.Add(new VertexInfo());
                vertexInfoList[i].VertexIndex = i;
#if DEBUG
                taggedVertexInfoList.Add(false);
#endif
            }

            // set the triangle index
            // create collection of index for all mesh contexts
            List <UInt32> indexList        = new List <UInt32>();
            Int32         meshContextIndex = 0;
            foreach (H1MeshContext meshContext in meshContexts)
            {
                // using meshContextOffsetsList information, remap indices correctly
                foreach (UInt32 vertexIndex in meshContext.Indices)
                {
                    indexList.Add(Convert.ToUInt32(meshContextOffsetsList[meshContextIndex]) + vertexIndex);
                }

                meshContextIndex++;
            }

            UInt32[] indices = indexList.ToArray();
#if DEBUG
            Boolean[] taggedIndices = new Boolean[indexList.Count];
#endif

            // looping index, set triangle index for each vertexInfoList
            Int32 indexOfIndex = 0;
            foreach (UInt32 index in indices)
            {
                Int32 vertexIndex   = Convert.ToInt32(index);
                Int32 triangleIndex = indexOfIndex / 3;

                // set the triangle index
                vertexInfoList[vertexIndex].TriangleIndices.Add(triangleIndex);
#if DEBUG
                taggedIndices[indexOfIndex] = false;
#endif
                indexOfIndex++;
            }

            // process vertex weights and bone index in advance by looping all H1MeshBoneInfo
            Int32 meshBoneInfoIndex = 0;
            foreach (H1MeshBoneInfo meshBoneInfo in refSkeleton.RefBoneInfoList)
            {
                Int32 jointNodeIndex             = skeletalContext.JointNodes.FindIndex(x => x.JointName == meshBoneInfo.Name);
                H1SkeletalContext.JointNode node = skeletalContext.JointNodes[jointNodeIndex];

                foreach (H1SkeletalContext.Joint nodeData in node.JointDataList)
                {
                    // looping weighted vertices
                    Int32 vertexIndexOffset = nodeData.MeshContextIndex == -1 ? 0 : meshContextOffsetsList[nodeData.MeshContextIndex];
                    // process vertex weights and bone index
                    foreach (H1SkeletalContext.WeightedVertex weightedVertex in nodeData.WeightedVertices)
                    {
                        VertexInfo.InfluenceBoneData influencedBoneData = new VertexInfo.InfluenceBoneData();
                        influencedBoneData.BoneIndex  = meshBoneInfoIndex;
                        influencedBoneData.BoneWeight = weightedVertex.Weight;

                        vertexInfoList[vertexIndexOffset + weightedVertex.VertexIndex].InfluencedBones.Add(influencedBoneData);
                    }
                }
                meshBoneInfoIndex++;
            }

#if DEBUG
            // verification code for vertex weights
            List <float> taggedVertexWeights = new List <float>();
            foreach (VertexInfo vertexInfo in vertexInfoList)
            {
                float totalWeight = 0.0f;
                foreach (VertexInfo.InfluenceBoneData influencedBoneData in vertexInfo.InfluencedBones)
                {
                    totalWeight += influencedBoneData.BoneWeight;
                }
                taggedVertexWeights.Add(totalWeight);
            }

            List <Int32> invalidVertexIndices = new List <Int32>();
            Int32        currVertexIndex      = 0;
            foreach (float totalWeight in taggedVertexWeights)
            {
                if (totalWeight < 0.99f)
                {
                    invalidVertexIndices.Add(currVertexIndex);
                }
                currVertexIndex++;
            }

            if (invalidVertexIndices.Count > 0)
            {
                return(false);
            }
#endif

            // looping meshBoneInfo, set bone index and bone weight
            foreach (H1MeshBoneInfo meshBoneInfo in refSkeleton.RefBoneInfoList)
            {
                Int32 jointNodeIndex             = skeletalContext.JointNodes.FindIndex(x => x.JointName == meshBoneInfo.Name);
                H1SkeletalContext.JointNode node = skeletalContext.JointNodes[jointNodeIndex];
                List <UInt32> ChunkVertexIndices = new List <UInt32>(); // vertex indices for this chunk (bone node)

                foreach (H1SkeletalContext.Joint nodeData in node.JointDataList)
                {
                    // looping weighted vertices
                    Int32 vertexIndexOffset = nodeData.MeshContextIndex == -1 ? 0 : meshContextOffsetsList[nodeData.MeshContextIndex];
                    // add chunk vertex indices
                    foreach (H1SkeletalContext.WeightedVertex weightedVertex in nodeData.WeightedVertices)
                    {
                        ChunkVertexIndices.Add(Convert.ToUInt32(vertexIndexOffset + weightedVertex.VertexIndex));
                    }
                }

                // exceptional handling for MeshBoneInfo which doesn't contain any mesh data, no need to generate chunk for this BasePose
                if (ChunkVertexIndices.Count == 0)
                {
                    continue;
                }

                // process skeletal mesh chunk
                H1SkelMeshChunk skelMeshChunk = new H1SkelMeshChunk();
                // calculate triangles for this mesh chunk
                List <UInt32> triangles = new List <UInt32>();

                foreach (Int32 vertexIndex in ChunkVertexIndices)
                {
                    VertexInfo vertexInfo = vertexInfoList[vertexIndex];

                    H1SoftSkinVertex newSoftSkinVertex = new H1SoftSkinVertex();
                    newSoftSkinVertex.Position = positions[vertexInfo.VertexIndex];
                    newSoftSkinVertex.TangentX = tangentX[vertexInfo.VertexIndex];
                    newSoftSkinVertex.TangentY = tangentY[vertexInfo.VertexIndex];
                    newSoftSkinVertex.TangentZ = tangentZ[vertexInfo.VertexIndex];

                    // @TODO - in the future, it could increase texcoords (ex. light map texcoord)
                    newSoftSkinVertex.UVs[0] = texcoords[vertexInfo.VertexIndex];

                    for (Int32 i = 0; i < H1ObjectGlobalDefinitions.MAX_TOTAL_INFLUENCES; ++i)
                    {
                        if (vertexInfo.InfluencedBones.Count <= i)
                        {
                            // insert the default value
                            newSoftSkinVertex.InfluenceWeights[i] = 0;
                            newSoftSkinVertex.InfluenceBones[i]   = 0;
                            continue;
                        }

                        VertexInfo.InfluenceBoneData boneData = vertexInfo.InfluencedBones[i];
                        newSoftSkinVertex.InfluenceWeights[i] = Convert.ToByte(boneData.BoneWeight * 255.0f);
                        // @TODO - for this bone index, we can replace with 'm_BoneMap'
                        newSoftSkinVertex.InfluenceBones[i] = Convert.ToByte(boneData.BoneIndex);
                    }

                    skelMeshChunk.SoftVertices.Add(newSoftSkinVertex);

                    // process triangle indices
                    foreach (Int32 triangleIndex in vertexInfo.TriangleIndices)
                    {
                        UInt32 triangleIndexUInt32 = Convert.ToUInt32(triangleIndex);
                        if (!triangles.Exists(x => { return(x == triangleIndexUInt32); }))
                        {
                            triangles.Add(triangleIndexUInt32);
                        }
                    }
                }

                // build vertex buffers
                List <Vector4> chunkPositions   = new List <Vector4>();
                List <Vector4> chunkTangentZs   = new List <Vector4>();
                List <Vector4> chunkTangentXs   = new List <Vector4>();
                List <Vector2> chunkTexcoords   = new List <Vector2>();
                List <Int4>    chunkBoneIndices = new List <Int4>();
                List <Vector4> chunkBoneWeights = new List <Vector4>();
                List <Vector4> chunkColors      = new List <Vector4>();

                Dictionary <Int32, Int32> vertexToChunkVertexMap = new Dictionary <Int32, Int32>();
                foreach (Int32 triangleIndex in triangles)
                {
                    for (Int32 faceIndex = 0; faceIndex < 3; ++faceIndex)
                    {
                        Int32 vertexIndex = Convert.ToInt32(indices[triangleIndex * 3 + faceIndex]);

#if DEBUG
                        taggedVertexInfoList[vertexIndex] = true;
#endif

                        // determine if the same vertex exists based on chunkPositions
                        //if (chunkPositions.Contains(new Vector4(positions[vertexIndex], 1.0f)))
                        if (vertexToChunkVertexMap.ContainsKey(vertexIndex))
                        {
                            continue;
                        }

                        // position index is base-index
                        Int32 newIndex = chunkPositions.Count;
                        vertexToChunkVertexMap.Add(vertexIndex, newIndex);

                        chunkPositions.Add(new Vector4(positions[vertexIndex], 1.0f));
                        chunkTangentZs.Add(new Vector4(tangentZ[vertexIndex], 1.0f));
                        chunkTangentXs.Add(new Vector4(tangentX[vertexIndex], 1.0f));
                        chunkTexcoords.Add(new Vector2(texcoords[vertexIndex].X, texcoords[vertexIndex].Y));

                        VertexInfo vertexInfo        = vertexInfoList[vertexIndex];
                        Int4       influencedBones   = new Int4(0);
                        Vector4    influencedWeights = new Vector4(0.0f);

                        Int32 insertedIndex = 0;
                        foreach (VertexInfo.InfluenceBoneData boneData in vertexInfo.InfluencedBones)
                        {
                            influencedBones[insertedIndex]   = boneData.BoneIndex;
                            influencedWeights[insertedIndex] = boneData.BoneWeight;
                            insertedIndex++;
                        }

                        chunkBoneIndices.Add(influencedBones);
                        chunkBoneWeights.Add(influencedWeights);

                        //@TODO - temporary set it as 'RED'
                        chunkColors.Add(new Vector4(1.0f, 0.0f, 0.0f, 1.0f));
                    }
                }

                // create skeletal mesh vertex data
                // 1. position
                H1SkeletalMeshVertexData <Vector4> positionVertexData = new H1SkeletalMeshVertexData <Vector4>();
                positionVertexData.SetVertexData(chunkPositions.ToArray(), H1SkeletalMeshVertexDataInterface.VertexDataType.Position, false);
                // 2. tangentZ
                H1SkeletalMeshVertexData <Vector4> tangentZVertexData = new H1SkeletalMeshVertexData <Vector4>();
                tangentZVertexData.SetVertexData(chunkTangentZs.ToArray(), H1SkeletalMeshVertexDataInterface.VertexDataType.TangentZ, false);
                // 3. tangentX
                H1SkeletalMeshVertexData <Vector4> tangentXVertexData = new H1SkeletalMeshVertexData <Vector4>();
                tangentXVertexData.SetVertexData(chunkTangentXs.ToArray(), H1SkeletalMeshVertexDataInterface.VertexDataType.TangentX, false);
                // 4. bone indices
                H1SkeletalMeshVertexData <Int4> boneIndicesVertexData = new H1SkeletalMeshVertexData <Int4>();
                boneIndicesVertexData.SetVertexData(chunkBoneIndices.ToArray(), H1SkeletalMeshVertexDataInterface.VertexDataType.InfluencedBones, false);
                // 5. bone weights
                H1SkeletalMeshVertexData <Vector4> boneWeightsVertexData = new H1SkeletalMeshVertexData <Vector4>();
                boneWeightsVertexData.SetVertexData(chunkBoneWeights.ToArray(), H1SkeletalMeshVertexDataInterface.VertexDataType.InfluencedWeights, false);
                // 6. texcoord
                H1SkeletalMeshVertexData <Vector2> texcoordVertexData = new H1SkeletalMeshVertexData <Vector2>();
                texcoordVertexData.SetVertexData(chunkTexcoords.ToArray(), H1SkeletalMeshVertexDataInterface.VertexDataType.Texcoord, false);
                // 7. colors
                H1SkeletalMeshVertexData <Vector4> colorVertexData = new H1SkeletalMeshVertexData <Vector4>();
                colorVertexData.SetVertexData(chunkColors.ToArray(), H1SkeletalMeshVertexDataInterface.VertexDataType.Color);

                Int32 newSkelMeshChunkIndex = staticLODModel.VertexBufferGPUSkin.SkeletalMeshVertexBuffers.Count;
                staticLODModel.VertexBufferGPUSkin.SkeletalMeshVertexBuffers.Add(new H1SkeletalMeshVertexBuffers(newSkelMeshChunkIndex));
                staticLODModel.VertexBufferGPUSkin.SkeletalMeshVertexBuffers[newSkelMeshChunkIndex].AddSkeletalMeshVertexData(positionVertexData);
                staticLODModel.VertexBufferGPUSkin.SkeletalMeshVertexBuffers[newSkelMeshChunkIndex].AddSkeletalMeshVertexData(tangentZVertexData);
                staticLODModel.VertexBufferGPUSkin.SkeletalMeshVertexBuffers[newSkelMeshChunkIndex].AddSkeletalMeshVertexData(tangentXVertexData);
                staticLODModel.VertexBufferGPUSkin.SkeletalMeshVertexBuffers[newSkelMeshChunkIndex].AddSkeletalMeshVertexData(boneIndicesVertexData);
                staticLODModel.VertexBufferGPUSkin.SkeletalMeshVertexBuffers[newSkelMeshChunkIndex].AddSkeletalMeshVertexData(boneWeightsVertexData);
                staticLODModel.VertexBufferGPUSkin.SkeletalMeshVertexBuffers[newSkelMeshChunkIndex].AddSkeletalMeshVertexData(texcoordVertexData);
                staticLODModel.VertexBufferGPUSkin.SkeletalMeshVertexBuffers[newSkelMeshChunkIndex].AddSkeletalMeshVertexData(colorVertexData);

                // build index buffer
                List <UInt32> chunkIndices = new List <UInt32>();
                foreach (Int32 triangleIndex in triangles)
                {
                    for (Int32 faceIndex = 0; faceIndex < 3; ++faceIndex)
                    {
#if DEBUG
                        taggedIndices[triangleIndex * 3 + faceIndex] = true;
#endif
                        Int32 vertexIndex = Convert.ToInt32(indices[triangleIndex * 3 + faceIndex]);
                        chunkIndices.Add(Convert.ToUInt32(vertexToChunkVertexMap[vertexIndex]));
                    }
                }

                staticLODModel.MultiSizeIndexContainer.Indices.AddRange(chunkIndices.ToArray());

                // add new chunk
                Int32 newChunkIndex = staticLODModel.Chunks.Count;
                staticLODModel.Chunks.Add(skelMeshChunk);

                // process skeletal mesh section
                H1SkelMeshSection skelMeshSection = new H1SkelMeshSection();
                skelMeshSection.ChunkIndex = Convert.ToUInt16(newChunkIndex);

                // @TODO - fix this num triangle inconsistency
                //skelMeshSection.NumTriangles = Convert.ToUInt16(triangles.Count);
                skelMeshSection.NumTriangles = Convert.ToUInt16(chunkIndices.Count / 3);

                //@TODO - add material index

                // add skeletal sections
                staticLODModel.Sections.Add(skelMeshSection);
            }

#if DEBUG
            // debugging code for detecting missing vertex to draw meshes
            List <Int32> notTaggedVertexIndex  = new List <Int32>();
            Int32        currTaggedVertexIndex = 0;
            foreach (Boolean isTaggedVertex in taggedVertexInfoList)
            {
                if (isTaggedVertex == false)
                {
                    notTaggedVertexIndex.Add(currTaggedVertexIndex);
                }
                currTaggedVertexIndex++;
            }
            if (notTaggedVertexIndex.Count > 0)
            {
                return(false);
            }

            // debugging code for detecting missing index to draw meshes
            List <Int32> notTaggedIndex   = new List <Int32>();
            Int32        currIndexOfIndex = 0;
            foreach (Boolean isTaggedIndex in taggedIndices)
            {
                if (isTaggedIndex == false)
                {
                    notTaggedIndex.Add(currIndexOfIndex);
                }
                currIndexOfIndex++;
            }
            if (notTaggedIndex.Count > 0)
            {
                return(false);
            }
#endif

            return(true);
        }
        public Boolean GenerateSkeleltalMeshObjectGpuSkin()
        {
            // allocate new instance of SkeletalMeshGpuSkin
            m_SkeletalMeshObject = new H1SkeletalMeshObjectGPUSkin(m_SkeletalMesh.SkeletalMeshResource);
            H1SkeletalMeshObjectGPUSkin refSkeletalMeshObject = m_SkeletalMeshObject as H1SkeletalMeshObjectGPUSkin;

            // process soft vertices for each chunk to separate vertex buffers
            // @TODO - handle LOD variation
            List <H1SkelMeshChunk> skelChunks = SkeletalMesh.SkeletalMeshResource.GetLODModel(0).Chunks;

            // @TODO - temporary add LOD_0
            H1SkeletalMeshObjectGPUSkin.H1SkeletalMeshObjectLOD skeletalMeshObjectLOD_0 = refSkeletalMeshObject.AddSkeletalMeshObjectLOD();

            Int32 skelChunkIndex = 0;

            foreach (H1SkelMeshChunk skelChunk in skelChunks)
            {
                H1SkeletalMeshVertexBuffers skeletalMeshVBsRef = skeletalMeshObjectLOD_0.SkelMeshResourceRef.GetLODModel(0).VertexBufferGPUSkin.SkeletalMeshVertexBuffers[skelChunkIndex];

                // add GPUSkinFactory
                skeletalMeshObjectLOD_0.GPUSkinVertexFactories.VertexFactories.Add(new H1GpuSkinVertexFactory());
                H1GpuSkinVertexFactory newGpuSkinVertexFactoryRef = skeletalMeshObjectLOD_0.GPUSkinVertexFactories.VertexFactories.Last();

                // offset tracking
                Int32 currOffset = 0;

                Int32 skelMeshVBsCount = skeletalMeshVBsRef.GetSkeletalMeshVertexDataCount();
                for (Int32 skelMeshVBIndex = 0; skelMeshVBIndex < skelMeshVBsCount; ++skelMeshVBIndex)
                {
                    H1SkeletalMeshVertexDataInterface skeletalMeshVertexData = skeletalMeshVBsRef.GetSkeletalMeshVertexData(skelMeshVBIndex);
                    switch (skeletalMeshVertexData.DataType)
                    {
                    case H1SkeletalMeshVertexDataInterface.VertexDataType.Position:
                    {
                        H1SkeletalMeshVertexData <Vector4> positionVertexData = skeletalMeshVertexData as H1SkeletalMeshVertexData <Vector4>;
                        newGpuSkinVertexFactoryRef.ShaderData.PositionBuffer = H1VertexBuffer.ProcessVertexBuffer(positionVertexData.VertexBuffer);
                        newGpuSkinVertexFactoryRef.PositionStreamComponent   = new H1VertexStreamComponent(H1VertexStreamSematicType.Position, H1VertexElementType.Float4, currOffset++);
                        break;
                    }

                    case H1SkeletalMeshVertexDataInterface.VertexDataType.TangentZ:
                    {
                        H1SkeletalMeshVertexData <Vector4> tangentZVertexData = skeletalMeshVertexData as H1SkeletalMeshVertexData <Vector4>;
                        newGpuSkinVertexFactoryRef.ShaderData.TangentZBuffer = H1VertexBuffer.ProcessVertexBuffer(tangentZVertexData.VertexBuffer);
                        newGpuSkinVertexFactoryRef.TangentZStreamComponent   = new H1VertexStreamComponent(H1VertexStreamSematicType.TangentZ, H1VertexElementType.Float4, currOffset++);
                        break;
                    }

                    case H1SkeletalMeshVertexDataInterface.VertexDataType.TangentX:
                    {
                        H1SkeletalMeshVertexData <Vector4> tangentXVertexData = skeletalMeshVertexData as H1SkeletalMeshVertexData <Vector4>;
                        newGpuSkinVertexFactoryRef.ShaderData.TangentXBuffer = H1VertexBuffer.ProcessVertexBuffer(tangentXVertexData.VertexBuffer);
                        newGpuSkinVertexFactoryRef.TangentXStreamComponent   = new H1VertexStreamComponent(H1VertexStreamSematicType.TangentX, H1VertexElementType.Float4, currOffset++);
                        break;
                    }

                    case H1SkeletalMeshVertexDataInterface.VertexDataType.InfluencedBones:
                    {
                        H1SkeletalMeshVertexData <Int4> boneIndicesVertexData = skeletalMeshVertexData as H1SkeletalMeshVertexData <Int4>;
                        newGpuSkinVertexFactoryRef.ShaderData.BoneIndices     = H1VertexBuffer.ProcessVertexBuffer(boneIndicesVertexData.VertexBuffer);
                        newGpuSkinVertexFactoryRef.BoneIndicesStreamComponent = new H1VertexStreamComponent(H1VertexStreamSematicType.BoneIndices, H1VertexElementType.Int4, currOffset++);
                        break;
                    }

                    case H1SkeletalMeshVertexDataInterface.VertexDataType.InfluencedWeights:
                    {
                        H1SkeletalMeshVertexData <Vector4> blendWeightsVertexData = skeletalMeshVertexData as H1SkeletalMeshVertexData <Vector4>;
                        newGpuSkinVertexFactoryRef.ShaderData.BoneWeights     = H1VertexBuffer.ProcessVertexBuffer(blendWeightsVertexData.VertexBuffer);
                        newGpuSkinVertexFactoryRef.BoneWeightsStreamComponent = new H1VertexStreamComponent(H1VertexStreamSematicType.BoneWeights, H1VertexElementType.Float4, currOffset++);
                        break;
                    }

                    // @TODO - support multiple texcoords
                    case H1SkeletalMeshVertexDataInterface.VertexDataType.Texcoord:
                    {
                        H1SkeletalMeshVertexData <Vector2> texcoordVertexData = skeletalMeshVertexData as H1SkeletalMeshVertexData <Vector2>;
                        newGpuSkinVertexFactoryRef.ShaderData.TexcoordBuffers.Add(H1VertexBuffer.ProcessVertexBuffer(texcoordVertexData.VertexBuffer));
                        newGpuSkinVertexFactoryRef.TexcoordStreamComponents.Add(new H1VertexStreamComponent(H1VertexStreamSematicType.Texcoord, H1VertexElementType.Float2, currOffset++));
                        break;
                    }

                    case H1SkeletalMeshVertexDataInterface.VertexDataType.Color:
                    {
                        H1SkeletalMeshVertexData <Vector4> colorVertexData = skeletalMeshVertexData as H1SkeletalMeshVertexData <Vector4>;
                        newGpuSkinVertexFactoryRef.ShaderData.ColorBuffer = H1VertexBuffer.ProcessVertexBuffer(colorVertexData.VertexBuffer);
                        newGpuSkinVertexFactoryRef.ColorStreamComponent   = new H1VertexStreamComponent(H1VertexStreamSematicType.Color, H1VertexElementType.Float4, currOffset++);
                        break;
                    }
                    }
                }

                // generate RHIVertexFormat Declaration
                newGpuSkinVertexFactoryRef.GenerateVertexDeclaration();

                skelChunkIndex++;
            }

            // add index buffer (containing multiple skeletal mesh chunks's indices)
            List <UInt32> indices    = SkeletalMesh.SkeletalMeshResource.GetLODModel(0).MultiSizeIndexContainer.Indices;
            UInt32        bufferSize = Convert.ToUInt32(Utilities.SizeOf <UInt32>() * indices.Count);

            skeletalMeshObjectLOD_0.IndexBuffer = H1Global <H1ManagedRenderer> .Instance.CreateIndexBuffer(bufferSize);

            // write indices data
            skeletalMeshObjectLOD_0.IndexBuffer.WriteData(indices.ToArray());

            return(true);
        }