public void GetCurrentSnapShot()
 {
     if (lastFrameStatus == null)
     {
         lastFrameStatus = new BoneStatus();
         lastFrameStatus.Init();
         for (int i = 0; i < bo.Count; i++)
         {
             lastFrameStatus.BoneQuat.Add(new MyQuaternion());
             if (i == 0)
             {
                 lastFrameStatus.BonePos = new MyVector();
             }
         }
         for (int i = 0; i < dummy.Count; i++)
         {
             lastFrameStatus.DummyQuat.Add(new MyQuaternion());
             lastFrameStatus.DummyPos.Add(new MyVector());
         }
     }
     for (int i = 0; i < bo.Count; i++)
     {
         lastFrameStatus.BoneQuat[i] = bo[i].localRotation;
         if (i == 0)
         {
             lastFrameStatus.BonePos = bo[i].localPosition;
         }
     }
     for (int i = 0; i < dummy.Count; i++)
     {
         lastFrameStatus.DummyQuat[i] = dummy[i].localRotation;
         lastFrameStatus.DummyPos[i]  = dummy[i].localPosition;
     }
 }
Example #2
0
 public static void HermiteInterpolatePose(BoneStatus prev, BoneStatus next, ref BoneStatus calcOut, float percent)
 {
     if (prev == null && next != null)
     {
         next.Clone(ref calcOut);
         return;
     }
     else if (prev != null && next == null)
     {
         prev.Clone(ref calcOut);
         return;
     }
     calcOut.BonePos = Vector3.Lerp(prev.BonePos, next.BonePos, percent);
     for (int i = 0; i < calcOut.DummyQuat.Count; i++)
     {
         calcOut.DummyQuat[i] = Quaternion.Slerp(prev.DummyQuat[i], next.DummyQuat[i], percent);
     }
     for (int i = 0; i < calcOut.DummyPos.Count; i++)
     {
         calcOut.DummyPos[i] = Vector3.Lerp(prev.DummyPos[i], next.DummyPos[i], percent);
     }
     for (int i = 0; i < calcOut.BoneQuat.Count; i++)
     {
         calcOut.BoneQuat[i] = Quaternion.Slerp(prev.BoneQuat[i], next.BoneQuat[i], percent);
     }
 }
Example #3
0
    public SortedDictionary <int, BoneStatus> Parse(byte[] memory)
    {
        MemoryStream ms      = new MemoryStream(memory);
        BinaryReader binRead = new BinaryReader(ms);

        //BANIM=BoneAnimation
        binRead.BaseStream.Seek(5, SeekOrigin.Begin);
        int bone   = binRead.ReadInt32();
        int dummy  = binRead.ReadInt32();
        int frames = binRead.ReadInt32();

        Pose.FPS = binRead.ReadInt32();
        Pose.FCS = 1.0f / Pose.FPS;
        //Debug.Log("Fps:" + Pose.FPS);
        SortedDictionary <int, BoneStatus> innerValue = new SortedDictionary <int, BoneStatus>();

        for (int i = 0; i < frames; i++)
        {
            BoneStatus status = new BoneStatus();
            status.Init();
            status.startflag = binRead.ReadInt32();
            if (status.startflag != -1)
            {
                Debug.LogError("frame:" + i + " startflag:" + status.startflag);
            }
            int   frameindex = binRead.ReadInt32();
            float x          = binRead.ReadSingle();
            float y          = binRead.ReadSingle();
            float z          = binRead.ReadSingle();
            status.BonePos = new Vector3(x, z, y);//首骨骼的相对坐标.
            for (int j = 0; j < bone; j++)
            {
                float      w    = binRead.ReadSingle();
                float      xx   = -binRead.ReadSingle();
                float      zz   = -binRead.ReadSingle();
                float      yy   = -binRead.ReadSingle();
                Quaternion quat = new Quaternion(xx, yy, zz, w);
                status.BoneQuat.Add(quat);
            }
            for (int k = 0; k < dummy; k++)
            {
                binRead.BaseStream.Seek(5, SeekOrigin.Current);
                float dx  = binRead.ReadSingle();
                float dy  = binRead.ReadSingle();
                float dz  = binRead.ReadSingle();
                float dw  = binRead.ReadSingle();
                float dxx = -binRead.ReadSingle();
                float dzz = -binRead.ReadSingle();
                float dyy = -binRead.ReadSingle();
                status.DummyPos.Add(new Vector3(dx, dz, dy));
                status.DummyQuat.Add(new Quaternion(dxx, dyy, dzz, dw));
            }
            innerValue.Add(frameindex, status);
        }

        //豪微秒 10^-7秒
        //Debug.Log(string.Format("{0}", (double)(System.DateTime.Now.Ticks - s1) / 10000000.0));
        return(innerValue);
    }
    public void ChangeFrame(int source, int frame)
    {
        Pause = true;
        BoneStatus status = null;

        if (source == 0)
        {
            status = AmbLoader.CharCommon[frame];
        }
        else if (source == 1)
        {
            status = AmbLoader.PlayerAnimation[owner.UnitId][frame];
        }
        else
        {
            status = AmbLoader.GetBoneStatus(po.SourceIdx, owner.UnitId, frame);
        }
        for (int i = 0; i < bo.Count; i++)
        {
            bo[i].localRotation = status.BoneQuat[i];
            if (i == 0)
            {
                bo[i].localPosition = status.BonePos;
            }
        }
        for (int i = 0; i < dummy.Count; i++)
        {
            //if (i == 0)
            //{
            //Debug.LogError("action move");
            //if (lastPosIdx == po.Idx && !inlooping)
            //{
            //    Vector3 targetPos = status.DummyPos[i];
            //    Vector3 vec = Target.rotation * (targetPos - lastDBasePos) * moveScale;
            //    //如果忽略位移,或者在动作的循环帧中,即第一次从循环头开始播放后,不再计算位移.
            //    moveDelta += vec;
            //    //if (po.Idx == 151)
            //    //    Debug.LogError(string.Format("pose:{0} frame:{1} move: x ={2}, y ={3} z = {4}", po.Idx, curIndex, moveDelta.x, moveDelta.y, moveDelta.z));
            //    lastDBasePos = targetPos;
            //}
            // }
            // else
            {
                dummy[i].localRotation = status.DummyQuat[i];
                dummy[i].localPosition = status.DummyPos[i];
            }
        }
    }
