Exemple #1
0
 public Position Inverse()
 {
     return(new Position(
                rot.Inverse().Xform(-pos),
                rot.Inverse()
                ));
 }
    //Apply the hinge rotation limit

    private Quat LimitHinge(Quat rotation)
    {
        // If limit is zero return rotation fixed to axis
        if (min == 0 && max == 0 && useLimits)
        {
            return(Quat.AngleAxis(0, axis));
        }

        // Get 1 degree of freedom rotation along axis
        Quat free1DOF = Limit1DOF(rotation, axis);

        if (!useLimits)
        {
            return(free1DOF);
        }

        // Get offset from last rotation in angle-axis representation
        Quat addR = free1DOF * Quat.Inverse(lastRotation);

        float addA = Quat.Angle(Quat.identity, addR);

        Vec3 secondaryAxis = new Vec3(axis.z, axis.x, axis.y);
        Vec3 cross         = secondaryAxis.CrossProduct(axis);

        if (cross.DotProduct(addR * secondaryAxis) > 0f)
        {
            addA = -addA;
        }

        // Clamp to limits
        lastAngle = Mathf.Clamp(lastAngle + addA, min, max);

        return(Quat.AngleAxis(lastAngle, axis));
    }
Exemple #3
0
    public static Quat Slerping(Quat lhs, Quat rhs, float t)
    {
        t = Mathf.Clamp(t, 0.0f, 1.0f);
        Quat    d         = rhs * lhs.Inverse();
        Vector4 AxisAngle = d.GetAxisAngle();
        Quat    dt        = new Quat(AxisAngle.w * t, new MyVector3(AxisAngle.x, AxisAngle.y, AxisAngle.z));

        return(dt * lhs);
    }
        public static Quat SLERP(Quat q, Quat r, float t)
        {
            t = Mathf.Clamp(t, 0.0f, 1.0f);
            Quat    d         = r * q.Inverse();
            Vector4 AxisAngle = d.GetAxisAngle();
            Quat    dT        = new Quat(AxisAngle.w * t, new Vector3(AxisAngle.x, AxisAngle.y, AxisAngle.z));

            return(dT * q);
        }
Exemple #5
0
    public static float Angle(Quat lhs, Quat rhs)
    {
        lhs.Normalize();
        rhs.Normalize();

        rhs.Inverse();
        Quat q = Multiply(lhs, rhs);

        return(2 * Mathf.Acos(q.w) * Mathf.Rad2Deg);
    }
    void orbit()
    {
        angle += Time.deltaTime * orbitSpeed * speedScalar;
        Quat q = new Quat(angle, new Vector3(0, 1, 0));
        //positionVector is used to set how far from the sun the object orbits
        Vector3 p    = positionVector;
        Quat    k    = new Quat(1.0f, p);
        Quat    newk = q * k * q.Inverse();
        Vector3 newp = newk.GetAxis();

        transform.position = newp;
    }
Exemple #7
0
    //function for applying the transformations to the object model
    public void transformModel()
    {
        applyMouseInputs();
        Vector3[] TransformedVertices = new Vector3[ModelSpaceVertices.Length];
        //set quaternions to rotate by
        Quat q1 = new Quat(pitchAng - lastpitchAng, new Vector3(1, 0, 0));
        Quat q2 = new Quat(yawAng - lastyawAng, new Vector3(0, 1, 0));
        Quat q3 = new Quat(rollAng - lastrollAng, new Vector3(0, 0, 1));

        //rotate orientation quaternion by pitch yaw and roll quaternion representations;
        q = ((q * q2) * q1) * q3;
        for (int i = 0; i < TransformedVertices.Length; i++)
        {
            //rotate each vertex by the orientation from model space;
            Quat    K        = new Quat(ModelSpaceVertices[i]);
            Quat    newK     = q * K * q.Inverse();
            Vector3 newP     = newK.GetAxis();
            Vector3 quatVert = newP;

            //scale each vertex by the scale multiplier;
            Matrix4by4 sMatrix = scale(scaleMul);
            Vector3    scaVert = sMatrix * quatVert;

            //translate the object so it will be a set distance ahead of the player;
            Matrix4by4 tMat     = translate(new Vector3(0, 0, distanceAhead));
            Vector4    ratVert  = new Vector4(scaVert.x, scaVert.y, scaVert.z, 1);
            Vector4    scatVert = tMat * ratVert;

            //rotate the object around the origin(camera), so it is always in front of the camera;
            Matrix4by4 yawMatrix   = yawRot(g);
            Matrix4by4 pitchMatrix = pitchRot(y);
            Matrix4by4 pyMatrix    = yawMatrix * pitchMatrix;
            Vector3    scarotVert  = pyMatrix * scatVert;

            //translate the object so it is correctly positioned in the world;
            Matrix4by4 tMatrix   = translate(new Vector3(pos.x, 0, pos.z));
            Vector4    tVert     = new Vector4(scarotVert.x, scarotVert.y, scarotVert.z, 1);
            Vector4    finalVert = tMatrix * tVert;
            TransformedVertices[i] = finalVert;
        }
        //set mesh to the transformed vertices
        MeshFilter MF = GetComponent <MeshFilter>();

        MF.mesh.vertices = TransformedVertices;
        MF.mesh.RecalculateBounds();
        MF.mesh.RecalculateNormals();

        //sets angles so it doesn't accumulate and increase speed over time;
        lastpitchAng = pitchAng;
        lastyawAng   = yawAng;
        lastrollAng  = rollAng;
    }
