示例#1
0
    private void Update()
    {
        if (Box == null)
        {
            return;
        }

        float dt = Time.deltaTime;

        Box.transform.rotation.ToAngleAxis(out float qAngle, out Vector3 qAxis);
        Vector3 c = Mathf.Deg2Rad * qAngle * qAxis;

        c.x = 0f;
        c.y = 0f;

        Matrix3x3 effectiveMass = inertia;
        Vector3   jV            = a;

        jV.x = 0f;
        jV.y = 0f;
        Vector3 lambda = effectiveMass * (-(jV + (Beta / dt) * c));

        a += inertiaInv * lambda;
        //a *= 0.9f; // temp magic cheat

        // integration
        Quaternion q = QuaternionUtil.AxisAngle(VectorUtil.NormalizeSafe(a, Vector3.forward), a.magnitude * dt);

        Box.transform.rotation = q * Box.transform.rotation;
    }
示例#2
0
    public void FixedUpdateState()
    {
        if (isFinishedRotating)
        {
            return;
        }

        // Calculate direction to target
        Vector3 targetRot = stateMachine.taskDestinationPosition - stateMachine.transform.position;

        targetRot.y = 0.0f;
        targetRot.Normalize();

        // SmoothDamp towards to target rotation
        stateMachine.transform.rotation = QuaternionUtil.SmoothDamp(stateMachine.transform.rotation, Quaternion.LookRotation(targetRot), ref angularVelocity, stateMachine.rotationSpeed);

        // Calculate the angle between target position and customer forward vector
        float fromToDelta = Vector3.Angle(stateMachine.transform.forward, targetRot);

        Debug.DrawRay(stateMachine.transform.position, targetRot * 5.0f, Color.green);
        Debug.DrawRay(stateMachine.transform.position, stateMachine.transform.forward * 5.0f, Color.red);

        // Stop rotation if angle between target and forward vector is lower than margin of error
        if (fromToDelta <= marginOfErrorAmount)
        {
            isFinishedRotating = true;
            Debug.Log("Customer is now looking at the target!", stateMachine.gameObject);
        }
    }
示例#3
0
        public void Set(object targ, object valueObj)
        {
            var value = ConvertUtil.ToQuaternion(valueObj);

            if (targ is Rigidbody)
            {
                var rb = targ as Rigidbody;
                rb.MoveRotation(QuaternionUtil.FromToRotation(rb.rotation, value));
            }
            else
            {
                var trans = GameObjectUtil.GetTransformFromSource(targ);
                if (trans == null)
                {
                    return;
                }

                var rb = trans.GetComponent <Rigidbody>();
                if (rb != null && !rb.isKinematic)
                {
                    rb.MoveRotation(QuaternionUtil.FromToRotation(rb.rotation, value));
                    return;
                }

                //just update the rotation
                trans.rotation = value;
            }
        }
    // master sterp function
    public static Quaternion Sterp
    (
        Quaternion a,
        Quaternion b,
        Vector3 twistAxis,
        float tSwing,
        float tTwist,
        out Quaternion swing,
        out Quaternion twist,
        SterpMode mode
    )
    {
        Quaternion q = b * Quaternion.Inverse(a);
        Quaternion swingFull;
        Quaternion twistFull;

        QuaternionUtil.DecomposeSwingTwist(q, twistAxis, out swingFull, out twistFull);

        switch (mode)
        {
        default:
        case SterpMode.Nlerp:
            swing = Quaternion.Lerp(Quaternion.identity, swingFull, tSwing);
            twist = Quaternion.Lerp(Quaternion.identity, twistFull, tTwist);
            break;

        case SterpMode.Slerp:
            swing = Quaternion.Slerp(Quaternion.identity, swingFull, tSwing);
            twist = Quaternion.Slerp(Quaternion.identity, twistFull, tTwist);
            break;
        }

        return(twist * swing);
    }
示例#5
0
    public void Update()
    {
        var     player         = getPlayerTransform();
        var     transform      = getCameraTransform();
        Vector3 playerPosition = player.position;

        Torus.GetPoint(playerPosition, out TorusPointInfo pInfo);
        Vector3 slope          = -pInfo.minorCenterUp;
        Vector3 playerUp       = -pInfo.minorCenterForward;
        Vector3 playerRight    = -pInfo.minorCenterRight;
        Vector3 targetPosition = playerPosition + slope * config.offset.z + playerUp * config.offset.y;

        if (Application.isPlaying)
        {
            transform.position = Vector3.SmoothDamp(transform.position, targetPosition, ref velocity, config.smoothTime);
        }
        else
        {
            transform.position = targetPosition;
        }

        var lookAtTarget = playerPosition + slope * config.lootAtOffset.z + playerUp * config.lootAtOffset.y;
        var lookAt       = (lookAtTarget - transform.position).normalized;
        var up           = Vector3.Cross(playerRight, lookAt);

        if (Application.isPlaying)
        {
            transform.rotation = QuaternionUtil.SmoothDamp(transform.rotation, Quaternion.LookRotation(lookAt, up), ref quaternionDeriv, config.smoothTime);
        }
        else
        {
            transform.rotation = Quaternion.LookRotation(lookAt, up);
        }
    }
