예제 #1
0
    public void PrintAnimationDebugInfo()
    {
        if (loaded && hasStates)
        {
            if (a3d != null)
            {
                for (int i = 0; i < a3d.num_NTTO; i++)
                {
                    AnimNTTO ntto = a3d.ntto[i + a3d.start_NTTO];
                    print("NTTO " + i + ": FLAGS:" + ntto.flags + " - OBJIND:" + ntto.object_index +
                          " - UNK4:" + ntto.unk4 + " - UNK5:" + ntto.unk5);
                }
                for (int i = 0; i < a3d.num_deformations; i++)
                {
                    AnimDeformation d = a3d.deformations[i + a3d.start_deformations];
                    print("Deform " + i + ": CH1:" + d.channel + " - BI1:" + d.bone +
                          " - CH2:" + d.linkChannel + " - BI2:" + d.linkBone);
                }
                for (int i = 0; i < a3d.num_hierarchies; i++)
                {
                    AnimHierarchy h = a3d.hierarchies[i + a3d.start_hierarchies];
                    print("Hierarchy " + i + ": Child:" + h.childChannelID + " - Parent:" + h.parentChannelID);
                }
                for (int i = 0; i < a3d.num_channels; i++)
                {
                    AnimChannel       ch  = a3d.channels[i + a3d.start_channels];
                    AnimFramesKFIndex kfi = a3d.framesKFIndex[currentFrame + ch.framesKF];
                    AnimKeyframe      kf  = a3d.keyframes[kfi.kf];
                    print("Channel " + i + ": ID:" + ch.id + " - U0:" + ch.unk0 + " - V:" + ch.vector + " - ");
                    print("Current keyframe: Flags:" + kf.flags + " - Q2:" + kf.quaternion2 + " - Frame:" + kf.frame);
                }

                //AnimOnlyFrame of = a3d.onlyFrames[a3d.start_onlyFrames + currentFrame];
                print("POs offset: " + perso.family.off_physical_list_first);
            }
            else if (state != null)
            {
                MapLoader l          = MapLoader.Loader;
                ushort    anim_index = 0;
                byte      bank_index = 0;
                if (state.anim_ref != null)
                {
                    anim_index = state.anim_ref.anim_index;
                    bank_index = perso.family.animBank;
                }
                print(state.anim_ref != null);
                print(l.animationBanks != null);
                print(l.animationBanks.Length > bank_index);
                print(l.animationBanks[bank_index] != null);
                print(l.animationBanks[bank_index].animations != null);
                print(l.animationBanks[bank_index].animations.Length > anim_index);
                print(l.animationBanks[bank_index].animations[anim_index] != null);
            }
        }
    }
        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;
            }
        }