Exemple #8
0
        public static Vector3f AngularVelocity(Quat previous, Quat rotation, float deltaTime)
        {
            // https://www.gamedev.net/forums/topic/347752-quaternion-and-angular-velocity/

            var q = rotation * Quat.Inverse(previous);

            float length = Math.Sqrt(q.x * q.x + q.y * q.y + q.z * q.z);

            if (length <= Math.Epsilon)
            {
                return(new Vector3f(2f * q.x, 2f * q.y, 2f * q.z));
            }

            float angle = 2f * Math.Atan2(length, q.w);

            return((new Vector3f(q.x, q.y, q.z)) * (angle / (length * deltaTime)));
        }
    // Update is called once per frame
    void Update()
    {
        Vector3[] TransformedVertices = new Vector3[ModelSpaceVertices.Length];
        angle    += Time.deltaTime * 1;
        Rotation *= new Quat(EulerMaths.DegtoRag(RotationSpeed), VectorMaths.VectorNormalised(new Vector3(0, 1, 0)));
        for (int i = 0; i < TransformedVertices.Length; i++)
        {
            Quat    p      = new Quat(ModelSpaceVertices[i]);
            Quat    newp   = ((Rotation * p) * Rotation.Inverse());
            Vector3 newpos = newp.GetAxisAngle();
            TransformedVertices[i] = newpos;
        }
        MeshFilter MF = GetComponent <MeshFilter>();

        MF.mesh.vertices = TransformedVertices;
        MF.mesh.RecalculateNormals();
        MF.mesh.RecalculateBounds();
    }
