예제 #1
0
    /**
     * 更新
     * 首を中央から左右に振るときの平均的な早さは  秒程度。加速・減速を考慮して、その2倍を最高速度とする
     * 顔のふり具合を、中央(0)から、左右は(±1)とする
     */
    public void update()
    {
        //
        const float TIME_TO_MAX_SPEED = 0.15f;             //最高速度になるまでの時間
        const float FACE_PARAM_MAX_V  = 40.0f / 7.5f;      //7.5秒間に40分移動(5.3/sc)

        const float MAX_V = FACE_PARAM_MAX_V / FRAME_RATE; //1frameあたりに変化できる速度の上限

        if (lastTimeSec == 0)
        {
            lastTimeSec = UtSystem.getUserTimeMSec();
            return;
        }

        long curTimeSec = UtSystem.getUserTimeMSec();

        float deltaTimeWeight = (float)(curTimeSec - lastTimeSec) * FRAME_RATE / 1000.0f;

        lastTimeSec = curTimeSec;

        const float FRAME_TO_MAX_SPEED = TIME_TO_MAX_SPEED * FRAME_RATE;    //sec*frame/sec
        float       MAX_A = deltaTimeWeight * MAX_V / FRAME_TO_MAX_SPEED;   //1frameあたりの加速度

        float dx = (faceTargetX - faceX);
        float dy = (faceTargetY - faceY);

        if (dx == 0 && dy == 0)
        {
            return;
        }
        float d = (float)Math.Sqrt(dx * dx + dy * dy);

        float vx = MAX_V * dx / d;
        float vy = MAX_V * dy / d;

        float ax = vx - faceVX;
        float ay = vy - faceVY;

        float a = (float)Math.Sqrt(ax * ax + ay * ay);

        if (a < -MAX_A || a > MAX_A)
        {
            ax *= MAX_A / a;
            ay *= MAX_A / a;
            a   = MAX_A;
        }

        faceVX += ax;
        faceVY += ay;

        {
            //            2  6           2               3
            //      sqrt(a  t  + 16 a h t  - 8 a h) - a t
            // v = --------------------------------------
            //                    2
            //                 4 t  - 2
            //(t=1)

            float max_v = 0.5f * ((float)Math.Sqrt(MAX_A * MAX_A + 16 * MAX_A * d - 8 * MAX_A * d) - MAX_A);
            float cur_v = (float)Math.Sqrt(faceVX * faceVX + faceVY * faceVY);

            if (cur_v > max_v)
            {
                faceVX *= max_v / cur_v;
                faceVY *= max_v / cur_v;
            }
        }

        faceX += faceVX;
        faceY += faceVY;
    }
예제 #2
0
        /*
         * モデルのパラメータを更新。
         * @param model
         */
        public void updateParam(ALive2DModel model)
        {
            long  time = UtSystem.getUserTimeMSec();
            float eyeParamValue;// 設定する値
            float t = 0;

            switch (this.eyeState)
            {
            case EYE_STATE.STATE_CLOSING:
                // 閉じるまでの割合を0..1に直す(blinkMotionMsecの半分の時間で閉じる)
                t = (time - stateStartTime) / (float)closingMotionMsec;
                if (t >= 1)
                {
                    t                   = 1;
                    this.eyeState       = EYE_STATE.STATE_CLOSED;// 次から開き始める
                    this.stateStartTime = time;
                }
                eyeParamValue = 1 - t;
                break;

            case EYE_STATE.STATE_CLOSED:
                t = (time - stateStartTime) / (float)closedMotionMsec;
                if (t >= 1)
                {
                    this.eyeState       = EYE_STATE.STATE_OPENING;// 次から開き始める
                    this.stateStartTime = time;
                }
                eyeParamValue = 0;    // 閉じた状態
                break;

            case EYE_STATE.STATE_OPENING:
                t = (time - stateStartTime) / (float)openingMotionMsec;
                if (t >= 1)
                {
                    t                  = 1;
                    this.eyeState      = EYE_STATE.STATE_INTERVAL; // 次から開き始める
                    this.nextBlinkTime = calcNextBlink();          // 次回のまばたきのタイミングを始める時刻
                }
                eyeParamValue = t;
                break;

            case EYE_STATE.STATE_INTERVAL:
                //
                if (this.nextBlinkTime < time)
                {
                    this.eyeState       = EYE_STATE.STATE_CLOSING;
                    this.stateStartTime = time;
                }
                eyeParamValue = 1;    // 開いた状態
                break;

            case EYE_STATE.STATE_FIRST:
            default:
                this.eyeState      = EYE_STATE.STATE_INTERVAL;
                this.nextBlinkTime = calcNextBlink(); // 次回のまばたきのタイミングを始める時刻
                eyeParamValue      = 1;               // 開いた状態
                break;
            }

            if (!closeIfZero)
            {
                eyeParamValue = -eyeParamValue;
            }

            // ---- 値を設定 ----
            model.setParamFloat(eyeID_L, eyeParamValue);
            model.setParamFloat(eyeID_R, eyeParamValue);
        }
