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;
            }
        }
Beispiel #2
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);
           *        }
           *    }
           * }
           * }*/
    }