Example #5
0
 public void Clone(ref BoneStatus clone)
 {
     clone.BonePos = BonePos;
     for (int i = 0; i < DummyPos.Count; i++)
     {
         clone.DummyPos[i] = DummyPos[i];
     }
     for (int i = 0; i < BoneQuat.Count; i++)
     {
         clone.BoneQuat[i] = BoneQuat[i];
     }
     for (int i = 0; i < DummyQuat.Count; i++)
     {
         clone.DummyQuat[i] = DummyQuat[i];
     }
 }
    public void ChangeFrame(int source, int frame)
    {
        Pause = true;
        BoneStatus status = null;

        if (source == 0)
        {
            status = AmbLoader.CharCommon[frame];
        }
        else if (source == 1)
        {
            status = AmbLoader.FrameBoneAni[CharacterIdx][frame];
        }

        for (int i = 0; i < bo.Count; i++)
        {
            bo[i].localRotation = status.BoneQuat[i];
            if (i == 0)
            {
                bo[i].localPosition = status.BonePos;
            }
        }
        for (int i = 0; i < dummy.Count; i++)
        {
            if (i == 0)
            {
                if (lastPosIdx == po.Idx)
                {
                    Vector3 targetPos = status.DummyPos[i];
                    Vector3 moveDelta = transform.rotation * (targetPos - vTmp);
                    mOwner.Move(moveDelta);
                    vTmp = targetPos;
                }
            }
            else
            {
                dummy[i].localRotation = status.DummyQuat[i];
                dummy[i].localPosition = status.DummyPos[i];
            }
        }

        if (mOwner.Attr.IsPlayer && FightWnd.Exist)
        {
            FightWnd.Instance.UpdatePoseStatus(-1, frame);
        }
    }
Example #7
0
 public void Add(BoneStatus other)
 {
     BonePos.x += other.BonePos.x;
     BonePos.y += other.BonePos.y;
     BonePos.z += other.BonePos.z;
     for (int i = 0; i < DummyPos.Count; i++)
     {
         DummyPos[i] = other.DummyPos[i] + DummyPos[i];
     }
     for (int i = 0; i < BoneQuat.Count; i++)
     {
         BoneQuat[i] = other.BoneQuat[i] + BoneQuat[i];
     }
     for (int i = 0; i < DummyQuat.Count; i++)
     {
         DummyQuat[i] = other.DummyQuat[i] + DummyQuat[i];
     }
 }
