Exemplo n.º 1
0
        private void ReadSeqInfo()
        {
            SeqList    = new List <SeqInfo>();
            TargetSeqs = new List <SeqInfo>();
            string[] lines = Properties.Resources.SEQS.Split(new[] { Environment.NewLine }, StringSplitOptions.None);
            int      i     = 0;

            while (i < lines.Length)
            {
                SeqInfo s = new SeqInfo();
                SeqInfo t = new SeqInfo();
                s.Name = lines[i];
                s.Type = Array.ConvertAll(lines[i + 1].Split(','), int.Parse).ToList();
                s.Inst = Convert.ToInt32(lines[i + 2], 16);
                t.Name = lines[i];
                t.Type = Array.ConvertAll(lines[i + 1].Split(','), int.Parse).ToList();
                t.Inst = Convert.ToInt32(lines[i + 2], 16);
                if (s.Name.StartsWith("mm-"))
                {
                    t.Replaces = Convert.ToInt32(lines[i + 3], 16);
                    s.MM_seq   = Convert.ToInt32(lines[i + 3], 16);
                    TargetSeqs.Add(t);
                    i += 4;
                }
                else
                {
                    if (s.Name == "mmr-f-sot")
                    {
                        s.Replaces = 0x33;
                    }
                    ;
                    i += 3;
                };
                if (s.MM_seq != 0x18)
                {
                    SeqList.Add(s);
                }
                ;
            }
            ;
        }