示例#6
0
        void Update()
        {
            Vector3 axis         = Vector3.down;
            float   angularSpeed = 1.0f;
            float   dt           = m_timeScale * Time.fixedDeltaTime;

            // render
            Quaternion baseRot = Quaternion.FromToRotation(Vector3.one, Vector3.up);

            DebugUtil.DrawBox(Vector3.zero, m_quatClosedForm * baseRot, Vector3.one, m_closedColor, true, DebugUtil.Style.FlatShaded);
            DebugUtil.DrawBox(Vector3.zero, m_quatPower * baseRot, 1.05f * Vector3.one, m_powerColor, true, DebugUtil.Style.Wireframe);
            DebugUtil.DrawBox(Vector3.zero, m_quatDerivative * baseRot, 1.1f * Vector3.one, m_derivativeColor, true, DebugUtil.Style.Wireframe);

            // integrate
            Quaternion v = QuaternionUtil.AxisAngle(axis, angularSpeed);
            Vector3    o = angularSpeed * axis;

            m_quatClosedForm = QuaternionUtil.Normalize(QuaternionUtil.AxisAngle(axis, (m_angle += angularSpeed * dt)));
            m_quatPower      = QuaternionUtil.Normalize(QuaternionUtil.Integrate(m_quatPower, v, dt));
            m_quatDerivative = QuaternionUtil.Normalize(QuaternionUtil.Integrate(m_quatDerivative, o, dt));

            if (Input.GetKey(KeyCode.Space))
            {
                Reset();
            }
        }
示例#7
0
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.Escape))
        {
            followTransform = null;
        }
        if (followTransform != null)
        {
            position = followTransform.position;
        }
        else
        {
            HandleInput();
        }

        position.x = Mathf.Clamp(position.x, center.x - panLimit.x, center.x + panLimit.x);
        position.z = Mathf.Clamp(position.z, center.z - panLimit.y, center.z + panLimit.y);
        zoom.y     = Mathf.Clamp(zoom.y, minZoom, maxZoom);
        zoom.z     = Mathf.Clamp(zoom.z, -maxZoom, -minZoom);

        transform.position = Vector3.SmoothDamp(transform.position, position, ref velocity, panRate);
        transform.rotation = QuaternionUtil.SmoothDamp(transform.rotation, rotation, ref deriv, rotateRate);

        cameraTransform.localPosition = Vector3.SmoothDamp(cameraTransform.localPosition, zoom, ref zoomVelocity, zoomRate);
    }
示例#8
0
    public void Fire(Vector2 direction)
    {
        var rotation = QuaternionUtil.FromDirection2D(direction);

        var bulletInstance = (GameObject)Instantiate(bullet, origin.position, rotation);

        bulletInstance.GetComponent <Rigidbody2D>().velocity    = direction.normalized * 20;
        bulletInstance.GetComponent <BulletController>().ignore = ignore;
    }
示例#9
0
    public GameObject CreateRocket()
    {
        Vector2    pos   = mainCircle.GetRandomPoint();
        GameObject probe = Instantiate(ProbePrefab, pos, Quaternion.identity);

        probe.transform.rotation = QuaternionUtil.GetOppositeDirection(probe, MainObject);
        probe.transform.SetParent(MainObject.transform);
        probe.GetComponent <RocketBehaviour>().Init(endCircle);
        return(probe);
    }
示例#10
0
        public static Quaternion GetQuaternion(IBcx bcx, int jointIndex, float time)
        {
            var animatedJoint = bcx.Anx1.Joints[jointIndex];
            var values        = animatedJoint.Values;

            var xRadians = animatedJoint.GetAnimValue(values.rotationsX, time);
            var yRadians = animatedJoint.GetAnimValue(values.rotationsY, time);
            var zRadians = animatedJoint.GetAnimValue(values.rotationsZ, time);

            return(QuaternionUtil.Create(xRadians, yRadians, zRadians));
        }
示例#11
0
        public void Integrate(float dt)
        {
            if (!LockPosition)
            {
                transform.position = VectorUtil.Integrate(transform.position, LinearVelocity, dt);
            }

            if (!LockRotation)
            {
                transform.rotation = QuaternionUtil.Integrate(transform.rotation, AngularVelocity, dt);
            }
        }
    // Update is called once per frame
    void FixedUpdate()
    {
        //if (!target2.gameObject.activeInHierarchy) {
        Vector3 desiredPosition = target.position + target.forward * offset;

        transform.position = Vector3.SmoothDamp(transform.position, desiredPosition, ref velocity, smoothTimePos);
        Quaternion desiredRotation = target.rotation;

        transform.rotation = QuaternionUtil.SmoothDamp(transform.rotation, desiredRotation, ref deriv, smoothTimeRot);
        //} else {
        //this.gameObject.SetActive(false);
        //}
    }
示例#13
0
    void LateUpdate()
    {
        if (desiredPose != null)
        {
            transform.position = Vector3.SmoothDamp(transform.position, desiredPose.position, ref currentPositionCorrectionVelocity, positionSmoothTime, positionMaxSpeed, Time.deltaTime);

            var targForward = desiredPose.forward;
            //var targForward = (target.position - this.transform.position).normalized;

            transform.rotation = QuaternionUtil.SmoothDamp(transform.rotation,
                                                           Quaternion.LookRotation(targForward, Vector3.up), ref quaternionDeriv, rotationSmoothTime);
        }
    }
示例#14
0
        public void Integrate(float dt)
        {
            if (!LockPosition)
            {
                transform.position += LinearVelocity * dt;;
            }

            if (!LockRotation)
            {
                Quaternion q = QuaternionUtil.AxisAngle(VectorUtil.NormalizeSafe(AngularVelocity, Vector3.forward), AngularVelocity.magnitude * dt);
                transform.rotation = q * transform.rotation;
            }
        }