예제 #3
0
    /*
     * 更新
     */
    public void Update()
    {
        if (!isInitialized() || isUpdating())
        {
            return;
        }


        view.Update(Input.acceleration);
        if (live2DModel == null)
        {
            if (LAppDefine.DEBUG_LOG)
            {
                Debug.Log("Can not update there is no model data");
            }
            return;
        }

        if (!Application.isPlaying)
        {
            live2DModel.update();
            return;
        }

        long   timeMSec = UtSystem.getUserTimeMSec() - startTimeMSec;
        double timeSec  = timeMSec / 1000.0;
        double t        = timeSec * 2 * Math.PI;// 2πt

        // 待機モーション判定
        if (mainMotionManager.isFinished())
        {
            // モーションの再生がない場合、待機モーションの中からランダムで再生する
            StartRandomMotion(LAppDefine.MOTION_GROUP_IDLE, LAppDefine.PRIORITY_IDLE);
        }
        //-----------------------------------------------------------------
        live2DModel.loadParam();                                  // 前回セーブされた状態をロード

        bool update = mainMotionManager.updateParam(live2DModel); // モーションを更新

        if (!update)
        {
            // メインモーションの更新がないとき
            eyeBlink.updateParam(live2DModel);// 目パチ
        }

        live2DModel.saveParam();// 状態を保存
        //-----------------------------------------------------------------

        if (expressionManager != null)
        {
            expressionManager.updateParam(live2DModel);                           //  表情でパラメータ更新(相対変化)
        }
        // ドラッグによる変化
        // ドラッグによる顔の向きの調整
        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_X, dragX * 30, 1);// -30から30の値を加える
        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_Y, dragY * 30, 1);
        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_Z, (dragX * dragY) * -30, 1);

        // ドラッグによる体の向きの調整
        live2DModel.addToParamFloat(L2DStandardID.PARAM_BODY_ANGLE_X, dragX, 10);// -10から10の値を加える

        // ドラッグによる目の向きの調整
        live2DModel.addToParamFloat(L2DStandardID.PARAM_EYE_BALL_X, dragX, 1);// -1から1の値を加える
        live2DModel.addToParamFloat(L2DStandardID.PARAM_EYE_BALL_Y, dragY, 1);

        // 呼吸など
        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_X, (float)(15 * Math.Sin(t / 6.5345)), 0.5f);
        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_Y, (float)(8 * Math.Sin(t / 3.5345)), 0.5f);
        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_Z, (float)(10 * Math.Sin(t / 5.5345)), 0.5f);
        live2DModel.addToParamFloat(L2DStandardID.PARAM_BODY_ANGLE_X, (float)(4 * Math.Sin(t / 15.5345)), 0.5f);
        live2DModel.setParamFloat(L2DStandardID.PARAM_BREATH, (float)(0.5f + 0.5f * Math.Sin(t / 3.2345)), 1);


        // 加速度による変化
        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_X, 90 * accelX, 0.5f);
        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_Z, 10 * accelX, 0.5f);


        if (physics != null)
        {
            physics.updateParam(live2DModel);                 // 物理演算でパラメータ更新
        }
        // リップシンクの設定
        if (lipSync)
        {
            live2DModel.setParamFloat(L2DStandardID.PARAM_MOUTH_OPEN_Y, lipSyncValue, 0.8f);
        }

        // ポーズの設定
        if (pose != null)
        {
            pose.updateParam(live2DModel);
        }

        live2DModel.update();
    }