Exemplo n.º 2
0
        public MDLFile(Stream FileInput, Boolean parseAnims = false, Boolean parseHitboxes = false)
        {
            using (uReader FileStream = new uReader(FileInput))
            {
                FileStream.ReadTypeFixed(ref MDL_Header, 392);

                if (MDL_Header.id != 0x54534449)
                {
                    throw new FileLoadException("File signature does not match 'IDST'");
                }

                //Bones
                #region Bones
                //Bones
                MDL_StudioBones = new mstudiobone_t[MDL_Header.bone_count];
                MDL_BoneNames   = new String[MDL_Header.bone_count];
                for (Int32 BoneID = 0; BoneID < MDL_Header.bone_count; BoneID++)
                {
                    Int32 boneOffset = MDL_Header.bone_offset + (216 * BoneID);
                    FileStream.ReadTypeFixed(ref MDL_StudioBones[BoneID], 216, boneOffset);
                    MDL_BoneNames[BoneID] = FileStream.ReadNullTerminatedString(boneOffset + MDL_StudioBones[BoneID].sznameindex);
                }
                //Bones
                #endregion

                #region Hitboxes
                if (parseHitboxes)
                {
                    MDL_Hitboxsets = new mstudiohitboxset_t[MDL_Header.hitbox_count];
                    Hitboxes       = new Hitbox[MDL_Header.hitbox_count][];
                    for (Int32 HitboxsetID = 0; HitboxsetID < MDL_Header.hitbox_count; HitboxsetID++)
                    {
                        Int32 HitboxsetOffset = MDL_Header.hitbox_offset + (12 * HitboxsetID);
                        FileStream.ReadTypeFixed(ref MDL_Hitboxsets[HitboxsetID], 12, HitboxsetOffset);
                        Hitboxes[HitboxsetID] = new Hitbox[MDL_Hitboxsets[HitboxsetID].numhitboxes];

                        for (Int32 HitboxID = 0; HitboxID < MDL_Hitboxsets[HitboxsetID].numhitboxes; HitboxID++)
                        {
                            Int32 HitboxOffset = HitboxsetOffset + (68 * HitboxID) + MDL_Hitboxsets[HitboxsetID].hitboxindex;
                            Hitboxes[HitboxsetID][HitboxID].BBox = new mstudiobbox_t();

                            FileStream.ReadTypeFixed(ref Hitboxes[HitboxsetID][HitboxID].BBox, 68, HitboxOffset);
                        }
                    }
                }
                #endregion

                #region Animations
                if (parseAnims)
                {
                    try
                    {
                        //Animations
                        MDL_AniDescriptions = new mstudioanimdesc_t[MDL_Header.localanim_count];
                        Animations          = new AniInfo[MDL_Header.localanim_count];

                        for (Int32 AnimID = 0; AnimID < MDL_Header.localanim_count; AnimID++)
                        {
                            Int32 AnimOffset = MDL_Header.localanim_offset + (100 * AnimID);
                            FileStream.ReadTypeFixed(ref MDL_AniDescriptions[AnimID], 100, AnimOffset);
                            mstudioanimdesc_t StudioAnim = MDL_AniDescriptions[AnimID];

                            String StudioAnimName = FileStream.ReadNullTerminatedString(AnimOffset + StudioAnim.sznameindex);
                            Animations[AnimID] = new AniInfo {
                                name = StudioAnimName, studioAnim = StudioAnim
                            };
                            Animations[AnimID].AnimationBones = new List <AnimationBone>();

                            //mstudioanim_t
                            FileStream.BaseStream.Position = AnimOffset;

                            Int64 StartOffset = FileStream.BaseStream.Position;

                            Int32 CurrentOffset = MDL_AniDescriptions[AnimID].animindex;
                            Int16 NextOffset;
                            do
                            {
                                FileStream.BaseStream.Position = StartOffset + CurrentOffset;
                                Byte BoneIndex = FileStream.ReadByte();
                                Byte BoneFlag  = FileStream.ReadByte();
                                NextOffset     = FileStream.ReadInt16();
                                CurrentOffset += NextOffset;

                                AnimationBone AnimatedBone = new AnimationBone(BoneIndex, BoneFlag, MDL_AniDescriptions[AnimID].numframes);
                                AnimatedBone.ReadData(FileStream);
                                Animations[AnimID].AnimationBones.Add(AnimatedBone);
                            } while (NextOffset != 0);
                            //mstudioanim_t

                            List <AnimationBone> AnimationBones = Animations[AnimID].AnimationBones;
                            Int32 NumBones  = MDL_Header.bone_count;
                            Int32 NumFrames = StudioAnim.numframes;

                            //Used to avoid "Assertion failed" key count in Unity (if frames less than 2)
                            Boolean FramesLess = NumFrames < 2;
                            if (FramesLess)
                            {
                                NumFrames += 1;
                            }

                            Animations[AnimID].PosX = new Keyframe[NumFrames][];
                            Animations[AnimID].PosY = new Keyframe[NumFrames][];
                            Animations[AnimID].PosZ = new Keyframe[NumFrames][];

                            Animations[AnimID].RotX = new Keyframe[NumFrames][];
                            Animations[AnimID].RotY = new Keyframe[NumFrames][];
                            Animations[AnimID].RotZ = new Keyframe[NumFrames][];
                            Animations[AnimID].RotW = new Keyframe[NumFrames][];
                            for (Int32 FrameID = 0; FrameID < NumFrames; FrameID++)
                            {
                                Animations[AnimID].PosX[FrameID] = new Keyframe[NumBones];
                                Animations[AnimID].PosY[FrameID] = new Keyframe[NumBones];
                                Animations[AnimID].PosZ[FrameID] = new Keyframe[NumBones];

                                Animations[AnimID].RotX[FrameID] = new Keyframe[NumBones];
                                Animations[AnimID].RotY[FrameID] = new Keyframe[NumBones];
                                Animations[AnimID].RotZ[FrameID] = new Keyframe[NumBones];
                                Animations[AnimID].RotW[FrameID] = new Keyframe[NumBones];
                            }

                            for (Int32 boneID = 0; boneID < NumBones; boneID++)
                            {
                                AnimationBone AnimBone = AnimationBones.FirstOrDefault(x => x.Bone == boneID);

                                //frameIndex < 30 && studioAnimName == "@ak47_reload"
                                for (Int32 frameID = 0; frameID < NumFrames; frameID++)
                                {
                                    //get current animation time (length) by divide frame index on "fps"
                                    Single time = frameID / StudioAnim.fps;

                                    mstudiobone_t StudioBone = MDL_StudioBones[boneID];
                                    //Transform bone = Bones[boneIndex];

                                    Vector3 Position = StudioBone.pos;
                                    Vector3 Rotation = StudioBone.rot;

                                    //BINGO! All animations are corrected :p
                                    if (AnimBone != null)
                                    {
                                        if ((AnimBone.Flags & STUDIO_ANIM_RAWROT) > 0)
                                        {
                                            Rotation = MathLibrary.ToEulerAngles(AnimBone.pQuat48);
                                        }

                                        if ((AnimBone.Flags & STUDIO_ANIM_RAWROT2) > 0)
                                        {
                                            Rotation = MathLibrary.ToEulerAngles(AnimBone.pQuat64);
                                        }

                                        if ((AnimBone.Flags & STUDIO_ANIM_RAWPOS) > 0)
                                        {
                                            Position = AnimBone.pVec48;
                                        }

                                        if ((AnimBone.Flags & STUDIO_ANIM_ANIMROT) > 0)
                                        {
                                            Rotation += AnimBone.FrameAngles[(FramesLess && frameID != 0) ? frameID - 1 : frameID].Multiply(StudioBone.rotscale);
                                        }

                                        if ((AnimBone.Flags & STUDIO_ANIM_ANIMPOS) > 0)
                                        {
                                            Position += AnimBone.FramePositions[(FramesLess && frameID != 0) ? frameID - 1 : frameID].Multiply(StudioBone.posscale);
                                        }

                                        if ((AnimBone.Flags & STUDIO_ANIM_DELTA) > 0)
                                        {
                                            Position = Vector3.zero;
                                            Rotation = Vector3.zero;
                                        }
                                    }

                                    //Invert right-handed position to left-handed
                                    if (StudioBone.parent == -1)
                                    {
                                        Position = MathLibrary.SwapY(Position);
                                    }
                                    else
                                    {
                                        Position.x = -Position.x;
                                    }

                                    //Corrects global scale and convert radians to degrees
                                    Position *= uLoader.UnitScale;
                                    Rotation *= Mathf.Rad2Deg;
                                    Quaternion quat;

                                    //Fix up bone rotations from right-handed to left-handed
                                    if (StudioBone.parent == -1)
                                    {
                                        quat = Quaternion.Euler(-90, 180, -90) * MathLibrary.AngleQuaternion(Rotation);
                                    }
                                    else
                                    {
                                        quat = MathLibrary.AngleQuaternion(Rotation);
                                    }

                                    Animations[AnimID].PosX[frameID][boneID] = new Keyframe(time, Position.x);
                                    Animations[AnimID].PosY[frameID][boneID] = new Keyframe(time, Position.y);
                                    Animations[AnimID].PosZ[frameID][boneID] = new Keyframe(time, Position.z);

                                    Animations[AnimID].RotX[frameID][boneID] = new Keyframe(time, quat.x);
                                    Animations[AnimID].RotY[frameID][boneID] = new Keyframe(time, quat.y);
                                    Animations[AnimID].RotZ[frameID][boneID] = new Keyframe(time, quat.z);
                                    Animations[AnimID].RotW[frameID][boneID] = new Keyframe(time, quat.w);
                                }
                            }
                        }
                        //Animations

                        //Sequences
                        MDL_SeqDescriptions = new mstudioseqdesc_t[MDL_Header.localseq_count];
                        Sequences           = new SeqInfo[MDL_Header.localseq_count];

                        for (Int32 seqID = 0; seqID < MDL_Header.localseq_count; seqID++)
                        {
                            Int32 sequenceOffset = MDL_Header.localseq_offset + (212 * seqID);
                            FileStream.ReadTypeFixed(ref MDL_SeqDescriptions[seqID], 212, sequenceOffset);
                            mstudioseqdesc_t Sequence = MDL_SeqDescriptions[seqID];
                            Sequences[seqID] = new SeqInfo {
                                name = FileStream.ReadNullTerminatedString(sequenceOffset + Sequence.szlabelindex), seq = Sequence
                            };

                            FileStream.BaseStream.Position = sequenceOffset + Sequence.animindexindex;

                            var animID = FileStream.ReadShortArray(Sequence.groupsize[0] * Sequence.groupsize[1]);
                            //Debug.LogWarning(animIndices[0]);
                            // Just use the first animation for now
                            Sequences[seqID].ani = Animations[animID[0]];
                        }
                        //Sequences
                    }
                    catch (Exception ex)
                    {
                        Debug.LogError(String.Format("\"{0}\" Parse animation failed: {1}", MDL_Header.Name, ex));
                    }
                }
                #endregion

                #region Materials
                //Materials
                MDL_TexturesInfo = new mstudiotexture_t[MDL_Header.texture_count];
                MDL_Textures     = new String[MDL_Header.texture_count];
                for (Int32 TexID = 0; TexID < MDL_Header.texture_count; TexID++)
                {
                    Int32 TextureOffset = MDL_Header.texture_offset + (64 * TexID);
                    FileStream.ReadTypeFixed(ref MDL_TexturesInfo[TexID], 64, TextureOffset);
                    MDL_Textures[TexID] = FileStream.ReadNullTerminatedString(TextureOffset + MDL_TexturesInfo[TexID].sznameindex);
                }

                Int32[] TDirOffsets = new Int32[MDL_Header.texturedir_count];
                MDL_TDirectories = new String[MDL_Header.texturedir_count];
                for (Int32 DirID = 0; DirID < MDL_Header.texturedir_count; DirID++)
                {
                    FileStream.ReadTypeFixed(ref TDirOffsets[DirID], 4, MDL_Header.texturedir_offset + (4 * DirID));
                    MDL_TDirectories[DirID] = FileStream.ReadNullTerminatedString(TDirOffsets[DirID]);
                }
                //Materials
                #endregion

                #region BodyParts
                //Bodyparts
                MDL_Bodyparts = new StudioBodyPart[MDL_Header.bodypart_count];
                for (Int32 BodypartID = 0; BodypartID < MDL_Header.bodypart_count; BodypartID++)
                {
                    mstudiobodyparts_t BodyPart = new mstudiobodyparts_t();
                    Int32 BodyPartOffset        = MDL_Header.bodypart_offset + (16 * BodypartID);
                    FileStream.ReadTypeFixed(ref BodyPart, 16, BodyPartOffset);

                    if (BodyPart.sznameindex != 0)
                    {
                        MDL_Bodyparts[BodypartID].Name = FileStream.ReadNullTerminatedString(BodyPartOffset + BodyPart.sznameindex);
                    }
                    else
                    {
                        MDL_Bodyparts[BodypartID].Name = String.Empty;
                    }

                    MDL_Bodyparts[BodypartID].Models = new StudioModel[BodyPart.nummodels];

                    for (Int32 ModelID = 0; ModelID < BodyPart.nummodels; ModelID++)
                    {
                        mstudiomodel_t Model       = new mstudiomodel_t();
                        Int64          ModelOffset = BodyPartOffset + (148 * ModelID) + BodyPart.modelindex;
                        FileStream.ReadTypeFixed(ref Model, 148, ModelOffset);

                        MDL_Bodyparts[BodypartID].Models[ModelID].isBlank = (Model.numvertices <= 0 || Model.nummeshes <= 0);
                        MDL_Bodyparts[BodypartID].Models[ModelID].Model   = Model;

                        MDL_Bodyparts[BodypartID].Models[ModelID].Meshes = new mstudiomesh_t[Model.nummeshes];
                        for (Int32 MeshID = 0; MeshID < Model.nummeshes; MeshID++)
                        {
                            mstudiomesh_t Mesh       = new mstudiomesh_t();
                            Int64         MeshOffset = ModelOffset + (116 * MeshID) + Model.meshindex;
                            FileStream.ReadTypeFixed(ref Mesh, 116, MeshOffset);

                            MDL_Bodyparts[BodypartID].Models[ModelID].Meshes[MeshID] = Mesh;
                        }

                        MDL_Bodyparts[BodypartID].Models[ModelID].IndicesPerLod = new Dictionary <Int32, List <Int32> > [8];

                        for (Int32 i = 0; i < 8; i++)
                        {
                            MDL_Bodyparts[BodypartID].Models[ModelID].IndicesPerLod[i] = new Dictionary <Int32, List <Int32> >();
                        }

                        MDL_Bodyparts[BodypartID].Models[ModelID].VerticesPerLod = new mstudiovertex_t[8][];
                    }
                }
                //BodyParts
                #endregion
            }
        }