Exemple #10
0
        public static void Calculate(Vector3f top, Vector3f mid, Vector3f low, Vector3f target, Vector3f hint, Quat topRotation, Quat midRotation, ref Quat topLocalRotation, ref Quat midLocalRotation)
        {
            // Epsilon is used to prevent the chain to be fully extended (in order to prevent float point errors).
            float epsilon         = 0.0001f;
            float lengthTopMid    = (mid - top).length;
            float lengthMidLow    = (low - mid).length;
            float lengthTopLow    = (low - top).length;
            float lengthTopTarget = Math.Clamp((target - top).length, epsilon, lengthTopMid + lengthMidLow - epsilon);

            // Get angle difference using current and desired angle for mid.
            // Axis is multiplied by the inverse of mid global rotation in order to make the new rotation in local space (this is done every time).
            float    currentMidAngle  = Math.TriangleAngle(lengthTopLow, lengthTopMid, lengthMidLow);
            float    desiredMidAngle  = Math.TriangleAngle(lengthTopTarget, lengthTopMid, lengthMidLow);
            float    midAngleDiff     = (currentMidAngle - desiredMidAngle);
            Vector3f midAxis          = Vector3f.Normalize(Vector3f.Cross(top - mid, mid - low));
            Quat     finalMidRotation = new Quat(midAngleDiff, Quat.Inverse(midRotation) * midAxis);

            midLocalRotation *= finalMidRotation;

            // Rotate low in global space.
            Vector3f rotatedLow = (new Quat(midAngleDiff, midAxis) * (low - mid)) + mid;

            // Get angle difference by calculating the angle between top-low-target.
            float    topAngleDiff     = Vector3f.Angle(rotatedLow - top, target - top);
            Vector3f topAxis          = Vector3f.Normalize(Vector3f.Cross(rotatedLow - top, target - top));
            Quat     finalTopRotation = new Quat(topAngleDiff, Quat.Inverse(topRotation) * topAxis);

            topLocalRotation *= finalTopRotation;

            // Rotate mid and low (again) in global space.
            Vector3f rotatedMid     = (new Quat(topAngleDiff, topAxis) * (mid - top)) + top;
            Vector3f lastRotatedLow = (new Quat(topAngleDiff, topAxis) * new Quat(midAngleDiff, midAxis) * (low - mid)) + rotatedMid;

            // Get a plane using top and the normal top-low (rotated).
            // This will be used to calculate how many degrees needs top to be rotated in order to align mid with hint position (top and low won't be moved).
            Vector3f planeNormal            = Vector3f.Normalize(top - lastRotatedLow);
            var      plane                  = new Plane(planeNormal, top);
            Vector3f projectedMid           = plane.ClosestPoint(rotatedMid);
            Vector3f projectedHint          = plane.ClosestPoint(hint);
            float    angleDiff              = Vector3f.SignedAngle(top - projectedMid, top - projectedHint, plane.normal);
            Quat     finalAdjustTopRotation = new Quat(angleDiff, Quat.Inverse(topRotation) * planeNormal);

            topLocalRotation = finalAdjustTopRotation * topLocalRotation;
        }
    // Update is called once per frame
    void Update()
    {
        t += Time.deltaTime * 0.5f;
        //defining two rotations
        Quat q = new Quat(Mathf.PI * 1.0f, new Vector3(0, 1, 0));
        Quat r = new Quat(Mathf.PI * 0.5f, new Vector3(1, 0, 0));
        //slerped value
        Quat slerped = Quat.SLERP(q, r, t);
        //define vector that will be rotated
        Vector3 p = new Vector3(0, 8, 0);
        //store that vector in a quaternion
        Quat K = new Quat(p);
        //newk will have new position inside
        Quat newK = slerped * K * slerped.Inverse();
        //get this position as avector
        Vector3 newP = newK.GetAxis();

        transform.position = newP;
    }
    //rotates the vertices of the planet model using the custom-made quaternions
    void Rotate()
    {
        Vector3[] TransformedVertices = new Vector3[ModelSpaceVertices.Length];
        rotAngle += Time.deltaTime * rotSpeed * speedScalar;
        Quat Rotation = new Quat(VectorMaths.DegToRad(rotAngle), VectorMaths.VectorNormalize(new Vector3(1, 1, 1)));

        for (int i = 0; i < TransformedVertices.Length; i++)
        {
            Quat    p      = new Quat(ModelSpaceVertices[i]);
            Quat    newp   = ((Rotation * p) * Rotation.Inverse());
            Vector3 newpos = newp.GetAxisAngle();
            TransformedVertices[i] = newpos;
        }
        // TransformedVertices[0].x = -300;
        MeshFilter MF = GetComponent <MeshFilter>();

        MF.mesh.vertices = TransformedVertices;
        MF.mesh.RecalculateNormals();
        MF.mesh.RecalculateBounds();
    }
Exemple #13
0
    void RotatePlanet() //Same concept just x it by all the vertices e.t.c
    {
        Vector3[] TransformedVertices = new Vector3[ModelSpaceVertices.Length];
        angle += Time.deltaTime * 50;
        Quat Rotation = new Quat(VectorMaths.DegToRad(angle), VectorMaths.VectorNormalize(new Vector3(1, 1, 1)));

        for (int i = 0; i < TransformedVertices.Length; i++)
        {
            Quat    p      = new Quat(ModelSpaceVertices[i]);
            Quat    newp   = ((Rotation * p) * Rotation.Inverse());
            Vector3 newpos = newp.GetAxisAngle();
            TransformedVertices[i] = newpos;
        }
        // TransformedVertices[0].x = -300;
        MeshFilter MF = GetComponent <MeshFilter>();

        MF.mesh.vertices = TransformedVertices;
        MF.mesh.RecalculateNormals();
        MF.mesh.RecalculateBounds();
    }
