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;
            }
        }
        void InitAnimation(AnimA3DGeneral a3d)
        {
            if (a3d != this.a3d || forceAnimUpdate)
            {
                forceAnimUpdate = false;
                DeinitAnimation();
                // Init animation
                this.a3d     = a3d;
                currentFrame = 0;
                if (a3d != null)
                {
                    //animationSpeed = a3d.speed;
                    // Init channels & subobjects
                    subObjects     = new PhysicalObject[a3d.num_channels][];
                    channelObjects = new GameObject[a3d.num_channels];
                    if (a3d.num_morphData > 0)
                    {
                        fullMorphPOs = new Dictionary <ushort, PhysicalObject> [a3d.num_channels];
                    }
                    currentActivePO = new int[a3d.num_channels];
                    channelParents  = new bool[a3d.num_channels];
                    for (int i = 0; i < a3d.num_channels; i++)
                    {
                        short id = a3d.channels[a3d.start_channels + i].id;
                        channelObjects[i] = new GameObject("Channel " + id);
                        channelObjects[i].transform.SetParent(perso.gameObject.transform);
                        currentActivePO[i] = -1;
                        AddChannelID(id, i);
                        subObjects[i] = new PhysicalObject[a3d.num_NTTO];
                        AnimChannel   ch = a3d.channels[a3d.start_channels + i];
                        List <ushort> listOfNTTOforChannel = new List <ushort>();
                        for (int j = 0; j < a3d.num_onlyFrames; j++)
                        {
                            AnimOnlyFrame of = a3d.onlyFrames[a3d.start_onlyFrames + j];
                            //print(ch.numOfNTTO + " - " + of.numOfNTTO + " - " + a3d.numOfNTTO.Length);
                            AnimNumOfNTTO numOfNTTO = a3d.numOfNTTO[ch.numOfNTTO + of.numOfNTTO];
                            if (!listOfNTTOforChannel.Contains(numOfNTTO.numOfNTTO))
                            {
                                listOfNTTOforChannel.Add(numOfNTTO.numOfNTTO);
                            }
                        }
                        for (int k = 0; k < listOfNTTOforChannel.Count; k++)
                        {
                            int      j    = listOfNTTOforChannel[k] - a3d.start_NTTO;
                            AnimNTTO ntto = a3d.ntto[a3d.start_NTTO + j];
                            if (ntto.IsInvisibleNTTO)
                            {
                                subObjects[i][j] = new PhysicalObject();
                                subObjects[i][j].Gao.transform.parent = channelObjects[i].transform;
                                subObjects[i][j].Gao.name             = "[" + j + "] Invisible PO";
                                subObjects[i][j].Gao.SetActive(false);

                                /*GameObject boneVisualisation = new GameObject("Bone vis");
                                *  boneVisualisation.transform.SetParent(subObjects[i][j].Gao.transform);
                                *  MeshRenderer mr = boneVisualisation.AddComponent<MeshRenderer>();
                                *  MeshFilter mf = boneVisualisation.AddComponent<MeshFilter>();
                                *  Mesh mesh = Util.CreateBox(0.1f);
                                *  mf.mesh = mesh;
                                *  boneVisualisation.transform.localScale = Vector3.one / 4f;*/
                            }
                            else
                            {
                                if (perso.Perso3dData.ObjectList != null && perso.Perso3dData.ObjectList.Count > ntto.object_index)
                                {
                                    PhysicalObject o = perso.Perso3dData.ObjectList.entries[ntto.object_index].po;
                                    if (o != null)
                                    {
                                        //if (o.visualSetType == 1) print(name);
                                        PhysicalObject c = o.Clone();
                                        subObjects[i][j] = c;
                                        subObjects[i][j].Gao.transform.localScale =
                                            subObjects[i][j].scaleMultiplier.HasValue ? subObjects[i][j].scaleMultiplier.Value : Vector3.one;
                                        c.Gao.transform.parent = channelObjects[i].transform;
                                        c.Gao.name             = "[" + j + "] " + c.Gao.name;
                                        if (Controller.Settings.hasDeformations && c.Bones != null)
                                        {
                                            hasBones = true;
                                        }
                                        foreach (VisualSetLOD l in c.visualSet)
                                        {
                                            if (l.obj != null)
                                            {
                                                GameObject gao = l.obj.Gao; // TODO: Create gameobjects explicitly?
                                            }
                                        }

                                        c.Gao.SetActive(false);
                                    }
                                }
                            }
                        }
                    }

                    if (a3d.num_morphData > 0 && a3d.morphData != null && Controller.Settings.engineVersion < Settings.EngineVersion.R3)
                    {
                        morphDataArray = new AnimMorphData[a3d.num_channels, a3d.num_onlyFrames];
                        // Iterate over morph data to find the correct channel and keyframe
                        for (int i = 0; i < a3d.num_morphData; i++)
                        {
                            AnimMorphData m = a3d.morphData[a3d.start_morphData + i];
                            if (m != null)
                            {
                                /*print("F:" + a3d.num_onlyFrames + " - C:" + a3d.num_channels + " - CF" + (a3d.num_onlyFrames * a3d.num_channels) + " - " +
                                 *  m.channel + " - " + m.frame + " - " + m.morphProgress + " - " + m.objectIndexTo + " - " + m.byte5 + " - " + m.byte6 + " - " + m.byte7);*/
                                int channelIndex = this.GetChannelByID(m.channel)[0];
                                if (channelIndex < morphDataArray.GetLength(0) && m.frame < morphDataArray.GetLength(1))
                                {
                                    morphDataArray[channelIndex, m.frame] = m;
                                    if (m.morphProgress == 100 && perso.Perso3dData.ObjectList != null && perso.Perso3dData.ObjectList.Count > m.objectIndexTo)
                                    {
                                        if (fullMorphPOs[channelIndex] == null)
                                        {
                                            fullMorphPOs[channelIndex] = new Dictionary <ushort, PhysicalObject>();
                                        }
                                        if (!fullMorphPOs[channelIndex].ContainsKey(m.objectIndexTo))
                                        {
                                            PhysicalObject o = perso.Perso3dData.ObjectList.entries[m.objectIndexTo].po;
                                            if (o != null)
                                            {
                                                PhysicalObject c = o.Clone();
                                                c.Gao.transform.localScale = c.scaleMultiplier.HasValue ? c.scaleMultiplier.Value : Vector3.one;
                                                c.Gao.transform.parent     = channelObjects[channelIndex].transform;
                                                c.Gao.name = "[Morph] " + c.Gao.name;
                                                if (Controller.Settings.hasDeformations && c.Bones != null)
                                                {
                                                    hasBones = true;
                                                }
                                                foreach (VisualSetLOD l in c.visualSet)
                                                {
                                                    if (l.obj != null)
                                                    {
                                                        GameObject gao = l.obj.Gao; // TODO: Create gameobjects explicitly?
                                                    }
                                                }

                                                c.Gao.SetActive(false);
                                                fullMorphPOs[channelIndex][m.objectIndexTo] = c;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        morphDataArray = null;
                    }

                    // Keep lighting last so that it is applied to all new sub objects

                    /*if (!perso.IsAlways) {
                     *  Controller.SectorManager.ApplySectorLighting(sector, gameObject, LightInfo.ObjectLightedFlag.Perso);
                     * } else {
                     *  Controller.SectorManager.ApplySectorLighting(sector, gameObject, LightInfo.ObjectLightedFlag.None);
                     * }*/
                    // TODO: perso lighting
                }
                loaded = true;
            }
        }
Esempio n. 3
0
    public void UpdateAnimation()
    {
        if (IsLoaded && shAnim != null && animCuts != null && animCuts.Length > 0 && channelObjects != null && subObjects != null)
        {
            if (currentFrame >= shAnim.num_frames)
            {
                currentFrame %= shAnim.num_frames;
            }
            UpdateAnimationCut();
            // First pass: reset TRS for all sub objects
            for (int i = 0; i < channelParents[currentAnimCut].Length; i++)
            {
                channelParents[currentAnimCut][i] = false;
            }
            ROMAnimation  anim = ROMStruct.Loader.romAnims[animCuts[currentAnimCut].index];
            uint          currentRelativeFrame = currentFrame - anim.a3d.this_start_onlyFrames;
            AnimOnlyFrame of = anim.onlyFrames[currentRelativeFrame];
            // 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 = anim.hierarchies[i];

                if (!channelIDDictionary[currentAnimCut].ContainsKey(h.childChannelID) || !channelIDDictionary[currentAnimCut].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[currentAnimCut][ch_child].transform.SetParent(channelObjects[currentAnimCut][ch_parent].transform);
                        channelParents[currentAnimCut][ch_child] = true;
                    }
                }

                //channelObjects[ch_child].transform.SetParent(channelObjects[ch_parent].transform);
            }

            // Final pass
            int currentKFIndex = 0;
            for (int i = 0; i < anim.channels.Length; i++)
            {
                AnimChannel ch = anim.channels[i];

                // Select keyframe
                AnimKeyframe kf = null;
                int          selectedKFindex = 0;
                for (int k = 0; k < ch.num_keyframes; k++)
                {
                    if (anim.keyframes[currentKFIndex + k].frame <= currentFrame)
                    {
                        kf = anim.keyframes[currentKFIndex + k];
                        selectedKFindex = k;
                    }
                    else
                    {
                        break;
                    }
                }
                AnimVector     pos            = anim.vectors[kf.positionVector];
                AnimQuaternion qua            = anim.quaternions[kf.quaternion];
                AnimVector     scl            = anim.vectors[kf.scaleVector];
                AnimNumOfNTTO  numOfNTTO      = anim.numOfNTTO[(i * anim.a3d.num_numNTTO) + of.numOfNTTO];
                AnimNTTO       ntto           = null;
                int            poNum          = -1;
                GameObject     physicalObject = null;
                if (numOfNTTO.numOfNTTO != 0xFFFF)
                {
                    poNum          = numOfNTTO.numOfNTTO;
                    ntto           = anim.ntto[poNum];
                    physicalObject = subObjects[currentAnimCut][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 (selectedKFindex == ch.num_keyframes - 1)
                {
                    nextKF           = anim.keyframes[currentKFIndex];
                    framesDifference = anim.a3d.total_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           = anim.keyframes[currentKFIndex + selectedKFindex + 1];
                    framesDifference = (int)nextKF.frame - (int)kf.frame;
                    //interpolation = (float)(nextKF.interpolationFactor * (framesSinceKF / (float)framesDifference) + 1.0 * nextKF.interpolationFactor);
                    interpolation = framesSinceKF / (float)framesDifference;
                }

                currentKFIndex += ch.num_keyframes;


                //print(interpolation);
                //print(a3d.vectors.Length + " - " + nextKF.positionVector);
                //print(perso.p3dData.family.animBank);
                AnimVector     pos2 = anim.vectors[nextKF.positionVector];
                AnimQuaternion qua2 = anim.quaternions[nextKF.quaternion];
                AnimVector     scl2 = anim.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[currentAnimCut][i])
                {
                    if (currentActivePO[currentAnimCut][i] == -2 && fullMorphPOs[currentAnimCut] != null && fullMorphPOs[currentAnimCut][i] != null)
                    {
                        foreach (GameObject morphPO in fullMorphPOs[currentAnimCut][i].Values)
                        {
                            if (morphPO.activeSelf)
                            {
                                morphPO.SetActive(false);
                            }
                        }
                    }
                    if (currentActivePO[currentAnimCut][i] >= 0 && subObjects[currentAnimCut][i][currentActivePO[currentAnimCut][i]] != null)
                    {
                        subObjects[currentAnimCut][i][currentActivePO[currentAnimCut][i]].SetActive(false);
                    }
                    currentActivePO[currentAnimCut][i] = poNum;
                    if (physicalObject != null)
                    {
                        physicalObject.SetActive(true);
                    }
                }
                if (!channelParents[currentAnimCut][i])
                {
                    channelObjects[currentAnimCut][i].transform.SetParent(transform);
                }
                channelObjects[currentAnimCut][i].transform.localPosition = vector;                // * positionMultiplier;
                channelObjects[currentAnimCut][i].transform.localRotation = quaternion;
                channelObjects[currentAnimCut][i].transform.localScale    = scale;

                if (physicalObject != null &&
                    anim.a3d.num_morphData > 0 &&
                    morphDataArray[currentAnimCut] != null &&
                    i < morphDataArray[currentAnimCut].GetLength(0) &&
                    currentRelativeFrame < morphDataArray[currentAnimCut].GetLength(1))
                {
                    AnimMorphData   morphData = morphDataArray[currentAnimCut][i, currentRelativeFrame];
                    GeometricObject ogPO      = perso.p3dData.Value.objectsTable.Value.data.Value.entries[anim.ntto[poNum].object_index].obj.Value.visual.Value;
                    if (morphData != null && morphData.morphProgress != 0 && morphData.morphProgress != 100)
                    {
                        //print("morphing " + physicalObject.name);
                        GeometricObject morphToPO = perso.p3dData.Value.objectsTable.Value.data.Value.entries[morphData.objectIndexTo].obj.Value.visual.Value;
                        ogPO.MorphVertices(physicalObject, morphToPO, morphData.morphProgress / 100f);
                    }
                    else if (morphData != null && morphData.morphProgress == 100)
                    {
                        physicalObject.SetActive(false);
                        GameObject c = fullMorphPOs[currentAnimCut][i][morphData.objectIndexTo];
                        c.transform.localScale    = objectIndexScales.ContainsKey(morphData.objectIndexTo) ? objectIndexScales[morphData.objectIndexTo] : Vector3.one;
                        c.transform.localPosition = Vector3.zero;
                        c.transform.localRotation = Quaternion.identity;
                        c.SetActive(true);
                        currentActivePO[currentAnimCut][i] = -2;
                    }
                    else
                    {
                        ogPO.ResetMorph(physicalObject);
                    }
                }
            }
        }
    }
Esempio n. 4
0
    void SwitchAnimationCut(int newAnimCut)
    {
        if (currentAnimCut != newAnimCut || forceAnimUpdate)
        {
            forceAnimUpdate = false;
            // Init animation
            this.currentAnimCut = newAnimCut;

            ROMAnimation anim   = ROMStruct.Loader.romAnims[animCuts[currentAnimCut].index];
            bool         newCut = subObjects[currentAnimCut] == null;
            if (anim != null && newCut)
            {
                //animationSpeed = a3d.speed;
                // Init channels & subobjects
                channelObjects[currentAnimCut]  = new GameObject[anim.a3d.num_channels];
                currentActivePO[currentAnimCut] = new int[anim.a3d.num_channels];
                channelParents[currentAnimCut]  = new bool[anim.a3d.num_channels];
                subObjects[currentAnimCut]      = new GameObject[anim.a3d.num_channels][];
                if (anim.a3d.num_morphData > 0)
                {
                    fullMorphPOs[currentAnimCut] = new Dictionary <ushort, GameObject> [anim.a3d.num_channels];
                }
                for (int i = 0; i < anim.a3d.num_channels; i++)
                {
                    short id = anim.channels[i].id;
                    channelObjects[currentAnimCut][i] = new GameObject($"[Cut {currentAnimCut}] Channel {id}");
                    channelObjects[currentAnimCut][i].transform.SetParent(transform);
                    currentActivePO[currentAnimCut][i] = -1;
                    AddChannelID(id, i);
                    if (newCut)
                    {
                        subObjects[currentAnimCut][i] = new GameObject[anim.a3d.num_NTTO];
                    }
                    AnimChannel   ch = anim.channels[i];
                    List <ushort> listOfNTTOforChannel = new List <ushort>();
                    for (int j = 0; j < anim.onlyFrames.Length; j++)
                    {
                        AnimOnlyFrame of = anim.onlyFrames[j];
                        //print(ch.numOfNTTO + " - " + of.numOfNTTO + " - " + a3d.numOfNTTO.Length);
                        AnimNumOfNTTO numOfNTTO = anim.numOfNTTO[(i * anim.a3d.num_numNTTO) + of.numOfNTTO];
                        if (!listOfNTTOforChannel.Contains(numOfNTTO.numOfNTTO) && numOfNTTO.numOfNTTO != 0xFFFF)
                        {
                            listOfNTTOforChannel.Add(numOfNTTO.numOfNTTO);
                        }
                    }
                    if (newCut)
                    {
                        for (int k = 0; k < listOfNTTOforChannel.Count; k++)
                        {
                            int      j    = listOfNTTOforChannel[k];
                            AnimNTTO ntto = anim.ntto[j];
                            if (ntto.IsInvisibleNTTO)
                            {
                                subObjects[currentAnimCut][i][j] = new GameObject();
                                subObjects[currentAnimCut][i][j].transform.parent = channelObjects[currentAnimCut][i].transform;
                                subObjects[currentAnimCut][i][j].name             = "[" + j + "] Invisible NTTO";
                                subObjects[currentAnimCut][i][j].SetActive(false);
                            }
                            else
                            {
                                if (perso.p3dData.Value.objectsTable.Value != null &&
                                    perso.p3dData.Value.objectsTable.Value.length > ntto.object_index)
                                {
                                    ObjectsTableData.Entry entry = perso.p3dData.Value.objectsTable.Value.data.Value.entries[ntto.object_index];
                                    PhysicalObject         o     = entry.obj.Value;
                                    if (o != null)
                                    {
                                        //if (o.visualSetType == 1) print(name);
                                        GameObject c = o.GetGameObject().gameObject;
                                        subObjects[currentAnimCut][i][j] = c;
                                        if (entry.scale.HasValue)
                                        {
                                            objectIndexScales[ntto.object_index] = new Vector3(entry.scale.Value.x, entry.scale.Value.z, entry.scale.Value.y);
                                            subObjects[currentAnimCut][i][j].transform.localScale = objectIndexScales[ntto.object_index];
                                        }
                                        c.transform.parent = channelObjects[currentAnimCut][i].transform;
                                        c.name             = "[" + j + "] " + c.name;
                                        c.SetActive(false);
                                    }
                                }
                            }
                        }
                    }
                }


                if (anim.a3d.num_morphData > 0 && anim.morphData != null)
                {
                    morphDataArray[currentAnimCut] = new AnimMorphData[anim.channels.Length, anim.onlyFrames.Length];
                    // Iterate over morph data to find the correct channel and keyframe
                    for (int i = 0; i < anim.a3d.num_morphData; i++)
                    {
                        AnimMorphData m = anim.morphData[i];
                        if (m != null)
                        {
                            /*print("F:" + a3d.num_onlyFrames + " - C:" + a3d.num_channels + " - CF" + (a3d.num_onlyFrames * a3d.num_channels) + " - " +
                             *      m.channel + " - " + m.frame + " - " + m.morphProgress + " - " + m.objectIndexTo + " - " + m.byte5 + " - " + m.byte6 + " - " + m.byte7);*/
                            int channelIndex = this.GetChannelByID(m.channel)[0];
                            if (channelIndex < morphDataArray[currentAnimCut].GetLength(0) && m.frame < morphDataArray[currentAnimCut].GetLength(1))
                            {
                                morphDataArray[currentAnimCut][channelIndex, m.frame] = m;
                                if (m.morphProgress == 100 && perso.p3dData.Value.objectsTable.Value != null &&
                                    perso.p3dData.Value.objectsTable.Value.length > m.objectIndexTo)
                                {
                                    if (fullMorphPOs[currentAnimCut][channelIndex] == null)
                                    {
                                        fullMorphPOs[currentAnimCut][channelIndex] = new Dictionary <ushort, GameObject>();
                                    }
                                    if (!fullMorphPOs[currentAnimCut][channelIndex].ContainsKey(m.objectIndexTo))
                                    {
                                        ObjectsTableData.Entry entry = perso.p3dData.Value.objectsTable.Value.data.Value.entries[m.objectIndexTo];
                                        PhysicalObject         o     = entry.obj.Value;
                                        if (o != null)
                                        {
                                            //if (o.visualSetType == 1) print(name);
                                            GameObject c = o.GetGameObject().gameObject;
                                            fullMorphPOs[currentAnimCut][channelIndex][m.objectIndexTo] = c;
                                            if (entry.scale.HasValue)
                                            {
                                                objectIndexScales[m.objectIndexTo] = new Vector3(entry.scale.Value.x, entry.scale.Value.z, entry.scale.Value.y);
                                                c.transform.localScale             = objectIndexScales[m.objectIndexTo];
                                            }

                                            /*subObjects[i][j].transform.localScale =
                                             *      subObjects[i][j].scaleMultiplier.HasValue ? subObjects[i][j].scaleMultiplier.Value : Vector3.one;*/
                                            c.transform.parent = channelObjects[currentAnimCut][channelIndex].transform;
                                            c.name             = "[Morph] " + c.name;
                                            c.SetActive(false);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    morphDataArray = null;
                }

                // Keep lighting last so that it is applied to all new sub objects
                if (!IsAlways)
                {
                    controller.sectorManager.ApplySectorLighting(sector, gameObject, OpenSpace.Visual.LightInfo.ObjectLightedFlag.Perso);
                }
                else
                {
                    controller.sectorManager.ApplySectorLighting(sector, gameObject, OpenSpace.Visual.LightInfo.ObjectLightedFlag.None);
                }
            }
            if (channelObjects != null)
            {
                for (int i = 0; i < animCuts.Length; i++)
                {
                    if (channelObjects[i] != null)
                    {
                        if (currentAnimCut == i)
                        {
                            foreach (GameObject g in channelObjects[i])
                            {
                                g.SetActive(true);
                            }
                        }
                        else
                        {
                            foreach (GameObject g in channelObjects[i])
                            {
                                g.SetActive(false);
                            }
                        }
                    }
                }
            }
            IsLoaded = true;
        }
    }
Esempio n. 5
0
        public static AnimationBank[] Read(EndianBinaryReader reader, Pointer offset, uint index, uint num_banks, bool append = false)
        {
            MapLoader l = MapLoader.Loader;

            AnimationBank[] banks = new AnimationBank[num_banks];

            for (int i = 0; i < num_banks; i++)
            {
                // In R3, each animation bank is of size 0x104 = 13 times a stack description of 5 uint32s.
                banks[i]                 = new AnimationBank(Pointer.Current(reader));
                banks[i].a3d_general     = AnimationStack.Read(reader);
                banks[i].vectors         = AnimationStack.Read(reader);
                banks[i].quaternions     = AnimationStack.Read(reader);
                banks[i].hierarchies     = AnimationStack.Read(reader);
                banks[i].NTTO            = AnimationStack.Read(reader);
                banks[i].onlyFrames      = AnimationStack.Read(reader);
                banks[i].channels        = AnimationStack.Read(reader);
                banks[i].framesNumOfNTTO = AnimationStack.Read(reader);
                banks[i].framesKFIndex   = AnimationStack.Read(reader);
                banks[i].keyframes       = AnimationStack.Read(reader);
                banks[i].events          = AnimationStack.Read(reader);
                banks[i].morphData       = AnimationStack.Read(reader);
                if (l.mode != MapLoader.Mode.Rayman2PC)
                {
                    banks[i].deformations = AnimationStack.Read(reader);
                }
                else
                {
                    banks[i].deformations = null;
                }
                banks[i].animations = new AnimA3DGeneral[banks[i].a3d_general.count];
            }
            if (l.mode == MapLoader.Mode.Rayman3PC || (l.mode == MapLoader.Mode.Rayman2PC && !append))
            {
                for (int i = 0; i < num_banks; i++)
                {
                    if (banks[i].a3d_general.reservedMemory > 0)
                    {
                        banks[i].a3d_general.off_data = Pointer.Read(reader);
                    }
                    if (banks[i].vectors.reservedMemory > 0)
                    {
                        banks[i].vectors.off_data = Pointer.Read(reader);
                    }
                    if (banks[i].quaternions.reservedMemory > 0)
                    {
                        banks[i].quaternions.off_data = Pointer.Read(reader);
                    }
                    if (banks[i].hierarchies.reservedMemory > 0)
                    {
                        banks[i].hierarchies.off_data = Pointer.Read(reader);
                    }
                    if (banks[i].NTTO.reservedMemory > 0)
                    {
                        banks[i].NTTO.off_data = Pointer.Read(reader);
                    }
                    if (banks[i].onlyFrames.reservedMemory > 0)
                    {
                        banks[i].onlyFrames.off_data = Pointer.Read(reader);
                    }
                    if (banks[i].channels.reservedMemory > 0)
                    {
                        banks[i].channels.off_data = Pointer.Read(reader);
                    }
                    if (banks[i].framesNumOfNTTO.reservedMemory > 0)
                    {
                        banks[i].framesNumOfNTTO.off_data = Pointer.Read(reader);
                    }
                    if (banks[i].framesKFIndex.reservedMemory > 0)
                    {
                        banks[i].framesKFIndex.off_data = Pointer.Read(reader);
                    }
                    if (banks[i].keyframes.reservedMemory > 0)
                    {
                        banks[i].keyframes.off_data = Pointer.Read(reader);
                    }
                    if (banks[i].events.reservedMemory > 0)
                    {
                        banks[i].events.off_data = Pointer.Read(reader);
                    }
                    if (banks[i].morphData.reservedMemory > 0)
                    {
                        banks[i].morphData.off_data = Pointer.Read(reader);
                    }
                    if (l.mode != MapLoader.Mode.Rayman2PC && banks[i].deformations.reservedMemory > 0)
                    {
                        banks[i].deformations.off_data = Pointer.Read(reader);
                    }
                }
            }
            Pointer off_current = Pointer.Current(reader);
            Pointer off_a3d     = null;
            uint    num_a3d     = (uint)banks.Sum(b => b.a3d_general.count);

            FileFormat.FileWithPointers kfFile = null;
            if (index == 0 && l.files_array[MapLoader.Mem.FixKeyFrames] != null)
            {
                kfFile = MapLoader.Loader.files_array[MapLoader.Mem.FixKeyFrames];
            }
            if (index > 0 && l.files_array[MapLoader.Mem.LvlKeyFrames] != null)
            {
                kfFile = MapLoader.Loader.files_array[MapLoader.Mem.LvlKeyFrames];
            }
            if (kfFile != null && l.mode == MapLoader.Mode.Rayman3GC)
            {
                kfFile.GotoHeader();
                reader = kfFile.reader;
                uint[] a3d_sizes = new uint[num_a3d];
                for (uint i = 0; i < num_a3d; i++)
                {
                    a3d_sizes[i] = reader.ReadUInt32();
                }
                off_a3d = Pointer.Current(reader);
                uint current_anim = 0;
                for (uint i = 0; i < banks.Length; i++)
                {
                    uint num_a3d_in_bank = banks[i].a3d_general.count;
                    for (uint j = 0; j < num_a3d_in_bank; j++)
                    {
                        Pointer.Goto(ref reader, off_a3d);
                        // Read animation data here
                        banks[i].animations[j] = AnimA3DGeneral.Read(reader, off_a3d);
                        AnimA3DGeneral a = banks[i].animations[j];
                        a.vectors       = new AnimVector[a.num_vectors];
                        a.quaternions   = new AnimQuaternion[a.num_quaternions];
                        a.hierarchies   = new AnimHierarchy[a.num_hierarchies];
                        a.ntto          = new AnimNTTO[a.num_NTTO];
                        a.onlyFrames    = new AnimOnlyFrame[a.num_onlyFrames];
                        a.channels      = new AnimChannel[a.num_channels];
                        a.numOfNTTO     = new AnimNumOfNTTO[a.num_numNTTO * a.num_channels];
                        a.framesKFIndex = new AnimFramesKFIndex[a.num_onlyFrames * a.num_channels];
                        a.keyframes     = new AnimKeyframe[a.num_keyframes];
                        a.events        = new AnimEvent[a.num_events];
                        a.morphData     = new AnimMorphData[a.num_morphData];
                        a.deformations  = new AnimDeformation[a.num_deformations];
                        for (uint k = 0; k < a.vectors.Length; k++)
                        {
                            a.vectors[k] = AnimVector.Read(reader);
                        }
                        for (uint k = 0; k < a.quaternions.Length; k++)
                        {
                            a.quaternions[k] = AnimQuaternion.Read(reader);
                        }
                        for (uint k = 0; k < a.hierarchies.Length; k++)
                        {
                            a.hierarchies[k] = AnimHierarchy.Read(reader);
                        }
                        for (uint k = 0; k < a.ntto.Length; k++)
                        {
                            a.ntto[k] = AnimNTTO.Read(reader);
                        }
                        for (uint k = 0; k < a.onlyFrames.Length; k++)
                        {
                            a.onlyFrames[k] = AnimOnlyFrame.Read(reader);
                        }
                        reader.Align(4);
                        for (uint k = 0; k < a.channels.Length; k++)
                        {
                            a.channels[k] = AnimChannel.Read(reader);
                        }
                        for (uint k = 0; k < a.numOfNTTO.Length; k++)
                        {
                            a.numOfNTTO[k] = AnimNumOfNTTO.Read(reader);
                        }
                        reader.Align(4);
                        for (uint k = 0; k < a.framesKFIndex.Length; k++)
                        {
                            a.framesKFIndex[k] = AnimFramesKFIndex.Read(reader);
                        }
                        for (uint k = 0; k < a.keyframes.Length; k++)
                        {
                            a.keyframes[k] = AnimKeyframe.Read(reader);
                        }
                        reader.Align(4);
                        for (uint k = 0; k < a.events.Length; k++)
                        {
                            a.events[k] = AnimEvent.Read(reader);
                        }
                        for (uint k = 0; k < a.morphData.Length; k++)
                        {
                            a.morphData[k] = AnimMorphData.Read(reader);
                        }
                        reader.Align(4);
                        for (uint k = 0; k < a.deformations.Length; k++)
                        {
                            a.deformations[k] = AnimDeformation.Read(reader);
                        }
                        off_a3d += a3d_sizes[current_anim];

                        // Check if read correctly
                        Pointer off_postAnim = Pointer.Current(reader);
                        if (off_postAnim != off_a3d)
                        {
                            l.print("Animation block size does not match data size: " +
                                    "Current offset: " + off_postAnim + " - Expected offset: " + off_a3d +
                                    " - Block start: " + (off_a3d + -(int)(a3d_sizes[current_anim])));
                        }

                        current_anim++;
                    }
                }
            }
            else if (kfFile == null && (l.mode == MapLoader.Mode.Rayman3PC || l.mode == MapLoader.Mode.Rayman2PC))
            {
                bool readArraysDirectly = l.mode == MapLoader.Mode.Rayman2PC && index == 0;
                for (uint i = 0; i < banks.Length; i++)
                {
                    banks[i].animations           = new AnimA3DGeneral[banks[i].a3d_general.Count(append)];
                    banks[i].global_vectors       = new AnimVector[banks[i].vectors.Count(append)];
                    banks[i].global_quaternions   = new AnimQuaternion[banks[i].quaternions.Count(append)];
                    banks[i].global_hierarchies   = new AnimHierarchy[banks[i].hierarchies.Count(append)];
                    banks[i].global_NTTO          = new AnimNTTO[banks[i].NTTO.Count(append)];
                    banks[i].global_onlyFrames    = new AnimOnlyFrame[banks[i].onlyFrames.Count(append)];
                    banks[i].global_channels      = new AnimChannel[banks[i].channels.Count(append)];
                    banks[i].global_numOfNTTO     = new AnimNumOfNTTO[banks[i].framesNumOfNTTO.Count(append)];
                    banks[i].global_framesKFIndex = new AnimFramesKFIndex[banks[i].framesKFIndex.Count(append)];
                    banks[i].global_keyframes     = new AnimKeyframe[banks[i].keyframes.Count(append)];
                    banks[i].global_events        = new AnimEvent[banks[i].events.Count(append)];
                    banks[i].global_morphData     = new AnimMorphData[banks[i].morphData.Count(append)];
                    if (l.mode != MapLoader.Mode.Rayman2PC)
                    {
                        banks[i].global_deformations = new AnimDeformation[banks[i].deformations.Count(append)];
                    }
                    if (banks[i].animations.Length > 0)
                    {
                        if (banks[i].a3d_general.off_data != null)
                        {
                            Pointer.Goto(ref reader, banks[i].a3d_general.off_data);
                        }
                        for (uint j = 0; j < banks[i].animations.Length; j++)
                        {
                            banks[i].animations[j] = AnimA3DGeneral.Read(reader, Pointer.Current(reader));
                        }
                        if (l.mode == MapLoader.Mode.Rayman2PC)
                        {
                            reader.PreAlign(56 * banks[i].animations.Length, 4);
                        }
                    }
                    if (banks[i].global_vectors.Length > 0)
                    {
                        if (banks[i].vectors.off_data != null)
                        {
                            Pointer.Goto(ref reader, banks[i].vectors.off_data);
                        }
                        for (uint j = 0; j < banks[i].global_vectors.Length; j++)
                        {
                            banks[i].global_vectors[j] = AnimVector.Read(reader);
                        }
                        if (l.mode == MapLoader.Mode.Rayman2PC)
                        {
                            reader.PreAlign(12 * banks[i].global_vectors.Length, 4);
                        }
                    }
                    if (banks[i].global_quaternions.Length > 0)
                    {
                        if (banks[i].quaternions.off_data != null)
                        {
                            Pointer.Goto(ref reader, banks[i].quaternions.off_data);
                        }
                        for (uint j = 0; j < banks[i].global_quaternions.Length; j++)
                        {
                            banks[i].global_quaternions[j] = AnimQuaternion.Read(reader);
                        }
                        if (l.mode == MapLoader.Mode.Rayman2PC)
                        {
                            reader.PreAlign(8 * banks[i].global_quaternions.Length, 4);
                        }
                    }
                    if (banks[i].global_hierarchies.Length > 0)
                    {
                        if (banks[i].hierarchies.off_data != null)
                        {
                            Pointer.Goto(ref reader, banks[i].hierarchies.off_data);
                        }
                        for (uint j = 0; j < banks[i].global_hierarchies.Length; j++)
                        {
                            banks[i].global_hierarchies[j] = AnimHierarchy.Read(reader);
                        }
                        if (l.mode == MapLoader.Mode.Rayman2PC)
                        {
                            reader.PreAlign(4 * banks[i].global_hierarchies.Length, 4);
                        }
                    }
                    if (banks[i].global_NTTO.Length > 0)
                    {
                        if (banks[i].NTTO.off_data != null)
                        {
                            Pointer.Goto(ref reader, banks[i].NTTO.off_data);
                        }
                        for (uint j = 0; j < banks[i].global_NTTO.Length; j++)
                        {
                            banks[i].global_NTTO[j] = AnimNTTO.Read(reader);
                        }
                        if (l.mode == MapLoader.Mode.Rayman2PC)
                        {
                            reader.PreAlign(6 * banks[i].global_NTTO.Length, 4);
                        }
                    }
                    if (banks[i].global_onlyFrames.Length > 0)
                    {
                        if (banks[i].onlyFrames.off_data != null)
                        {
                            Pointer.Goto(ref reader, banks[i].onlyFrames.off_data);
                        }
                        for (uint j = 0; j < banks[i].global_onlyFrames.Length; j++)
                        {
                            banks[i].global_onlyFrames[j] = AnimOnlyFrame.Read(reader);
                        }
                        if (l.mode == MapLoader.Mode.Rayman2PC)
                        {
                            reader.PreAlign(10 * banks[i].global_onlyFrames.Length, 4);
                        }
                    }
                    if (banks[i].global_channels.Length > 0)
                    {
                        if (banks[i].channels.off_data != null)
                        {
                            Pointer.Goto(ref reader, banks[i].channels.off_data);
                        }
                        for (uint j = 0; j < banks[i].global_channels.Length; j++)
                        {
                            banks[i].global_channels[j] = AnimChannel.Read(reader);
                        }
                        if (l.mode == MapLoader.Mode.Rayman2PC)
                        {
                            reader.PreAlign(16 * banks[i].global_channels.Length, 4);
                        }
                    }
                    if (banks[i].global_numOfNTTO.Length > 0)
                    {
                        if (banks[i].framesNumOfNTTO.off_data != null)
                        {
                            Pointer.Goto(ref reader, banks[i].framesNumOfNTTO.off_data);
                        }
                        for (uint j = 0; j < banks[i].global_numOfNTTO.Length; j++)
                        {
                            banks[i].global_numOfNTTO[j] = AnimNumOfNTTO.Read(reader);
                        }
                        if (l.mode == MapLoader.Mode.Rayman2PC)
                        {
                            reader.PreAlign(2 * banks[i].global_numOfNTTO.Length, 4);
                        }
                    }
                    if (banks[i].global_framesKFIndex.Length > 0)
                    {
                        if (banks[i].framesKFIndex.off_data != null)
                        {
                            Pointer.Goto(ref reader, banks[i].framesKFIndex.off_data);
                        }
                        for (uint j = 0; j < banks[i].global_framesKFIndex.Length; j++)
                        {
                            banks[i].global_framesKFIndex[j] = AnimFramesKFIndex.Read(reader);
                        }
                        if (l.mode == MapLoader.Mode.Rayman2PC)
                        {
                            reader.PreAlign(4 * banks[i].global_framesKFIndex.Length, 4);
                        }
                    }
                    if (banks[i].global_keyframes.Length > 0)
                    {
                        if (banks[i].keyframes.off_data != null)
                        {
                            Pointer.Goto(ref reader, banks[i].keyframes.off_data);
                        }
                        for (uint j = 0; j < banks[i].global_keyframes.Length; j++)
                        {
                            banks[i].global_keyframes[j] = AnimKeyframe.Read(reader);
                        }
                        if (l.mode == MapLoader.Mode.Rayman2PC)
                        {
                            reader.PreAlign(36 * banks[i].global_keyframes.Length, 4);
                        }
                    }
                    if (banks[i].global_events.Length > 0)
                    {
                        if (banks[i].events.off_data != null)
                        {
                            Pointer.Goto(ref reader, banks[i].events.off_data);
                        }
                        for (uint j = 0; j < banks[i].global_events.Length; j++)
                        {
                            banks[i].global_events[j] = AnimEvent.Read(reader);
                        }
                        if (l.mode == MapLoader.Mode.Rayman2PC)
                        {
                            reader.PreAlign(12 * banks[i].global_events.Length, 4);
                        }
                    }
                    if (banks[i].global_morphData.Length > 0)
                    {
                        if (banks[i].morphData.off_data != null)
                        {
                            Pointer.Goto(ref reader, banks[i].morphData.off_data);
                        }
                        for (uint j = 0; j < banks[i].global_morphData.Length; j++)
                        {
                            banks[i].global_morphData[j] = AnimMorphData.Read(reader);
                        }
                        if (l.mode == MapLoader.Mode.Rayman2PC)
                        {
                            reader.PreAlign(8 * banks[i].global_morphData.Length, 4);
                        }
                    }
                    if (banks[i].global_deformations != null && banks[i].global_deformations.Length > 0)
                    {
                        if (banks[i].deformations.off_data != null)
                        {
                            Pointer.Goto(ref reader, banks[i].deformations.off_data);
                        }
                        for (uint j = 0; j < banks[i].global_deformations.Length; j++)
                        {
                            banks[i].global_deformations[j] = AnimDeformation.Read(reader);
                        }
                    }
                    if (append)
                    {
                        AnimationBank b = l.animationBanks[index + i];
                        b.a3d_general     = banks[i].a3d_general;
                        b.vectors         = banks[i].vectors;
                        b.quaternions     = banks[i].quaternions;
                        b.hierarchies     = banks[i].hierarchies;
                        b.NTTO            = banks[i].NTTO;
                        b.onlyFrames      = banks[i].onlyFrames;
                        b.channels        = banks[i].channels;
                        b.framesNumOfNTTO = banks[i].framesNumOfNTTO;
                        b.framesKFIndex   = banks[i].framesKFIndex;
                        b.keyframes       = banks[i].keyframes;
                        b.events          = banks[i].events;
                        b.morphData       = banks[i].morphData;
                        b.deformations    = banks[i].deformations;
                        //Util.AppendArray(ref b.animations, ref banks[i].animations);
                        Util.AppendArrayAndMergeReferences(ref b.global_vectors, ref banks[i].global_vectors, (int)banks[i].vectors.countInFix);
                        Util.AppendArrayAndMergeReferences(ref b.global_quaternions, ref banks[i].global_quaternions, (int)banks[i].quaternions.countInFix);
                        Util.AppendArrayAndMergeReferences(ref b.global_hierarchies, ref banks[i].global_hierarchies, (int)banks[i].hierarchies.countInFix);
                        Util.AppendArrayAndMergeReferences(ref b.global_NTTO, ref banks[i].global_NTTO, (int)banks[i].NTTO.countInFix);
                        Util.AppendArrayAndMergeReferences(ref b.global_onlyFrames, ref banks[i].global_onlyFrames, (int)banks[i].onlyFrames.countInFix);
                        Util.AppendArrayAndMergeReferences(ref b.global_channels, ref banks[i].global_channels, (int)banks[i].channels.countInFix);
                        Util.AppendArrayAndMergeReferences(ref b.global_numOfNTTO, ref banks[i].global_numOfNTTO, (int)banks[i].framesNumOfNTTO.countInFix);
                        Util.AppendArrayAndMergeReferences(ref b.global_framesKFIndex, ref banks[i].global_framesKFIndex, (int)banks[i].framesKFIndex.countInFix);
                        Util.AppendArrayAndMergeReferences(ref b.global_keyframes, ref banks[i].global_keyframes, (int)banks[i].keyframes.countInFix);
                        Util.AppendArrayAndMergeReferences(ref b.global_events, ref banks[i].global_events, (int)banks[i].events.countInFix);
                        Util.AppendArrayAndMergeReferences(ref b.global_morphData, ref banks[i].global_morphData, (int)banks[i].morphData.countInFix);
                        if (banks[i].deformations != null)
                        {
                            Util.AppendArrayAndMergeReferences(ref b.global_deformations, ref banks[i].global_deformations, (int)banks[i].deformations.countInFix);
                        }

                        /*Array.Resize(ref b.animations, b.animations.Length + banks[i].animations.Length);
                         * Array.Resize(ref b.global_vectors, b.global_vectors.Length + banks[i].global_vectors.Length);
                         * Array.Resize(ref b.global_quaternions, b.global_quaternions.Length + banks[i].global_quaternions.Length);
                         * Array.Resize(ref b.global_hierarchies, b.global_hierarchies.Length + banks[i].global_hierarchies.Length);
                         * Array.Resize(ref b.global_NTTO, b.global_NTTO.Length + banks[i].global_NTTO.Length);
                         * Array.Resize(ref b.global_onlyFrames, b.global_onlyFrames.Length + banks[i].global_onlyFrames.Length);
                         * Array.Resize(ref b.global_channels, b.global_channels.Length + banks[i].global_channels.Length);
                         * Array.Resize(ref b.global_numOfNTTO, b.global_numOfNTTO.Length + banks[i].global_numOfNTTO.Length);
                         * Array.Resize(ref b.global_framesKFIndex, b.global_framesKFIndex.Length + banks[i].global_framesKFIndex.Length);
                         * Array.Resize(ref b.global_keyframes, b.global_keyframes.Length + banks[i].global_keyframes.Length);
                         * Array.Resize(ref b.global_events, b.global_events.Length + banks[i].global_events.Length);
                         * Array.Resize(ref b.global_morphData, b.global_morphData.Length + banks[i].global_morphData.Length);
                         * if (banks[i].deformations != null) Array.Resize(ref b.global_deformations, b.global_deformations.Length + banks[i].global_deformations.Length);
                         * Array.Copy(banks[i].global_vectors, 0, b.global_vectors, banks[i].vectors.countInFix, banks[i].global_vectors.Length);
                         * Array.Copy(banks[i].global_quaternions, 0, b.global_quaternions, banks[i].quaternions.countInFix, banks[i].global_quaternions.Length);
                         * Array.Copy(banks[i].global_hierarchies, 0, b.global_hierarchies, banks[i].hierarchies.countInFix, banks[i].global_hierarchies.Length);
                         * Array.Copy(banks[i].global_NTTO, 0, b.global_NTTO, banks[i].NTTO.countInFix, banks[i].global_NTTO.Length);
                         * Array.Copy(banks[i].global_onlyFrames, 0, b.global_onlyFrames, banks[i].onlyFrames.countInFix, banks[i].global_onlyFrames.Length);
                         * Array.Copy(banks[i].global_channels, 0, b.global_channels, banks[i].channels.countInFix, banks[i].global_channels.Length);
                         * Array.Copy(banks[i].global_numOfNTTO, 0, b.global_numOfNTTO, banks[i].framesNumOfNTTO.countInFix, banks[i].global_numOfNTTO.Length);
                         * Array.Copy(banks[i].global_framesKFIndex, 0, b.global_framesKFIndex, banks[i].framesKFIndex.countInFix, banks[i].global_framesKFIndex.Length);
                         * Array.Copy(banks[i].global_keyframes, 0, b.global_keyframes, banks[i].keyframes.countInFix, banks[i].global_keyframes.Length);
                         * Array.Copy(banks[i].global_events, 0, b.global_events, banks[i].events.countInFix, banks[i].global_events.Length);
                         * Array.Copy(banks[i].global_morphData, 0, b.global_morphData, banks[i].morphData.countInFix, banks[i].global_morphData.Length);
                         * if (banks[i].deformations != null) Array.Copy(banks[i].global_deformations, 0, b.global_deformations, banks[i].deformations.countInFix, banks[i].global_deformations.Length);*/
                    }

                    if (banks[i].animations.Length > 0)
                    {
                        AnimationBank srcBank = append ? l.animationBanks[index + i] : banks[i];
                        for (uint j = 0; j < banks[i].animations.Length; j++)
                        {
                            banks[i].animations[j].vectors       = srcBank.global_vectors;
                            banks[i].animations[j].quaternions   = srcBank.global_quaternions;
                            banks[i].animations[j].hierarchies   = srcBank.global_hierarchies;
                            banks[i].animations[j].ntto          = srcBank.global_NTTO;
                            banks[i].animations[j].onlyFrames    = srcBank.global_onlyFrames;
                            banks[i].animations[j].channels      = srcBank.global_channels;
                            banks[i].animations[j].numOfNTTO     = srcBank.global_numOfNTTO;
                            banks[i].animations[j].framesKFIndex = srcBank.global_framesKFIndex;
                            banks[i].animations[j].keyframes     = srcBank.global_keyframes;
                            banks[i].animations[j].events        = srcBank.global_events;
                            banks[i].animations[j].morphData     = srcBank.global_morphData;
                            banks[i].animations[j].deformations  = srcBank.global_deformations;
                        }
                    }
                    if (append)
                    {
                        Util.AppendArrayAndMergeReferences(ref l.animationBanks[index + i].animations, ref banks[i].animations, (int)banks[i].a3d_general.countInFix);
                    }
                }
            }
            Pointer.Goto(ref reader, off_current);
            return(banks);
        }
Esempio n. 6
0
        public void ReadData()
        {
            if (!dataParsed)
            {
                dataParsed = true;
                if (data != null && data.Length > 0)
                {
                    //Util.ByteArrayToFile(MapLoader.Loader.gameDataBinFolder + "exported_anims/anim_" + index + ".bin", data);
                    using (MemoryStream ms = new MemoryStream(data)) {
                        using (Reader r = new Reader(ms, Settings.s.IsLittleEndian)) {
                            a3d         = new AnimA3DGeneral(r);
                            vectors     = new AnimVector[a3d.num_vectors];
                            quaternions = new AnimQuaternion[a3d.num_quaternions];
                            hierarchies = new AnimHierarchy[a3d.num_hierarchies];
                            ntto        = new AnimNTTO[a3d.num_NTTO];
                            onlyFrames  = new AnimOnlyFrame[a3d.this_num_onlyFrames - a3d.this_start_onlyFrames];
                            channels    = new AnimChannel[a3d.num_channels];
                            numOfNTTO   = new AnimNumOfNTTO[a3d.num_channels * a3d.num_numNTTO];
                            keyframes   = new AnimKeyframe[a3d.num_keyframes];
                            events      = new AnimEvent[a3d.num_events];
                            morphData   = new AnimMorphData[a3d.num_morphData];

                            for (int i = 0; i < vectors.Length; i++)
                            {
                                vectors[i] = new AnimVector(r);
                            }
                            for (int i = 0; i < quaternions.Length; i++)
                            {
                                quaternions[i] = new AnimQuaternion(r);
                            }
                            for (int i = 0; i < hierarchies.Length; i++)
                            {
                                hierarchies[i] = new AnimHierarchy(r);
                            }
                            for (int i = 0; i < ntto.Length; i++)
                            {
                                ntto[i] = new AnimNTTO(r);
                            }
                            for (int i = 0; i < onlyFrames.Length; i++)
                            {
                                onlyFrames[i] = new AnimOnlyFrame(r);
                            }
                            for (int i = 0; i < channels.Length; i++)
                            {
                                channels[i] = new AnimChannel(r);
                            }
                            for (int i = 0; i < numOfNTTO.Length; i++)
                            {
                                numOfNTTO[i] = new AnimNumOfNTTO(r);
                            }
                            for (int i = 0; i < keyframes.Length; i++)
                            {
                                keyframes[i] = new AnimKeyframe(r);
                            }
                            r.Align(4);
                            for (int i = 0; i < events.Length; i++)
                            {
                                events[i] = new AnimEvent(r);
                            }
                            for (int i = 0; i < morphData.Length; i++)
                            {
                                morphData[i] = new AnimMorphData(r);
                            }
                            if (r.BaseStream.Position != r.BaseStream.Length)
                            {
                                MapLoader.Loader.print("Animation " + index + ": bad read");
                            }
                        }
                    }
                }
            }
        }