예제 #1
0
    void newMoveHead(ExternalValues externalValues, TBody tbody, ref Vector3 thatHeadEulerAngle, ref Vector3 thatHeadEulerAngleG, ref Vector3 thatEyeEulerAngle, Vector3 eyeTarget_world)
    {
        TBody that = tbody;
        Maid  maid = tbody.maid;

        float paramSpeed   = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.speed", 0.05f);
        float paramLateral = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.lateral", 60.0f);
        float paramAbove   = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.above", 40.0f);
        float paramBelow   = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.below", 20.0f);
        float paramBehind  = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.behind", 170.0f);
        float paramOfsX    = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsx", 0.0f);
        float paramOfsY    = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsy", 0.0f);
        float paramOfsZ    = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsz", 0.0f);

        // モーションにしたがっている場合 (HeadToCamPer=0f) はオフセットをつけない
        paramOfsX *= that.HeadToCamPer;
        paramOfsY *= that.HeadToCamPer;
        paramOfsZ *= that.HeadToCamPer;

        Vector3    basePosition = that.trsNeck.position;
        Quaternion baseRotation = that.trsNeck.rotation;
        Vector3    target_local = Quaternion.Inverse(baseRotation) * (eyeTarget_world - basePosition);

        target_local = Quaternion.Euler(paramOfsX, 0f, paramOfsY) * target_local;
        Vector3 target_world = (baseRotation * target_local) + basePosition;

        // 顔が向くべき方向を算出
        Quaternion newHeadRotation_world = CalcNewHeadRotation(
            paramLateral,
            paramAbove,
            paramBelow,
            paramBehind,
            baseRotation,
            basePosition,
            target_world);

        newHeadRotation_world = newHeadRotation_world * Quaternion.Euler(0f, paramOfsZ, 0f);

        // TBody.HeadToCamPer を「正面向き度合い」として加味する
        newHeadRotation_world = Quaternion.Slerp(that.trsHead.rotation, newHeadRotation_world, that.HeadToCamPer);

        float s = paramSpeed;

        // 前回の回転よりも差が大きすぎる場合はリセットする
        if (externalValues.bReset)
        {
            externalValues.bReset   = false;
            externalValues.prevQuat = that.trsHead.rotation;
            s = 0f;
        }

        // モーションにしたがっている場合 (HeadToCamPer=0f) は補間しない
        s = Mathf.Lerp(1f, s, that.HeadToCamPer);

        // 実際の回転
        that.trsHead.rotation = Quaternion.Slerp(externalValues.prevQuat, newHeadRotation_world, s);
    }
예제 #2
0
    public void Callback(TBody tbody)
    {
        TBody that = tbody;

        if (that.trsHead == null)
        {
            return;
        }
        CameraMain mainCamera = GameMain.Instance.MainCamera;

        if (mainCamera == null)
        {
            return;
        }

        try
        {
            bool bParamHeadTrack = false;
            Maid maid            = tbody.maid;
            if (maid != null)
            {
                bParamHeadTrack = ExSaveData.GetBool(maid, PluginName, "HEAD_TRACK", false);
            }

            Vector3 thatHeadEulerAngle  = (Vector3)Helper.GetInstanceField(typeof(TBody), that, "HeadEulerAngle");
            Vector3 thatHeadEulerAngleG = (Vector3)Helper.GetInstanceField(typeof(TBody), that, "HeadEulerAngleG");
            Vector3 thatEyeEulerAngle   = (Vector3)Helper.GetInstanceField(typeof(TBody), that, "EyeEulerAngle");

            if (bParamHeadTrack)
            {
                ExternalValues externalValues = PluginHelper.GetOrAddComponent <ExternalValues>(tbody.gameObject);
                externalValues.tbody = tbody;
                newTbodyMoveHeadAndEyeCallback2(externalValues, tbody, ref thatHeadEulerAngle, ref thatHeadEulerAngleG, ref thatEyeEulerAngle);
            }
            else
            {
                originalTbodyMoveHeadAndEyeCallback2(tbody, ref thatHeadEulerAngle, ref thatHeadEulerAngleG, ref thatEyeEulerAngle);
            }

            Helper.SetInstanceField(typeof(TBody), that, "HeadEulerAngle", thatHeadEulerAngle);
            Helper.SetInstanceField(typeof(TBody), that, "HeadEulerAngleG", thatHeadEulerAngleG);
            Helper.SetInstanceField(typeof(TBody), that, "EyeEulerAngle", thatEyeEulerAngle);
        }
        catch (Exception ex)
        {
            Helper.ShowException(ex);
        }
    }