示例#15
0
    private void FixedUpdate()
    {
        if (Object == null)
        {
            return;
        }

        if (Target == null)
        {
            return;
        }

        float dt = Time.fixedDeltaTime;

        Vector3 r = Object.transform.rotation * rLocal;

        var       t           = Object.transform;
        Matrix3x3 world2Local =
            Matrix3x3.FromRows
            (
                t.TransformVector(new Vector3(1.0f, 0.0f, 0.0f)),
                t.TransformVector(new Vector3(0.0f, 1.0f, 0.0f)),
                t.TransformVector(new Vector3(0.0f, 0.0f, 1.0f))
            );
        Matrix3x3 inertiaInvWs = world2Local.Transposed * inertiaInvLs * world2Local;

        // gravity
        v += Gravity * dt;

        // constraint errors
        Vector3 cPos = (Object.transform.position + r) - Target.transform.position;
        Vector3 cVel = v + Vector3.Cross(a, r);

        // constraint resolution
        Matrix3x3 s             = Matrix3x3.Skew(-r);
        Matrix3x3 k             = massInv * Matrix3x3.Identity + s * inertiaInvWs * s.Transposed;
        Matrix3x3 effectiveMass = k.Inverted;
        Vector3   lambda        = effectiveMass * (-(cVel + (Beta / dt) * cPos));

        // velocity correction
        v += massInv * lambda;
        a += (inertiaInvWs * s.Transposed) * lambda;
        v *= 0.98f; // temp magic
        a *= 0.98f; // temp magic

        // integration
        Object.transform.position += v * dt;
        Object.transform.rotation  = QuaternionUtil.Integrate(Object.transform.rotation, a, dt);
    }
示例#16
0
    void OnAITargetting(AIShooterInfo info)
    {
        if (info.State == AIShooterState.NOT_IN_RANGE)
        {
            this.visualElement.gameObject.SetActive(false);
            return;
        }

        float width = maxThickness * (1 - info.TimeToShoot / info.ShootDelay);

        visualElement.SetWidth(width, width);

        this.visualElement.gameObject.SetActive(true);
        this.visualElement.gameObject.transform.position = info.From;
        this.visualElement.gameObject.transform.rotation = QuaternionUtil.FromDirection2D(info.Target);
    }
示例#17
0
    public void UpdateCurrentPose(Transform transform)
    {
        current_pose.position    = transform.position;
        current_pose.orientation = transform.rotation;

        // Offset position to initial frame
        current_pose.position -= initial_pose.position;
        current_pose.position  = Quaternion.Inverse(initial_pose.orientation) *
                                 current_pose.position;

        current_pose.orientation = QuaternionUtil.DispQ(initial_pose.orientation,
                                                        current_pose.orientation);

        // Convert to robot frame
        current_pose.position    = UnityToRobotFramePosition(current_pose.position);
        current_pose.orientation = UnityToRobotFrameOrientation(current_pose.orientation);
    }
示例#18
0
    // Convert an array of rotation vectors back to quaternions
    public static Quaternion[] RotVecsToQuats(Vector3[] rotVecs, Quaternion q0)
    {
        Quaternion[] quaternions = new Quaternion[rotVecs.Length - 1];
        Quaternion   qProd       = q0;

        for (int i = 0; i < rotVecs.Length - 1; i++)
        {
            for (int j = 0; j < i - 1; j++)
            {
                qProd *= QuaternionUtil.Exp(rotVecs[j + 1] - rotVecs[j]);
            }
            quaternions[i] = qProd;
            qProd          = q0;
        }

        return(quaternions);
    }
        void ISupportRedirectToMemberCurve.ConfigureAsRedirectTo(System.Type memberType, float totalDur, object current, object start, object end, object option)
        {
            _option = ConvertUtil.ToEnum <QuaternionTweenOption>(option);
            if (_option == QuaternionTweenOption.Long)
            {
                var c = QuaternionUtil.MassageAsEuler(current);
                var s = QuaternionUtil.MassageAsEuler(start);
                var e = QuaternionUtil.MassageAsEuler(end);

                c.x = MathUtil.NormalizeAngleToRange(c.x, s.x, e.x, false);
                c.y = MathUtil.NormalizeAngleToRange(c.y, s.y, e.y, false);
                c.z = MathUtil.NormalizeAngleToRange(c.z, s.z, e.z, false);

                _startLong = c;
                _endLong   = e;
                _start     = Quaternion.Euler(_startLong);
                _end       = Quaternion.Euler(_endLong);

                c            -= s;
                e            -= s;
                this.Duration = totalDur * (VectorUtil.NearZeroVector(e) ? 0f : 1f - c.magnitude / e.magnitude);
            }
            else
            {
                //treat as quat
                var c = QuaternionUtil.MassageAsQuaternion(current);
                var s = QuaternionUtil.MassageAsQuaternion(start);
                var e = QuaternionUtil.MassageAsQuaternion(end);
                _start     = c;
                _end       = e;
                _startLong = _start.eulerAngles;
                _endLong   = _end.eulerAngles;

                var at = Quaternion.Angle(s, e);
                if ((System.Math.Abs(at) < MathUtil.EPSILON))
                {
                    this.Duration = 0f;
                }
                else
                {
                    var ap = Quaternion.Angle(s, c);
                    this.Duration = (1f - ap / at) * totalDur;
                }
            }
        }
 protected override void ReflectiveInit(System.Type memberType, object start, object end, object option)
 {
     _option = ConvertUtil.ToEnum <QuaternionTweenOption>(option);
     if (_option == QuaternionTweenOption.Long)
     {
         _startLong = QuaternionUtil.MassageAsEuler(start);
         _endLong   = QuaternionUtil.MassageAsEuler(end);
         _start     = Quaternion.Euler(_startLong);
         _end       = Quaternion.Euler(_endLong);
     }
     else
     {
         _start     = QuaternionUtil.MassageAsQuaternion(start);
         _end       = QuaternionUtil.MassageAsQuaternion(end);
         _startLong = _start.eulerAngles;
         _endLong   = _end.eulerAngles;
     }
 }
