Пример #1
0
        public double LocalToPathPercent(double localPercent, int elementIndex)
        {
            if (root == null)
            {
                return(0.0);
            }
            int totalSpan = 0;

            foreach (Element element in _elements)
            {
                totalSpan += element.span;
            }
            double passed = 0.0;

            for (int i = 0; i < _elements.Length; i++)
            {
                double computerPercent = (double)_elements[i].span / totalSpan;
                passed += computerPercent;
                if (i == elementIndex)
                {
                    passed -= computerPercent;
                    double normalized = DMath.InverseLerp(_elements[i].startPercent, _elements[i].endPercent, localPercent);
                    return(passed + computerPercent * normalized);
                }
            }
            return(0.0);
        }
Пример #2
0
        public void GetEvaluationValues(double inputPercent, out SplineComputer computer, out double percent, out Spline.Direction direction)
        {
            computer  = null;
            percent   = 0.0;
            direction = Spline.Direction.Forward;
            if (root == null)
            {
                return;
            }
            int totalSpan = 0;

            foreach (Element element in _elements)
            {
                totalSpan += element.span;
            }
            double passed = 0.0;

            for (int i = 0; i < _elements.Length; i++)
            {
                if (passed > inputPercent)
                {
                    break;
                }
                double computerPercent = (double)_elements[i].span / totalSpan;
                percent  = DMath.Lerp(_elements[i].startPercent, _elements[i].endPercent, DMath.InverseLerp(passed, passed + computerPercent, inputPercent));
                computer = _elements[i].computer;
                passed  += computerPercent;
            }
        }
Пример #3
0
        public Vector3 EvaluatePosition(double percent)
        {
            if (root == null)
            {
                return(Vector3.zero);
            }
            if (_elements.Length == 1)
            {
                return(_elements[0].computer.EvaluatePosition(percent));
            }
            double totalLength = 0.0;

            for (int i = 0; i < _elements.Length; i++)
            {
                totalLength += _elements[i].span;
            }
            double passed = 0.0;

            for (int i = 0; i < _elements.Length; i++)
            {
                double computerPercent = _elements[i].span / totalLength;
                passed += computerPercent;
                if (passed >= percent || Mathf.Approximately((float)passed, (float)percent))
                {
                    double localPercent = DMath.Lerp(_elements[i].startPercent, _elements[i].endPercent, DMath.InverseLerp(passed - computerPercent, passed, percent));
                    return(_elements[i].computer.EvaluatePosition(localPercent));
                }
            }
            return(Vector3.zero);
        }