Example #8
0
    public BoneStatus Scale(float scale)
    {
        BoneStatus clone = new BoneStatus();

        clone.InitWith(BoneQuat.Count, DummyQuat.Count);
        clone.BonePos.x = BonePos.x * scale;
        clone.BonePos.y = BonePos.y * scale;
        clone.BonePos.z = BonePos.z * scale;
        for (int i = 0; i < DummyPos.Count; i++)
        {
            clone.DummyPos[i] = DummyPos[i].Scale(scale);
        }
        for (int i = 0; i < BoneQuat.Count; i++)
        {
            clone.BoneQuat[i] = BoneQuat[i].Scale(scale);
        }
        for (int i = 0; i < DummyQuat.Count; i++)
        {
            clone.DummyQuat[i] = DummyQuat[i].Scale(scale);
        }
        return(clone);
    }
    public void CharacterUpdate()
    {
        if (Pause)
        {
            return;
        }
        if (po != null)
        {
            moveDelta = Vector3.zero;
            if (CheckStraight)
            {
                PoseStraight -= Time.deltaTime;
                //检查僵直是否过期.
                if (PoseStraight < 0.0f && loop)
                {
                    loop          = false;
                    curIndex      = po.LoopEnd;
                    CheckStraight = false;
                }
            }
            if (blendTime == 0.0f)
            {
                lastFramePlayedTimes += Time.deltaTime;

                float speedScale = GetSpeedScale();
                float fps        = FPS / (Speed * speedScale);
                if (lastFramePlayedTimes < fps)
                {
                }
                else
                {
                    while (lastFramePlayedTimes >= fps)
                    {
                        PlayNextFrame(fps);
                        lastFramePlayedTimes -= fps;
                        speedScale            = GetSpeedScale();
                        fps = FPS / (Speed * speedScale);
                    }
                }
            }
            else
            {
                playedTime += Time.deltaTime;
                //TryPlayEffect();
                ChangeWeaponTrail();

                BoneStatus status = null;
                if (po.SourceIdx == 0)
                {
                    status = AmbLoader.CharCommon[blendStart];
                }
                else if (po.SourceIdx == 1)
                {
                    status = AmbLoader.FrameBoneAni[CharacterIdx][blendStart];
                }

                if (playedTime < blendTime && blendTime != 0.0f && lastFrameStatus != null)
                {
                    for (int i = 0; i < bo.Count; i++)
                    {
                        bo[i].localRotation = Quaternion.Slerp(lastFrameStatus.BoneQuat[i], status.BoneQuat[i], playedTime / blendTime);
                        if (i == 0)
                        {
                            bo[i].localPosition = Vector3.Lerp(lastFrameStatus.BonePos, status.BonePos, playedTime / blendTime);
                        }
                    }
                    for (int i = 0; i < dummy.Count; i++)
                    {
                        if (i == 0)
                        {
                            //混合动作,不许移动角色
                            //if (lastPosIdx == po.Idx)
                            //{
                            //    Vector3 targetPos = Vector3.Lerp(lastFrameStatus.DummyPos[i], status.DummyPos[i], playedTime / blendTime);
                            //    Vector3 vec = transform.rotation * (targetPos - lastDBasePos) * moveScale;
                            //    if (IgnoreActionMove(po.Idx))
                            //    {
                            //        vec.x = 0;
                            //        vec.z = 0;
                            //        vec.y = 0;
                            //    }
                            //    else
                            //    {
                            //    }
                            //    moveDelta += vec;
                            //    lastDBasePos = targetPos;
                            //}
                        }
                        else
                        {
                            dummy[i].localRotation = Quaternion.Slerp(lastFrameStatus.DummyQuat[i], status.DummyQuat[i], playedTime / blendTime);
                            dummy[i].localPosition = Vector3.Lerp(lastFrameStatus.DummyPos[i], status.DummyPos[i], playedTime / blendTime);
                        }
                    }
                }
                else
                {
                    blendTime            = 0.0f;
                    curIndex             = lastFrameIndex = blendStart;
                    playedTime           = 0;
                    lastFramePlayedTimes = 0;
                    lastSource           = po.SourceIdx;
                }
            }
        }
    }
    public void AnimationUpdate(float timeRatio)
    {
        float speedScale = GetSpeedScale();

        TryPlayEffect();
        ChangeAttack();
        ChangeWeaponTrail();
        if (TestInputLink())
        {
            return;
        }
        //超过末尾了.
        if (loop)
        {
            if (curIndex >= po.LoopEnd)
            {
                if (curIndex >= po.LoopStart && po.LoopStart == po.LoopEnd)
                {
                    PlayPosEvent();
                    curIndex = po.LoopStart;
                    if (loop)
                    {
                        return;
                    }
                }
                curIndex = po.LoopStart;
            }
        }
        //else
        //{
        //    if (curIndex >= po.End)
        //    {
        //        if (single)
        //            Pause = true;
        //        else
        //            posMng.OnActionFinished();
        //        return;
        //    }
        //if (TheFirstFrame == curIndex)
        //    ActionEvent.HandlerFirstActionFrame(mOwner, po.Idx);
        //if (TheLastFrame == curIndex)
        //    ActionEvent.HandlerFinalActionFrame(mOwner, po.Idx);
        //}

        //curIndex = targetIndex;
        BoneStatus status     = null;
        BoneStatus lastStatus = null;

        if (lastSource == 0)
        {
            lastStatus = AmbLoader.CharCommon[lastFrameIndex];
        }
        else
        {
            lastStatus = AmbLoader.FrameBoneAni[CharacterIdx][lastFrameIndex];
        }
        if (po.SourceIdx == 0)
        {
            status = AmbLoader.CharCommon[curIndex];
        }
        else if (po.SourceIdx == 1)
        {
            status = AmbLoader.FrameBoneAni[CharacterIdx][curIndex];
        }

        if (mOwner.Attr.IsPlayer && FightWnd.Exist)
        {
            FightWnd.Instance.UpdatePoseStatus(po.Idx, lastFrameIndex);
        }

        for (int i = 0; i < bo.Count; i++)
        {
            if (bo[i] == owner.HeadBone && GameBattleEx.Instance.autoTarget != null && owner.Attr.IsPlayer)
            {
            }
            else
            {
                bo[i].localRotation = Quaternion.Slerp(lastStatus.BoneQuat[i], status.BoneQuat[i], timeRatio);
            }

            if (i == 0)
            {
                bo[i].localPosition = Vector3.Lerp(lastStatus.BonePos, status.BonePos, timeRatio);
            }
        }

        for (int i = 0; i < dummy.Count; i++)
        {
            if (i == 0)
            {
                if (lastPosIdx == po.Idx)
                {
                    Vector3 targetPos = Vector3.Lerp(lastStatus.DummyPos[i], status.DummyPos[i], timeRatio);
                    Vector3 vec       = transform.rotation * (targetPos - lastDBasePos) * moveScale;
                    if (IgnoreActionMove(po.Idx))
                    {
                        vec.x = 0;
                        vec.z = 0;
                        vec.y = 0;
                    }
                    else
                    {
                    }
                    moveDelta   += vec;
                    lastDBasePos = targetPos;
                }
            }
            else
            {
                dummy[i].localRotation = Quaternion.Slerp(lastStatus.DummyQuat[i], status.DummyQuat[i], timeRatio);
                dummy[i].localPosition = Vector3.Lerp(lastStatus.DummyPos[i], status.DummyPos[i], timeRatio);
            }
        }

        //lastFrameIndex = curIndex;
        //lastSource = po.SourceIdx;
        //lastPosIdx = po.Idx;
    }
    //人物自身动作,0帧为TPose
    //招式通用动作,从1帧开始,没有0帧
    public Dictionary <int, BoneStatus> LoadAmb(string file)
    {
        long      s1    = System.DateTime.Now.Ticks;
        TextAsset asset = Resources.Load <TextAsset>(file);

        if (asset == null)
        {
            Debug.LogError("amb file:" + file + " can not found");
            return(null);
        }
        MemoryStream ms      = new MemoryStream(asset.bytes);
        BinaryReader binRead = new BinaryReader(ms);

        binRead.BaseStream.Seek(5, SeekOrigin.Begin);
        int bone    = binRead.ReadInt32();
        int dummy   = binRead.ReadInt32();
        int frames  = binRead.ReadInt32();
        int unknown = binRead.ReadInt32();
        Dictionary <int, BoneStatus> innerValue = new Dictionary <int, BoneStatus>();

        for (int i = 1; i <= frames; i++)
        {
            BoneStatus status = new BoneStatus();
            status.Init();
            status.startflag = binRead.ReadInt32();
            if (status.startflag != -1)
            {
                Debug.LogError("frame:" + i + " startflag:" + status.startflag);
            }
            int   frameindex = binRead.ReadInt32();
            float x          = binRead.ReadSingle();
            float y          = binRead.ReadSingle();
            float z          = binRead.ReadSingle();
            status.BonePos = new Vector3(x, z, y);//首骨骼的相对坐标.
            for (int j = 0; j < bone; j++)
            {
                float      w    = binRead.ReadSingle();
                float      xx   = -binRead.ReadSingle();
                float      zz   = -binRead.ReadSingle();
                float      yy   = -binRead.ReadSingle();
                Quaternion quat = new Quaternion(xx, yy, zz, w);
                status.BoneQuat.Add(quat);
            }
            for (int k = 0; k < dummy; k++)
            {
                binRead.BaseStream.Seek(5, SeekOrigin.Current);
                float dx  = binRead.ReadSingle();
                float dy  = binRead.ReadSingle();
                float dz  = binRead.ReadSingle();
                float dw  = binRead.ReadSingle();
                float dxx = -binRead.ReadSingle();
                float dzz = -binRead.ReadSingle();
                float dyy = -binRead.ReadSingle();
                status.DummyPos.Add(new Vector3(dx, dz, dy));
                status.DummyQuat.Add(new Quaternion(dxx, dyy, dzz, dw));
            }

            innerValue.Add(frameindex, status);
        }

        //豪微秒 10^-7秒
        //Debug.Log(string.Format("{0}", (double)(System.DateTime.Now.Ticks - s1) / 10000000.0));
        return(innerValue);
    }
    public void NetUpdate()
    {
        if (Pause)
        {
            return;
        }
        if (po != null)
        {
            moveDelta = Vector3.zero;
            if (blendTime == 0.0f)
            {
                //过渡时间不算硬直,非过渡时间,算在硬直内.
                if (PoseStraight > 0.0f)
                {
                    PoseStraight -= FrameReplay.deltaTime;
                }
                lastFramePlayedTimes += FrameReplay.deltaTime;
                float speedScale = owner.ActionSpeed * GetSpeedScale();
                float fps        = Main.Ins.CombatData.FPS / speedScale;
                while (lastFramePlayedTimes >= fps)
                {
                    PlayNextKeyFrame();
                    lastFramePlayedTimes -= fps;
                    speedScale            = GetSpeedScale();
                    fps = Main.Ins.CombatData.FPS / speedScale;
                }

                if (lastFramePlayedTimes < fps && lastFramePlayedTimes > 0)
                {
                    PlayFrame(lastFramePlayedTimes / fps);
                }
            }
            else
            {
                playedTime += FrameReplay.deltaTime;
                ChangeWeaponTrail();

                BoneStatus status = null;
                if (po.SourceIdx == 0 && AmbLoader.CharCommon.Count > blendStart && blendStart >= 0)
                {
                    status = AmbLoader.CharCommon[blendStart];
                }
                else if (po.SourceIdx == 1 && AmbLoader.PlayerAnimation.ContainsKey(mOwner.UnitId) && AmbLoader.PlayerAnimation[mOwner.UnitId].Count > blendStart && blendStart >= 0)
                {
                    status = AmbLoader.PlayerAnimation[mOwner.UnitId][blendStart];
                }
                else
                {
                    status = AmbLoader.GetBoneStatus(po.SourceIdx, owner.UnitId, blendStart);
                }
                if (playedTime < blendTime && blendTime != 0.0f && lastFrameStatus != null && status != null)
                {
                    bo[0].localRotation = Quaternion.Slerp(lastFrameStatus.BoneQuat[0], status.BoneQuat[0], playedTime / blendTime);
                    bo[0].localPosition = Vector3.Lerp(lastFrameStatus.BonePos, status.BonePos, playedTime / blendTime);
                    for (int i = 1; i < bo.Count; i++)
                    {
                        bo[i].localRotation = Quaternion.Slerp(lastFrameStatus.BoneQuat[i], status.BoneQuat[i], playedTime / blendTime);
                    }
                    lastDBasePos = status.DummyPos[0];
                    for (int i = 1; i < dummy.Count; i++)
                    {
                        dummy[i].localRotation = Quaternion.Slerp(lastFrameStatus.DummyQuat[i], status.DummyQuat[i], playedTime / blendTime);
                        dummy[i].localPosition = Vector3.Lerp(lastFrameStatus.DummyPos[i], status.DummyPos[i], playedTime / blendTime);
                    }
                }
                else
                {
                    blendTime            = 0.0f;
                    curIndex             = lastFrameIndex = blendStart;
                    playedTime           = 0;
                    lastFramePlayedTimes = 0;
                    lastSource           = po.SourceIdx;
                }
            }
        }
    }
    public void PlayFrame(float timeRatio)
    {
        TryPlayEffect();
        ChangeAttack();
        ChangeWeaponTrail();
        ActionEvent.HandlerActionEvent(owner, po.Idx, curIndex);
        if (PoseEvent.ContainsKey(po.Idx))
        {
            //当218发射飞轮,很快返回,还未到219动作时,下次播放219,就得立即取消循环,221 223
            PoseEvent.Remove(po.Idx);
            loop     = false;
            curIndex = po.LoopEnd;
        }
        if (TestInputLink())
        {
            return;
        }
        if (loop)
        {
            if (LockCurrentFrame)
            {
                if (PoseStraight <= 0.0f)
                {
                    loop             = false;
                    curIndex         = po.LoopEnd + 1;
                    LockCurrentFrame = false;
                    return;
                }
            }

            if (curIndex >= po.LoopEnd)
            {
                LoopCount++;
                PlayPosEvent();
                if (loop)
                {
                    curIndex = po.LoopStart;
                }
                return;
            }
        }
        else
        {
            if (curIndex > po.End)
            {
                posMng.OnActionFinished();
                return;
            }
            if (TheFirstFrame <= curIndex && TheFirstFrame != -1)
            {
                ActionEvent.HandlerFirstActionFrame(mOwner, po.Idx);
                TheFirstFrame = -1;
            }
            if (TheLastFrame <= curIndex && TheLastFrame != -1)
            {
                ActionEvent.HandlerFinalActionFrame(mOwner, po.Idx);
                TheLastFrame = -1;
            }
        }
        //Debug.Log("PlayKeyFrame:" + Time.frameCount);
        //curIndex = targetIndex;
        BoneStatus status     = null;
        BoneStatus lastStatus = null;

        if (lastSource == 0 && AmbLoader.CharCommon.Count > lastFrameIndex && lastFrameIndex >= 0)
        {
            lastStatus = AmbLoader.CharCommon[lastFrameIndex];
        }
        else if (AmbLoader.PlayerAnimation.ContainsKey(owner.UnitId) && AmbLoader.PlayerAnimation[owner.UnitId].Count > lastFrameIndex && lastFrameIndex >= 0)
        {
            lastStatus = AmbLoader.PlayerAnimation[owner.UnitId][lastFrameIndex];
        }
        if (po.SourceIdx == 0)
        {
            status = AmbLoader.CharCommon[curIndex];
        }
        else if (po.SourceIdx == 1)
        {
            status = AmbLoader.PlayerAnimation[owner.UnitId][curIndex];
        }
        else
        {
            status = AmbLoader.GetBoneStatus(po.SourceIdx, owner.UnitId, curIndex);
        }

        if (status != null && lastStatus != null)
        {
            bo[0].localRotation = Quaternion.Slerp(lastStatus.BoneQuat[0], status.BoneQuat[0], timeRatio);
            bo[0].localPosition = Vector3.Lerp(lastStatus.BonePos, status.BonePos, timeRatio);
            for (int i = 1; i < bo.Count; i++)
            {
                bo[i].localRotation = Quaternion.Slerp(lastStatus.BoneQuat[i], status.BoneQuat[i], timeRatio);
            }
        }

        bool IgnoreActionMoves = PoseStatus.IgnoreActionMove(po.Idx);

        if (owner.IsDebugUnit())
        {
            if (OnAnimationFrame != null)
            {
                OnAnimationFrame(po.SourceIdx, po.Idx, curIndex, timeRatio);
            }
            //IgnoreActionMoves = false;
        }

        bool IgnoreActionXZMove = PoseStatus.IgnoreXZMove(po.Idx);

        if (lastStatus != null && status != null)
        {
            if (lastPosIdx == po.Idx)
            {
                Vector3 targetPos = Vector3.Lerp(lastStatus.DummyPos[0], status.DummyPos[0], timeRatio);
                Vector3 vec       = Target.rotation * (targetPos - lastDBasePos) * moveScale;
                if (IgnoreActionMoves)
                {
                    vec.x = 0;
                    vec.z = 0;
                    vec.y = 0;
                }
                else if (IgnoreActionXZMove)
                {
                    vec.x = vec.z = 0;
                }
                moveDelta   += vec;
                lastDBasePos = targetPos;
            }

            for (int i = 1; i < dummy.Count; i++)
            {
                dummy[i].localRotation = Quaternion.Slerp(lastStatus.DummyQuat[i], status.DummyQuat[i], timeRatio);
                dummy[i].localPosition = Vector3.Lerp(lastStatus.DummyPos[i], status.DummyPos[i], timeRatio);
            }
        }
    }
    void PlayNextKeyFrame()
    {
        TryPlayEffect();
        ChangeAttack();
        ChangeWeaponTrail();
        ActionEvent.HandlerActionEvent(owner, po.Idx, curIndex);
        if (PoseEvent.ContainsKey(po.Idx))
        {
            //当218发射飞轮,很快返回,还未到219动作时,下次播放219,就得立即取消循环,221 223
            PoseEvent.Remove(po.Idx);
            loop     = false;
            curIndex = po.LoopEnd;
        }

        //有连招.
        if (TestInputLink())
        {
            return;
        }

        if (loop)
        {
            if (LockCurrentFrame)
            {
                if (PoseStraight <= 0.0f)
                {
                    loop             = false;
                    curIndex         = po.LoopEnd + 1;
                    LockCurrentFrame = false;
                    return;
                }
            }
            if (curIndex > po.LoopEnd)
            {
                if (curIndex > po.LoopStart)
                {
                    LoopCount++;
                    PlayPosEvent();
                    if (loop)
                    {
                        curIndex = po.LoopStart;
                    }
                    return;
                }
                curIndex = po.LoopStart;
            }
        }
        else
        {
            if (curIndex > po.End)
            {
                posMng.OnActionFinished();
                return;
            }

            if (TheFirstFrame <= curIndex && TheFirstFrame != -1)
            {
                ActionEvent.HandlerFirstActionFrame(mOwner, po.Idx);
                TheFirstFrame = -1;
            }
            if (TheLastFrame <= curIndex && TheLastFrame != -1)
            {
                ActionEvent.HandlerFinalActionFrame(mOwner, po.Idx);
                TheLastFrame = -1;
            }
        }
        //Debug.Log("PlayKeyFrame:" + Time.frameCount);
        BoneStatus status = null;

        if (po.SourceIdx == 0)
        {
            status = AmbLoader.CharCommon[curIndex];
        }
        else if (po.SourceIdx == 1)
        {
            status = AmbLoader.PlayerAnimation[owner.UnitId][curIndex];
        }
        else
        {
            status = AmbLoader.GetBoneStatus(po.SourceIdx, owner.UnitId, curIndex);
        }

        //Debug.LogError("play keyframe " + " idx:" + curIndex);
        if (bo.Count != 0)
        {
            bo[0].localRotation = status.BoneQuat[0];
            bo[0].localPosition = status.BonePos;
        }

        for (int i = 1; i < bo.Count; i++)
        {
            bo[i].localRotation = status.BoneQuat[i];
        }

        bool IgnoreActionMoves = PoseStatus.IgnoreActionMove(po.Idx);
        //if (owner.IsDebugUnit())
        //    IgnoreActionMoves = false;
        bool IgnoreActionXZMove = PoseStatus.IgnoreXZMove(po.Idx);

        if (lastPosIdx == po.Idx)
        {
            Vector3 targetPos = status.DummyPos[0];
            Vector3 vec       = Target.rotation * (targetPos - lastDBasePos) * moveScale;
            //如果忽略位移,或者在动作的循环帧中,即第一次从循环头开始播放后,不再计算位移.
            if (IgnoreActionMoves)
            {
                vec.x = 0;
                vec.z = 0;
                vec.y = 0;
            }
            else if (IgnoreActionXZMove)
            {
                vec.x = vec.z = 0;
            }
            moveDelta += vec;
            //if (po.Idx == 151)
            //    Debug.LogError(string.Format("pose:{0} frame:{1} move: x ={2}, y ={3} z = {4}", po.Idx, curIndex, moveDelta.x, moveDelta.y, moveDelta.z));
            lastDBasePos = targetPos;
        }

        for (int i = 1; i < dummy.Count; i++)
        {
            dummy[i].localRotation = status.DummyQuat[i];
            dummy[i].localPosition = status.DummyPos[i];
        }

        lastFrameIndex = curIndex;
        curIndex++;
        lastSource = po.SourceIdx;
        lastPosIdx = po.Idx;
    }