Exemple #14
0
    //function for applying transformation to the demo object, rotating around to always face the player to make it easier to work out the correct orientation. functions the same as transformModel();
    public void transformDemo()
    {
        Vector3[] TransformedVertices = new Vector3[ModelSpaceVertices.Length];
        Quat      q1 = new Quat(pitchAng - lastpitchAng, new Vector3(1, 0, 0));
        Quat      q2 = new Quat(yawAng - lastyawAng, new Vector3(0, 1, 0));
        Quat      q3 = new Quat(rollAng - lastrollAng, new Vector3(0, 0, 1));

        q = ((q * q2) * q1) * q3;
        for (int i = 0; i < TransformedVertices.Length; i++)
        {
            Quat    K    = new Quat(ModelSpaceVertices[i]);
            Quat    newK = q * K * q.Inverse();
            Vector3 newP = newK.GetAxis();

            Vector3 quatVert = newP;

            Matrix4by4 sMatrix = scale(scaleMul);
            Vector3    scaVert = sMatrix * quatVert;

            Matrix4by4 yawMatrix = new Matrix4by4(new Vector3(Mathf.Cos(g), 0, -Mathf.Sin(g)),
                                                  new Vector3(0, 1, 0),
                                                  new Vector3(Mathf.Sin(g), 0, Mathf.Cos(g)),
                                                  Vector3.zero);
            Vector3 scarotVert = yawMatrix * scaVert;

            Matrix4by4 tMatrix   = translate(new Vector3(pos.x, 0, pos.z));
            Vector4    tVert     = new Vector4(scarotVert.x, scarotVert.y, scarotVert.z, 1);
            Vector4    finalVert = tMatrix * tVert;
            TransformedVertices[i] = finalVert;
        }
        MeshFilter MF = GetComponent <MeshFilter>();

        MF.mesh.vertices = TransformedVertices;
        MF.mesh.RecalculateBounds();
        MF.mesh.RecalculateNormals();

        lastpitchAng = pitchAng;
        lastyawAng   = yawAng;
        lastrollAng  = rollAng;
    }
Exemple #15
0
    //Returns the limited local rotation.
    public Quat GetLimitedLocalRotation(Quat localRotation, out bool changed)
    {
        // Making sure the Rotation Limit is initiated
        if (!initiated)
        {
            Awake();
        }

        // Subtracting defaultLocalRotation
        Quat rotation = Quat.Inverse(defaultLocalRotation) * localRotation;

        Quat limitedRotation = LimitRotation(rotation);

        changed = limitedRotation != rotation;

        if (!changed)
        {
            return(localRotation);
        }

        // Apply defaultLocalRotation back on
        return(defaultLocalRotation * limitedRotation);
    }
Exemple #16
0
 public static Quat Inverse(Quat q)
 {
     return(Quat.Inverse(q));
 }
Exemple #17
0
        public void Quat4()
        {
            FQuat fq  = FQuat.Euler(( Fix64 )45, ( Fix64 )(-23), ( Fix64 )(-48.88));
            FQuat fq2 = FQuat.Euler(( Fix64 )23, ( Fix64 )(-78), ( Fix64 )(-132.43f));
            Quat  q   = Quat.Euler(45, -23, -48.88f);
            Quat  q2  = Quat.Euler(23, -78, -132.43f);
            FVec3 fv  = new FVec3(12.5f, 9, 8);
            FVec3 fv2 = new FVec3(1, 0, 0);
            Vec3  v   = new Vec3(12.5f, 9, 8);
            Vec3  v2  = new Vec3(1, 0, 0);

            this._output.WriteLine(fq.ToString());
            this._output.WriteLine(q.ToString());
            this._output.WriteLine(fq2.ToString());
            this._output.WriteLine(q2.ToString());
            Fix64 fa = FQuat.Angle(fq, fq2);
            float a  = Quat.Angle(q, q2);

            this._output.WriteLine(fa.ToString());
            this._output.WriteLine(a.ToString());
            fq = FQuat.AngleAxis(( Fix64 )(-123.324), fv);
            q  = Quat.AngleAxis(-123.324f, v);
            this._output.WriteLine(fq.ToString());
            this._output.WriteLine(q.ToString());
            fa = FQuat.Dot(fq, fq2);
            a  = Quat.Dot(q, q2);
            this._output.WriteLine(fa.ToString());
            this._output.WriteLine(a.ToString());
            fq = FQuat.FromToRotation(FVec3.Normalize(fv), fv2);
            q  = Quat.FromToRotation(Vec3.Normalize(v), v2);
            this._output.WriteLine(fq.ToString());
            this._output.WriteLine(q.ToString());
            fq = FQuat.Lerp(fq, fq2, ( Fix64 )0.66);
            q  = Quat.Lerp(q, q2, 0.66f);
            this._output.WriteLine(fq.ToString());
            this._output.WriteLine(q.ToString());
            fq = FQuat.Normalize(fq);
            q.Normalize();
            this._output.WriteLine(fq.ToString());
            this._output.WriteLine(q.ToString());
            fq.Inverse();
            q = Quat.Inverse(q);
            this._output.WriteLine(fq.ToString());
            this._output.WriteLine(q.ToString());
            fv = FQuat.Orthogonal(fv);
            v  = Quat.Orthogonal(v);
            this._output.WriteLine(fv.ToString());
            this._output.WriteLine(v.ToString());
            fq = FQuat.Slerp(fq, fq2, ( Fix64 )0.66);
            q  = Quat.Slerp(q, q2, 0.66f);
            this._output.WriteLine(fq.ToString());
            this._output.WriteLine(q.ToString());
            fq = FQuat.LookRotation(FVec3.Normalize(fv), fv2);
            q  = Quat.LookRotation(Vec3.Normalize(v), v2);
            this._output.WriteLine(fq.ToString());
            this._output.WriteLine(q.ToString());
            fq.ToAngleAxis(out fa, out fv);
            q.ToAngleAxis(out a, out v);
            this._output.WriteLine(fa.ToString());
            this._output.WriteLine(a.ToString());
            this._output.WriteLine(fv.ToString());
            this._output.WriteLine(v.ToString());
            fq = fq.Conjugate();
            q  = q.Conjugate();
            this._output.WriteLine(fq.ToString());
            this._output.WriteLine(q.ToString());
            fq.SetLookRotation(FVec3.Normalize(fv), fv2);
            q.SetLookRotation(Vec3.Normalize(v), v2);
            this._output.WriteLine(fq.ToString());
            this._output.WriteLine(q.ToString());
        }