예제 #3
0
    // 新しい MoveHeadAndEye
    void newTbodyMoveHeadAndEyeCallback2(ExternalValues externalValues, TBody tbody, ref Vector3 thatHeadEulerAngle, ref Vector3 thatHeadEulerAngleG, ref Vector3 thatEyeEulerAngle)
    {
        TBody      that       = tbody;
        Maid       maid       = tbody.maid;
        CameraMain mainCamera = GameMain.Instance.MainCamera;

        // eyeTarget_world:視線の目標位置(ワールド座標系)
        Vector3 eyeTarget_world = updateEyeTargetPos(tbody);

        // HeadToCamPer:最終的に顔がカメラを向く度合い
        //  0 なら元の頭の向き、1 ならカメラの向き
        if (that.boHeadToCam)
        {
            that.HeadToCamPer += Time.deltaTime * that.HeadToCamFadeSpeed;
        }
        else
        {
            that.HeadToCamPer -= Time.deltaTime * that.HeadToCamFadeSpeed;
        }
        that.HeadToCamPer = Mathf.Clamp01(that.HeadToCamPer);

        that.boChkEye = false;

        newMoveHead(externalValues, tbody, ref thatHeadEulerAngle, ref thatHeadEulerAngleG, ref thatEyeEulerAngle, eyeTarget_world);

        externalValues.prevQuat = that.trsHead.rotation;

        if (that.boMAN || that.trsEyeL == null || that.trsEyeR == null)
        {
            return;
        }

        that.boChkEye = false;
        {
            float paramEyeAng = ExSaveData.GetFloat(maid, PluginName, "EYE_ANG.angle", 0f);
            paramEyeAng = Mathf.Clamp(paramEyeAng, -180f, 180f);
            float paramSpeed = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.speed", 0.05f);

            float   paramInside    = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.inside", 60f);
            float   paramOutside   = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.outside", 60f);
            float   paramAbove     = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.above", 40f);
            float   paramBelow     = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.below", 20f);
            float   paramBehind    = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.behind", 170f);
            float   paramOfsX      = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.ofsx", 0f);
            float   paramOfsY      = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.ofsy", 0f);
            Vector3 targetPosition = eyeTarget_world;

            if (!that.boEyeToCam)
            {
                // 視線を正面に戻す
                eyeTarget_world = that.trsHead.TransformPoint(Vector3.up * 1000.0f);
            }

            {
                Transform  trsEye   = that.trsEyeL;
                Quaternion defQuat  = that.quaDefEyeL * Quaternion.Euler(paramEyeAng, -paramOfsX, -paramOfsY);
                Quaternion prevQuat = externalValues.prevLeftEyeQuat;

                Transform  trsParent         = trsEye.parent;
                Quaternion newRotation_world = CalcNewEyeRotation(
                    paramOutside,
                    paramInside,
                    paramBelow,
                    paramAbove,
                    paramBehind,
                    trsParent.rotation,
                    trsEye.position,
                    eyeTarget_world
                    );
                Quaternion q = Quaternion.Inverse(trsParent.rotation) * newRotation_world;
                q                    = Quaternion.Slerp(Quaternion.identity, q, 0.2f); // 眼球モデルの中心に、眼球のトランスフォームの原点が無いため、ごまかしている
                q                    = Quaternion.Slerp(prevQuat, q, paramSpeed);
                prevQuat             = q;
                trsEye.localRotation = q * defQuat;

                externalValues.prevLeftEyeQuat = prevQuat;
            }

            {
                Transform  trsEye   = that.trsEyeR;
                Quaternion defQuat  = that.quaDefEyeR * Quaternion.Euler(-paramEyeAng, -paramOfsX, paramOfsY);
                Quaternion prevQuat = externalValues.prevRightEyeQuat;

                Transform  trsParent         = trsEye.parent;
                Quaternion newRotation_world = CalcNewEyeRotation(
                    paramOutside,
                    paramInside,
                    paramAbove,
                    paramBelow,
                    paramBehind,
                    trsParent.rotation,
                    trsEye.position,
                    eyeTarget_world
                    );
                Quaternion q = Quaternion.Inverse(trsParent.rotation) * newRotation_world;
                q                    = Quaternion.Slerp(Quaternion.identity, q, 0.2f);
                q                    = Quaternion.Slerp(prevQuat, q, paramSpeed);
                prevQuat             = q;
                trsEye.localRotation = q * defQuat;

                externalValues.prevRightEyeQuat = prevQuat;
            }
        }
    }