Exemplo n.º 3
0
        public Transform BuildModel(Boolean GenerateUV2 = false)
        {
            GameObject ModelObject = new GameObject(MDL_Header.Name);

            #region Bones
            Transform[] Bones = new Transform[MDL_Header.bone_count];
            Dictionary <Int32, String> bonePathDict = new Dictionary <Int32, String>();
            for (Int32 boneID = 0; boneID < MDL_Header.bone_count; boneID++)
            {
                GameObject BoneObject = new GameObject(MDL_BoneNames[boneID]);

                Bones[boneID] = BoneObject.transform;//MDL_Bones.Add(BoneObject.transform);

                Vector3 pos = MDL_StudioBones[boneID].pos * uLoader.UnitScale;
                Vector3 rot = MDL_StudioBones[boneID].rot * Mathf.Rad2Deg;

                //Invert x for convert right-handed to left-handed
                pos.x = -pos.x;

                if (MDL_StudioBones[boneID].parent >= 0)
                {
                    Bones[boneID].parent = Bones[MDL_StudioBones[boneID].parent];
                }
                else
                {
                    //Swap Z & Y and invert Y (ex: X Z -Y)
                    //only for parents, cuz parents used different order vectors
                    float temp = pos.y;
                    pos.y = pos.z;
                    pos.z = -temp;

                    Bones[boneID].parent = ModelObject.transform;
                }

                bonePathDict.Add(boneID, Bones[boneID].GetTransformPath(ModelObject.transform));

                Bones[boneID].localPosition = pos;
                //Bones[i].localRotation = MDL_StudioBones[i].quat;

                if (MDL_StudioBones[boneID].parent == -1)
                {
                    //Fix up parents
                    Bones[boneID].localRotation = Quaternion.Euler(-90, 90, -90) * MathLibrary.AngleQuaternion(rot);
                }
                else
                {
                    Bones[boneID].localRotation = MathLibrary.AngleQuaternion(rot);
                }
            }

            if (uLoader.DrawArmature)
            {
                MDLArmatureInfo DebugArmature = ModelObject.AddComponent <MDLArmatureInfo>();
                DebugArmature.boneNodes = Bones;
            }
            #endregion

            #region Hitboxes
            if (MDL_Hitboxsets != null)
            {
                for (Int32 HitboxsetID = 0; HitboxsetID < MDL_Header.hitbox_count; HitboxsetID++)
                {
                    for (Int32 HitboxID = 0; HitboxID < MDL_Hitboxsets[HitboxsetID].numhitboxes; HitboxID++)
                    {
                        mstudiobbox_t Hitbox = Hitboxes[HitboxsetID][HitboxID].BBox;
                        BoxCollider   BBox   = new GameObject(String.Format("Hitbox_{0}", Bones[Hitbox.bone].name)).AddComponent <BoxCollider>();

                        BBox.size   = MathLibrary.NegateX(Hitbox.bbmax - Hitbox.bbmin) * uLoader.UnitScale;
                        BBox.center = (MathLibrary.NegateX(Hitbox.bbmax + Hitbox.bbmin) / 2) * uLoader.UnitScale;

                        BBox.transform.parent        = Bones[Hitbox.bone];
                        BBox.transform.localPosition = Vector3.zero;
                        BBox.transform.localRotation = Quaternion.identity;

                        //bbox.transform.tag = HitTagType(MDL_BBoxes[i].group);
                    }
                }
            }
            #endregion

            #region BodyParts
            if (BuildMesh)
            {
                for (Int32 BodypartID = 0; BodypartID < MDL_Header.bodypart_count; BodypartID++)
                {
                    StudioBodyPart BodyPart = MDL_Bodyparts[BodypartID];

                    for (Int32 ModelID = 0; ModelID < BodyPart.Models.Length; ModelID++)
                    {
                        StudioModel Model = BodyPart.Models[ModelID];

                        //Skip if model is blank
                        if (Model.isBlank)
                        {
                            continue;
                        }

                        #region TODO: Remove this code after find way to strip unused vertexes for lod's (VTXStripGroup / VTXStrip)
                        mstudiovertex_t[] Vertexes = Model.VerticesPerLod[0];

                        BoneWeight[] BoneWeight = new BoneWeight[Vertexes.Length];
                        Vector3[]    Vertices   = new Vector3[Vertexes.Length];
                        Vector3[]    Normals    = new Vector3[Vertexes.Length];
                        Vector2[]    UvBuffer   = new Vector2[Vertexes.Length];

                        for (Int32 i = 0; i < Vertexes.Length; i++)
                        {
                            Vertices[i] = MathLibrary.SwapZY(Vertexes[i].m_vecPosition * uLoader.UnitScale);
                            Normals[i]  = MathLibrary.SwapZY(Vertexes[i].m_vecNormal);

                            Vector2 UV = Vertexes[i].m_vecTexCoord;
                            if (uLoader.SaveAssetsToUnity && uLoader.ExportTextureAsPNG)
                            {
                                UV.y = -UV.y;
                            }

                            UvBuffer[i]   = UV;
                            BoneWeight[i] = GetBoneWeight(Vertexes[i].m_BoneWeights);
                        }
                        #endregion

                        #region LOD Support
                        Boolean DetailModeEnabled =
                            uLoader.DetailMode == DetailMode.Lowest ||
                            uLoader.DetailMode == DetailMode.Low ||
                            uLoader.DetailMode == DetailMode.Medium ||
                            uLoader.DetailMode == DetailMode.High;

                        Boolean   LODExist       = uLoader.EnableLODParsing && !DetailModeEnabled && Model.NumLODs > 1;
                        Transform FirstLODObject = null;
                        LODGroup  LODGroup       = null;
                        LOD[]     LODs           = null;
                        Single    MaxSwitchPoint = 100;
                        Int32     StartLODIndex  = 0;

                        if (LODExist)
                        {
                            LODs = new LOD[Model.NumLODs];

                            for (Int32 LODID = 1; LODID < 3; LODID++)
                            {
                                Int32            LastID = Model.NumLODs - LODID;
                                ModelLODHeader_t LOD    = Model.LODData[LastID];

                                //ignore $shadowlod
                                if (LOD.switchPoint != -1)
                                {
                                    if (LOD.switchPoint > 0)
                                    {
                                        MaxSwitchPoint = LOD.switchPoint;
                                    }

                                    //Set switchPoint from MaxSwitchPoint (if switchPoint is zero or negative)
                                    if (LODID == 2 || LOD.switchPoint == 0)
                                    {
                                        MaxSwitchPoint += MaxSwitchPoint * uLoader.NegativeAddLODPrecent;
                                        Model.LODData[LOD.switchPoint == 0 ? LastID : LastID + 1].switchPoint = MaxSwitchPoint;
                                    }

                                    // + Threshold used to avoid errors with LODGroup
                                    MaxSwitchPoint += uLoader.ThresholdMaxSwitch;
                                    break;
                                }
                            }
                        }
                        else
                        {
                            if (!uLoader.EnableLODParsing)
                            {
                                Model.NumLODs = 1;
                            }
                        }

                        if (uLoader.EnableLODParsing && DetailModeEnabled)
                        {
                            StartLODIndex =
                                uLoader.DetailMode == DetailMode.Lowest ? (Model.NumLODs - 1) :
                                uLoader.DetailMode == DetailMode.Low ? (Int32)(Model.NumLODs / 1.5f) :
                                uLoader.DetailMode == DetailMode.Medium ? (Model.NumLODs / 2) : (Int32)(Model.NumLODs / 2.5f);
                        }
                        #endregion

                        #region Build Meshes
                        for (Int32 LODID = StartLODIndex; LODID < Model.NumLODs; LODID++)
                        {
                            #region TODO: Uncomment after find way to strip unused vertexes for lod's (VTXStripGroup / VTXStrip)

                            /*mstudiovertex_t[] Vertexes = Model.VerticesPerLod[LODID];
                             *
                             * BoneWeight[] BoneWeight = new BoneWeight[Vertexes.Length];
                             * Vector3[] Vertices = new Vector3[Vertexes.Length];
                             * Vector3[] Normals = new Vector3[Vertexes.Length];
                             * Vector2[] UvBuffer = new Vector2[Vertexes.Length];
                             *
                             * for (Int32 i = 0; i < Vertexes.Length; i++)
                             * {
                             *  Vertices[i] = MathLibrary.SwapZY(Vertexes[i].m_vecPosition * uLoader.UnitScale);
                             *  Normals[i] = MathLibrary.SwapZY(Vertexes[i].m_vecNormal);
                             *
                             *  Vector2 UV = Vertexes[i].m_vecTexCoord;
                             *  if (uLoader.SaveAssetsToUnity && uLoader.ExportTextureAsPNG)
                             *      UV.y = -UV.y;
                             *
                             *  UvBuffer[i] = UV;
                             *  BoneWeight[i] = GetBoneWeight(Vertexes[i].m_BoneWeights);
                             * }*/
                            #endregion

                            #region LOD
                            ModelLODHeader_t ModelLOD = Model.LODData[LODID];

                            if (LODExist)
                            {
                                if (ModelLOD.switchPoint == 0)
                                {
                                    ModelLOD.switchPoint = MaxSwitchPoint;
                                }
                                else
                                {
                                    ModelLOD.switchPoint = MaxSwitchPoint - ModelLOD.switchPoint;
                                }

                                ModelLOD.switchPoint -= ModelLOD.switchPoint * uLoader.SubstractLODPrecent;
                            }
                            #endregion

                            #region Mesh
                            //Create empty object for mesh
                            GameObject MeshObject = new GameObject(Model.Model.Name);
                            MeshObject.name            += "_vLOD" + LODID;
                            MeshObject.transform.parent = ModelObject.transform;

                            //Create empty mesh and fill parsed data
                            Mesh Mesh = new Mesh();
                            Mesh.name = MeshObject.name;

                            Mesh.subMeshCount = Model.Model.nummeshes;
                            Mesh.vertices     = Vertices;
                            //Make sure if mesh exist any vertexes
                            if (Mesh.vertexCount <= 0)
                            {
                                Debug.LogWarning(String.Format("Mesh: \"{0}\" has no vertexes, skip building... (MDL Version: {1})", Mesh.name, MDL_Header.version));
                                continue;
                            }

                            Mesh.normals = Normals;
                            Mesh.uv      = UvBuffer;
                            #endregion

                            #region Renderers
                            Renderer Renderer;
                            //SkinnedMeshRenderer (Models with "animated" bones & skin data)
                            if (!MDL_Header.flags.HasFlag(StudioHDRFlags.STUDIOHDR_FLAGS_STATIC_PROP))
                            {
                                //Bind poses & bone weights
                                SkinnedMeshRenderer SkinnedRenderer = MeshObject.AddComponent <SkinnedMeshRenderer>();
                                Renderer = SkinnedRenderer;
                                Matrix4x4[] BindPoses = new Matrix4x4[Bones.Length];

                                for (Int32 i = 0; i < BindPoses.Length; i++)
                                {
                                    BindPoses[i] = Bones[i].worldToLocalMatrix * MeshObject.transform.localToWorldMatrix;
                                }

                                Mesh.boneWeights = BoneWeight;
                                Mesh.bindposes   = BindPoses;

                                SkinnedRenderer.sharedMesh = Mesh;

                                SkinnedRenderer.bones = Bones;
                                SkinnedRenderer.updateWhenOffscreen = true;
                            }
                            //MeshRenderer (models with "STUDIOHDR_FLAGS_STATIC_PROP" flag or with generic "static_prop" bone)
                            else
                            {
                                MeshFilter MeshFilter = MeshObject.AddComponent <MeshFilter>();
                                Renderer = MeshObject.AddComponent <MeshRenderer>();
                                MeshFilter.sharedMesh = Mesh;
                            }

                            Renderer.shadowCastingMode = UnityEngine.Rendering.ShadowCastingMode.TwoSided;
                            #endregion

                            #region Debug Stuff
                            #if UNITY_EDITOR
                            DebugMaterial DebugMat = null;
                            if (uLoader.DebugMaterials)
                            {
                                DebugMat = MeshObject.AddComponent <DebugMaterial>();
                            }
                            #endif
                            #endregion

                            #region Triangles and Materials
                            Material[] Materials = new Material[Mesh.subMeshCount];

                            for (Int32 MeshID = 0; MeshID < Model.Model.nummeshes; MeshID++)
                            {
                                //Set triangles per lod & submeshes
                                Mesh.SetTriangles(Model.IndicesPerLod[LODID][MeshID], MeshID);

                                //Find & parse materials
                                String MaterialPath;
                                Int32  LastDirID = MDL_TDirectories.Length - 1;
                                for (Int32 DirID = 0; DirID < MDL_TDirectories.Length; DirID++)
                                {
                                    MaterialPath = MDL_TDirectories[DirID] + MDL_Textures[Model.Meshes[MeshID].material];

                                    //If material exist
                                    if (uResourceManager.ContainsFile(MaterialPath, uResourceManager.MaterialsSubFolder, uResourceManager.MaterialsExtension[0]))
                                    {
                                        VMTFile VMT = uResourceManager.LoadMaterial(MaterialPath);

                                        #region Debug Stuff
                                        #if UNITY_EDITOR
                                        if (uLoader.DebugMaterials)
                                        {
                                            DebugMat.Init(VMT);
                                        }
                                        #endif
                                        #endregion

                                        //Set material
                                        Materials[MeshID] = VMT.Material;
                                        break;
                                    }
                                    else if (DirID == LastDirID)
                                    {
                                        Materials[MeshID] = uResourceManager.LoadMaterial(String.Empty).Material;
                                    }
                                }
                            }

                            Renderer.sharedMaterials = Materials;
                            #endregion

                            #region UV2
                            #if UNITY_EDITOR
                            if (GenerateUV2)
                            {
                                UnityEditor.SerializedObject so = new UnityEditor.SerializedObject(Renderer);
                                so.FindProperty("m_ScaleInLightmap").floatValue = uLoader.ModelsLightmapSize;
                                so.ApplyModifiedProperties();

                                MeshObject.isStatic = GenerateUV2;
                                uResourceManager.UV2GenerateCache.Add(Mesh);
                            }
                            #endif
                            #endregion

                            #region Set LOD's
                            if (LODExist)
                            {
                                if (LODID == 0)
                                {
                                    LODGroup       = MeshObject.AddComponent <LODGroup>();
                                    FirstLODObject = MeshObject.transform;
                                }
                                else if (FirstLODObject != null)
                                {
                                    MeshObject.transform.parent = FirstLODObject;
                                }

                                LODs[LODID] = new LOD(ModelLOD.switchPoint / MaxSwitchPoint, new Renderer[] { Renderer });
                            }

                            if (uLoader.EnableLODParsing && DetailModeEnabled)
                            {
                                break;
                            }
                            #endregion
                        }//lod's per model

                        //Init all parsed lod's into LODGroup
                        if (LODGroup != null)
                        {
                            LODGroup.SetLODs(LODs);
                        }
                        #endregion
                    } //models in bodypart
                }     //Bodypart
            }
            #endregion

            #region Animations
            if (MDL_SeqDescriptions != null)
            {
                var AnimationComponent = ModelObject.AddComponent <Animation>();
                for (Int32 seqID = 0; seqID < MDL_SeqDescriptions.Length; seqID++)
                {
                    SeqInfo Sequence  = Sequences[seqID];
                    AniInfo Animation = Sequence.ani;

                    //Creating "AnimationCurve" for animation "paths" (aka frames where stored position (XYZ) & rotation (XYZW))
                    AnimationCurve[] posX = new AnimationCurve[MDL_Header.bone_count];    //X
                    AnimationCurve[] posY = new AnimationCurve[MDL_Header.bone_count];    //Y
                    AnimationCurve[] posZ = new AnimationCurve[MDL_Header.bone_count];    //Z

                    AnimationCurve[] rotX = new AnimationCurve[MDL_Header.bone_count];    //X
                    AnimationCurve[] rotY = new AnimationCurve[MDL_Header.bone_count];    //Y
                    AnimationCurve[] rotZ = new AnimationCurve[MDL_Header.bone_count];    //Z
                    AnimationCurve[] rotW = new AnimationCurve[MDL_Header.bone_count];    //W

                    //Fill "AnimationCurve" arrays
                    for (Int32 boneIndex = 0; boneIndex < MDL_Header.bone_count; boneIndex++)
                    {
                        posX[boneIndex] = new AnimationCurve();
                        posY[boneIndex] = new AnimationCurve();
                        posZ[boneIndex] = new AnimationCurve();

                        rotX[boneIndex] = new AnimationCurve();
                        rotY[boneIndex] = new AnimationCurve();
                        rotZ[boneIndex] = new AnimationCurve();
                        rotW[boneIndex] = new AnimationCurve();
                    }

                    Int32 numFrames = Animation.studioAnim.numframes;

                    //Used to avoid "Assertion failed" key count in Unity (if frames less than 2)
                    if (numFrames < 2)
                    {
                        numFrames += 1;
                    }

                    //Create animation clip
                    AnimationClip clip = new AnimationClip();
                    //Make it for legacy animation system (for now, but it possible to rework for Mecanim)
                    clip.legacy = true;
                    //Set animation clip name
                    clip.name = Animation.name;

                    //To avoid problems with "obfuscators" / "protectors" for models, make sure if model have name in sequence
                    if (String.IsNullOrEmpty(clip.name))
                    {
                        clip.name = "(empty)" + seqID;
                    }

                    for (Int32 frameIndex = 0; frameIndex < numFrames; frameIndex++)
                    {
                        //Get current frame from blend (meaning from "Animation") by index
                        //AnimationFrame frame = Animation.Frames[frameIndex];

                        //Set keys (position / rotation) from current frame
                        for (Int32 boneIndex = 0; boneIndex < Bones.Length; boneIndex++)
                        {
                            posX[boneIndex].AddKey(Animation.PosX[frameIndex][boneIndex]);
                            posY[boneIndex].AddKey(Animation.PosY[frameIndex][boneIndex]);
                            posZ[boneIndex].AddKey(Animation.PosZ[frameIndex][boneIndex]);

                            rotX[boneIndex].AddKey(Animation.RotX[frameIndex][boneIndex]);
                            rotY[boneIndex].AddKey(Animation.RotY[frameIndex][boneIndex]);
                            rotZ[boneIndex].AddKey(Animation.RotZ[frameIndex][boneIndex]);
                            rotW[boneIndex].AddKey(Animation.RotW[frameIndex][boneIndex]);

                            //Set default pose from the first animation
                            if (seqID == 0 && frameIndex == 0)
                            {
                                Bones[boneIndex].localPosition = new Vector3
                                                                 (
                                    Animation.PosX[0][boneIndex].value,
                                    Animation.PosY[0][boneIndex].value,
                                    Animation.PosZ[0][boneIndex].value
                                                                 );

                                Bones[boneIndex].localRotation = new Quaternion
                                                                 (
                                    Animation.RotX[0][boneIndex].value,
                                    Animation.RotY[0][boneIndex].value,
                                    Animation.RotZ[0][boneIndex].value,
                                    Animation.RotW[0][boneIndex].value
                                                                 );
                            }
                        }
                    }

                    //Apply animation paths (Position / Rotation) to clip
                    for (Int32 boneIndex = 0; boneIndex < MDL_Header.bone_count; boneIndex++)
                    {
                        clip.SetCurve(bonePathDict[boneIndex], typeof(Transform), "localPosition.x", posX[boneIndex]);
                        clip.SetCurve(bonePathDict[boneIndex], typeof(Transform), "localPosition.y", posY[boneIndex]);
                        clip.SetCurve(bonePathDict[boneIndex], typeof(Transform), "localPosition.z", posZ[boneIndex]);

                        clip.SetCurve(bonePathDict[boneIndex], typeof(Transform), "localRotation.x", rotX[boneIndex]);
                        clip.SetCurve(bonePathDict[boneIndex], typeof(Transform), "localRotation.y", rotY[boneIndex]);
                        clip.SetCurve(bonePathDict[boneIndex], typeof(Transform), "localRotation.z", rotZ[boneIndex]);
                        clip.SetCurve(bonePathDict[boneIndex], typeof(Transform), "localRotation.w", rotW[boneIndex]);
                    }

                    if (Animation.studioAnim.fps > 0.0f)
                    {
                        clip.frameRate = Animation.studioAnim.fps;
                    }

                    //This ensures a smooth interpolation (corrects the problem of "jitter" after 180~270 degrees rotation path)
                    //can be "comment" if have idea how to replace this
                    clip.EnsureQuaternionContinuity();
                    AnimationComponent.AddClip(clip, clip.name);
                }
            }
            #endregion

            //If model has compiled flag "$staticprop"
            //then rotate this model by 90 degrees (Y)
            //https://github.com/ValveSoftware/source-sdk-2013/blob/master/sp/src/public/studio.h#L1965
            //Big thanks for this tip:
            //ShadelessFox
            //REDxEYE
            if (MDL_Header.flags.HasFlag(StudioHDRFlags.STUDIOHDR_FLAGS_STATIC_PROP))
            {
                ModelObject.transform.eulerAngles = new Vector3(0, 90, 0);
            }

            return(ModelObject.transform);
        }
Exemplo n.º 4
0
 private void label4_MouseUp(object sender, MouseEventArgs e)
 {
     ((Label) sender).Font = new Font(((Label) sender).Font.FontFamily, 9);
     if (!_seq.IsLoaded)
     {
         label1.Text = "No Standard Midi File";
         return;
     }
     var i = (int) _info;
     if (sender == label4)
     {
         i--;
         if (i < 0)
             i = 2;
     }
     else
     {
         i++;
         if (i > 2)
             i = 0;
     }
     _info = (SeqInfo) i;
 }
Exemplo n.º 5
0
 private void label4_Click(object sender, EventArgs e)
 {
     var i = (int) _info;
     i--;
     if (i < 0)
         i = 2;
     _info = (SeqInfo) i;
     switch (_info)
     {
         case SeqInfo.Title:
             label1.Text = _seq.Title;
             break;
         case SeqInfo.Copyright:
             label1.Text = _seq.Copyright;
             break;
         case SeqInfo.Lyric:
             label1.Text = _seq.Lyrics;
             break;
     }
 }