Пример #1
0
 public void InitGameObjects()
 {
     for (uint i = 0; i < num_subblocks; i++)
     {
         if (subblocks[i] != null)
         {
             if (subblocks[i] is MeshElement)
             {
                 GameObject child = ((MeshElement)subblocks[i]).Gao;
                 child.transform.SetParent(gao.transform);
                 child.transform.localPosition = Vector3.zero;
             }
             else if (subblocks[i] is DeformSet)
             {
                 DeformSet ds = ((DeformSet)subblocks[i]);
                 for (int j = 0; j < ds.num_bones; j++)
                 {
                     Transform b = ds.bones[j];
                     b.transform.SetParent(gao.transform);
                 }
             }
             else if (subblocks[i] is SpriteElement)
             {
                 GameObject child = ((SpriteElement)subblocks[i]).Gao;
                 child.transform.SetParent(gao.transform);
                 child.transform.localPosition = Vector3.zero;
             }
         }
     }
 }
        void UpdateAnimation()
        {
            if (loaded && a3d != null && channelObjects != null & subObjects != null)
            {
                if (currentFrame >= a3d.num_onlyFrames)
                {
                    currentFrame %= a3d.num_onlyFrames;
                }
                // First pass: reset TRS for all sub objects
                for (int i = 0; i < channelParents.Length; i++)
                {
                    channelParents[i] = false;
                }
                AnimOnlyFrame of = a3d.onlyFrames[a3d.start_onlyFrames + currentFrame];
                // Create hierarchy for this frame
                for (int i = of.start_hierarchies_for_frame;
                     i < of.start_hierarchies_for_frame + of.num_hierarchies_for_frame; i++)
                {
                    AnimHierarchy h = a3d.hierarchies[i];

                    if (Controller.Settings.engineVersion <= Settings.EngineVersion.TT)
                    {
                        channelObjects[h.childChannelID].transform.SetParent(channelObjects[h.parentChannelID].transform);
                        channelParents[h.childChannelID] = true;
                    }
                    else
                    {
                        if (!channelIDDictionary.ContainsKey(h.childChannelID) || !channelIDDictionary.ContainsKey(h.parentChannelID))
                        {
                            continue;
                        }
                        List <int> ch_child_list  = GetChannelByID(h.childChannelID);
                        List <int> ch_parent_list = GetChannelByID(h.parentChannelID);
                        foreach (int ch_child in ch_child_list)
                        {
                            foreach (int ch_parent in ch_parent_list)
                            {
                                channelObjects[ch_child].transform.SetParent(channelObjects[ch_parent].transform);
                                channelParents[ch_child] = true;
                            }
                        }
                    }

                    //channelObjects[ch_child].transform.SetParent(channelObjects[ch_parent].transform);
                }
                // Final pass
                for (int i = 0; i < a3d.num_channels; i++)
                {
                    AnimChannel       ch        = a3d.channels[a3d.start_channels + i];
                    AnimFramesKFIndex kfi       = a3d.framesKFIndex[currentFrame + ch.framesKF];
                    AnimKeyframe      kf        = a3d.keyframes[kfi.kf];
                    AnimVector        pos       = a3d.vectors[kf.positionVector];
                    AnimQuaternion    qua       = a3d.quaternions[kf.quaternion];
                    AnimVector        scl       = a3d.vectors[kf.scaleVector];
                    AnimNumOfNTTO     numOfNTTO = a3d.numOfNTTO[ch.numOfNTTO + of.numOfNTTO];
                    AnimNTTO          ntto      = a3d.ntto[numOfNTTO.numOfNTTO];
                    //if (ntto.IsBoneNTTO) continue;
                    int            poNum          = numOfNTTO.numOfNTTO - a3d.start_NTTO;
                    PhysicalObject physicalObject = subObjects[i][poNum];
                    Vector3        vector         = pos.vector;
                    Quaternion     quaternion     = qua.quaternion;
                    Vector3        scale          = scl.vector;
                    int            framesSinceKF  = (int)currentFrame - (int)kf.frame;
                    AnimKeyframe   nextKF         = null;
                    int            framesDifference;
                    float          interpolation;
                    if (kf.IsEndKeyframe)
                    {
                        AnimFramesKFIndex next_kfi = a3d.framesKFIndex[0 + ch.framesKF];
                        nextKF           = a3d.keyframes[next_kfi.kf];
                        framesDifference = a3d.num_onlyFrames - 1 + (int)nextKF.frame - (int)kf.frame;
                        if (framesDifference == 0)
                        {
                            interpolation = 0;
                        }
                        else
                        {
                            //interpolation = (float)(nextKF.interpolationFactor * (framesSinceKF / (float)framesDifference) + 1.0 * nextKF.interpolationFactor);
                            interpolation = framesSinceKF / (float)framesDifference;
                        }
                    }
                    else
                    {
                        nextKF           = a3d.keyframes[kfi.kf + 1];
                        framesDifference = (int)nextKF.frame - (int)kf.frame;
                        //interpolation = (float)(nextKF.interpolationFactor * (framesSinceKF / (float)framesDifference) + 1.0 * nextKF.interpolationFactor);
                        interpolation = framesSinceKF / (float)framesDifference;
                    }
                    //print(interpolation);
                    //print(a3d.vectors.Length + " - " + nextKF.positionVector);
                    AnimVector     pos2 = a3d.vectors[nextKF.positionVector];
                    AnimQuaternion qua2 = a3d.quaternions[nextKF.quaternion];
                    AnimVector     scl2 = a3d.vectors[nextKF.scaleVector];
                    vector     = Vector3.Lerp(pos.vector, pos2.vector, interpolation);
                    quaternion = Quaternion.Lerp(qua.quaternion, qua2.quaternion, interpolation);
                    scale      = Vector3.Lerp(scl.vector, scl2.vector, interpolation);
                    float positionMultiplier = Mathf.Lerp(kf.positionMultiplier, nextKF.positionMultiplier, interpolation);

                    if (poNum != currentActivePO[i])
                    {
                        if (currentActivePO[i] == -2 && fullMorphPOs != null && fullMorphPOs[i] != null)
                        {
                            foreach (PhysicalObject morphPO in fullMorphPOs[i].Values)
                            {
                                if (morphPO.Gao.activeSelf)
                                {
                                    morphPO.Gao.SetActive(false);
                                }
                            }
                        }
                        if (currentActivePO[i] >= 0 && subObjects[i][currentActivePO[i]] != null)
                        {
                            subObjects[i][currentActivePO[i]].Gao.SetActive(false);
                        }
                        currentActivePO[i] = poNum;
                        if (physicalObject != null)
                        {
                            physicalObject.Gao.SetActive(true);
                        }
                    }
                    if (!channelParents[i])
                    {
                        channelObjects[i].transform.SetParent(perso.gameObject.transform);
                    }
                    channelObjects[i].transform.localPosition = vector * positionMultiplier;
                    channelObjects[i].transform.localRotation = quaternion;
                    channelObjects[i].transform.localScale    = scale;

                    if (physicalObject != null && a3d.num_morphData > 0 && morphDataArray != null && i < morphDataArray.GetLength(0) && currentFrame < morphDataArray.GetLength(1))
                    {
                        AnimMorphData morphData = morphDataArray[i, currentFrame];

                        if (morphData != null && morphData.morphProgress != 0 && morphData.morphProgress != 100)
                        {
                            PhysicalObject morphToPO  = perso.Perso3dData.ObjectList.entries[morphData.objectIndexTo].po;
                            Vector3[]      morphVerts = null;

                            for (int j = 0; j < physicalObject.visualSet.Length; j++)
                            {
                                IGeometricObject obj = physicalObject.visualSet[j].obj;
                                if (obj == null || obj as MeshObject == null)
                                {
                                    continue;
                                }
                                MeshObject fromM = obj as MeshObject;
                                MeshObject toM   = morphToPO.visualSet[j].obj as MeshObject;
                                if (toM == null)
                                {
                                    continue;
                                }
                                if (fromM.vertices.Length != toM.vertices.Length)
                                {
                                    // For those special cases like the mistake in the Clark cinematic
                                    continue;
                                }
                                int numVertices = fromM.vertices.Length;
                                morphVerts = new Vector3[numVertices];
                                for (int vi = 0; vi < numVertices; vi++)
                                {
                                    morphVerts[vi] = Vector3.Lerp(fromM.vertices[vi], toM.vertices[vi], morphData.morphProgressFloat);
                                }
                                for (int k = 0; k < fromM.num_subblocks; k++)
                                {
                                    if (fromM.subblocks[k] == null || fromM.subblock_types[k] != 1)
                                    {
                                        continue;
                                    }
                                    MeshElement el = (MeshElement)fromM.subblocks[k];
                                    if (el != null)
                                    {
                                        el.UpdateMeshVertices(morphVerts);
                                    }
                                }
                            }
                        }
                        else if (morphData != null && morphData.morphProgress == 100)
                        {
                            physicalObject.Gao.SetActive(false);
                            PhysicalObject c = fullMorphPOs[i][morphData.objectIndexTo];
                            c.Gao.transform.localScale    = c.scaleMultiplier.HasValue ? c.scaleMultiplier.Value : Vector3.one;
                            c.Gao.transform.localPosition = Vector3.zero;
                            c.Gao.transform.localRotation = Quaternion.identity;
                            c.Gao.SetActive(true);
                            currentActivePO[i] = -2;
                        }
                        else
                        {
                            for (int j = 0; j < physicalObject.visualSet.Length; j++)
                            {
                                IGeometricObject obj = physicalObject.visualSet[j].obj;
                                if (obj == null || obj as MeshObject == null)
                                {
                                    continue;
                                }
                                MeshObject fromM = obj as MeshObject;
                                for (int k = 0; k < fromM.num_subblocks; k++)
                                {
                                    if (fromM.subblocks[k] == null || fromM.subblock_types[k] != 1)
                                    {
                                        continue;
                                    }
                                    MeshElement el = (MeshElement)fromM.subblocks[k];
                                    if (el != null)
                                    {
                                        el.ResetVertices();
                                    }
                                }
                            }
                        }
                    }
                }
                if (hasBones)
                {
                    for (int i = 0; i < a3d.num_channels; i++)
                    {
                        AnimChannel    ch = a3d.channels[a3d.start_channels + i];
                        Transform      baseChannelTransform = channelObjects[i].transform;
                        Vector3        invertedScale        = new Vector3(1f / baseChannelTransform.localScale.x, 1f / baseChannelTransform.localScale.y, 1f / baseChannelTransform.localScale.z);
                        AnimNumOfNTTO  numOfNTTO            = a3d.numOfNTTO[ch.numOfNTTO + of.numOfNTTO];
                        AnimNTTO       ntto           = a3d.ntto[numOfNTTO.numOfNTTO];
                        PhysicalObject physicalObject = subObjects[i][numOfNTTO.numOfNTTO - a3d.start_NTTO];
                        if (physicalObject == null)
                        {
                            continue;
                        }
                        DeformSet bones = physicalObject.Bones;
                        // Deformations
                        if (bones != null)
                        {
                            for (int j = 0; j < a3d.num_deformations; j++)
                            {
                                AnimDeformation d = a3d.deformations[a3d.start_deformations + j];
                                if (d.channel < ch.id)
                                {
                                    continue;
                                }
                                if (d.channel > ch.id)
                                {
                                    break;
                                }
                                if (!channelIDDictionary.ContainsKey(d.linkChannel))
                                {
                                    continue;
                                }
                                List <int> ind_linkChannel_list = GetChannelByID(d.linkChannel);
                                foreach (int ind_linkChannel in ind_linkChannel_list)
                                {
                                    AnimChannel    ch_link             = a3d.channels[a3d.start_channels + ind_linkChannel];
                                    AnimNumOfNTTO  numOfNTTO_link      = a3d.numOfNTTO[ch_link.numOfNTTO + of.numOfNTTO];
                                    AnimNTTO       ntto_link           = a3d.ntto[numOfNTTO_link.numOfNTTO];
                                    PhysicalObject physicalObject_link = subObjects[ind_linkChannel][numOfNTTO_link.numOfNTTO - a3d.start_NTTO];
                                    if (physicalObject_link == null)
                                    {
                                        continue;
                                    }
                                    if (bones == null || bones.bones.Length <= d.bone + 1)
                                    {
                                        continue;
                                    }
                                    DeformBone bone = bones.r3bones[d.bone + 1];
                                    if (bone != null)
                                    {
                                        Transform channelTransform = channelObjects[ind_linkChannel].transform;
                                        bone.UnityBone.transform.SetParent(channelTransform);
                                        bone.UnityBone.localPosition = Vector3.zero;
                                        bone.UnityBone.localRotation = Quaternion.identity;
                                        bone.UnityBone.localScale    = Vector3.one;

                                        /*bone.UnityBone.position = channelTransform.position;
                                         * bone.UnityBone.rotation = channelTransform.rotation;
                                         * //bone.UnityBone.localScale = Vector3.one;
                                         * bone.UnityBone.localScale = channelTransform.localScale;*/
                                    }
                                }
                            }
                        }
                    }
                }
                //this.currentFrame = (currentFrame + 1) % a3d.num_onlyFrames;
            }
        }