예제 #4
0
    public void Update()
    {
        if (!isInitialized() || isUpdating())
        {
            return;
        }


        view.Update(Input.acceleration);
        if (live2DModel == null)
        {
            if (LAppDefine.DEBUG_LOG)
            {
                Debug.Log("Can not update there is no model data");
            }
            return;
        }

        if (!Application.isPlaying)
        {
            live2DModel.update();
            return;
        }

        long   timeMSec = UtSystem.getUserTimeMSec() - startTimeMSec;
        double timeSec  = timeMSec / 1000.0;
        double t        = timeSec * 2 * Math.PI;


        if (mainMotionManager.isFinished())
        {
            StartRandomMotion(LAppDefine.MOTION_GROUP_IDLE, LAppDefine.PRIORITY_IDLE);
        }
        //-----------------------------------------------------------------
        live2DModel.loadParam();

        bool update = mainMotionManager.updateParam(live2DModel);

        if (!update)
        {
            eyeBlink.updateParam(live2DModel);
        }

        live2DModel.saveParam();
        //-----------------------------------------------------------------

        if (expressionManager != null)
        {
            expressionManager.updateParam(live2DModel);
        }

        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_X, dragX * 30, 1);
        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_Y, dragY * 30, 1);
        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_Z, (dragX * dragY) * -30, 1);


        live2DModel.addToParamFloat(L2DStandardID.PARAM_BODY_ANGLE_X, dragX, 10);


        live2DModel.addToParamFloat(L2DStandardID.PARAM_EYE_BALL_X, dragX, 1);
        live2DModel.addToParamFloat(L2DStandardID.PARAM_EYE_BALL_Y, dragY, 1);


        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_X, (float)(15 * Math.Sin(t / 6.5345)), 0.5f);
        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_Y, (float)(8 * Math.Sin(t / 3.5345)), 0.5f);
        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_Z, (float)(10 * Math.Sin(t / 5.5345)), 0.5f);
        live2DModel.addToParamFloat(L2DStandardID.PARAM_BODY_ANGLE_X, (float)(4 * Math.Sin(t / 15.5345)), 0.5f);
        live2DModel.setParamFloat(L2DStandardID.PARAM_BREATH, (float)(0.5f + 0.5f * Math.Sin(t / 3.2345)), 1);



        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_X, 90 * accelX, 0.5f);
        live2DModel.addToParamFloat(L2DStandardID.PARAM_ANGLE_Z, 10 * accelX, 0.5f);


        if (physics != null)
        {
            physics.updateParam(live2DModel);
        }

        if (lipSync)
        {
            live2DModel.setParamFloat(L2DStandardID.PARAM_MOUTH_OPEN_Y, lipSyncValue, 0.8f);
        }


        if (pose != null)
        {
            pose.updateParam(live2DModel);
        }

        if (thalmicMyo.pose == Pose.Rest)
        {
            SetExpression("f01");
        }
        else if (thalmicMyo.pose == Pose.WaveIn)
        {
            SetExpression("f02");
        }
        else if (thalmicMyo.pose == Pose.Fist)
        {
            SetExpression("f03");
        }
        else if (thalmicMyo.pose == Pose.FingersSpread)
        {
            SetExpression("f04");
        }
        if (thalmicMyo.pose == Pose.DoubleTap)
        {
            acVoice = FileManager.LoadAssetsSound(modelHomeDir + "sounds/pinchOut_02");
            StartVoice(acVoice);
        }

        live2DModel.update();
    }
예제 #5
0
 /**
  * コンストラクタ
  */
 public L2DPhysics()
 {
     physicsList   = new List <PhysicsHair>();
     startTimeMSec = UtSystem.getUserTimeMSec();
 }
예제 #6
0
        public void updateParam(ALive2DModel model)
        {
            long  time = UtSystem.getUserTimeMSec();
            float eyeParamValue;
            float t = 0;

            switch (this.eyeState)
            {
            case EYE_STATE.STATE_CLOSING:

                t = (time - stateStartTime) / (float)closingMotionMsec;
                if (t >= 1)
                {
                    t                   = 1;
                    this.eyeState       = EYE_STATE.STATE_CLOSED;
                    this.stateStartTime = time;
                }
                eyeParamValue = 1 - t;
                break;

            case EYE_STATE.STATE_CLOSED:
                t = (time - stateStartTime) / (float)closedMotionMsec;
                if (t >= 1)
                {
                    this.eyeState       = EYE_STATE.STATE_OPENING;
                    this.stateStartTime = time;
                }
                eyeParamValue = 0;
                break;

            case EYE_STATE.STATE_OPENING:
                t = (time - stateStartTime) / (float)openingMotionMsec;
                if (t >= 1)
                {
                    t                  = 1;
                    this.eyeState      = EYE_STATE.STATE_INTERVAL;
                    this.nextBlinkTime = calcNextBlink();
                }
                eyeParamValue = t;
                break;

            case EYE_STATE.STATE_INTERVAL:
                //
                if (this.nextBlinkTime < time)
                {
                    this.eyeState       = EYE_STATE.STATE_CLOSING;
                    this.stateStartTime = time;
                }
                eyeParamValue = 1;
                break;

            case EYE_STATE.STATE_FIRST:
            default:
                this.eyeState      = EYE_STATE.STATE_INTERVAL;
                this.nextBlinkTime = calcNextBlink();
                eyeParamValue      = 1;
                break;
            }

            if (!closeIfZero)
            {
                eyeParamValue = -eyeParamValue;
            }


            model.setParamFloat(eyeID_L, eyeParamValue);
            model.setParamFloat(eyeID_R, eyeParamValue);
        }