Esempio n. 1
0
        private IList <Object3D> Load(BinaryReader reader)
        {
            var name         = reader.ReadCMO_wchar();
            int numMaterials = (int)reader.ReadUInt32();
            var materials    = new List <Tuple <PhongMaterial, IList <string> > >(numMaterials);

            for (int i = 0; i < numMaterials; ++i)
            {
                var material = new PhongMaterial
                {
                    Name              = reader.ReadCMO_wchar(),
                    AmbientColor      = reader.ReadStructure <Color4>(),
                    DiffuseColor      = reader.ReadStructure <Color4>(),
                    SpecularColor     = reader.ReadStructure <Color4>(),
                    SpecularShininess = reader.ReadSingle(),
                    EmissiveColor     = reader.ReadStructure <Color4>()
                };
                var uvTransform = reader.ReadStructure <Matrix>();
                if (uvTransform == Matrix.Zero)
                {
                    uvTransform = Matrix.Identity;
                }
                uvTransform.Decompose(out var s, out var r, out var tra);
                material.UVTransform = new UVTransform(r.Angle, new Vector2(s.X, s.Y), new Vector2(tra.X, tra.Y));
                var pixelShaderName = reader.ReadCMO_wchar();//Not used
                var textures        = new List <string>();
                for (int t = 0; t < MaxTextures; ++t)
                {
                    textures.Add(reader.ReadCMO_wchar());
                }
                materials.Add(new Tuple <PhongMaterial, IList <string> >(material, textures));
            }

            //      BYTE - 1 if there is skeletal animation data present

            // is there skeletal animation data present?
            bool isAnimationData = reader.ReadByte() == 1;
            //      UINT - SubMesh count
            //      { [SubMesh count]
            //          SubMesh structure
            //      }

            // load sub meshes if any

            var mesh         = new MeshGeometry3D();
            int subMeshCount = (int)reader.ReadUInt32();

            var subMesh = new List <SubMesh>(subMeshCount);

            for (int i = 0; i < subMeshCount; i++)
            {
                subMesh.Add(reader.ReadStructure <SubMesh>());
            }

            //      UINT - IB Count
            //      { [IB Count]
            //          UINT - Number of USHORTs in IB
            //          USHORT[] - Array of indices
            //      }

            // load triangle indices
            int indexBufferCount = (int)reader.ReadUInt32();
            var indices          = new List <ushort[]>(indexBufferCount);

            for (var i = 0; i < indexBufferCount; i++)
            {
                indices.Add(reader.ReadUInt16((int)reader.ReadUInt32()));
            }

            //      UINT - VB Count
            //      { [VB Count]
            //          UINT - Number of verts in VB
            //          Vertex[] - Array of vertices
            //      }

            // load vertex positions
            int vertexBufferCount = (int)reader.ReadUInt32();
            var vertexBuffers     = new List <Vertex[]>(vertexBufferCount);

            for (var i = 0; i < vertexBufferCount; i++)
            {
                vertexBuffers.Add(reader.ReadStructure <Vertex>((int)reader.ReadUInt32()));
            }
            //      UINT - Skinning VB Count
            //      { [Skinning VB Count]
            //          UINT - Number of verts in Skinning VB
            //          SkinningVertex[] - Array of skinning verts
            //      }

            // load vertex skinning parameters
            int skinningVertexBufferCount = (int)reader.ReadUInt32();
            var skinningVertexBuffers     = new List <SkinningVertex[]>(skinningVertexBufferCount);

            for (var i = 0; i < skinningVertexBufferCount; i++)
            {
                skinningVertexBuffers.Add(reader.ReadStructure <SkinningVertex>((int)reader.ReadUInt32()));
            }
            // load mesh extent
            var            extent             = reader.ReadStructure <MeshExtent>();
            var            animationHierarchy = new AnimationHierarchy();
            IList <string> boneNames          = null;

            if (isAnimationData)
            {
                //      UINT - Bone count
                //      { [Bone count]
                //          UINT - Length of bone name
                //          wchar_t[] - Bone name (if length > 0)
                //          Bone structure
                //      }
                int boneCount = (int)reader.ReadUInt32();
                boneNames = new string[boneCount];
                for (var i = 0; i < boneCount; i++)
                {
                    boneNames[i] = reader.ReadCMO_wchar();
                    animationHierarchy.Bones.Add(reader.ReadStructure <BoneStruct>());
                }

                //      UINT - Animation clip count
                //      { [Animation clip count]
                //          UINT - Length of clip name
                //          wchar_t[] - Clip name (if length > 0)
                //          float - Start time
                //          float - End time
                //          UINT - Keyframe count
                //          { [Keyframe count]
                //              Keyframe structure
                //          }
                //      }
                int animationCount = (int)reader.ReadUInt32();
                for (var i = 0; i < animationCount; i++)
                {
                    Animation animation     = new Animation(AnimationType.Keyframe);
                    string    animationName = reader.ReadCMO_wchar();
                    animation.StartTime = reader.ReadSingle();
                    animation.EndTime   = reader.ReadSingle();
                    animation.Name      = animationName;
                    int keyframeCount = (int)reader.ReadUInt32();
                    for (var j = 0; j < keyframeCount; j++)
                    {
                        var keyframe = reader.ReadStructure <KeyframeCMO>();
                        keyframe.Transform.Decompose(out var s, out var q, out var t);
                        animation.Keyframes.Add(new Keyframe()
                        {
                            Translation = t, Rotation = q, Scale = s, Time = keyframe.Time
                        });
                    }
                    animationHierarchy.Animations.Add(animation.Name, animation);
                    if (!UniqueAnimations.ContainsKey(animation.Name))
                    {
                        UniqueAnimations.Add(animation.Name, new List <Guid>());
                    }
                    UniqueAnimations[animation.Name].Add(animation.GUID);
                }
            }
            var obj3Ds = new List <Object3D>(subMeshCount);

            for (int i = 0; i < subMesh.Count; ++i)
            {
                var sub              = subMesh[i];
                var material         = materials.Count == 0 ? new PhongMaterial() : materials[(int)sub.MaterialIndex].Item1;
                var vertexCollection = new Vector3Collection(vertexBuffers[(int)sub.VertexDataIndex].Select(x => x.Position));
                var normal           = new Vector3Collection(vertexBuffers[(int)sub.VertexDataIndex].Select(x => x.Normal));
                var tex              = new Vector2Collection(vertexBuffers[(int)sub.VertexDataIndex].Select(x => x.UV));
                var tangent          = new Vector3Collection(vertexBuffers[(int)sub.VertexDataIndex].Select(x => x.Tangent.ToVector3()));
                var biTangent        = new Vector3Collection(normal.Zip(tangent, (x, y) => { return(Vector3.Cross(x, y)); }));
                var indexCollection  = new IntCollection(indices[(int)sub.IndexDataIndex].Select(x => (int)x));
                var meshGeo          = new MeshGeometry3D()
                {
                    Positions          = vertexCollection,
                    Indices            = indexCollection, Normals = normal,
                    Tangents           = tangent, BiTangents = biTangent,
                    TextureCoordinates = tex
                };
                if (isAnimationData)
                {
                    var boneskinmesh = new BoneSkinnedMeshGeometry3D(meshGeo);
                    boneskinmesh.VertexBoneIds = new List <BoneIds>(skinningVertexBuffers[(int)sub.VertexDataIndex]
                                                                    .Select(x => new BoneIds()
                    {
                        Bone1   = (int)x.BoneIndex0,
                        Bone2   = (int)x.BoneIndex1,
                        Bone3   = (int)x.BoneIndex2,
                        Bone4   = (int)x.BoneIndex3,
                        Weights = new Vector4(x.BoneWeight0, x.BoneWeight1, x.BoneWeight2, x.BoneWeight3),
                    }));
                    meshGeo = boneskinmesh;
                }
                //Todo Load textures
                obj3Ds.Add(new Object3D()
                {
                    Geometry = meshGeo, Material = material, Name = name
                });
                animationHierarchy.Meshes.Add(obj3Ds.Last());
            }
            AnimationHierarchy.Add(animationHierarchy);
            return(obj3Ds);
        }