예제 #4
0
    void newMoveHead(ExternalValues externalValues, TBody tbody, ref Vector3 thatHeadEulerAngle, ref Vector3 thatHeadEulerAngleG, ref Vector3 thatEyeEulerAngle, Vector3 eyeTarget_world)
    {
        TBody that = tbody;
        Maid  maid = tbody.maid;

        float paramSpeed   = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.speed", 0.05f);
        float paramLateral = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.lateral", 60.0f);
        float paramAbove   = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.above", 40.0f);
        float paramBelow   = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.below", 20.0f);
        float paramBehind  = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.behind", 170.0f);
        float paramOfsX    = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsx", 0.0f);
        float paramOfsY    = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsy", 0.0f);
        float paramOfsZ    = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsz", 0.0f);

        // 正面の角度
        float      frontangle      = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.frontangle", 0f);
        Quaternion frontquaternion = Quaternion.Euler(0f, 0f, frontangle);

        // モーションにしたがっている場合 (HeadToCamPer=0f) はオフセットをつけない
        paramOfsX *= that.HeadToCamPer;
        paramOfsY *= that.HeadToCamPer;
        paramOfsZ *= that.HeadToCamPer;

        Vector3    basePosition = that.trsHead.position;
        Quaternion baseRotation = that.trsNeck.rotation * frontquaternion;
        Vector3    target_local = Quaternion.Inverse(baseRotation) * (eyeTarget_world - basePosition);

        //追従割合
        Quaternion local_angle     = Quaternion.FromToRotation(Vector3.up, target_local);
        Vector3    local_auler     = local_angle.eulerAngles;
        float      headrateup      = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.headrateup", 1f);
        float      headratedown    = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.headratedown", 1f);
        float      headratehorizon = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.headratehorizon", 1f);
        float      dx = 0;
        float      dy = 0;

        if (local_auler.x < 180f)
        {
            dx = local_auler.x * (headratehorizon - 1f);
        }
        else
        {
            dx = (local_auler.x - 360f) * (headratehorizon - 1f);
        }
        if (local_auler.z < 180f)
        {
            dy = local_auler.z * (headrateup - 1f);
        }
        else
        {
            dy = (local_auler.z - 360f) * (headratedown - 1f);
        }
        target_local = Quaternion.Euler(dx, 0f, dy) * target_local;

        target_local = Quaternion.Euler(paramOfsX, 0f, paramOfsY) * target_local;
        Vector3 target_world = (baseRotation * target_local) + basePosition;

        // 顔が向くべき方向を算出
        Quaternion newHeadRotation_world = CalcNewHeadRotation(
            paramLateral,
            paramAbove,
            paramBelow,
            paramBehind,
            baseRotation,
            basePosition,
            target_world,
            eyeTarget_world);

        newHeadRotation_world = newHeadRotation_world * Quaternion.Euler(0f, paramOfsZ, 0f);

        // TBody.HeadToCamPer を「正面向き度合い」として加味する
        newHeadRotation_world = Quaternion.Slerp(that.trsHead.rotation, newHeadRotation_world, that.HeadToCamPer);

        // 角度
        float      inclinerate               = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.inclinerate", 0f);
        Quaternion newHeadRotation_Local     = Quaternion.Inverse(baseRotation) * newHeadRotation_world;
        Vector3    newHeadRotationEulerLocal = newHeadRotation_Local.eulerAngles;

        if (newHeadRotationEulerLocal.x > 180f)
        {
            newHeadRotationEulerLocal = new Vector3(
                newHeadRotationEulerLocal.x - 360f,
                newHeadRotationEulerLocal.y,
                newHeadRotationEulerLocal.z);
        }
        newHeadRotationEulerLocal = new Vector3(
            newHeadRotationEulerLocal.x,
            newHeadRotationEulerLocal.y + (newHeadRotationEulerLocal.x * inclinerate),
            newHeadRotationEulerLocal.z);
        newHeadRotation_Local = Quaternion.Euler(newHeadRotationEulerLocal);
        newHeadRotation_world = baseRotation * newHeadRotation_Local;

        float s = paramSpeed;

        // 前回の回転よりも差が大きすぎる場合はリセットする
        if (externalValues.bReset)
        {
            externalValues.bReset   = false;
            externalValues.prevQuat = that.trsHead.rotation;
            s = 0f;
        }

        // モーションにしたがっている場合 (HeadToCamPer=0f) は補間しない
        s = Mathf.Lerp(1f, s, that.HeadToCamPer);

        // 実際の回転
        that.trsHead.rotation = Quaternion.Slerp(externalValues.prevQuat, newHeadRotation_world, s);
    }
    // 新しい MoveHeadAndEye
    void newTbodyMoveHeadAndEyeCallback2(ExternalValues externalValues, TBody tbody, ref Vector3 thatHeadEulerAngle, ref Vector3 thatHeadEulerAngleG, ref Vector3 thatEyeEulerAngle)
    {
        TBody that = tbody;
        Maid maid = tbody.maid;
        CameraMain mainCamera = GameMain.Instance.MainCamera;

        // eyeTarget_world:視線の目標位置(ワールド座標系)
        Vector3 eyeTarget_world = updateEyeTargetPos(tbody);

        // HeadToCamPer:最終的に顔がカメラを向く度合い
        //  0 なら元の頭の向き、1 ならカメラの向き
        if (that.boHeadToCam)
        {
            that.HeadToCamPer += Time.deltaTime * that.HeadToCamFadeSpeed;
        }
        else
        {
            that.HeadToCamPer -= Time.deltaTime * that.HeadToCamFadeSpeed;
        }
        that.HeadToCamPer = Mathf.Clamp01(that.HeadToCamPer);

        that.boChkEye = false;

        newMoveHead(externalValues, tbody, ref thatHeadEulerAngle, ref thatHeadEulerAngleG, ref thatEyeEulerAngle, eyeTarget_world);

        externalValues.prevQuat = that.trsHead.rotation;

        if (that.boMAN || that.trsEyeL == null || that.trsEyeR == null)
        {
            return;
        }

        that.boChkEye = false;
        if (that.boEyeToCam)
        {
            float paramEyeAng = ExSaveData.GetFloat(maid, PluginName, "EYE_ANG.angle", 0f);
            paramEyeAng = Mathf.Clamp(paramEyeAng, -180f, 180f);
            float paramSpeed = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.speed", 0.05f);

            float paramInside = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.inside", 60f);
            float paramOutside = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.outside", 60f);
            float paramAbove = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.above", 40f);
            float paramBelow = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.below", 20f);
            float paramBehind = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.behind", 170f);
            float paramOfsX = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.ofsx", 0f);
            float paramOfsY = ExSaveData.GetFloat(maid, PluginName, "EYE_TRACK.ofsy", 0f);
            Vector3 targetPosition = eyeTarget_world;
            {
                Transform trsEye = that.trsEyeL;
                Quaternion defQuat = that.quaDefEyeL * Quaternion.Euler(paramEyeAng, -paramOfsX, -paramOfsY);
                Quaternion prevQuat = externalValues.prevLeftEyeQuat;

                Transform trsParent = trsEye.parent;
                Quaternion newRotation_world = CalcNewEyeRotation(
                    paramOutside,
                    paramInside,
                    paramBelow,
                    paramAbove,
                    paramBehind,
                    trsParent.rotation,
                    trsEye.position,
                    eyeTarget_world
                );
                Quaternion q = Quaternion.Inverse(trsParent.rotation) * newRotation_world;
                q = Quaternion.Slerp(Quaternion.identity, q, 0.2f);     // 眼球モデルの中心に、眼球のトランスフォームの原点が無いため、ごまかしている
                q = Quaternion.Slerp(prevQuat, q, paramSpeed);
                prevQuat = q;
                trsEye.localRotation = q * defQuat;

                externalValues.prevLeftEyeQuat = prevQuat;
            }

            {
                Transform trsEye = that.trsEyeR;
                Quaternion defQuat = that.quaDefEyeR * Quaternion.Euler(-paramEyeAng, -paramOfsX, paramOfsY);
                Quaternion prevQuat = externalValues.prevRightEyeQuat;

                Transform trsParent = trsEye.parent;
                Quaternion newRotation_world = CalcNewEyeRotation(
                    paramOutside,
                    paramInside,
                    paramAbove,
                    paramBelow,
                    paramBehind,
                    trsParent.rotation,
                    trsEye.position,
                    eyeTarget_world
                );
                Quaternion q = Quaternion.Inverse(trsParent.rotation) * newRotation_world;
                q = Quaternion.Slerp(Quaternion.identity, q, 0.2f);
                q = Quaternion.Slerp(prevQuat, q, paramSpeed);
                prevQuat = q;
                trsEye.localRotation = q * defQuat;

                externalValues.prevRightEyeQuat = prevQuat;
            }
        }
    }
    void newMoveHead(ExternalValues externalValues, TBody tbody, ref Vector3 thatHeadEulerAngle, ref Vector3 thatHeadEulerAngleG, ref Vector3 thatEyeEulerAngle, Vector3 eyeTarget_world)
    {
        TBody that = tbody;
        Maid maid = tbody.maid;

        float paramSpeed = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.speed", 0.05f);
        float paramLateral = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.lateral", 60.0f);
        float paramAbove = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.above", 40.0f);
        float paramBelow = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.below", 20.0f);
        float paramBehind = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.behind", 170.0f);
        float paramOfsX = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsx", 0.0f);
        float paramOfsY = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsy", 0.0f);
        float paramOfsZ = ExSaveData.GetFloat(maid, PluginName, "HEAD_TRACK.ofsz", 0.0f);

        // モーションにしたがっている場合 (HeadToCamPer=0f) はオフセットをつけない
        paramOfsX *= that.HeadToCamPer;
        paramOfsY *= that.HeadToCamPer;
        paramOfsZ *= that.HeadToCamPer;

        Vector3 basePosition = that.trsNeck.position;
        Quaternion baseRotation = that.trsNeck.rotation;
        Vector3 target_local = Quaternion.Inverse(baseRotation) * (eyeTarget_world - basePosition);
        target_local = Quaternion.Euler(paramOfsX, 0f, paramOfsY) * target_local;
        Vector3 target_world = (baseRotation * target_local) + basePosition;

        // 顔が向くべき方向を算出
        Quaternion newHeadRotation_world = CalcNewHeadRotation(
            paramLateral,
            paramAbove,
            paramBelow,
            paramBehind,
            baseRotation,
            basePosition,
            target_world);

        newHeadRotation_world = newHeadRotation_world * Quaternion.Euler(0f, paramOfsZ, 0f);

        // TBody.HeadToCamPer を「正面向き度合い」として加味する
        newHeadRotation_world = Quaternion.Slerp(that.trsHead.rotation, newHeadRotation_world, that.HeadToCamPer);

        float s = paramSpeed;

        // 前回の回転よりも差が大きすぎる場合はリセットする
        if (externalValues.bReset)
        {
            externalValues.bReset = false;
            externalValues.prevQuat = that.trsHead.rotation;
            s = 0f;
        }

        // モーションにしたがっている場合 (HeadToCamPer=0f) は補間しない
        s = Mathf.Lerp(1f, s, that.HeadToCamPer);

        // 実際の回転
        that.trsHead.rotation = Quaternion.Slerp(externalValues.prevQuat, newHeadRotation_world, s);
    }