Пример #4
0
        private static Func <decimal, decimal> FunctionFromType(EasingType easing)
        {
            switch (easing)
            {
            case EasingType.Constant:
                return(x => 1);

            case EasingType.Linear:
                return(x => x);

            case EasingType.Quadratic:
                return(x => DMath.Pow(x, 2));

            case EasingType.Cubic:
                return(x => DMath.Pow(x, 3));

            case EasingType.Quartic:
                return(x => DMath.Pow(x, 4));

            case EasingType.Quintic:
                return(x => DMath.Pow(x, 5));

            case EasingType.Sinusoidal:
                return(x => 1 - DMath.Cos(x * DMath.PI / 2));    // Wait... That's not Sine!

            case EasingType.Exponential:
                return(x => DMath.Pow(x, 5));

            case EasingType.Circular:
                return(x => 1 - DMath.Sqrt(1 - x * x));

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Пример #5
0
        public void GetSamplingValues(double percent, out int sampleIndex, out double lerp)
        {
            lerp = 0.0;
            if (sampleMode == SplineComputer.SampleMode.Optimized)
            {
                double indexValue = percent * (optimizedIndices.Length - 1);
                int    index      = DMath.FloorInt(indexValue);
                sampleIndex = optimizedIndices[index];
                double lerpPercent = 0.0;
                if (index < optimizedIndices.Length - 1)
                {
                    //Percent 0-1 between the sampleIndex and the next sampleIndex
                    double indexLerp              = indexValue - index;
                    double sampleIndexPercent     = (double)index / (optimizedIndices.Length - 1);
                    double nextSampleIndexPercent = (double)(index + 1) / (optimizedIndices.Length - 1);
                    //Percent 0-1 of the sample between the sampleIndices' percents
                    lerpPercent = DMath.Lerp(sampleIndexPercent, nextSampleIndexPercent, indexLerp);
                }
                if (sampleIndex < Count - 1)
                {
                    lerp = DMath.InverseLerp(samples[sampleIndex].percent, samples[sampleIndex + 1].percent, lerpPercent);
                }
                return;
            }

            sampleIndex = DMath.FloorInt(percent * (Count - 1));
            lerp        = (Count - 1) * percent - sampleIndex;
        }
Пример #6
0
        void SplitAtPoint(int index, ref SplinePoint[] points)
        {
            Undo.RecordObject(computer, "Split At Point " + index);
            EditorUtility.SetDirty(computer);
            SplinePoint[] splitPoints = new SplinePoint[computer.pointCount - index];
            for (int i = 0; i < splitPoints.Length; i++)
            {
                splitPoints[i] = computer.GetPoint(index + i);
            }
            SplineComputer spline = CreateNewSpline();

            spline.SetPoints(splitPoints);

            SplineUser[] users = spline.GetSubscribers();
            for (int i = 0; i < users.Length; i++)
            {
                users[i].clipFrom = DMath.InverseLerp((double)index / (computer.pointCount - 1), 1.0, users[i].clipFrom);
                users[i].clipTo   = DMath.InverseLerp((double)index / (computer.pointCount - 1), 1.0, users[i].clipTo);
            }
            splitPoints = new SplinePoint[index + 1];
            for (int i = 0; i <= index; i++)
            {
                splitPoints[i] = computer.GetPoint(i);
            }
            points = splitPoints;
            users  = computer.GetSubscribers();
            for (int i = 0; i < users.Length; i++)
            {
                users[i].clipFrom = DMath.InverseLerp(0.0, ((double)index) / (computer.pointCount - 1), users[i].clipFrom);
                users[i].clipTo   = DMath.InverseLerp(0.0, ((double)index) / (computer.pointCount - 1), users[i].clipTo);
            }
            HandleNodes(spline, index);
        }
Пример #7
0
        public override void SetAnimatorParameters()
        {
            if (InputAxisFloatHash != 0)
            {
                Animator.SetFloat(InputAxisFloatHash, _axis);
            }

            if (InputBoolHash != 0)
            {
                Animator.SetBool(InputBoolHash, !DMath.Equalsf(_axis));
            }

            if (AcceleratingBoolHash != 0)
            {
                Animator.SetBool(AcceleratingBoolHash, Accelerating);
            }

            if (BrakingBoolHash != 0)
            {
                Animator.SetBool(BrakingBoolHash, Braking);
            }

            if (TopSpeedPercentFloatHash != 0)
            {
                Animator.SetFloat(TopSpeedPercentFloatHash, Mathf.Abs(Controller.GroundVelocity) / TopSpeed);
            }
        }
Пример #8
0
        public override void OnActiveEnter(State previousState)
        {
            //Debug.Log("Jump");
            Used = true;

            Controller.Detach();
            Controller.Velocity += DMath.AngleToVector((Controller.SurfaceAngle + 90.0f) * Mathf.Deg2Rad) * ActivateSpeed;

            var roll = Manager.Get <Roll>();

            if (roll == null)
            {
                return;
            }

            if (roll.Active)
            {
                // Disable air control if jumping while rolling
                Manager.End <AirControl>();
            }
            else
            {
                Manager.Perform <Roll>(true, true);
            }
        }
Пример #9
0
 private void BezierGetTangent(ref Vector3 tangent, double t, int i)
 {
     if (points.Length > 0)
     {
         tangent = points[0].tangent2;
     }
     else
     {
         return;
     }
     if (points.Length == 1)
     {
         return;
     }
     if (i < points.Length - 1)
     {
         t = DMath.Clamp01(t);
         i = Mathf.Clamp(i, 0, points.Length - 2);
         float ft = (float)t;
         float nt = 1f - ft;
         tangent = -3 * nt * nt * points[i].position +
                   3 * nt * nt * points[i].tangent2 -
                   6 * ft * nt * points[i].tangent2 -
                   3 * ft * ft * points[i + 1].tangent +
                   6 * ft * nt * points[i + 1].tangent +
                   3 * ft * ft * points[i + 1].position;
     }
 }
Пример #10
0
 private void LinearGetPoint(ref Vector3 point, double t, int i)
 {
     if (points.Length == 0)
     {
         point = Vector3.zero;
         return;
     }
     if (i + 1 < points.Length)
     {
         t     = DMath.Clamp01(t);
         i     = Mathf.Clamp(i, 0, points.Length - 2);
         point = Vector3.Lerp(points[i].position, points[i + 1].position, (float)t);
     }
     else
     {
         if (i < points.Length)
         {
             point = points[i].position;
         }
         else
         {
             point = Vector3.zero;
         }
     }
 }
Пример #11
0
        /// <summary>
        /// Returns the percent from the spline at a given distance from the start point
        /// </summary>
        /// <param name="start">The start point</param>
        /// /// <param name="distance">The distance to travel</param>
        /// <param name="direction">The direction towards which to move</param>
        /// <returns></returns>
        public double Travel(double start, float distance, Spline.Direction direction)
        {
            float   moved        = 0f;
            float   lastMoved    = 0f;
            Vector3 lastPoint    = EvaluatePosition(start);
            Vector3 currentPoint = lastPoint;
            int     step         = DMath.FloorInt(start / moveStep);
            double  percent      = moveStep * (step + 1);
            double  lastPercent  = start;

            while (moved < distance)
            {
                if (direction == Spline.Direction.Forward)
                {
                    step++;
                }
                else
                {
                    step--;
                }
                lastPercent = percent;
                percent     = moveStep * step;
                if (percent < 0.0 || percent > 1.0)
                {
                    break;
                }
                currentPoint = EvaluatePosition(percent);
                lastMoved    = moved;
                moved       += Vector3.Distance(currentPoint, lastPoint);
                lastPoint    = currentPoint;
            }
            double distancePercent = DMath.InverseLerp(lastMoved, moved, distance);

            return(DMath.Lerp(lastPercent, percent, distancePercent));
        }
Пример #12
0
 private void BezierGetPoint(ref Vector3 point, double t, int i)
 {
     //Used for getting a point on a Bezier spline
     if (points.Length > 0)
     {
         point = points[0].position;
     }
     else
     {
         return;
     }
     if (points.Length == 1)
     {
         return;
     }
     if (i < points.Length - 1)
     {
         t = DMath.Clamp01(t);
         i = Mathf.Clamp(i, 0, points.Length - 2);
         float ft = (float)t;
         float nt = 1f - ft;
         point = nt * nt * nt * points[i].position +
                 3f * nt * nt * ft * points[i].tangent2 +
                 3f * nt * ft * ft * points[i + 1].tangent +
                 ft * ft * ft * points[i + 1].position;
     }
 }
Пример #13
0
        public override void OnActiveEnter(State previousState)
        {
            if (DMath.Equalsf(Controller.GroundVelocity))
            {
                Controller.FacingForward = Controller.Footing == Footing.Left;
            }

            if (!AllowDuck)
            {
                var duck = Manager.Get <Duck>();
                if (duck != null)
                {
                    duck.AllowShouldPerform = false;
                }
            }

            if (!AllowLookUp)
            {
                var lookUp = Manager.Get <LookUp>();
                if (lookUp != null)
                {
                    lookUp.AllowShouldPerform = false;
                }
            }
        }
Пример #14
0
 public override void OnActiveUpdate()
 {
     if (DMath.Equalsf(Controller.GroundVelocity))
     {
         Controller.FacingForward = Controller.Footing == Footing.Left;
     }
 }
Пример #15
0
        public int GetClippedSampleCount(double clipFrom, double clipTo, out int startIndex, out int endIndex)
        {
            startIndex = endIndex = 0;
            if (sampleMode == SplineComputer.SampleMode.Default)
            {
                startIndex = DMath.FloorInt((Count - 1) * clipFrom);
                endIndex   = DMath.CeilInt((Count - 1) * clipTo);
            }
            else
            {
                double clipFromLerp = 0.0, clipToLerp = 0.0;
                GetSamplingValues(clipFrom, out startIndex, out clipFromLerp);
                GetSamplingValues(clipTo, out endIndex, out clipToLerp);
                if (clipToLerp > 0.0 && endIndex < Count - 1)
                {
                    endIndex++;
                }
            }

            if (clipTo < clipFrom) //Handle looping segments
            {
                int toSamples   = endIndex + 1;
                int fromSamples = Count - startIndex;
                return(toSamples + fromSamples);
            }

            return(endIndex - startIndex + 1);
        }
Пример #16
0
        /// <summary>
        /// Evaluates the spline segment based on the spline's precision and returns only the position.
        /// </summary>
        /// <param name="positions">The position buffer</param>
        /// <param name="from">Start position [0-1]</param>
        /// <param name="to">Target position [from-1]</param>
        /// <returns></returns>
        public void EvaluatePositions(ref Vector3[] positions, double from = 0.0, double to = 1.0)
        {
            if (points.Length == 0)
            {
                positions = new Vector3[0];
                return;
            }
            from = DMath.Clamp01(from);
            to   = DMath.Clamp(to, from, 1.0);
            double fromValue         = from * (iterations - 1);
            double toValue           = to * (iterations - 1);
            int    clippedIterations = DMath.CeilInt(toValue) - DMath.FloorInt(fromValue) + 1;

            if (positions.Length != clippedIterations)
            {
                positions = new Vector3[clippedIterations];
            }
            double percent = from;
            double ms      = moveStep;
            int    index   = 0;

            while (true)
            {
                positions[index] = EvaluatePosition(percent);
                index++;
                if (index >= positions.Length)
                {
                    break;
                }
                percent = DMath.Move(percent, to, ms);
            }
        }
Пример #17
0
        public void GetEvaluationValues(double inputPercent, out SplineComputer computer, out double percent, out Spline.Direction direction)
        {
            computer  = null;
            percent   = 0.0;
            direction = Spline.Direction.Forward;
            if (root == null)
            {
                return;
            }
            int num = 0;

            Element[] elements = _elements;
            foreach (Element element in elements)
            {
                num += element.span;
            }
            double num2 = 0.0;

            for (int j = 0; j < _elements.Length; j++)
            {
                if (num2 > inputPercent)
                {
                    break;
                }
                double num3 = (double)_elements[j].span / (double)num;
                percent  = DMath.Lerp(_elements[j].startPercent, _elements[j].endPercent, DMath.InverseLerp(num2, num2 + num3, inputPercent));
                computer = _elements[j].computer;
                num2    += num3;
            }
        }
Пример #18
0
        public override void OnActiveFixedUpdate()
        {
            UpdateControlLockTimer();

            // Accelerate as long as the control lock isn't on
            if (!ControlLockTimerOn)
            {
                Accelerate(_axis);
            }

            // If we're on a wall and aren't going quickly enough, start the control lock
            if (Mathf.Abs(Controller.GroundVelocity) < Controller.DetachSpeed &&
                DMath.AngleInRange_d(Controller.RelativeSurfaceAngle, 50.0f, 310.0f))
            {
                Lock();
            }

            // Disable slope gravity when we're not moving, so that Sonic can stand on slopes
            Controller.DisableSlopeGravity = !(Accelerating || ControlLockTimerOn ||
                                               Mathf.Abs(Controller.GroundVelocity) > MinSlopeGravitySpeed);

            // Disable ground friction while we have player input
            Controller.DisableGroundFriction =
                (!DisableAcceleration && Accelerating) ||
                (!DisableDeceleration && Braking);

            // Orient the player in the direction we're moving (not graphics-wise, just internally!)
            if (!ControlLockTimerOn && !DMath.Equalsf(_axis))
            {
                Controller.FacingForward = Controller.GroundVelocity >= 0.0f;
            }
        }
Пример #19
0
        public double LocalToPathPercent(double localPercent, int elementIndex)
        {
            if (root == null)
            {
                return(0.0);
            }
            int num = 0;

            Element[] elements = _elements;
            foreach (Element element in elements)
            {
                num += element.span;
            }
            double num2 = 0.0;

            for (int j = 0; j < _elements.Length; j++)
            {
                double num3 = (double)_elements[j].span / (double)num;
                num2 += num3;
                if (j == elementIndex)
                {
                    num2 -= num3;
                    double num4 = DMath.InverseLerp(_elements[j].startPercent, _elements[j].endPercent, localPercent);
                    return(num2 + num3 * num4);
                }
            }
            return(0.0);
        }
Пример #20
0
        public Vector3 EvaluatePosition(double percent)
        {
            if (root == null)
            {
                return(Vector3.zero);
            }
            if (_elements.Length == 1)
            {
                return(_elements[0].computer.EvaluatePosition(percent));
            }
            double num = 0.0;

            for (int i = 0; i < _elements.Length; i++)
            {
                num += (double)_elements[i].span;
            }
            double num2 = 0.0;

            for (int j = 0; j < _elements.Length; j++)
            {
                double num3 = (double)_elements[j].span / num;
                num2 += num3;
                if (num2 >= percent || Mathf.Approximately((float)num2, (float)percent))
                {
                    double percent2 = DMath.Lerp(_elements[j].startPercent, _elements[j].endPercent, DMath.InverseLerp(num2 - num3, num2, percent));
                    return(_elements[j].computer.EvaluatePosition(percent2));
                }
            }
            return(Vector3.zero);
        }
Пример #21
0
        public void AlignTextureWithFace(Face face)
        {
            // Get reference values for the axes
            var refU = face.Texture.UAxis;
            var refV = face.Texture.VAxis;
            // Reference points in the texture plane to use for shifting later on
            var refX = face.Texture.UAxis * face.Texture.XShift * face.Texture.XScale;
            var refY = face.Texture.VAxis * face.Texture.YShift * face.Texture.YScale;

            // Two non-parallel planes intersect at an edge. We want the textures on this face
            // to line up with the textures on the provided face. To do this, we rotate the texture
            // normal on the provided face around the intersection edge to get the new texture axes.
            // Then we rotate the texture reference point around this edge as well to get the new shift values.
            // The scale values on both faces will always end up being the same value.

            // Find the intersection edge vector
            var intersectionEdge = face.Plane.Normal.Cross(Plane.Normal);
            // Create a plane using the intersection edge as the normal
            var intersectionPlane = new Plane(intersectionEdge, 0);

            // If the planes are parallel, the texture doesn't need any rotation - just different shift values.
            var intersect = Plane.Intersect(face.Plane, Plane, intersectionPlane);

            if (intersect != null)
            {
                var texNormal = face.Texture.GetNormal();

                // Since the intersection plane is perpendicular to both face planes, we can find the angle
                // between the two planes (the original texture plane and the plane of this face) by projecting
                // the normals of the planes onto the perpendicular plane and taking the cross product.

                // Project the two normals onto the perpendicular plane
                var ptNormal = intersectionPlane.Project(texNormal).Normalise();
                var ppNormal = intersectionPlane.Project(Plane.Normal).Normalise();

                // Get the angle between the projected normals
                var dot   = Math.Round(ptNormal.Dot(ppNormal), 4);
                var angle = DMath.Acos(dot); // A.B = cos(angle)

                // Rotate the texture axis by the angle around the intersection edge
                var transform = new UnitRotate(angle, new Line(Coordinate.Zero, intersectionEdge));
                refU = transform.Transform(refU);
                refV = transform.Transform(refV);

                // Rotate the texture reference points as well, but around the intersection line, not the origin
                refX = transform.Transform(refX + intersect) - intersect;
                refY = transform.Transform(refY + intersect) - intersect;
            }

            // Convert the reference points back to get the final values
            Texture.Rotation = 0;
            Texture.UAxis    = refU;
            Texture.VAxis    = refV;
            Texture.XShift   = refU.Dot(refX) / face.Texture.XScale;
            Texture.YShift   = refV.Dot(refY) / face.Texture.YScale;
            Texture.XScale   = face.Texture.XScale;
            Texture.YScale   = face.Texture.YScale;

            CalculateTextureCoordinates(true);
        }
Пример #22
0
        private void BezierGetPoint(ref Vector3 point, double t, int i)
        {
            //Used for getting a point on a Bezier spline
            if (points.Length > 0)
            {
                point = points[0].position;
            }
            else
            {
                return;
            }
            if (points.Length == 1)
            {
                return;
            }
            if (i < points.Length - 1)
            {
                t = DMath.Clamp01(t);
                i = Mathf.Clamp(i, 0, points.Length - 2);

                Vector3 P0 = points[i].position;
                Vector3 P1 = points[i].tangent2;
                Vector3 P2 = points[i + 1].tangent;
                Vector3 P3 = points[i + 1].position;
                float   ft = (float)t;
                point = Mathf.Pow(1 - ft, 3) * P0 + 3 * Mathf.Pow((1 - ft), 2) * ft * P1 + 3 * (1 - ft) * Mathf.Pow(ft, 2) * P2 + Mathf.Pow(ft, 3) * P3;
            }
        }
Пример #23
0
        /// <summary>
        /// The Inverse of the matrix copied into mInv.
        /// Returns false if the matrix has no inverse.
        /// A matrix multipled by its inverse is the idenity.
        /// Invert a 3x3 using cofactors.  This is about 8 times faster than
        /// the Numerical Recipes code which uses Gaussian elimination.
        /// </summary>
        public bool TryInverse(ref Matrix3x3d mInv)
        {
            mInv.m00 = m11 * m22 - m12 * m21;
            mInv.m01 = m02 * m21 - m01 * m22;
            mInv.m02 = m01 * m12 - m02 * m11;
            mInv.m10 = m12 * m20 - m10 * m22;
            mInv.m11 = m00 * m22 - m02 * m20;
            mInv.m12 = m02 * m10 - m00 * m12;
            mInv.m20 = m10 * m21 - m11 * m20;
            mInv.m21 = m01 * m20 - m00 * m21;
            mInv.m22 = m00 * m11 - m01 * m10;

            double det = m00 * mInv.m00 + m01 * mInv.m10 + m02 * mInv.m20;

            if (DMath.IsZero(det))
            {
                return(false);
            }

            double invDet = 1.0 / det;

            mInv.m00 *= invDet; mInv.m01 *= invDet; mInv.m02 *= invDet;
            mInv.m10 *= invDet; mInv.m11 *= invDet; mInv.m12 *= invDet;
            mInv.m20 *= invDet; mInv.m21 *= invDet; mInv.m22 *= invDet;

            return(true);
        }
Пример #24
0
        /// <summary>
        /// Calculate the length of the spline
        /// </summary>
        /// <param name="from">Calculate from [0-1] default: 0f</param>
        /// <param name="to">Calculate to [0-1] default: 1f</param>
        /// <param name="resolution">Resolution multiplier for precision [0-1] default: 1f</param>
        /// <returns></returns>
        public float CalculateLength(double from = 0.0, double to = 1.0, double resolution = 1.0)
        {
            if (points.Length == 0)
            {
                return(0f);
            }
            resolution = DMath.Clamp01(resolution);
            if (resolution == 0.0)
            {
                return(0f);
            }
            from = DMath.Clamp01(from);
            to   = DMath.Clamp01(to);
            if (to < from)
            {
                to = from;
            }
            double  percent = from;
            Vector3 lastPos = EvaluatePosition(percent);
            float   sum     = 0f;

            while (true)
            {
                percent = DMath.Move(percent, to, moveStep / resolution);
                Vector3 pos = EvaluatePosition(percent);
                sum    += (pos - lastPos).magnitude;
                lastPos = pos;
                if (percent == to)
                {
                    break;
                }
            }
            return(sum);
        }
Пример #25
0
        /// <summary>
        /// Casts rays along the spline against all colliders in the scene
        /// </summary>
        /// <param name="hit">Hit information</param>
        /// <param name="hitPercent">The percent of evaluation where the hit occured</param>
        /// <param name="layerMask">Layer mask for the raycast</param>
        /// <param name="resolution">Resolution multiplier for precision [0-1] default: 1f</param>
        /// <param name="from">Raycast from [0-1] default: 0f</param>
        /// <param name="to">Raycast to [0-1] default: 1f</param>
        /// <param name="hitTriggers">Should hit triggers? (not supported in 5.1)</param>
        /// <returns></returns>
        public bool Raycast(out RaycastHit hit, out double hitPercent, LayerMask layerMask, double resolution = 1.0, double from = 0.0, double to = 1.0, QueryTriggerInteraction hitTriggers = QueryTriggerInteraction.UseGlobal
                            )
        {
            resolution = DMath.Clamp01(resolution);
            from       = DMath.Clamp01(from);
            to         = DMath.Clamp01(to);
            double  percent = from;
            Vector3 fromPos = EvaluatePosition(percent);

            hitPercent = 0f;
            if (resolution == 0f)
            {
                hit        = new RaycastHit();
                hitPercent = 0f;
                return(false);
            }
            while (true)
            {
                double prevPercent = percent;
                percent = DMath.Move(percent, to, moveStep / resolution);
                Vector3 toPos = EvaluatePosition(percent);
                if (Physics.Linecast(fromPos, toPos, out hit, layerMask, hitTriggers))
                {
                    double segmentPercent = (hit.point - fromPos).sqrMagnitude / (toPos - fromPos).sqrMagnitude;
                    hitPercent = DMath.Lerp(prevPercent, percent, segmentPercent);
                    return(true);
                }
                fromPos = toPos;
                if (percent == to)
                {
                    break;
                }
            }
            return(false);
        }
Пример #26
0
        public IEnumerable <MapObject> Create(IDGenerator generator, Box box, ITexture texture, int roundDecimals)
        {
            var numSides = (int)_numSides.GetValue();

            if (numSides < 3)
            {
                yield break;
            }

            // This is all very similar to the cylinder brush.
            var width  = box.Width;
            var length = box.Length;
            var major  = width / 2;
            var minor  = length / 2;
            var angle  = 2 * DMath.PI / numSides;

            var points = new Coordinate[numSides];

            for (var i = 0; i < numSides; i++)
            {
                var a    = i * angle;
                var xval = box.Center.X + major * DMath.Cos(a);
                var yval = box.Center.Y + minor * DMath.Sin(a);
                var zval = box.Start.Z;
                points[i] = new Coordinate(xval, yval, zval).Round(roundDecimals);
            }

            var faces = new List <Coordinate[]>();

            var point = new Coordinate(box.Center.X, box.Center.Y, box.End.Z).Round(roundDecimals);

            for (var i = 0; i < numSides; i++)
            {
                var next = (i + 1) % numSides;
                faces.Add(new[] { points[i], point, points[next] });
            }
            faces.Add(points.ToArray());

            var solid = new Solid(generator.GetNextObjectID())
            {
                Colour = Colour.GetRandomBrushColour(), Flags = (System.UInt32)SolidFlags.solid
            };

            foreach (var arr in faces)
            {
                var face = new Face(generator.GetNextFaceID())
                {
                    Parent  = solid,
                    Plane   = new Plane(arr[0], arr[1], arr[2]),
                    Colour  = solid.Colour,
                    Texture = { Texture = texture }
                };
                face.Vertices.AddRange(arr.Select(x => new Vertex(x, face)));
                face.Init();
                solid.Faces.Add(face);
            }
            solid.UpdateBoundingBox();
            yield return(solid);
        }
Пример #27
0
 public override void Awake()
 {
     base.Awake();
     if (DMath.Equalsf(Friction))
     {
         Friction += DMath.Epsilon;
     }
 }
Пример #28
0
        /// <summary>
        /// Treats this vector as a directional unit vector and constructs a euler angle representation of that angle (in radians)
        /// </summary>
        /// <returns></returns>
        public Coordinate ToEulerAngles()
        {
            // http://www.gamedev.net/topic/399701-convert-vector-to-euler-cardan-angles/#entry3651854
            var yaw   = DMath.Atan2(_y, _x);
            var pitch = DMath.Atan2(-_z, DMath.Sqrt(_x * _x + _y * _y));

            return(new Coordinate(0, pitch, yaw)); // HL FGD has X = roll, Y = pitch, Z = yaw
        }
Пример #29
0
        private void EvaluateTangent(ref Vector3 tangent, double percent)
        {
            percent = DMath.Clamp01(percent);
            double doubleIndex = (points.Length - 1) * percent;
            int    pointIndex  = Mathf.Clamp(DMath.FloorInt(doubleIndex), 0, Mathf.Max(points.Length - 2, 0));

            GetTangent(ref tangent, doubleIndex - pointIndex, pointIndex);
        }
Пример #30
0
        private void EvaluatePosition(ref Vector3 point, double percent)
        {
            percent = DMath.Clamp01(percent);
            double num  = (double)(points.Length - 1) * percent;
            int    num2 = Mathf.Clamp(DMath.FloorInt(num), 0, Mathf.Max(points.Length - 2, 0));

            GetPoint(ref point, num - (double)num2, num2);
        }