Beispiel #1
0
        public bool Equals(Quaternion rhs, Real tolerance)
        {
            Real fCos  = Dot(rhs);
            Real angle = (Real)Utility.ACos(fCos);

            return(Utility.Abs(angle) <= tolerance);
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="time"></param>
        /// <param name="quatA"></param>
        /// <param name="quatB"></param>
        /// <param name="useShortestPath"></param>
        /// <returns></returns>
        public static Quaternion Slerp(Real time, Quaternion quatA, Quaternion quatB, bool useShortestPath)
        {
            Real cos = quatA.Dot(quatB);

            Real angle = (Real)Utility.ACos(cos);

            if (Utility.Abs(angle) < EPSILON)
            {
                return(quatA);
            }

            Real sin        = Utility.Sin(angle);
            Real inverseSin = 1.0f / sin;
            Real coeff0     = Utility.Sin((1.0f - time) * angle) * inverseSin;
            Real coeff1     = Utility.Sin(time * angle) * inverseSin;

            Quaternion result;

            if (cos < 0.0f && useShortestPath)
            {
                coeff0 = -coeff0;
                // taking the complement requires renormalisation
                Quaternion t = coeff0 * quatA + coeff1 * quatB;
                t.Normalize();
                result = t;
            }
            else
            {
                result = (coeff0 * quatA + coeff1 * quatB);
            }

            return(result);
        }
Beispiel #3
0
        /// <summary>
        ///		Calculates the logarithm of a Quaternion.
        /// </summary>
        /// <returns></returns>
        public Quaternion Log()
        {
            // BLACKBOX: Learn this
            // If q = cos(A)+sin(A)*(x*i+y*j+z*k) where (x,y,z) is unit length, then
            // log(q) = A*(x*i+y*j+z*k).  If sin(A) is near zero, use log(q) =
            // sin(A)*(x*i+y*j+z*k) since sin(A)/A has limit 1.

            // start off with a zero quat
            Quaternion result = Quaternion.Zero;

            if (Utility.Abs(w) < 1.0f)
            {
                Real angle = (Real)Utility.ACos(w);
                Real sin   = Utility.Sin(angle);

                if (Utility.Abs(sin) >= EPSILON)
                {
                    Real coeff = angle / sin;
                    result.x = coeff * x;
                    result.y = coeff * y;
                    result.z = coeff * z;
                }
                else
                {
                    result.x = x;
                    result.y = y;
                    result.z = z;
                }
            }

            return(result);
        }
Beispiel #4
0
        public bool Equals(Quaternion rhs, float tolerance)
        {
            float fCos  = Dot(rhs);
            float angle = (float)Utility.ACos(fCos);

            return(Utility.Abs(angle) <= tolerance);
        }
Beispiel #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="angle"></param>
        /// <param name="axis"></param>
        /// <returns></returns>
        public void ToAngleAxis(ref Real angle, ref Vector3 axis)
        {
            // The quaternion representing the rotation is
            //   q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k)

            Real sqrLength = x * x + y * y + z * z;

            if (sqrLength > 0.0f)
            {
                angle = 2.0f * (Real)Utility.ACos(w);
                Real invLength = Utility.InvSqrt(sqrLength);
                axis.X = x * invLength;
                axis.Y = y * invLength;
                axis.Z = z * invLength;
            }
            else
            {
                angle  = 0.0f;
                axis.X = 1.0f;
                axis.Y = 0.0f;
                axis.Z = 0.0f;
            }
        }
Beispiel #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="angle"></param>
        /// <param name="axis"></param>
        /// <returns></returns>
        public void ToAngleAxis(ref Real angle, ref Vector3 axis)
        {
            // The quaternion representing the rotation is
            //   q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k)

            var sqrLength = this.x * this.x + this.y * this.y + this.z * this.z;

            if (sqrLength > 0.0f)
            {
                angle = 2.0f * (Real)Utility.ACos(this.w);
                var invLength = Utility.InvSqrt(sqrLength);
                axis.x = this.x * invLength;
                axis.y = this.y * invLength;
                axis.z = this.z * invLength;
            }
            else
            {
                angle  = 0.0f;
                axis.x = 1.0f;
                axis.y = 0.0f;
                axis.z = 0.0f;
            }
        }
Beispiel #7
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="angle"></param>
        /// <param name="axis"></param>
        /// <returns></returns>
        public void ToAngleAxis(ref float angle, ref Vector3 axis)
        {
            // The quaternion representing the rotation is
            //   q = cos(A/2)+sin(A/2)*(x*i+y*j+z*k)

            float sqrLength = x * x + y * y + z * z;

            if (sqrLength > 0.0f)
            {
                angle = 2.0f * (float)Utility.ACos(w);
                float invLength = Utility.InvSqrt(sqrLength);
                axis.x = x * invLength;
                axis.y = y * invLength;
                axis.z = z * invLength;
            }
            else
            {
                angle  = 0.0f;
                axis.x = 1.0f;
                axis.y = 0.0f;
                axis.z = 0.0f;
            }
        }
        internal unsafe void  UpdateGeometry()
        {
            if (!this.IsCreated)
            {
                return;
            }
            // 95% of camera far clip distance
            float TODO_Radius = this.SkyX.Camera.FarClipDistance * 0.95f;

            _vertices[0].X       = 0;
            _vertices[0].Z       = 0;
            _vertices[0].Y       = TODO_Radius;
            _vertices[0].NX      = 0;
            _vertices[0].NZ      = 0;
            _vertices[0].NY      = 1;
            _vertices[0].U       = 4;
            _vertices[0].V       = 4;
            _vertices[0].Opacity = 1;

            float angleStep = (Utility.PI / 2.0f) / (this.Circles - 1.0f);

            float r, uvr, c, s, sc;
            int   x, y;

            for (y = 0; y < this.Circles - 1; y++)
            {
                r   = Utility.Cos(Utility.PI / 2.0f - angleStep * (y + 1.0f));
                uvr = (y + 1.0f) / (this.Circles - 1.0f);

                for (x = 0; x < this.Steps; x++)
                {
                    c  = Utility.Cos(Utility.TWO_PI * x / (float)this.Steps) * r;
                    s  = Utility.Sin(Utility.TWO_PI * x / (float)this.Steps) * r;
                    sc = Utility.Sin(Utility.ACos(r));

                    _vertices[1 + y * this.Steps + x].X = c * TODO_Radius;
                    _vertices[1 + y * this.Steps + x].Z = s * TODO_Radius;
                    _vertices[1 + y * this.Steps + x].Y = sc * TODO_Radius;

                    _vertices[1 + y * this.Steps + x].NX = c;
                    _vertices[1 + y * this.Steps + x].NZ = s;
                    _vertices[1 + y * this.Steps + x].NY = sc;

                    _vertices[1 + y * this.Steps + x].U = (1.0f + c * uvr / r) * 4.0f;
                    _vertices[1 + y * this.Steps + x].V = (1.0f + s * uvr / r) * 4.0f;

                    _vertices[1 + y * this.Steps + x].Opacity = 1;
                }
            }

            r   = Utility.Cos(angleStep);
            uvr = (this.Circles + 1.0f) / (this.Circles - 1.0f);

            for (x = 0; x < this.Steps; x++)
            {
                c = Utility.Cos(Utility.TWO_PI * x / (float)this.Steps) * r;
                s = Utility.Sin(Utility.TWO_PI * x / (float)this.Steps) * r;
                _vertices[1 + (this.Circles - 1) * this.Steps + x].X = _vertices[1 + (this.Circles - 2) * this.Steps + x].X;
                _vertices[1 + (this.Circles - 1) * this.Steps + x].Z = _vertices[1 + (this.Circles - 2) * this.Steps + x].Z;
                _vertices[1 + (this.Circles - 1) * this.Steps + x].Y = _vertices[1 + (this.Circles - 2) * this.Steps + x].Y - TODO_Radius * this.SkydomeFadingPercent;

                _vertices[1 + (this.Circles - 1) * this.Steps + x].NX = _vertices[1 + (this.Circles - 2) * this.Steps + x].NX;
                _vertices[1 + (this.Circles - 1) * this.Steps + x].NZ = _vertices[1 + (this.Circles - 2) * this.Steps + x].NZ;
                _vertices[1 + (this.Circles - 1) * this.Steps + x].NY = _vertices[1 + (this.Circles - 2) * this.Steps + x].NY;

                _vertices[1 + (this.Circles - 1) * this.Steps + x].U = (1.0f + c * uvr / 4) * 4.0f;
                _vertices[1 + (this.Circles - 1) * this.Steps + x].V = (1.0f + s * uvr / 4) * 4.0f;

                _vertices[1 + (this.Circles - 1) * this.Steps + x].Opacity = this.SmoothSkydomeFading ? 0 : 1;
            }

            // Update data
            fixed(PosUVVertex *addr = &_vertices[0])
            {
                _vertexBuffer.WriteData(0, _vertexBuffer.SizeInBytes, addr, true);
            }

            // Update bounds
            AxisAlignedBox meshBounds = new AxisAlignedBox(new Vector3(-TODO_Radius, 0, -TODO_Radius),
                                                           new Vector3(TODO_Radius, TODO_Radius, TODO_Radius));

            //_mesh.BoundingBox = meshBounds;
            _mesh._setBounds(meshBounds);
            _sceneNode.NeedUpdate();
            //for (int i = 0; i < _vertices.Length; i++)
            //    LogVertices(_vertices[i]);
        }