예제 #4
0
        public IEnumerable <AnimHierarchyWithChannelInfo> IterateAnimHierarchiesWithChannelInfosForGivenFrame(int animationFrameNumber)
        {
            for (int i = 0; i < animA3DGeneral.num_channels; i++)
            {
                AnimChannel       channel = animA3DGeneral.channels[animA3DGeneral.start_channels + i];
                AnimFramesKFIndex openspaceKeyframeIndex              = animA3DGeneral.framesKFIndex[animationFrameNumber + channel.framesKF];
                AnimKeyframe      openspaceKeyframe                   = animA3DGeneral.keyframes[openspaceKeyframeIndex.kf];
                AnimVector        openspaceKeyframePositionVector     = animA3DGeneral.vectors[openspaceKeyframe.positionVector];
                AnimQuaternion    openspaceKeyframeRotationQuaternion = animA3DGeneral.quaternions[openspaceKeyframe.quaternion];
                AnimVector        openspaceKeyframeScaleVector        = animA3DGeneral.vectors[openspaceKeyframe.scaleVector];
                Vector3           localPosition = openspaceKeyframePositionVector.vector;
                Quaternion        localRotation = openspaceKeyframeRotationQuaternion.quaternion;
                Vector3           localScale    = openspaceKeyframeScaleVector.vector;

                string channelName            = "Channel " + channel.id;
                var    channelInHierarchyInfo = GetParentChannelName(channel.id, animationFrameNumber, animA3DGeneral);

                int framesSinceKF = (int)animationFrameNumber - (int)openspaceKeyframe.frame;

                bool isKeyframe = framesSinceKF == 0;

                AnimKeyframe nextKF = null;
                int          framesDifference;
                float        interpolation;
                if (openspaceKeyframe.IsEndKeyframe)
                {
                    AnimFramesKFIndex next_kfi = animA3DGeneral.framesKFIndex[0 + channel.framesKF];
                    nextKF           = animA3DGeneral.keyframes[next_kfi.kf];
                    framesDifference = animA3DGeneral.num_onlyFrames - 1 + (int)nextKF.frame - (int)openspaceKeyframe.frame;
                    if (framesDifference == 0)
                    {
                        interpolation = 0;
                    }
                    else
                    {
                        interpolation = framesSinceKF / (float)framesDifference;
                    }
                }
                else
                {
                    nextKF           = animA3DGeneral.keyframes[openspaceKeyframeIndex.kf + 1];
                    framesDifference = (int)nextKF.frame - (int)openspaceKeyframe.frame;
                    interpolation    = framesSinceKF / (float)framesDifference;
                }
                AnimVector     pos2 = animA3DGeneral.vectors[nextKF.positionVector];
                AnimQuaternion qua2 = animA3DGeneral.quaternions[nextKF.quaternion];
                AnimVector     scl2 = animA3DGeneral.vectors[nextKF.scaleVector];
                localPosition = Vector3.Lerp(openspaceKeyframePositionVector.vector, pos2.vector, interpolation);
                localRotation = Quaternion.Lerp(openspaceKeyframeRotationQuaternion.quaternion, qua2.quaternion, interpolation);
                localScale    = Vector3.Lerp(openspaceKeyframeScaleVector.vector, scl2.vector, interpolation);

                if (channelInHierarchyInfo.found)
                {
                    yield return(new AnimHierarchyWithChannelInfo(
                                     channelInHierarchyInfo.parentName,
                                     channelName,
                                     localPosition,
                                     localRotation,
                                     localScale,
                                     isKeyframe));
                }
            }
        }
예제 #5
0
        public static ExportState CreateFromState(State s)
        {
            Family      fam = s.family;
            ExportState es  = new ExportState();

            Perso examplePerso = MapLoader.Loader.persos.Find(p => p.p3dData.family == s.family);

            if (examplePerso == null)
            {
                return(es);
            }

            examplePerso.Gao.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);
            examplePerso.Gao.transform.localScale = Vector3.one;
            PersoBehaviour pb = examplePerso.Gao.GetComponent <PersoBehaviour>();

            pb.SetState(s);
            if (pb.a3d == null)
            {
                return(es);
            }
            es.animationLength = pb.a3d.num_onlyFrames;

            es.instances = new List <ExportObjectInstance>();
            es.channels  = new Dictionary <int, ExportChannel>();

            for (int c = 0; c < pb.a3d.num_channels; c++)
            {
                es.channels.Add(c, new ExportChannel()
                {
                    positions = new Vector3[es.animationLength],
                    rotations = new Quaternion[es.animationLength],
                    scales    = new Vector3[es.animationLength],
                });

                AnimChannel   ch = pb.a3d.channels[pb.a3d.start_channels + c];
                List <ushort> listOfNTTOforChannel = new List <ushort>();
                for (int j = 0; j < pb.a3d.num_onlyFrames; j++)
                {
                    AnimOnlyFrame of = pb.a3d.onlyFrames[pb.a3d.start_onlyFrames + j];
                    //print(ch.numOfNTTO + " - " + of.numOfNTTO + " - " + a3d.numOfNTTO.Length);
                    AnimNumOfNTTO numOfNTTO = pb.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] - pb.a3d.start_NTTO;
                    AnimNTTO ntto = pb.a3d.ntto[pb.a3d.start_NTTO + j];
                    if (ntto.IsInvisibleNTTO)
                    {
                    }
                    else
                    {
                        es.instances.Add(new ExportObjectInstance()
                        {
                            channelId         = c,
                            familyObjectIndex = ntto.object_index,
                            visibilities      = new bool[es.animationLength]
                        });
                    }
                }
            }

            for (uint i = 0; i < es.animationLength; i++)
            {
                pb.currentFrame = i;

                pb.UpdateAnimation();

                for (int c = 0; c < pb.a3d.num_channels; c++)
                {
                    if (pb.channelObjects[c].transform.childCount == 0)
                    {
                        Debug.LogWarning("ChannelObject " + pb.channelObjects[c] + " has no children :(");
                        continue;
                    }

                    Vector3    position = pb.channelObjects[c].transform.GetChild(0).position;
                    Quaternion rotation = pb.channelObjects[c].transform.GetChild(0).rotation;
                    Vector3    scale    = pb.channelObjects[c].transform.GetChild(0).lossyScale;
                    bool       visible  = pb.channelObjects[c].transform.GetChild(0).gameObject.activeSelf;

                    //Vector3 exportRotation = AngleUtil.quaternion2Euler(rotation, AngleUtil.RotSeq.)

                    //Quaternion swappedRotation = Quaternion.Euler(rotation.eulerAngles.x, rotation.eulerAngles.y, rotation.eulerAngles.z);

                    es.channels[c].positions[i] = position;
                    es.channels[c].rotations[i] = rotation;
                    es.channels[c].scales[i]    = scale;
                    //es.channels[c].visibilities[i][objectIndex] = visible ? true : false;

                    foreach (var instance in es.instances.Where(instance => instance.channelId == c))
                    {
                        AnimChannel   ch        = pb.a3d.channels[pb.a3d.start_channels + c];
                        AnimOnlyFrame of        = pb.a3d.onlyFrames[pb.a3d.start_onlyFrames + i];
                        AnimNumOfNTTO numOfNTTO = pb.a3d.numOfNTTO[ch.numOfNTTO + of.numOfNTTO];
                        AnimNTTO      ntto      = pb.a3d.ntto[numOfNTTO.numOfNTTO];

                        if (ntto.object_index != instance.familyObjectIndex)
                        {
                            continue;
                        }

                        //if (ntto.IsBoneNTTO) continue;
                        int            poNum          = numOfNTTO.numOfNTTO - pb.a3d.start_NTTO;
                        PhysicalObject physicalObject = pb.subObjects[c][poNum];

                        instance.visibilities[i] = physicalObject == null ? false : true;

                        //instance.familyObjectIndex;
                    }
                }
            }

            return(es);
        }