Пример #3
0
        public static GeometricObject Read(Reader reader, Pointer offset)
        {
            MapLoader l = MapLoader.Loader;
            //l.print("Geometric Object: " + offset);
            GeometricObject m = new GeometricObject(offset);

            if (Settings.s.game == Settings.Game.LargoWinch)
            {
                uint flags = reader.ReadUInt32();
                m.num_vertices      = reader.ReadUInt16();
                m.num_elements      = reader.ReadUInt16();
                m.off_element_types = Pointer.Read(reader);
                m.off_elements      = Pointer.Read(reader);
                m.off_vertices      = Pointer.Read(reader);
                m.off_normals       = Pointer.Read(reader);
                reader.ReadSingle();
                reader.ReadSingle();
                reader.ReadSingle();
                reader.ReadSingle();
                m.lookAtMode = reader.ReadUInt32();
            }
            else if (Settings.s.game == Settings.Game.R2Revolution)
            {
                m.off_element_types = Pointer.Read(reader);
                m.off_elements      = Pointer.Read(reader);
                uint flags = reader.ReadUInt32();
                reader.ReadSingle();
                reader.ReadSingle();
                reader.ReadSingle();
                reader.ReadSingle();
                m.off_mapping  = Pointer.Read(reader);
                m.num_vertices = reader.ReadUInt16();
                m.num_elements = reader.ReadUInt16();
                m.off_vertices = Pointer.Read(reader);
                m.off_normals  = Pointer.Read(reader);
                m.lookAtMode   = flags & 3;
            }
            else
            {
                if (Settings.s.engineVersion <= Settings.EngineVersion.Montreal)
                {
                    m.num_vertices = (ushort)reader.ReadUInt32();
                }
                m.off_vertices = Pointer.Read(reader);
                m.off_normals  = Pointer.Read(reader);
                if (Settings.s.engineVersion < Settings.EngineVersion.R3)
                {
                    m.off_materials = Pointer.Read(reader);
                }
                else
                {
                    m.off_blendWeights = Pointer.Read(reader);
                }
                if (Settings.s.mode != Settings.Mode.RaymanArenaGC &&
                    Settings.s.mode != Settings.Mode.RaymanArenaGCDemo &&
                    Settings.s.game != Settings.Game.RM &&
                    Settings.s.mode != Settings.Mode.DonaldDuckPKGC &&
                    !(Settings.s.platform == Settings.Platform.PS2 && Settings.s.engineVersion == Settings.EngineVersion.R3))
                {
                    reader.ReadInt32();
                }
                if (Settings.s.engineVersion <= Settings.EngineVersion.Montreal)
                {
                    m.num_elements = (ushort)reader.ReadUInt32();
                }
                m.off_element_types = Pointer.Read(reader);
                m.off_elements      = Pointer.Read(reader);
                reader.ReadInt32();
                reader.ReadInt32();
                if (Settings.s.engineVersion == Settings.EngineVersion.R2)
                {
                    reader.ReadInt32();
                    reader.ReadInt32();
                }
                if (Settings.s.game == Settings.Game.Dinosaur)
                {
                    reader.ReadInt32();
                    reader.ReadInt32();
                    reader.ReadInt32();
                }
                if (Settings.s.engineVersion > Settings.EngineVersion.Montreal)
                {
                    m.lookAtMode = reader.ReadUInt32();
                    //if (m.lookAtMode != 0) l.print(m.lookAtMode);
                    m.num_vertices = reader.ReadUInt16();
                    m.num_elements = reader.ReadUInt16();
                    reader.ReadInt32();
                    reader.ReadSingle();                     // bounding volume radius
                    reader.ReadSingle();                     // x
                    reader.ReadSingle();                     // z
                    reader.ReadSingle();                     // y
                    reader.ReadInt32();
                    if (Settings.s.engineVersion == Settings.EngineVersion.R3)
                    {
                        reader.ReadInt32();
                        if (!(Settings.s.platform == Settings.Platform.PS2 && (Settings.s.game == Settings.Game.RM || Settings.s.game == Settings.Game.RA)))
                        {
                            reader.ReadInt16();
                            if (Settings.s.platform == Settings.Platform.PS2)
                            {
                                reader.ReadInt16();
                                reader.ReadUInt32();
                            }
                        }
                    }
                }
                else
                {
                    reader.ReadInt32();
                    reader.ReadInt32();
                    reader.ReadSingle();
                    reader.ReadSingle();
                    reader.ReadSingle();
                    reader.ReadSingle();
                }
            }
            m.name = "Mesh @ " + offset;
            if (Settings.s.hasNames)
            {
                m.name = reader.ReadString(0x32);
            }
            if (Settings.s.platform == Settings.Platform.PS2 && Settings.s.engineVersion >= Settings.EngineVersion.R3)
            {
                reader.Align(0x4);
                reader.ReadUInt32();
                reader.ReadUInt32();
                m.optimizedObject = new Pointer <PS2OptimizedSDCStructure>(reader, resolve: false);
                reader.ReadUInt32();
                reader.ReadUInt32();
                if (Settings.s.game == Settings.Game.R3)
                {
                    m.ps2IsSinus = reader.ReadUInt32();
                }
            }
            // Vertices
            Pointer.DoAt(ref reader, m.off_vertices, () => {
                m.vertices = new Vector3[m.num_vertices];
                for (int i = 0; i < m.num_vertices; i++)
                {
                    float x       = reader.ReadSingle();
                    float z       = reader.ReadSingle();
                    float y       = reader.ReadSingle();
                    m.vertices[i] = new Vector3(x, y, z);
                }
            });
            // Normals
            Pointer.DoAt(ref reader, m.off_normals, () => {
                m.normals = new Vector3[m.num_vertices];
                for (int i = 0; i < m.num_vertices; i++)
                {
                    float x      = reader.ReadSingle();
                    float z      = reader.ReadSingle();
                    float y      = reader.ReadSingle();
                    m.normals[i] = new Vector3(x, y, z);
                }
            });
            Pointer.DoAt(ref reader, m.off_blendWeights, () => {
                m.blendWeights = new float[4][];

                /*reader.ReadUInt32(); // 0
                 * R3Pointer off_blendWeightsStart = R3Pointer.Read(reader);
                 * R3Pointer.Goto(ref reader, off_blendWeightsStart);*/
                for (int i = 0; i < 4; i++)
                {
                    Pointer off_blendWeights = Pointer.Read(reader);
                    Pointer.DoAt(ref reader, off_blendWeights, () => {
                        m.blendWeights[i] = new float[m.num_vertices];
                        for (int j = 0; j < m.num_vertices; j++)
                        {
                            m.blendWeights[i][j] = reader.ReadSingle();
                        }
                    });
                }
                reader.ReadUInt32();
                reader.ReadUInt32();
                reader.ReadUInt32();
                reader.ReadUInt32();
            });
            Pointer.DoAt(ref reader, m.off_mapping, () => {
                // Revolution only
                reader.ReadUInt32();
                Pointer.Read(reader);
                Pointer off_mappingBlocks = Pointer.Read(reader);
                Pointer.Read(reader);
                Pointer.Read(reader);
                ushort num_mappingBlocks = reader.ReadUInt16();
                reader.ReadUInt16();
                Pointer.DoAt(ref reader, off_mappingBlocks, () => {
                    m.mapping = new int[num_mappingBlocks][];
                    for (int i = 0; i < num_mappingBlocks; i++)
                    {
                        Pointer off_mapping = Pointer.Read(reader);
                        Pointer.DoAt(ref reader, off_mapping, () => {
                            m.mapping[i] = new int[m.num_vertices];
                            for (int j = 0; j < m.num_vertices; j++)
                            {
                                m.mapping[i][j] = reader.ReadUInt16();
                                if (m.mapping[i][j] >= m.num_vertices)
                                {
                                    l.print(m.offset);
                                }
                            }
                        });
                    }
                });
            });
            // Read element types & initialize arrays
            Pointer.Goto(ref reader, m.off_element_types);
            m.element_types = new ushort[m.num_elements];
            m.elements      = new IGeometricObjectElement[m.num_elements];
            for (uint i = 0; i < m.num_elements; i++)
            {
                m.element_types[i] = reader.ReadUInt16();
            }
            // Process elements
            for (uint i = 0; i < m.num_elements; i++)
            {
                Pointer.Goto(ref reader, m.off_elements + (i * 4));
                Pointer block_offset = Pointer.Read(reader);
                Pointer.Goto(ref reader, block_offset);
                switch (m.element_types[i])
                {
                case 1:     // Material
                    m.elements[i] = GeometricObjectElementTriangles.Read(reader, block_offset, m);
                    break;

                case 3:     // Sprite
                    m.elements[i] = GeometricObjectElementSprites.Read(reader, block_offset, m);
                    break;

                case 13:
                case 15:
                    m.bones       = DeformSet.Read(reader, block_offset, m);
                    m.elements[i] = m.bones;
                    break;

                default:
                    m.elements[i] = null;

                    /*1 = indexedtriangles
                     * 2 = facemap
                     * 3 = sprite
                     * 4 = TMesh
                     * 5 = points
                     * 6 = lines
                     * 7 = spheres
                     * 8 = alignedboxes
                     * 9 = cones
                     * 13 = deformationsetinfo*/
                    l.print("Unknown geometric element type " + m.element_types[i] + " at offset " + block_offset);
                    break;
                }
            }
            ReadMeshFromATO(reader, m);
            if (Settings.s.platform == Settings.Platform.PS2 && Settings.s.engineVersion == Settings.EngineVersion.R3)
            {
                m.optimizedObject?.Resolve(reader, onPreRead: opt => opt.isSinus = m.ps2IsSinus);
                m.ReadMeshFromSDC();
            }
            m.InitGameObject();
            return(m);
        }