Example #15
0
    //把骨骼的Pose帧信息烘培到曲线上.
    public void BakeIntoCurve(int unitId, Pose source, AnimationCurve curve, int boneIndex, BakeInto bakeopt, bool keyFrameReduction = true, float epsilon = 0.00001f)
    {
        BoneStatus prevFrame = null;
        BoneStatus nextFrame = null;
        float      time      = 0.0f;
        float      value     = 0.0f;

        for (int i = source.Start; i <= source.End; i++)
        {
            nextFrame = GetBoneStatus(source.SourceIdx, unitId, i);
            if (prevFrame != null)
            {
                //根据烘培选项,决定如果误差小于某个值,就丢弃掉这个关键帧
                switch (bakeopt)
                {
                case BakeInto.BakeLocalDummyPosX:
                    if (Utility.CompareApproximately(prevFrame.DummyPos[boneIndex].x, nextFrame.DummyPos[boneIndex].x, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.DummyPos[boneIndex].x;
                    }
                    break;

                case BakeInto.BakeLocalDummyPosY:
                    if (Utility.CompareApproximately(prevFrame.DummyPos[boneIndex].y, nextFrame.DummyPos[boneIndex].y, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.DummyPos[boneIndex].y;
                    }
                    break;

                case BakeInto.BakeLocalDummyPosZ:
                    if (Utility.CompareApproximately(prevFrame.DummyPos[boneIndex].z, nextFrame.DummyPos[boneIndex].z, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.DummyPos[boneIndex].z;
                    }
                    break;

                case BakeInto.BakeLocalDummyRotationX:
                    if (Utility.CompareApproximately(prevFrame.DummyQuat[boneIndex].x, nextFrame.DummyQuat[boneIndex].x, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.DummyQuat[boneIndex].x;
                    }
                    break;

                case BakeInto.BakeLocalDummyRotationY:
                    if (Utility.CompareApproximately(prevFrame.DummyQuat[boneIndex].y, nextFrame.DummyQuat[boneIndex].y, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.DummyQuat[boneIndex].y;
                    }
                    break;

                case BakeInto.BakeLocalDummyRotationZ:
                    if (Utility.CompareApproximately(prevFrame.DummyQuat[boneIndex].z, nextFrame.DummyQuat[boneIndex].z, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.DummyQuat[boneIndex].z;
                    }
                    break;

                case BakeInto.BakeLocalDummyRotationW:
                    if (Utility.CompareApproximately(prevFrame.DummyQuat[boneIndex].w, nextFrame.DummyQuat[boneIndex].w, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.DummyQuat[boneIndex].w;
                    }
                    break;

                case BakeInto.BakeLocalPosX:
                    if (Utility.CompareApproximately(prevFrame.BonePos.x, nextFrame.BonePos.x, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.BonePos.x;
                    }
                    break;

                case BakeInto.BakeLocalPosY:
                    if (Utility.CompareApproximately(prevFrame.BonePos.y, nextFrame.BonePos.y, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.BonePos.y;
                    }
                    break;

                case BakeInto.BakeLocalPosZ:
                    if (Utility.CompareApproximately(prevFrame.BonePos.z, nextFrame.BonePos.z, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.BonePos.z;
                    }
                    break;

                case BakeInto.BakeLocalRotationX:
                    if (Utility.CompareApproximately(prevFrame.BoneQuat[boneIndex].x, nextFrame.BoneQuat[boneIndex].x, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.BoneQuat[boneIndex].x;
                    }
                    break;

                case BakeInto.BakeLocalRotationY:
                    if (Utility.CompareApproximately(prevFrame.BoneQuat[boneIndex].y, nextFrame.BoneQuat[boneIndex].y, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.BoneQuat[boneIndex].y;
                    }
                    break;

                case BakeInto.BakeLocalRotationZ:
                    if (Utility.CompareApproximately(prevFrame.BoneQuat[boneIndex].z, nextFrame.BoneQuat[boneIndex].z, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.BoneQuat[boneIndex].z;
                    }
                    break;

                case BakeInto.BakeLocalRotationW:
                    if (Utility.CompareApproximately(prevFrame.BoneQuat[boneIndex].w, nextFrame.BoneQuat[boneIndex].w, epsilon))
                    {
                        nextFrame = null;
                    }
                    else
                    {
                        value = nextFrame.BoneQuat[boneIndex].w;
                    }
                    break;
                }
            }
            else
            {
                //根据烘培选项,决定如果误差小于某个值,就丢弃掉这个关键帧
                switch (bakeopt)
                {
                case BakeInto.BakeLocalDummyPosX:
                    value = nextFrame.DummyPos[boneIndex].x;
                    break;

                case BakeInto.BakeLocalDummyPosY:
                    value = nextFrame.DummyPos[boneIndex].y;
                    break;

                case BakeInto.BakeLocalDummyPosZ:
                    value = nextFrame.DummyPos[boneIndex].z;
                    break;

                case BakeInto.BakeLocalDummyRotationX:
                    value = nextFrame.DummyQuat[boneIndex].x;
                    break;

                case BakeInto.BakeLocalDummyRotationY:
                    value = nextFrame.DummyQuat[boneIndex].y;
                    break;

                case BakeInto.BakeLocalDummyRotationZ:
                    value = nextFrame.DummyQuat[boneIndex].z;
                    break;

                case BakeInto.BakeLocalDummyRotationW:
                    value = nextFrame.DummyQuat[boneIndex].w;
                    break;

                case BakeInto.BakeLocalPosX:
                    value = nextFrame.BonePos.x;
                    break;

                case BakeInto.BakeLocalPosY:
                    value = nextFrame.BonePos.y;
                    break;

                case BakeInto.BakeLocalPosZ:
                    value = nextFrame.BonePos.z;
                    break;

                case BakeInto.BakeLocalRotationX:
                    value = nextFrame.BoneQuat[boneIndex].x;
                    break;

                case BakeInto.BakeLocalRotationY:
                    value = nextFrame.BoneQuat[boneIndex].y;
                    break;

                case BakeInto.BakeLocalRotationZ:
                    value = nextFrame.BoneQuat[boneIndex].z;
                    break;

                case BakeInto.BakeLocalRotationW:
                    value = nextFrame.BoneQuat[boneIndex].w;
                    break;
                }
            }

            //存在关键帧,记录关键帧的信息
            if (nextFrame != null)
            {
                curve.AddKey(time, value);
                prevFrame = keyFrameReduction ? nextFrame:null;
            }
            time += (1.0f / Pose.FPS);
        }

        if (curve.keys.Count() == 1)
        {
            curve.AddKey(time, value);
        }
    }
    void PlayNextFrame(float delta)
    {
        TryPlayEffect();
        ChangeAttack();
        ChangeWeaponTrail();

        if (PoseEvent.ContainsKey(po.Idx))
        {
            //当218发射飞轮,很快返回,还未到219动作时,下次播放219,就得立即取消循环,221 223
            if ((PoseEvent[po.Idx] & (int)PoseEvt.WeaponIsReturned) != 0)
            {
                PoseEvent[po.Idx] &= ~(int)PoseEvt.WeaponIsReturned;
                loop     = false;
                curIndex = po.LoopEnd;
            }
        }

        //有连招.
        if (TestInputLink())
        {
            return;
        }
        if (loop)
        {
            if (curIndex > po.LoopEnd)
            {
                if (curIndex > po.LoopStart)
                {
                    PlayPosEvent();
                    curIndex = po.LoopStart;
                    if (loop)
                    {
                        return;
                    }
                }
                curIndex = po.LoopStart;
            }
        }
        else
        {
            if (curIndex > po.End)
            {
                if (single)
                {
                    Pause = true;
                }
                else
                {
                    posMng.OnActionFinished();
                }
                return;
            }

            if (TheFirstFrame == curIndex)
            {
                ActionEvent.HandlerFirstActionFrame(mOwner, po.Idx);
            }
            if (TheLastFrame == curIndex)
            {
                ActionEvent.HandlerFinalActionFrame(mOwner, po.Idx);
            }
        }

        BoneStatus status = null;

        if (po.SourceIdx == 0)
        {
            status = AmbLoader.CharCommon[curIndex];
        }
        else if (po.SourceIdx == 1)
        {
            status = AmbLoader.FrameBoneAni[CharacterIdx][curIndex];
        }

        if (mOwner.Attr.IsPlayer && FightWnd.Exist)
        {
            FightWnd.Instance.UpdatePoseStatus(po.Idx, curIndex);
        }

        for (int i = 0; i < bo.Count; i++)
        {
            bo[i].localRotation = status.BoneQuat[i];
            if (i == 0)
            {
                bo[i].localPosition = status.BonePos;
            }
        }

        bool IgnoreActionMoves = IgnoreActionMove(po.Idx);

        for (int i = 0; i < dummy.Count; i++)
        {
            if (i == 0)
            {
                if (lastPosIdx == po.Idx)
                {
                    Vector3 targetPos = status.DummyPos[i];
                    Vector3 vec       = transform.rotation * (targetPos - lastDBasePos) * moveScale;
                    if (IgnoreActionMoves)
                    {
                        vec.x = 0;
                        vec.z = 0;
                        vec.y = 0;
                    }
                    else
                    {
                    }
                    moveDelta   += vec;
                    lastDBasePos = targetPos;
                }
            }
            else
            {
                dummy[i].localRotation = status.DummyQuat[i];
                dummy[i].localPosition = status.DummyPos[i];
            }
        }

        lastFrameIndex = curIndex;
        curIndex++;
        lastSource = po.SourceIdx;
        lastPosIdx = po.Idx;
    }
Example #17
0
    //Quaternion lastDBaseQuat = Quaternion.identity;
    //一种是用来动作融合的,指定时间内,从当前POS,转化到目标POS的第一帧
    //一种是用帧融合的,表明2个关键帧之间有多少普通帧,这些普通帧都插值

    //POSE切换时,不插值位移,只插值 旋转等
    //pose关键帧切换时,每个POSE第一帧作为TPOSE,如果后面的帧相对当前TPOSE有移动,旋转,那么计算每2个插值帧之间的差距
    //用这个差距来调用charController.Move
    //特效时间不是太准,需要考虑如何让特效和动作同步.
    void Update()
    {
        if (Pause)
        {
            return;
        }
        if (po != null)
        {
            float speedScale = 1.0f;
            for (int i = 0; i < po.ActionList.Count; i++)
            {
                if (curIndex >= po.ActionList[i].Start && curIndex <= po.ActionList[i].End)
                {
                    speedScale = (po.ActionList[i].Speed == 0.0f ? 1.0f : po.ActionList[i].Speed);
                    break;
                }
            }

            if (lastFrameToKey >= (1.0f / speedScale * Time.timeScale))
            {
                lastFrameIndex = curIndex;
                lastSource     = po.SourceIdx;
                lastPosIdx     = po.Idx;
                int targetIndex = curIndex + 1;
                //超过末尾了.
                if (loop)
                {
                    if (targetIndex > po.LoopEnd)
                    {
                        targetIndex = po.LoopStart;
                    }
                }
                else
                {
                    if (targetIndex > po.End)
                    {
                        posMng.TickAction();//整个动作完整播放完毕了,到下一个动作的第一帧
                        return;
                    }
                }

                //播放下一个关键帧
                curIndex       = targetIndex;
                lastFrameToKey = 0;
            }
            else
            {
            }

            BoneStatus status = null;
            if (po.SourceIdx == 0)
            {
                status = AmbLoader.CharCommon[curIndex];
            }
            else if (po.SourceIdx == 1)
            {
                status = AmbLoader.FrameBoneAni[CharacterIdx][curIndex];
            }

            for (int i = 0; i < bo.Count; i++)
            {
                bo[i].localRotation = status.BoneQuat[i];
                if (i == 0)
                {
                    bo[i].localPosition = status.BonePos;
                }
            }
            for (int i = 0; i < dummy.Count; i++)
            {
                if (i == 0)
                {
                    if (lastPosIdx == po.Idx)
                    {
                        //Vector3 targetPos = status.DummyPos[i];
                        //transform.position = targetPos;
                    }
                }
                else
                {
                    dummy[i].localRotation = status.DummyQuat[i];
                    dummy[i].localPosition = status.DummyPos[i];
                }
            }
            lastFrameToKey += 1;
        }
    }