예제 #6
0
        // A completely separate Read function for the Dreamcast version, since it's so different
        public static AnimationBank ReadDreamcast(Reader reader, Pointer offset, Pointer off_events_fix, uint num_events_fix)
        {
            MapLoader     l    = MapLoader.Loader;
            AnimationBank bank = new AnimationBank(offset);

            bank.a3d_general = new AnimationStack()
            {
                off_data = Pointer.Read(reader)
            };
            bank.vectors = new AnimationStack()
            {
                off_data = Pointer.Read(reader)
            };
            bank.quaternions = new AnimationStack()
            {
                off_data = Pointer.Read(reader)
            };
            bank.hierarchies = new AnimationStack()
            {
                off_data = Pointer.Read(reader)
            };
            bank.NTTO = new AnimationStack()
            {
                off_data = Pointer.Read(reader)
            };
            bank.onlyFrames = new AnimationStack()
            {
                off_data = Pointer.Read(reader)
            };
            bank.channels = new AnimationStack()
            {
                off_data = Pointer.Read(reader)
            };
            bank.framesNumOfNTTO = new AnimationStack()
            {
                off_data = Pointer.Read(reader)
            };
            bank.framesKFIndex = new AnimationStack()
            {
                off_data = Pointer.Read(reader)
            };
            bank.keyframes = new AnimationStack()
            {
                off_data = Pointer.Read(reader)
            };
            bank.events = new AnimationStack()
            {
                off_data = Pointer.Read(reader), countInFix = num_events_fix
            };
            bank.events.count = bank.events.countInFix + reader.ReadUInt32();
            bank.morphData    = new AnimationStack()
            {
                off_data = Pointer.Read(reader)
            };
            Pointer off_current = Pointer.Current(reader);

            uint max_a3d_ind = 0, num_vectors = 0, num_quaternions = 0, num_hierarchies = 0, num_NTTO = 0,
                 num_numNTTO = 0, num_channels = 0, num_onlyFrames = 0, num_framesKF = 0, num_keyframes = 0, num_morphData = 0;

            foreach (State s in l.states)
            {
                if (s.anim_ref != null && s.anim_ref.anim_index > max_a3d_ind)
                {
                    max_a3d_ind = s.anim_ref.anim_index;
                }
            }


            bank.a3d_general.count = max_a3d_ind + 1;
            bank.animations        = l.ReadArray <AnimA3DGeneral>(bank.a3d_general.count, reader, bank.a3d_general.off_data);
            for (int i = 0; i < bank.a3d_general.count; i++)
            {
                AnimA3DGeneral a = bank.animations[i];
                if (a.start_vectors + a.num_vectors > num_vectors)
                {
                    num_vectors = (uint)a.start_vectors + a.num_vectors;
                }
                if (a.start_quaternions + a.num_quaternions > num_quaternions)
                {
                    num_quaternions = (uint)a.start_quaternions + a.num_quaternions;
                }
                //if (a.start_hierarchies + a.num_hierarchies > num_hierarchies) num_hierarchies = (uint)a.start_hierarchies + a.num_hierarchies;
                if (a.start_NTTO + a.num_NTTO > num_NTTO)
                {
                    num_NTTO = (uint)a.start_NTTO + a.num_NTTO;
                }
                if (a.start_onlyFrames + a.num_onlyFrames > num_onlyFrames)
                {
                    num_onlyFrames = (uint)a.start_onlyFrames + a.num_onlyFrames;
                }
                if (a.start_channels + a.num_channels > num_channels)
                {
                    num_channels = (uint)a.start_channels + a.num_channels;
                }
                if (a.start_morphData + a.num_morphData > num_morphData)
                {
                    num_morphData = (uint)a.start_morphData + a.num_morphData;
                }
            }

            bank.vectors.count     = num_vectors;
            bank.quaternions.count = num_quaternions;
            bank.NTTO.count        = num_NTTO;
            bank.onlyFrames.count  = num_onlyFrames;
            bank.channels.count    = num_channels;
            bank.morphData.count   = num_morphData;

            bank.global_vectors     = l.ReadArray <AnimVector>(bank.vectors.Count(false), reader, bank.vectors.off_data);
            bank.global_quaternions = l.ReadArray <AnimQuaternion>(bank.quaternions.Count(false), reader, bank.quaternions.off_data);
            bank.global_NTTO        = l.ReadArray <AnimNTTO>(bank.NTTO.Count(false), reader, bank.NTTO.off_data);
            bank.global_onlyFrames  = l.ReadArray <AnimOnlyFrame>(bank.onlyFrames.Count(false), reader, bank.onlyFrames.off_data);
            bank.global_channels    = l.ReadArray <AnimChannel>(bank.channels.Count(false), reader, bank.channels.off_data);

            AnimEvent[] eventsFix = l.ReadArray <AnimEvent>(num_events_fix, reader, off_events_fix);
            AnimEvent[] eventsLvl = l.ReadArray <AnimEvent>(bank.events.Count(false) - num_events_fix, reader, bank.events.off_data);
            bank.global_events = new AnimEvent[bank.events.Count(false)];
            Array.Copy(eventsFix, 0, bank.global_events, 0, num_events_fix);
            Array.Copy(eventsLvl, 0, bank.global_events, num_events_fix, bank.global_events.Length - num_events_fix);

            bank.global_morphData = l.ReadArray <AnimMorphData>(bank.morphData.Count(false), reader, bank.morphData.off_data);

            for (int i = 0; i < bank.a3d_general.count; i++)
            {
                AnimA3DGeneral a = bank.animations[i];
                for (int j = a.start_channels; j < a.start_channels + a.num_channels; j++)
                {
                    AnimChannel ch = bank.global_channels[j];
                    if (ch.framesKF + a.num_onlyFrames > num_framesKF)
                    {
                        num_framesKF = (uint)ch.framesKF + a.num_onlyFrames;
                    }

                    for (int k = a.start_onlyFrames; k < a.start_onlyFrames + a.num_onlyFrames; k++)
                    {
                        AnimOnlyFrame of = bank.global_onlyFrames[k];
                        if (ch.numOfNTTO + of.numOfNTTO + 1 > num_numNTTO)
                        {
                            num_numNTTO = (uint)ch.numOfNTTO + of.numOfNTTO + 1;
                        }
                    }
                }
                for (int k = a.start_onlyFrames; k < a.start_onlyFrames + a.num_onlyFrames; k++)
                {
                    AnimOnlyFrame of = bank.global_onlyFrames[k];
                    if (of.start_hierarchies_for_frame + of.num_hierarchies_for_frame > num_hierarchies)
                    {
                        num_hierarchies = (uint)of.start_hierarchies_for_frame + of.num_hierarchies_for_frame;
                    }
                }
            }
            bank.hierarchies.count     = num_hierarchies;
            bank.framesNumOfNTTO.count = num_numNTTO;
            bank.framesKFIndex.count   = num_framesKF;

            bank.global_hierarchies   = l.ReadArray <AnimHierarchy>(bank.hierarchies.Count(false), reader, bank.hierarchies.off_data);
            bank.global_numOfNTTO     = l.ReadArray <AnimNumOfNTTO>(bank.framesNumOfNTTO.Count(false), reader, bank.framesNumOfNTTO.off_data);
            bank.global_framesKFIndex = l.ReadArray <AnimFramesKFIndex>(bank.framesKFIndex.Count(false), reader, bank.framesKFIndex.off_data);
            for (uint j = 0; j < bank.global_framesKFIndex.Length; j++)
            {
                if (bank.global_framesKFIndex[j].kf + 1 > num_keyframes)
                {
                    num_keyframes = bank.global_framesKFIndex[j].kf + 1;
                }
            }
            bank.keyframes.count  = num_keyframes;
            bank.global_keyframes = l.ReadArray <AnimKeyframe>(bank.keyframes.Count(false), reader, bank.keyframes.off_data);

            Pointer.Goto(ref reader, off_current);
            for (uint j = 0; j < bank.animations.Length; j++)
            {
                bank.animations[j].vectors       = bank.global_vectors;
                bank.animations[j].quaternions   = bank.global_quaternions;
                bank.animations[j].hierarchies   = bank.global_hierarchies;
                bank.animations[j].ntto          = bank.global_NTTO;
                bank.animations[j].onlyFrames    = bank.global_onlyFrames;
                bank.animations[j].channels      = bank.global_channels;
                bank.animations[j].numOfNTTO     = bank.global_numOfNTTO;
                bank.animations[j].framesKFIndex = bank.global_framesKFIndex;
                bank.animations[j].keyframes     = bank.global_keyframes;
                bank.animations[j].events        = bank.global_events;
                bank.animations[j].morphData     = bank.global_morphData;
                bank.animations[j].deformations  = bank.global_deformations;
            }

            return(bank);
        }