示例#21
0
    private void Update()
    {
        if (Object == null)
        {
            return;
        }

        if (Target == null)
        {
            return;
        }

        float dt = Time.deltaTime;

        Vector3 r = Object.transform.rotation * rLocal;

        // gravity
        v += Gravity * dt;

        // constraint errors
        Vector3 cPos = (Object.transform.position + r) - Target.transform.position;
        Vector3 cVel = v + Vector3.Cross(a, r);

        // constraint resolution
        Matrix3x3 s             = Matrix3x3.Skew(-r);
        Matrix3x3 k             = massInv * Matrix3x3.Identity + s * inertiaInv * s.Transposed;
        Matrix3x3 effectiveMass = k.Inverted;
        Vector3   lambda        = effectiveMass * (-(cVel + (Beta / dt) * cPos));

        // velocity correction
        v += massInv * lambda;
        a += (inertiaInv * s.Transposed) * lambda;
        v *= 0.98f; // temp magic cheat
        a *= 0.98f; // temp magic cheat

        // integration
        Object.transform.position += v * dt;
        Quaternion q = QuaternionUtil.AxisAngle(VectorUtil.NormalizeSafe(a, Vector3.forward), a.magnitude * dt);

        Object.transform.rotation = q * Object.transform.rotation;
    }
        public override bool Trigger(object arg)
        {
            if (!this.CanTrigger)
            {
                return(false);
            }

            var observer = this._observer.GetTarget <Transform>(arg);

            if (observer == null)
            {
                return(false);
            }
            var targ = this._target.GetTarget <Transform>(arg);

            if (targ == null)
            {
                return(false);
            }

            var dir = targ.position - observer.position;
            var ax  = (this._axisIsRelative) ? this.transform.GetAxis(this._axis) : TransformUtil.GetAxis(this._axis);

            if (this._flattenOnAxis)
            {
                dir = dir.SetLengthOnAxis(ax, 0f);
            }
            var q = Quaternion.LookRotation(dir, ax);

            if (this._slerp)
            {
                observer.rotation = QuaternionUtil.SpeedSlerp(observer.rotation, q, this._slerpAngularSpeed, Time.deltaTime);
            }
            else
            {
                observer.rotation = q;
            }
            return(true);
        }
    /// <summary>
    /// Rotates subject towards the target using SmoothDamp
    /// </summary>
    /// <param name="transformToTurn">Subject to turn.</param>
    /// <param name="target">Target to turn subject towards.</param>
    /// <param name="currentVelocity">The current velocity, this value is modified by the function every time you call it.</param>
    /// <param name="smoothTime">Approximately the time it will take to reach the target. A smaller value will reach the target faster.</param>
    /// <returns>The delta angle between the direction the subject is facing to target position.</returns>
    public static float RotateTowardsTargetSmoothDamp(Transform transformToTurn, Vector3 target, ref Quaternion currentVelocity, float smoothTime)
    {
        // Calculate direction to target
        Vector3 targetRot = target - transformToTurn.position;

        targetRot.y = 0.0f;
        targetRot.Normalize();

        // SmoothDamp towards to target rotation
        transformToTurn.rotation =
            QuaternionUtil.SmoothDamp(
                transformToTurn.rotation,
                Quaternion.LookRotation(targetRot),
                ref currentVelocity,
                smoothTime
                );

        // Debug visuals
        Debug.DrawRay(transformToTurn.position, targetRot * 5.0f, Color.green);
        Debug.DrawRay(transformToTurn.position, transformToTurn.forward * 5.0f, Color.red);

        return(Vector3.Angle(transformToTurn.forward, targetRot));
    }
    public void Update()
    {
        m_phase = 0.5f * Mathf.Sin(Time.timeSinceLevelLoad * MathUtil.Pi) + 0.5f;

        Vector3    twistAxis = m_rotInit * Vector3.up;
        Quaternion swing;
        Quaternion twist;

        QuaternionUtil.Sterp(m_rotInit, m_rotEnd, twistAxis, m_phase, out swing, out twist);

        switch (m_state)
        {
        case State.InitEnd:
        {
            m_rot0 = m_rotInit;
            m_rot1 = m_rotEnd;
            break;
        }

        case State.Comparison:
        {
            m_rot0 = Quaternion.Slerp(m_rotInit, m_rotEnd, m_phase);
            m_rot1 = swing * twist * m_rotInit;
            break;
        }

        /*
         * case State.TwistSwingTrajectory:
         * {
         * m_rot0 = Quaternion.Slerp(m_rotInit, m_rotEnd, m_phase);
         * m_rot1 = swing * twist * m_rotInit;
         *
         * const int kQueueCapacity = 20;
         * if (m_trajectory0.Count >= kQueueCapacity)
         *  m_trajectory0.Dequeue();
         * m_trajectory0.Enqueue(m_pos0 + m_rot0 * ((kRodLegnth - 0.5f * kRodThickness) * Vector3.up));
         * if (m_trajectory1.Count >= kQueueCapacity)
         *  m_trajectory1.Dequeue();
         * m_trajectory1.Enqueue(m_pos1 + m_rot1 * ((kRodLegnth - 0.5f * kRodThickness) * Vector3.up));
         *
         * Queue<Vector3> [] aTrajectory = { m_trajectory0, m_trajectory1 };
         * foreach (Queue<Vector3> trajectory in aTrajectory)
         * {
         *  Vector3 p0 = trajectory.Peek();
         *  foreach (Vector3 p1 in trajectory)
         *  {
         *    DebugUtil.DrawSphere(p0, 0.01f, 16, 32, Color.white, false, DebugUtil.Style.FlatShaded);
         *    DebugUtil.DrawCylinder(p0, p1, 0.005f, 16, Color.white, false, DebugUtil.Style.FlatShaded);
         *    p0 = p1;
         *  }
         * }
         *
         * break;
         * }
         */
        case State.TwistSwing:
        {
            m_rot0 = swing * m_rotInit;
            m_rot1 = twist * m_rotInit;
            break;
        }
        }

        DrawRod(m_pos0, m_rot0);
        DrawRod(m_pos1, m_rot1);

        if (Input.GetKeyDown(KeyCode.Space))
        {
            ++m_state;
            if (m_state >= State.Count)
            {
                m_state = 0;
            }
        }
    }
        public unsafe IModel LoadModel(GloModelFileBundle gloModelFileBundle)
        {
            var gloFile            = gloModelFileBundle.GloFile;
            var textureDirectories = gloModelFileBundle.TextureDirectories;
            var fps = 20;

            var glo = gloFile.Impl.ReadNew <Glo>(Endianness.LittleEndian);

            var textureFilesByName = new Dictionary <string, IFileHierarchyFile>();

            foreach (var textureDirectory in textureDirectories)
            {
                foreach (var textureFile in textureDirectory.Files)
                {
                    textureFilesByName[textureFile.Name.ToLower()] = textureFile;
                }
            }

            /*new MeshCsvWriter().WriteToFile(
             *  glo, new FinFile(Path.Join(outputDirectory.FullName, "mesh.csv")));
             * new FaceCsvWriter().WriteToFile(
             *  glo, new FinFile(Path.Join(outputDirectory.FullName, "face.csv")));
             * new VertexCsvWriter().WriteToFile(
             *  glo, new FinFile(Path.Join(outputDirectory.FullName, "vertex.csv")));*/

            var finModel = new ModelImpl();
            var finSkin  = finModel.Skin;

            var finRootBone = finModel.Skeleton.Root;

            var finTextureMap = new LazyDictionary <string, ITexture?>(
                textureFilename => {
                if (!textureFilesByName.TryGetValue(textureFilename.ToLower(),
                                                    out var textureFile))
                {
                    return(null);
                }

                using var rawTextureImage = FinImage.FromFile(textureFile.Impl);
                var textureImageWithAlpha =
                    GloModelLoader.AddTransparencyToGloImage_(rawTextureImage);

                var finTexture = finModel.MaterialManager.CreateTexture(
                    textureImageWithAlpha);
                finTexture.Name = textureFilename;

                if (this.mirrorTextures_.Contains(textureFilename))
                {
                    finTexture.WrapModeU = WrapMode.MIRROR_REPEAT;
                    finTexture.WrapModeV = WrapMode.MIRROR_REPEAT;
                }
                else
                {
                    finTexture.WrapModeU = WrapMode.REPEAT;
                    finTexture.WrapModeV = WrapMode.REPEAT;
                }

                return(finTexture);
            });
            var withCullingMap =
                new LazyDictionary <string, IMaterial>(textureFilename => {
                var finTexture = finTextureMap[textureFilename];
                if (finTexture == null)
                {
                    return(finModel.MaterialManager.AddStandardMaterial());
                }
                return(finModel.MaterialManager.AddTextureMaterial(finTexture));
            });
            var withoutCullingMap = new LazyDictionary <string, IMaterial>(
                textureFilename => {
                var finTexture        = finTextureMap[textureFilename];
                IMaterial finMaterial = finTexture == null
                                        ? finModel.MaterialManager
                                        .AddStandardMaterial()
                                        : finModel.MaterialManager
                                        .AddTextureMaterial(
                    finTexture);
                finMaterial.CullingMode = CullingMode.SHOW_BOTH;
                return(finMaterial);
            });

            var firstMeshMap = new Dictionary <string, GloMesh>();

            // TODO: Consider separating these out as separate models
            foreach (var gloObject in glo.Objects)
            {
                var finObjectRootBone = finRootBone.AddRoot(0, 0, 0);
                var meshQueue         = new Queue <(GloMesh, IBone)>();
                foreach (var topLevelGloMesh in gloObject.Meshes)
                {
                    meshQueue.Enqueue((topLevelGloMesh, finObjectRootBone));
                }

                List <(IAnimation, int, int)> finAndGloAnimations = new();
                foreach (var animSeg in gloObject.AnimSegs)
                {
                    var startFrame = (int)animSeg.StartFrame;
                    var endFrame   = (int)animSeg.EndFrame;

                    var finAnimation = finModel.AnimationManager.AddAnimation();
                    finAnimation.Name       = animSeg.Name;
                    finAnimation.FrameCount =
                        (int)(animSeg.EndFrame - animSeg.StartFrame + 1);

                    finAnimation.FrameRate = fps * animSeg.Speed;

                    finAndGloAnimations.Add((finAnimation, startFrame, endFrame));
                }

                while (meshQueue.Count > 0)
                {
                    var(gloMesh, parentFinBone) = meshQueue.Dequeue();

                    var name = gloMesh.Name;

                    GloMesh idealMesh;
                    if (!firstMeshMap.TryGetValue(name, out idealMesh))
                    {
                        firstMeshMap[name] = idealMesh = gloMesh;
                    }

                    var position = gloMesh.MoveKeys[0].Xyz;

                    var rotation   = gloMesh.RotateKeys[0];
                    var quaternion =
                        new Quaternion(rotation.X, rotation.Y, rotation.Z, rotation.W);
                    var xyzRadians = QuaternionUtil.ToEulerRadians(quaternion);

                    var scale = gloMesh.ScaleKeys[0].Scale;

                    var finBone = parentFinBone
                                  .AddChild(position.X, position.Y, position.Z)
                                  .SetLocalRotationRadians(
                        xyzRadians.X, xyzRadians.Y, xyzRadians.Z)
                                  .SetLocalScale(scale.X, scale.Y, scale.Z);
                    finBone.Name = name + "_bone";

                    var child = gloMesh.Pointers.Child;
                    if (child != null)
                    {
                        meshQueue.Enqueue((child, finBone));
                    }

                    var next = gloMesh.Pointers.Next;
                    if (next != null)
                    {
                        meshQueue.Enqueue((next, parentFinBone));
                    }

                    foreach (var(finAnimation, startFrame, endFrame) in
                             finAndGloAnimations)
                    {
                        var finBoneTracks = finAnimation.AddBoneTracks(finBone);

                        long prevTime = -1;
                        foreach (var moveKey in gloMesh.MoveKeys)
                        {
                            Asserts.True(moveKey.Time > prevTime);
                            prevTime = moveKey.Time;

                            if (!(moveKey.Time >= startFrame && moveKey.Time <= endFrame))
                            {
                                continue;
                            }

                            var time = (int)(moveKey.Time - startFrame);
                            Asserts.True(time >= 0 && time < finAnimation.FrameCount);

                            var moveValue = moveKey.Xyz;
                            finBoneTracks.Positions.Set(time, 0, moveValue.X);
                            finBoneTracks.Positions.Set(time, 1, moveValue.Y);
                            finBoneTracks.Positions.Set(time, 2, moveValue.Z);
                        }

                        prevTime = -1;
                        foreach (var rotateKey in gloMesh.RotateKeys)
                        {
                            Asserts.True(rotateKey.Time > prevTime);
                            prevTime = rotateKey.Time;

                            if (!(rotateKey.Time >= startFrame &&
                                  rotateKey.Time <= endFrame))
                            {
                                continue;
                            }

                            var time = (int)(rotateKey.Time - startFrame);
                            Asserts.True(time >= 0 && time < finAnimation.FrameCount);

                            var quaternionKey =
                                new Quaternion(rotateKey.X, rotateKey.Y, rotateKey.Z,
                                               rotateKey.W);
                            var xyzRadiansKey = QuaternionUtil.ToEulerRadians(quaternionKey);

                            finBoneTracks.Rotations.Set(time, 0,
                                                        xyzRadiansKey.X);
                            finBoneTracks.Rotations.Set(time, 1,
                                                        xyzRadiansKey.Y);
                            finBoneTracks.Rotations.Set(time, 2,
                                                        xyzRadiansKey.Z);
                        }

                        prevTime = -1;
                        foreach (var scaleKey in gloMesh.ScaleKeys)
                        {
                            Asserts.True(scaleKey.Time > prevTime);
                            prevTime = scaleKey.Time;

                            if (!(scaleKey.Time >= startFrame && scaleKey.Time <= endFrame))
                            {
                                continue;
                            }

                            var time = (int)(scaleKey.Time - startFrame);
                            Asserts.True(time >= 0 && time < finAnimation.FrameCount);

                            var scaleValue = scaleKey.Scale;
                            finBoneTracks.Scales.Set(time, 0, scaleValue.X);
                            finBoneTracks.Scales.Set(time, 1, scaleValue.Y);
                            finBoneTracks.Scales.Set(time, 2, scaleValue.Z);
                        }
                    }

                    // Anything with these names are debug objects and can be ignored.
                    if (this.hiddenNames_.Contains(name))
                    {
                        continue;
                    }

                    var finMesh = finSkin.AddMesh();
                    finMesh.Name = name;

                    var gloVertices = idealMesh.Vertices;

                    string    previousTextureName = null;
                    IMaterial?previousMaterial    = null;

                    foreach (var gloFace in idealMesh.Faces)
                    {
                        // TODO: What can we do if texture filename is empty?
                        var textureFilename = gloFace.TextureFilename;

                        var gloFaceColor = gloFace.Color;
                        var finFaceColor = ColorImpl.FromRgbaBytes(
                            gloFaceColor.R, gloFaceColor.G, gloFaceColor.B, gloFaceColor.A);

                        var enableBackfaceCulling = (gloFace.Flags & 1 << 2) == 0;

                        IMaterial?finMaterial;
                        if (textureFilename == previousTextureName)
                        {
                            finMaterial = previousMaterial;
                        }
                        else
                        {
                            previousTextureName = textureFilename;
                            finMaterial         = enableBackfaceCulling
                                ? withCullingMap[textureFilename]
                                : withoutCullingMap[textureFilename];
                            previousMaterial = finMaterial;
                        }

                        // Face flag:
                        // 0: potentially some kind of repeat mode??

                        var color = (gloFace.Flags & 1 << 6) != 0
                            ? ColorImpl.FromRgbaBytes(255, 0, 0, 255)
                            : ColorImpl.FromRgbaBytes(0, 255, 0, 255);

                        var finFaceVertices = new IVertex[3];
                        for (var v = 0; v < 3; ++v)
                        {
                            var gloVertexRef = gloFace.VertexRefs[v];
                            var gloVertex    = gloVertices[gloVertexRef.Index];

                            var finVertex = finSkin
                                            .AddVertex(gloVertex.X, gloVertex.Y, gloVertex.Z)
                                            .SetUv(gloVertexRef.U, gloVertexRef.V);
                            //.SetColor(color);
                            finVertex.SetBoneWeights(finSkin.GetOrCreateBoneWeights(
                                                         PreprojectMode.BONE, finBone));
                            finFaceVertices[v] = finVertex;
                        }

                        // TODO: Merge triangles together
                        var finTriangles = new (IVertex, IVertex, IVertex)[1];
        private System.Collections.IEnumerator DoUpdateRoutine()
        {
            while (true)
            {
                if (_linkTarget != null)
                {
                    Constraint c;
                    var        trans = this.transform;

                    //constrain position
                    c = (_constraint & Constraint.Position);
                    if (c == Constraint.Position)
                    {
                        if (_doPositionDamping)
                        {
                            switch (_positionDampingStyle)
                            {
                            case JointDampingStyle.Ease:
                                trans.position = Vector3.Lerp(trans.position, _linkTarget.position, Time.deltaTime * _positionDampingStrength);
                                break;

                            case JointDampingStyle.Linear:
                                trans.position = Vector3.MoveTowards(trans.position, _linkTarget.position, Time.deltaTime * _positionDampingStrength);
                                break;

                            case JointDampingStyle.Elastic:
                            {
                                var tpos = _linkTarget.position;
                                var pos  = trans.position;
                                if (_positionDampingStrength < 0.0001f)
                                {
                                    trans.position = tpos;
                                    break;
                                }

                                float t = 1f - Mathf.Clamp01(1f / _positionDampingStrength) * 0.99f;
                                tpos          += (tpos - pos);
                                trans.position = Vector3.LerpUnclamped(pos, tpos, t);
                            }
                            break;
                            }
                        }
                        else
                        {
                            trans.position = _linkTarget.position;
                        }
                    }
                    else if (c != 0)
                    {
                        Vector3 pos  = trans.position;
                        Vector3 tpos = _linkTarget.position;

                        if ((_constraint & Constraint.XPosition) != 0)
                        {
                            if (_doPositionDamping)
                            {
                                pos.x = DampFloat(pos.x, tpos.x, Time.deltaTime, _positionDampingStrength, _positionDampingStyle);
                            }
                            else
                            {
                                pos.x = tpos.x;
                            }
                        }
                        if ((_constraint & Constraint.YPosition) != 0)
                        {
                            if (_doPositionDamping)
                            {
                                pos.y = DampFloat(pos.y, tpos.y, Time.deltaTime, _positionDampingStrength, _positionDampingStyle);
                            }
                            else
                            {
                                pos.y = tpos.y;
                            }
                        }
                        if ((_constraint & Constraint.ZPosition) != 0)
                        {
                            if (_doPositionDamping)
                            {
                                pos.z = DampFloat(pos.z, tpos.z, Time.deltaTime, _positionDampingStrength, _positionDampingStyle);
                            }
                            else
                            {
                                pos.z = tpos.z;
                            }
                        }

                        trans.position = pos;
                    }

                    //constrain rotation
                    c = (_constraint & Constraint.Rotation);
                    if (c == Constraint.Rotation)
                    {
                        if (_doRotationDamping)
                        {
                            switch (_positionDampingStyle)
                            {
                            case JointDampingStyle.Ease:
                                trans.rotation = Quaternion.Slerp(trans.rotation, _linkTarget.rotation, Time.deltaTime * _positionDampingStrength);
                                break;

                            case JointDampingStyle.Linear:
                                trans.rotation = Quaternion.RotateTowards(trans.rotation, _linkTarget.rotation, Time.deltaTime * _positionDampingStrength);
                                break;

                            case JointDampingStyle.Elastic:
                            {
                                var tpos = _linkTarget.rotation;
                                var pos  = trans.rotation;
                                if (_positionDampingStrength < 0.0001f)
                                {
                                    trans.rotation = tpos;
                                    break;
                                }

                                float t = 1f - Mathf.Clamp01(1f / _positionDampingStrength) * 0.99f;
                                tpos          *= QuaternionUtil.FromToRotation(pos, tpos);
                                trans.rotation = Quaternion.SlerpUnclamped(pos, tpos, t);
                            }
                            break;
                            }
                        }
                        else
                        {
                            trans.rotation = _linkTarget.rotation;
                        }
                    }
                    else if (c != 0)
                    {
                        var rot     = trans.eulerAngles;
                        var targRot = _linkTarget.eulerAngles;
                        if ((_constraint & Constraint.XRotation) != 0)
                        {
                            if (_doRotationDamping)
                            {
                                rot.x = DampFloat(rot.x, targRot.x, Time.deltaTime, _rotationDampingStrength, _rotationDampingStyle);
                            }
                            else
                            {
                                rot.x = targRot.x;
                            }
                        }
                        if ((_constraint & Constraint.YRotation) != 0)
                        {
                            if (_doRotationDamping)
                            {
                                rot.y = DampFloat(rot.y, targRot.y, Time.deltaTime, _rotationDampingStrength, _rotationDampingStyle);
                            }
                            else
                            {
                                rot.y = targRot.y;
                            }
                        }
                        if ((_constraint & Constraint.ZRotation) != 0)
                        {
                            if (_doRotationDamping)
                            {
                                rot.z = DampFloat(rot.z, targRot.z, Time.deltaTime, _rotationDampingStrength, _rotationDampingStyle);
                            }
                            else
                            {
                                rot.z = targRot.z;
                            }
                        }
                        trans.eulerAngles = rot;
                    }
                }

                switch (_updateMode)
                {
                case UpdateSequence.None:
                case UpdateSequence.Update:
                    yield return(null);

                    break;

                case UpdateSequence.FixedUpdate:
                    yield return(RadicalCoroutine.WaitForFixedUpdate);

                    break;

                case UpdateSequence.LateUpdate:
                    yield return(WaitForLateUpdate.Create());

                    break;
                }
            }
        }
示例#27
0
 public static bool IsNaN(Trans t)
 {
     return(VectorUtil.IsNaN(t.Position) || VectorUtil.IsNaN(t.Scale) || QuaternionUtil.IsNaN(t.Rotation));
 }
示例#28
0
        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
        {
            var r0 = new Rect(position.xMin, position.yMin, position.width / 2f, position.height);
            var r1 = new Rect(r0.xMax, position.yMin, position.width - r0.width, position.height);

            var propName  = property.FindPropertyRelative(PROP_NAME);
            var propValue = property.FindPropertyRelative(PROP_VALUE);
            var propRef   = property.FindPropertyRelative(PROP_REF);

            int index = System.Array.IndexOf(_knownPlayerSettingPropNames, propName.stringValue);

            EditorGUI.BeginChangeCheck();
            index = EditorGUI.Popup(r0, GUIContent.none, index, _knownPlayerSettingPropNamesPretty);
            if (EditorGUI.EndChangeCheck())
            {
                if (index >= 0 && index < _knownPlayerSettingPropNames.Length)
                {
                    propName.stringValue = _knownPlayerSettingPropNames[index];
                }
                else
                {
                    propName.stringValue = string.Empty;
                }

                propValue.stringValue        = string.Empty;
                propRef.objectReferenceValue = null;
            }

            if (index < 0 || index >= _knownPlayerSettings.Length)
            {
                return;
            }

            var info = _knownPlayerSettings[index];

            if (info.PropertyType.IsEnum)
            {
                int ei = ConvertUtil.ToInt(propValue.stringValue);
                propValue.stringValue        = ConvertUtil.ToInt(EditorGUI.EnumPopup(r1, ConvertUtil.ToEnumOfType(info.PropertyType, ei))).ToString();
                propRef.objectReferenceValue = null;
            }
            else
            {
                var etp = VariantReference.GetVariantType(info.PropertyType);
                switch (etp)
                {
                case VariantType.Null:
                    propValue.stringValue        = string.Empty;
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.String:
                    propValue.stringValue        = EditorGUI.TextField(r1, propValue.stringValue);
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.Boolean:
                    propValue.stringValue        = EditorGUI.Toggle(r1, GUIContent.none, ConvertUtil.ToBool(propValue.stringValue)).ToString();
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.Integer:
                    propValue.stringValue        = EditorGUI.IntField(r1, GUIContent.none, ConvertUtil.ToInt(propValue.stringValue)).ToString();
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.Float:
                    propValue.stringValue        = EditorGUI.FloatField(r1, GUIContent.none, ConvertUtil.ToSingle(propValue.stringValue)).ToString();
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.Double:
                    propValue.stringValue        = EditorGUI.DoubleField(r1, GUIContent.none, ConvertUtil.ToDouble(propValue.stringValue)).ToString();
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.Vector2:
                    propValue.stringValue        = VectorUtil.Stringify(EditorGUI.Vector2Field(r1, GUIContent.none, ConvertUtil.ToVector2(propValue.stringValue)));
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.Vector3:
                    propValue.stringValue        = VectorUtil.Stringify(EditorGUI.Vector3Field(r1, GUIContent.none, ConvertUtil.ToVector3(propValue.stringValue)));
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.Vector4:
                    propValue.stringValue        = VectorUtil.Stringify(EditorGUI.Vector4Field(r1, (string)null, ConvertUtil.ToVector4(propValue.stringValue)));
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.Quaternion:
                    propValue.stringValue        = QuaternionUtil.Stringify(SPEditorGUI.QuaternionField(r1, GUIContent.none, ConvertUtil.ToQuaternion(propValue.stringValue)));
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.Color:
                    propValue.stringValue        = ConvertUtil.ToInt(EditorGUI.ColorField(r1, ConvertUtil.ToColor(propValue.stringValue))).ToString();
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.DateTime:
                    //TODO - should never actually occur
                    propValue.stringValue        = string.Empty;
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.GameObject:
                case VariantType.Component:
                case VariantType.Object:
                    propValue.stringValue        = string.Empty;
                    propRef.objectReferenceValue = EditorGUI.ObjectField(r1, GUIContent.none, propValue.objectReferenceValue, info.PropertyType, false);
                    break;

                case VariantType.LayerMask:
                    propValue.stringValue        = SPEditorGUI.LayerMaskField(r1, GUIContent.none, ConvertUtil.ToInt(propValue.stringValue)).ToString();
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.Rect:
                    //TODO - should never actually occur
                    propValue.stringValue        = string.Empty;
                    propRef.objectReferenceValue = null;
                    break;

                case VariantType.Numeric:

                    break;
                }
            }
        }
示例#29
0
 public static IFinMatrix4x4 FromRotation(IRotation rotation)
 => MatrixTransformUtil.FromRotation(QuaternionUtil.Create(rotation));
示例#30
0
 // Find rotation vector displacement between two quaternions (from q1 to q2)
 public static Vector3 Disp(Quaternion q1, Quaternion q2)
 {
     return(QuaternionUtil.Log(Quaternion.Inverse(q1) * q2));
 }