public (Redirector.GainType, float) RealMove(Object2D realUser, Redirector.GainType type, float degree)
    {
        Transform2D realUserTransform = realUser.transform;
        float       appliedGain       = 0;

        switch (type)
        {
        case Redirector.GainType.Translation:
            realUser.Translate(realUserTransform.forward * degree * Time.fixedDeltaTime, Space.World);
            break;

        case Redirector.GainType.Rotation:
            realUser.Rotate(degree * Time.fixedDeltaTime);
            break;

        case Redirector.GainType.Curvature:
            realUser.Translate(realUserTransform.forward * deltaPosition.magnitude * Time.fixedDeltaTime, Space.World);
            realUser.Rotate(degree * Time.fixedDeltaTime);
            break;

        default:
            break;
        }

        return(type, appliedGain);
    }
Example #2
0
    public string ApplyUserReset(Object2D realUser, Object2D virtualUser, Vector2 resetDirection)
    {
        //float ratio = 2;
        float rotationSpeed = 60.0f;

        if (isFirst)
        {
            initialAngle       = Vector2.SignedAngle(realUser.transform.forward, resetDirection);
            realTargetRotation = Matrix3x3.CreateRotation(initialAngle) * realUser.transform.forward;

            //virtualTargetRotation = Matrix3x3.CreateRotation(ratio * targetAngle) * virtualUser.transform.forward; freeze-turn when user reset
            isFirst = false;

            maxRotTime = Mathf.Abs(initialAngle) / rotationSpeed;
            //Debug.Log(maxRotTime);
            remainRotTime = 0;
        }

        float realAngle = Vector2.SignedAngle(realUser.transform.forward, realTargetRotation);

        if (remainRotTime < maxRotTime)
        {
            //Debug.Log(remainRotTime);
            realUser.Rotate(Mathf.Sign(initialAngle) * rotationSpeed * Time.fixedDeltaTime);
            //virtualUser.Rotate(ratio * rotationSpeed * Time.fixedDeltaTime);
            remainRotTime += Time.fixedDeltaTime;
        }
        else
        {
            SyncDirection(realUser, resetDirection);
            //Debug.Log("SYNC");

            //Utility.SyncDirection(virtualUser, realUser, virtualTargetRotation, realTargetRotation);

            //realUser.transform.position = realUser.transform.position + realUser.transform.forward * 0.1f;
            //if (realUser.gameObject != null) realUser.gameObject.transform.position = Utility.Cast2Dto3D(realUser.transform.position);

            //Utility.SyncPosition(virtualUser, realUser, virtualUser.transform.localPosition, newRealPosition);
            //bool isNeedReset = NeedWallReset(realUser, realSpace);

            //Debug.Log(virtualUser.transform);
            //Debug.Log(realUser.transform);
            ////Debug.Log(virtualUser.gameObject.transform.localPosition);
            ////Debug.Log(realUser.gameObject.transform.localPosition);
            //Debug.Log(isNeedReset);

            //realUser.transform.position = realUser.transform.position + realUser.transform.forward * 0.1f; // 다시 리셋 상태에 빠지는 것을 방지
            isFirst = true;
            return("DONE");
            //episode.DeleteTarget();
            //isFirst = true;
            //isFirst2 = true;
        }

        return("NOT_YET");
    }
    public override string ApplyReset(Object2D realUser, Object2D virtualUser, Space2D realSpace, string resetType)
    {
        if (isFirst)
        {
            realTargetRotation    = Matrix3x3.CreateRotation(targetAngle) * realUser.transform.forward;
            virtualTargetRotation = Matrix3x3.CreateRotation(ratio * targetAngle) * virtualUser.transform.forward;
            isFirst = false;
        }

        float realAngle = Vector2.SignedAngle(realUser.transform.forward, realTargetRotation);

        if (Mathf.Abs(realAngle) >= epsilonRotation)
        {
            realUser.Rotate(rotationSpeed * Time.deltaTime);
            virtualUser.Rotate(ratio * rotationSpeed * Time.deltaTime);
        }
        else
        {
            Utility.SyncDirection(virtualUser, realUser, virtualTargetRotation, realTargetRotation);

            switch (resetType)
            {
            case "Wall":
                while (NeedWallReset(realUser, realSpace))
                {
                    CalculationErrorAdjustment(realUser.transform, resetType, (Polygon2D)realSpace.space);
                }
                break;

            case "User":
                break;
            }

            if (realUser.gameObject != null)
            {
                realUser.gameObject.transform.position = Utility.Cast2Dto3D(realUser.transform.position);
            }

            isFirst = true;
            return("DONE");
        }

        return("NOT_YET");
    }
    public (Vector2, float) VirtualMove(Object2D realUser, Object2D virtualUser, Space2D virtualSpace)
    {
        Transform2D virtualUserTransform = virtualUser.transform;

        if (!initializing)
        {
            ResetCurrentState(virtualUserTransform);
            initializing = false;
        }

        if (episode.IsNotEnd())
        {
            if (isFirst)
            {
                isFirst         = false;
                targetPosition  = episode.GetTarget(virtualUserTransform, virtualSpace);
                initialToTarget = targetPosition - virtualUserTransform.localPosition;
                float InitialAngle    = Vector2.SignedAngle(virtualUserTransform.forward, initialToTarget);
                float initialDistance = Vector2.Distance(virtualUserTransform.localPosition, targetPosition);

                virtualTargetDirection = Matrix3x3.CreateRotation(InitialAngle) * virtualUser.transform.forward; // target을 향하는 direction(forward)를 구함
                //realTargetDirection = Matrix3x3.CreateRotation(InitialAngle) * realUser.transform.forward;

                virtualTargetPosition = virtualUser.transform.localPosition + virtualTargetDirection * initialDistance; // target에 도달하는 position을 구함
                //realTargetPosition = realUser.transform.localPosition + realTargetDirection * initialDistance;

                maxRotTime      = Mathf.Abs(InitialAngle) / rotationSpeed;
                maxTransTime    = initialDistance / translationSpeed;
                remainRotTime   = 0;
                remainTransTime = 0;

                initialAngleDirection = Mathf.Sign(InitialAngle);
            }

            float distance = (targetPosition - virtualUserTransform.localPosition).magnitude;
            float angle    = Vector2.SignedAngle(virtualUserTransform.forward, initialToTarget);

            if (remainRotTime < maxRotTime)
            {
                virtualUser.Rotate(initialAngleDirection * rotationSpeed * Time.fixedDeltaTime);
                remainRotTime += Time.fixedDeltaTime;
            }
            else if (remainTransTime < maxTransTime)
            {
                if (isFirst2) // 방향을 동기화
                {
                    isFirst2 = false;
                    SyncDirection(virtualUser, virtualTargetDirection);
                }
                else
                {
                    virtualUser.Translate(virtualUserTransform.forward * translationSpeed * Time.fixedDeltaTime, Space.World);
                    remainTransTime += Time.fixedDeltaTime;
                }
            }
            else
            {
                if (isFirst3) // 위치를 동기화
                {
                    isFirst3 = false;
                    SyncPosition(virtualUser, virtualTargetPosition);
                }
                else
                {
                    episode.DeleteTarget();

                    //Debug.Log(string.Format("realUser: {0}", realUser.transform));
                    //Debug.Log(string.Format("virtualUser: {0}", virtualUser.transform));

                    isFirst  = true;
                    isFirst2 = true;
                    isFirst3 = true;
                }
            }
        }

        UpdateCurrentState(virtualUserTransform);

        return(GetDelta(virtualUserTransform.forward));
    }