예제 #7
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);
                    }
                }
            }
        }
    }
예제 #8
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;
        }
    }
예제 #9
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);
           *        }
           *    }
           * }
           * }*/
    }
예제 #10
0
    void InitAnimation(AnimA3DGeneral a3d)
    {
        if (a3d != this.a3d)
        {
            loaded = false;
            // Destroy currently loaded subobjects
            if (subObjects != null)
            {
                for (int i = 0; i < subObjects.Length; i++)
                {
                    if (subObjects[i] == null)
                    {
                        continue;
                    }
                    for (int j = 0; j < subObjects[i].Length; j++)
                    {
                        if (subObjects[i][j] != null)
                        {
                            subObjects[i][j].Destroy();
                        }
                    }
                }
                subObjects = null;
            }
            if (channelObjects != null)
            {
                for (int i = 0; i < channelObjects.Length; i++)
                {
                    if (channelObjects[i] != null)
                    {
                        Destroy(channelObjects[i]);
                    }
                }
                channelObjects = null;
            }
            channelIDDictionary.Clear();
            // Init animation
            this.a3d     = a3d;
            currentFrame = 0;
            if (a3d != null)
            {
                // Init channels & subobjects
                subObjects     = new PhysicalObject[a3d.num_channels][];
                channelObjects = new GameObject[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.Gao.transform);
                    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];
                        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(null);
                            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.physical_objects != null && perso.physical_objects.Length > ntto.object_index)
                            {
                                PhysicalObject o = perso.physical_objects[ntto.object_index];
                                if (o != null)
                                {
                                    PhysicalObject c = o.Clone();
                                    subObjects[i][j]       = c;
                                    c.Gao.transform.parent = channelObjects[i].transform;
                                    c.Gao.name             = "[" + j + "] " + c.Gao.name;
                                    c.Gao.SetActive(false);
                                }
                            }
                        }
                    }
                }
            }
            loaded = true;
        }
    }
예제 #11
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);
        }
예제 #12
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");
                            }
                        }
                    }
                }
            }
        }