Пример #4
0
        public static MeshObject Read(EndianBinaryReader reader, PhysicalObject po, Pointer offset)
        {
            MapLoader  l = MapLoader.Loader;
            MeshObject m = new MeshObject(po, offset);
            Pointer    off_modelstart = Pointer.Read(reader);

            m.off_modelstart = off_modelstart;
            Pointer.Goto(ref reader, off_modelstart);
            m.off_vertices     = Pointer.Read(reader);
            m.off_normals      = Pointer.Read(reader);
            m.off_blendWeights = Pointer.Read(reader);
            if (l.mode == MapLoader.Mode.Rayman3PC || l.mode == MapLoader.Mode.RaymanArenaPC ||
                l.mode == MapLoader.Mode.Rayman3GC || l.mode == MapLoader.Mode.Rayman2PC)
            {
                reader.ReadInt32();
            }
            m.off_subblock_types = Pointer.Read(reader);
            m.off_subblocks      = Pointer.Read(reader);
            reader.ReadInt32();
            reader.ReadInt32();
            reader.ReadInt32();
            if (l.mode == MapLoader.Mode.Rayman2PC)
            {
                reader.ReadInt32();
                reader.ReadInt32();
            }
            m.num_vertices  = reader.ReadUInt16();
            m.num_subblocks = reader.ReadUInt16();
            reader.ReadInt32();
            reader.ReadSingle();
            reader.ReadSingle();
            reader.ReadSingle();
            reader.ReadSingle();
            reader.ReadInt32();
            if (l.mode != MapLoader.Mode.Rayman2PC)
            {
                reader.ReadInt32();
                reader.ReadInt16();
            }
            m.name = "Mesh";
            if (l.mode == MapLoader.Mode.Rayman3GC)
            {
                m.name = new string(reader.ReadChars(0x32)).TrimEnd('\0');
            }
            // Vertices
            Pointer off_current = Pointer.Goto(ref reader, m.off_vertices);

            //print("Loading vertices at " + String.Format("0x{0:X}", fs.Position) + " | Amount: " + num_vertices);
            m.vertices = new Vector3[m.num_vertices];
            for (int i = 0; i < m.num_vertices; i++)
            {
                float x = reader.ReadSingle();
                float z = reader.ReadSingle();
                float y = reader.ReadSingle();
                m.vertices[i] = new Vector3(x, y, z);
            }
            // Normals
            Pointer.Goto(ref reader, m.off_normals);
            m.normals = new Vector3[m.num_vertices];
            for (int i = 0; i < m.num_vertices; i++)
            {
                float x = reader.ReadSingle();
                float z = reader.ReadSingle();
                float y = reader.ReadSingle();
                m.normals[i] = new Vector3(x, y, z);
            }
            if (m.off_blendWeights != null)
            {
                Pointer.Goto(ref reader, m.off_blendWeights);

                /*reader.ReadUInt32(); // 0
                 * R3Pointer off_blendWeightsStart = R3Pointer.Read(reader);
                 * R3Pointer.Goto(ref reader, off_blendWeightsStart);*/
                reader.ReadUInt32();
                reader.ReadUInt32();
                reader.ReadUInt32();
                reader.ReadUInt32();
                reader.ReadUInt32();
                reader.ReadUInt32();
                reader.ReadUInt32();
                reader.ReadUInt32();
                m.blendWeights = new float[m.num_vertices];
                for (int i = 0; i < m.num_vertices; i++)
                {
                    m.blendWeights[i] = reader.ReadSingle();
                }
            }
            // Read subblock types & initialize arrays
            Pointer.Goto(ref reader, m.off_subblock_types);
            m.subblock_types = new ushort[m.num_subblocks];
            m.subblocks      = new IGeometricElement[m.num_subblocks];
            for (uint i = 0; i < m.num_subblocks; i++)
            {
                m.subblock_types[i] = reader.ReadUInt16();
            }
            m.gao     = new GameObject(m.name);
            m.gao.tag = "Visual";
            // Process blocks
            for (uint i = 0; i < m.num_subblocks; i++)
            {
                Pointer.Goto(ref reader, m.off_subblocks + (i * 4));
                Pointer block_offset = Pointer.Read(reader);
                Pointer.Goto(ref reader, block_offset);
                switch (m.subblock_types[i])
                {
                case 1:     // Material
                    m.subblocks[i] = MeshElement.Read(reader, block_offset, m);
                    break;

                case 3:     // Sprite
                    m.subblocks[i] = SpriteElement.Read(reader, block_offset, m);
                    break;

                case 13:
                    m.bones        = DeformSet.Read(reader, block_offset, m);
                    m.subblocks[i] = m.bones;
                    break;

                default:
                    m.subblocks[i] = null;

                    /*1 = indexedtriangles
                     * 2 = facemap
                     * 3 = sprite
                     * 4 = TMesh
                     * 5 = points
                     * 6 = lines
                     * 7 = spheres
                     * 8 = alignedboxes
                     * 9 = cones
                     * 13 = deformationsetinfo*/
                    l.print("Unknown geometric element type " + m.subblock_types[i] + " at offset " + block_offset);
                    break;
                }
            }
            m.InitGameObjects();
            return(m);
        }