Exemple #18
0
    public static float AngleTo(Quat from, Quat to)
    {
        float result = Mathf.Acos((from.Inverse() * to).Normalized().w) * 2.0f;

        return(result);
    }
Exemple #19
0
        private static void LegSolvePatch(IntPtr thisPtr, byte boolValue, IntPtr methodPtr)
        {
            var kneeMode = IkTweaksSettings.IktKneeMode.Value;

            if (kneeMode != KneeBendNormalMode.Default && ourLastIkController.field_Private_IkType_0 == IkController.IkType.SixPoint && (thisPtr == ourCachedSolver.LeftLeg.Pointer || thisPtr == ourCachedSolver.RightLeg.Pointer))
            {
                var isLeftLeg  = thisPtr == ourCachedSolver.LeftLeg.Pointer;
                var currentLeg = isLeftLeg
                    ? ourCachedSolver.LeftLeg
                    : ourCachedSolver.RightLeg;

                var weight           = currentLeg.bendGoalWeight;
                var oldUseKneeTarget = currentLeg.vrcUseKneeTarget;
                if (weight < 1)
                {
                    Float3 newNormal;
                    var    currentLegBones = isLeftLeg ? ourCachedSolver.LeftLegBones : ourCachedSolver.RightLegBones;
                    if (kneeMode == KneeBendNormalMode.Classic)
                    {
                        newNormal = (Quat)currentLeg.IKRotation * currentLeg.vrcBendNormalRelToFoot;
                    }
                    else
                    {
                        var baseFootUpDirectionG = currentLegBones[1].solverPosition - (Float3)currentLegBones[2].solverPosition;
                        var baseKneeBendGoalDirectionRelToFoot = (Quat)currentLeg.rotation * Quat.Inverse(currentLegBones[2].solverRotation) * baseFootUpDirectionG;
                        var legRootToFoot      = (Float3)currentLeg.position - (Float3)currentLegBones[0].solverPosition;
                        var newNormalCandidate = Float3.Cross(baseKneeBendGoalDirectionRelToFoot.normalized, legRootToFoot.normalized);

                        // mix between "dumb" normal and "smart" one based on cross product length;
                        // longer cross = presumably higher precision so mix more of "smart" normal in
                        var newNormalLength = newNormalCandidate.magnitude;
                        var baseNormal      = (Quat)currentLeg.IKRotation * currentLeg.vrcBendNormalRelToFoot;
                        newNormal = Float3.Lerp(baseNormal.normalized, newNormalCandidate, newNormalLength).normalized;
                    }

                    // this neat little thing seemingly makes VRC recalculate the normal in some weird way
                    // but also... we set it ourself? whatever
                    currentLeg.vrcUseKneeTarget = false;

                    currentLeg.bendNormal = Float3.Lerp(newNormal, currentLeg.bendNormal, weight);
                }

                ourOriginalLegSolve(thisPtr, boolValue, methodPtr);

                currentLeg.vrcUseKneeTarget = oldUseKneeTarget;

                return;
            }

            ourOriginalLegSolve(thisPtr, boolValue, methodPtr);
        }
Exemple #20
0
 public Vec3 VectorToLocal(Vec3 point)
 {
     return(Quat.Inverse(Quat.FromToRotation(Vec3.right, this.property.direction)) * point);
 }
Exemple #21
0
 public Vec3 PointToLocal(Vec3 point)
 {
     return(Quat.Inverse(Quat.FromToRotation(Vec3.right, this.property.direction)) * (point - this.property.position));
 }