Пример #5
0
    void UpdateFrame(uint currentFrame)
    {
        if (loaded && a3d != null && channelObjects != null & subObjects != null)
        {
            // First pass: reset TRS for all sub objects
            for (int i = 0; i < channelObjects.Length; i++)
            {
                GameObject c = channelObjects[i];
                if (c != null)
                {
                    c.transform.SetParent(perso.Gao.transform);
                    c.transform.localPosition    = Vector3.zero;
                    c.transform.localEulerAngles = Vector3.zero;
                    c.transform.localScale       = Vector3.one; // prevent float precision errors after a long time, lol
                }
                for (int j = 0; j < subObjects[i].Length; j++)
                {
                    if (subObjects[i][j] == null)
                    {
                        continue;
                    }
                    subObjects[i][j].Gao.transform.parent           = c.transform;
                    subObjects[i][j].Gao.transform.localPosition    = Vector3.zero;
                    subObjects[i][j].Gao.transform.localEulerAngles = Vector3.zero;
                    subObjects[i][j].Gao.transform.localScale       =
                        subObjects[i][j].scaleMultiplier.HasValue ? subObjects[i][j].scaleMultiplier.Value : Vector3.one;
                    subObjects[i][j].Gao.SetActive(false);
                }
            }
            AnimOnlyFrame of = a3d.onlyFrames[a3d.start_onlyFrames + currentFrame];
            // Create hierarchy for this frame
            for (int i = of.start_hierarchies_for_frame;
                 i < of.start_hierarchies_for_frame + of.num_hierarchies_for_frame; i++)
            {
                AnimHierarchy h = a3d.hierarchies[i];

                if (!channelIDDictionary.ContainsKey(h.childChannelID) ||
                    !channelIDDictionary.ContainsKey(h.parentChannelID))
                {
                    continue;
                }
                List <int> ch_child_list  = GetChannelByID(h.childChannelID);
                List <int> ch_parent_list = GetChannelByID(h.parentChannelID);
                foreach (int ch_child in ch_child_list)
                {
                    foreach (int ch_parent in ch_parent_list)
                    {
                        channelObjects[ch_child].transform.SetParent(channelObjects[ch_parent].transform);
                    }
                }

                //channelObjects[ch_child].transform.SetParent(channelObjects[ch_parent].transform);
            }
            // Final pass
            for (int i = 0; i < a3d.num_channels; i++)
            {
                AnimChannel       ch        = a3d.channels[a3d.start_channels + i];
                AnimFramesKFIndex kfi       = a3d.framesKFIndex[currentFrame + ch.framesKF];
                AnimKeyframe      kf        = a3d.keyframes[kfi.kf];
                AnimVector        pos       = a3d.vectors[kf.positionVector];
                AnimQuaternion    qua       = a3d.quaternions[kf.quaternion];
                AnimVector        scl       = a3d.vectors[kf.scaleVector];
                AnimNumOfNTTO     numOfNTTO = a3d.numOfNTTO[ch.numOfNTTO + of.numOfNTTO];
                AnimNTTO          ntto      = a3d.ntto[numOfNTTO.numOfNTTO];
                //if (ntto.IsBoneNTTO) continue;
                PhysicalObject physicalObject = subObjects[i][numOfNTTO.numOfNTTO - a3d.start_NTTO];
                Vector3        vector         = pos.vector;
                Quaternion     quaternion     = qua.quaternion;
                Vector3        scale          = scl.vector;
                int            framesSinceKF  = (int)currentFrame - (int)kf.frame;
                AnimKeyframe   nextKF         = null;
                int            framesDifference;
                float          interpolation;
                if (kf.IsEndKeyframe)
                {
                    AnimFramesKFIndex next_kfi = a3d.framesKFIndex[0 + ch.framesKF];
                    nextKF           = a3d.keyframes[next_kfi.kf];
                    framesDifference = a3d.num_onlyFrames - 1 + (int)nextKF.frame - (int)kf.frame;
                    if (framesDifference == 0)
                    {
                        interpolation = 0;
                    }
                    else
                    {
                        //interpolation = (float)(nextKF.interpolationFactor * (framesSinceKF / (float)framesDifference) + 1.0 * nextKF.interpolationFactor);
                        interpolation = framesSinceKF / (float)framesDifference;
                    }
                }
                else
                {
                    nextKF           = a3d.keyframes[kfi.kf + 1];
                    framesDifference = (int)nextKF.frame - (int)kf.frame;
                    //interpolation = (float)(nextKF.interpolationFactor * (framesSinceKF / (float)framesDifference) + 1.0 * nextKF.interpolationFactor);
                    interpolation = framesSinceKF / (float)framesDifference;
                }
                //print(interpolation);
                AnimVector     pos2 = a3d.vectors[nextKF.positionVector];
                AnimQuaternion qua2 = a3d.quaternions[nextKF.quaternion];
                AnimVector     scl2 = a3d.vectors[nextKF.scaleVector];
                vector     = Vector3.Lerp(pos.vector, pos2.vector, interpolation);
                quaternion = Quaternion.Lerp(qua.quaternion, qua2.quaternion, interpolation);
                scale      = Vector3.Lerp(scl.vector, scl2.vector, interpolation);
                float positionMultiplier = Mathf.Lerp(kf.positionMultiplier, nextKF.positionMultiplier, interpolation);

                if (physicalObject != null)
                {
                    physicalObject.Gao.SetActive(true);
                }
                channelObjects[i].transform.localPosition = vector * positionMultiplier;
                channelObjects[i].transform.localRotation = quaternion;
                channelObjects[i].transform.localScale    = scale;
            }
            for (int i = 0; i < a3d.num_channels; i++)
            {
                AnimChannel    ch = a3d.channels[a3d.start_channels + i];
                Transform      baseChannelTransform = channelObjects[i].transform;
                Vector3        invertedScale        = new Vector3(1f / baseChannelTransform.localScale.x, 1f / baseChannelTransform.localScale.y, 1f / baseChannelTransform.localScale.z);
                AnimNumOfNTTO  numOfNTTO            = a3d.numOfNTTO[ch.numOfNTTO + of.numOfNTTO];
                AnimNTTO       ntto           = a3d.ntto[numOfNTTO.numOfNTTO];
                PhysicalObject physicalObject = subObjects[i][numOfNTTO.numOfNTTO - a3d.start_NTTO];
                if (physicalObject == null)
                {
                    continue;
                }
                DeformSet bones = physicalObject.Bones;
                // Deformations
                if (bones != null)
                {
                    for (int j = 0; j < a3d.num_deformations; j++)
                    {
                        AnimDeformation d = a3d.deformations[a3d.start_deformations + j];
                        if (d.channel < ch.id)
                        {
                            continue;
                        }
                        if (d.channel > ch.id)
                        {
                            break;
                        }
                        if (!channelIDDictionary.ContainsKey(d.linkChannel))
                        {
                            continue;
                        }
                        List <int> ind_linkChannel_list = GetChannelByID(d.linkChannel);
                        foreach (int ind_linkChannel in ind_linkChannel_list)
                        {
                            AnimChannel    ch_link             = a3d.channels[a3d.start_channels + ind_linkChannel];
                            AnimNumOfNTTO  numOfNTTO_link      = a3d.numOfNTTO[ch_link.numOfNTTO + of.numOfNTTO];
                            AnimNTTO       ntto_link           = a3d.ntto[numOfNTTO_link.numOfNTTO];
                            PhysicalObject physicalObject_link = subObjects[ind_linkChannel][numOfNTTO_link.numOfNTTO - a3d.start_NTTO];
                            if (physicalObject_link == null)
                            {
                                continue;
                            }
                            if (bones == null || bones.bones.Length <= d.bone + 1)
                            {
                                continue;
                            }
                            DeformBone bone = bones.r3bones[d.bone + 1];
                            if (bone != null)
                            {
                                Transform channelTransform = channelObjects[ind_linkChannel].transform;
                                bone.UnityBone.transform.SetParent(channelTransform);
                                bone.UnityBone.localPosition = Vector3.zero;
                                bone.UnityBone.localRotation = Quaternion.identity;
                                bone.UnityBone.localScale    = Vector3.one;

                                /*bone.UnityBone.position = channelTransform.position;
                                 * bone.UnityBone.rotation = channelTransform.rotation;
                                 * //bone.UnityBone.localScale = Vector3.one;
                                 * bone.UnityBone.localScale = channelTransform.localScale;*/
                            }
                        }
                    }
                }
            }
            this.currentFrame = (currentFrame + 1) % a3d.num_onlyFrames;
        } /*else if (loaded && (a3d == null || !playAnimation) && perso.physical_objects != null) {
           * for (int i = 0; i < perso.physical_objects.Length; i++) {
           *    if (perso.physical_objects[i] != null) {
           *        GameObject poGao = perso.physical_objects[i].Gao;
           *        if (poGao != null && !poGao.activeSelf) {
           *            poGao.transform.SetParent(perso.Gao.transform);
           *            poGao.transform.localPosition = Vector3.zero;
           *            poGao.transform.localEulerAngles = Vector3.zero;
           *            poGao.SetActive(true);
           *        }
           *    }
           * }
           * }*/
    }