Beispiel #1
0
    private void BezierQuadraticTest(MyVector3 posA, MyVector3 posB, MyVector3 handle)
    {
        //Store the interpolated values so we later can display them
        List <Vector3> interpolatedValues = new List <Vector3>();

        //Loop between 0 and 1 in steps, where 1 step is minimum
        //So if steps is 5 then the line will be cut in 5 sections
        int steps = 10;

        float stepSize = 1f / (float)steps;

        float t = 0f;

        //+1 becuase wa also have to include the first point
        for (int i = 0; i < steps + 1; i++)
        {
            //Debug.Log(t);

            MyVector3 interpolatedValue = BezierQuadratic.GetPosition(posA, posB, handle, t);

            interpolatedValues.Add(interpolatedValue.ToVector3());

            t += stepSize;
        }


        //Display the curve
        DisplayInterpolation.DisplayCurve(interpolatedValues, useRandomColor: true);

        //Display the start and end values and the handle points
        DisplayInterpolation.DisplayHandle(handle.ToVector3(), posA.ToVector3());
        DisplayInterpolation.DisplayHandle(handle.ToVector3(), posB.ToVector3());



        //Display other related data
        //Get the forwrd dir of the point at t and display it
        MyVector3 forwardDir = BezierQuadratic.GetTangent(posA, posB, handle, tSliderValue);

        MyVector3 slidePos = BezierQuadratic.GetPosition(posA, posB, handle, tSliderValue);

        Gizmos.color = Color.blue;

        Gizmos.DrawRay(slidePos.ToVector3(), forwardDir.ToVector3());

        Gizmos.color = Color.red;

        Gizmos.DrawWireSphere(slidePos.ToVector3(), 0.15f);
    }
Beispiel #2
0
        private IEnumerator PerformMovementCoroutine(bool ignoreMoveCosts, Action postMovementCallback)
        {
            Animator.SetTrigger("Moving Requested");

            IHexCell startingCell = PositionCanon.GetOwnerOfPossession(this);
            IHexCell currentCell  = startingCell;

            Vector3 currentLocation = Grid.PerformIntersectionWithTerrainSurface(currentCell.AbsolutePosition);

            Vector3 a, b, c = currentLocation;

            yield return(LookAt(CurrentPath.First().AbsolutePosition));

            float t = Time.deltaTime * Config.TravelSpeedPerSecond;

            while ((ignoreMoveCosts || CurrentMovement > 0) && CurrentPath != null && CurrentPath.Count > 0)
            {
                var nextCell = CurrentPath.FirstOrDefault();

                Vector3 nextLocation = Grid.PerformIntersectionWithTerrainSurface(nextCell.AbsolutePosition);

                if (!PositionCanon.CanChangeOwnerOfPossession(this, nextCell) || nextCell == null)
                {
                    CurrentPath.Clear();
                    break;
                }

                if (!ignoreMoveCosts)
                {
                    CurrentMovement = Math.Max(0,
                                               CurrentMovement - PositionCanon.GetTraversalCostForUnit(this, currentCell, nextCell, false)
                                               );
                }

                PositionCanon.ChangeOwnerOfPossession(this, nextCell);

                CurrentPath.RemoveAt(0);

                a = c;
                b = currentLocation;
                c = (b + nextLocation) * 0.5f;

                for (; t < 1f; t += Time.deltaTime * Config.TravelSpeedPerSecond)
                {
                    transform.position = BezierQuadratic.GetPoint(a, b, c, t);
                    Vector3 d = BezierQuadratic.GetFirstDerivative(a, b, c, t);
                    d.y = 0f;
                    transform.localRotation = Quaternion.LookRotation(d);
                    yield return(null);
                }
                t -= 1f;

                currentCell = nextCell;

                currentLocation = Grid.PerformIntersectionWithTerrainSurface(currentCell.AbsolutePosition);
            }

            if (currentCell != startingCell)
            {
                a = c;
                b = currentLocation;
                c = b;

                for (; t < 1f; t += Time.deltaTime * Config.TravelSpeedPerSecond)
                {
                    transform.position = BezierQuadratic.GetPoint(a, b, c, t);
                    Vector3 d = BezierQuadratic.GetFirstDerivative(a, b, c, t);
                    d.y = 0f;
                    transform.localRotation = Quaternion.LookRotation(d);
                    yield return(null);
                }
            }

            postMovementCallback();

            Animator.SetTrigger("Idling Requested");
        }
    private void BezierQuadraticEqualSteps(MyVector3 posA, MyVector3 posB, MyVector3 handle)
    {
        //Store the interpolated values so we later can display them
        List <Vector3> actualPositions = new List <Vector3>();

        //Create a curve which is the data structure used in the following calculations
        BezierQuadratic bezierQuadratic = new BezierQuadratic(posA, posB, handle);


        //Step 1. Calculate the length of the entire curve
        //This is needed to so we know how long we should walk each step
        float lengthNaive = InterpolationHelpMethods.GetLength_Naive(bezierQuadratic, steps: 20, tEnd: 1f);

        float lengthExact = InterpolationHelpMethods.GetLength_SimpsonsRule(bezierQuadratic, tStart: 0f, tEnd: 1f);

        Debug.Log("Naive length: " + lengthNaive + " Exact length: " + lengthExact);



        int steps = 5;

        //Important not to confuse this with the step size we use to iterate t
        //This step size is distance in m
        float length = lengthNaive;

        float lengthStepSize = length / (float)steps;

        float stepSize = 1f / (float)steps;

        float t = 0f;

        float distanceTravelled = 0f;

        for (int i = 0; i < steps + 1; i++)
        {
            //MyVector3 inaccuratePos = bezierCubic.GetInterpolatedValue(t);



            //Calculate t to get to this distance
            //Method 1
            //float actualT = InterpolationHelpMethods.Find_t_FromDistance_Iterative(bezierQuadratic, distanceTravelled, length);
            //Method 2
            float actualT = InterpolationHelpMethods.Find_t_FromDistance_Lookup(bezierQuadratic, distanceTravelled, accumulatedDistances: null);

            MyVector3 actualPos = bezierQuadratic.GetInterpolatedValue(actualT);

            actualPositions.Add(actualPos.ToVector3());



            //Test that the derivative calculations are working
            float dEst = InterpolationHelpMethods.EstimateDerivative(bezierQuadratic, t);
            float dAct = bezierQuadratic.ExactDerivative(t);

            Debug.Log("Estimated derivative: " + dEst + " Actual derivative: " + dAct);



            //Debug.Log("Distance " + distanceTravelled);

            //Move on to next iteration
            distanceTravelled += lengthStepSize;

            t += stepSize;
        }

        //List<MyVector3> positionsOnCurve = InterpolationHelpMethods.SplitCurve(bezierQuadratic, 20, tEnd: 1f);

        //foreach (MyVector3 p in positionsOnCurve)
        //{
        //    Gizmos.DrawWireSphere(p.ToVector3(), 0.1f);
        //}

        DisplayInterpolatedValues(actualPositions, useRandomColor: true);

        //Display the start and end values and the handle points
        DisplayHandle(handle.ToVector3(), posA.ToVector3());
        DisplayHandle(handle.ToVector3(), posB.ToVector3());
    }
Beispiel #4
0
    private void BezierQuadraticTest_EqualSteps(MyVector3 posA, MyVector3 posB, MyVector3 handle)
    {
        //Create a curve which is the data structure used in the following calculations
        BezierQuadratic bezierQuadratic = new BezierQuadratic(posA, posB, handle);


        //Step 1. Calculate the length of the entire curve
        //This is needed to so we know how long we should walk each step
        float lengthNaive = InterpolationHelpMethods.GetLength_Naive(bezierQuadratic, steps: 20, tEnd: 1f);

        float lengthExact = InterpolationHelpMethods.GetLength_SimpsonsRule(bezierQuadratic, tStart: 0f, tEnd: 1f);

        //Debug.Log("Naive length: " + lengthNaive + " Exact length: " + lengthExact);


        //Step 2. Convert the t's to be percentage along the curve
        //Save the accurate t at each position on the curve
        List <float> accurateTs = new List <float>();

        int steps = 5;

        //Important not to confuse this with the step size we use to iterate t
        //This step size is distance in m
        float length = lengthNaive;

        float lengthStepSize = length / (float)steps;

        float stepSize = 1f / (float)steps;

        float t = 0f;

        float distanceTravelled = 0f;

        for (int i = 0; i < steps + 1; i++)
        {
            //MyVector3 inaccuratePos = bezierCubic.GetInterpolatedValue(t);

            //Calculate t to get to this distance
            //Method 1
            //float accurateT = InterpolationHelpMethods.Find_t_FromDistance_Iterative(bezierQuadratic, distanceTravelled, length);
            //Method 2
            float accurateT = InterpolationHelpMethods.Find_t_FromDistance_Lookup(bezierQuadratic, distanceTravelled, accumulatedDistances: null);

            accurateTs.Add(accurateT);

            //Test that the derivative calculations are working
            //float dEst = InterpolationHelpMethods.EstimateDerivative(bezierQuadratic, t);
            //float dAct = bezierQuadratic.GetDerivative(t);

            //Debug.Log("Estimated derivative: " + dEst + " Actual derivative: " + dAct);



            //Debug.Log("Distance " + distanceTravelled);

            //Move on to next iteration
            distanceTravelled += lengthStepSize;

            t += stepSize;
        }


        //Get the data we want from the curve

        //Store the interpolated values so we later can display them
        List <Vector3> actualPositions = new List <Vector3>();
        //
        List <Vector3> tangents = new List <Vector3>();
        //Orientation, which includes the tangent and position
        List <InterpolationTransform> orientations = new List <InterpolationTransform>();

        for (int i = 0; i < accurateTs.Count; i++)
        {
            float accurateT = accurateTs[i];

            MyVector3 actualPos = bezierQuadratic.GetPosition(accurateT);

            actualPositions.Add(actualPos.ToVector3());


            MyVector3 tangent = bezierQuadratic.GetTangent(accurateT);

            tangents.Add(tangent.ToVector3());


            //Orientation, which includes both position and tangent
            InterpolationTransform orientation = InterpolationTransform.GetTransform_UpRef(bezierQuadratic, accurateT, MyVector3.Up);

            orientations.Add(orientation);
        }



        //Display

        //Unity doesnt have a built-in method to display an accurate Qudratic bezier, so we have to create our own
        //DisplayInterpolation.DisplayBezierQuadratic(bezierQuadratic, Color.black);
        DisplayInterpolation.DisplayCurve(bezierQuadratic, Color.black);

        //DisplayInterpolation.DisplayCurve(actualPositions, useRandomColor: true);
        DisplayInterpolation.DisplayCurve(actualPositions, Color.gray);

        //Display the start and end values and the handle points
        DisplayInterpolation.DisplayHandle(handle.ToVector3(), posA.ToVector3());
        DisplayInterpolation.DisplayHandle(handle.ToVector3(), posB.ToVector3());


        //Stuff on the curve
        //DisplayInterpolation.DisplayDirections(actualPositions, tangents, 1f, Color.red);

        DisplayInterpolation.DisplayOrientations(orientations, 1f);
    }
Beispiel #5
0
        private void TriangulateCultureCorners_FlatEdge(
            IHexCell center, IHexCell left, IHexCell right, IHexCell nextRight, HexDirection direction,
            ICivilization centerOwner, ReadOnlyCollection <Vector2> centerRightContour,
            ReadOnlyCollection <Vector2> rightCenterContour, IHexMesh cultureMesh
            )
        {
            if (left != null && CivTerritoryLogic.GetCivClaimingCell(left) != centerOwner)
            {
                Color cultureColor = centerOwner.Template.Color;

                var centerLeftContour = CellEdgeContourCanon.GetContourForCellEdge(center, direction.Previous());
                var rightLeftContour  = CellEdgeContourCanon.GetContourForCellEdge(right, direction.Previous2());

                Vector2 centerLeftFirstInner = Vector2.Lerp(centerLeftContour.First(), center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);
                Vector2 centerLeftLastInner  = Vector2.Lerp(centerLeftContour.Last(), center.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);

                Vector2 rightLeftFirstInner = Vector2.Lerp(rightLeftContour.First(), right.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);
                Vector2 rightleftLastInner  = Vector2.Lerp(rightLeftContour.Last(), right.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);

                Vector2 rayAlongCenterLeft = (centerLeftLastInner - centerLeftFirstInner).normalized;
                Vector2 rayAlongRightLeft  = (rightLeftFirstInner - rightleftLastInner).normalized;

                Vector2 bezierControl;

                if (!Geometry2D.ClosestPointsOnTwoLines(
                        centerLeftLastInner, rayAlongCenterLeft, rightLeftFirstInner, rayAlongRightLeft,
                        out bezierControl, out bezierControl
                        ))
                {
                    Debug.LogError("TriangulateCultureCorners_FlatEdge failed to find a valid control point");
                    return;
                }


                Vector3 pivotXYZ = new Vector3(centerLeftContour.Last().x, 0f, centerLeftContour.Last().y);

                float paramDelta = 5f / RenderConfig.RiverQuadsPerCurve;

                for (float t = 0; t < 1f; t = Mathf.Clamp01(t + paramDelta))
                {
                    float nextT = Mathf.Clamp01(t + paramDelta);

                    Vector2 bezierOne = BezierQuadratic.GetPoint(centerLeftLastInner, bezierControl, rightLeftFirstInner, nextT);
                    Vector2 bezierTwo = BezierQuadratic.GetPoint(centerLeftLastInner, bezierControl, rightLeftFirstInner, t);

                    cultureMesh.AddTriangle(pivotXYZ, new Vector3(bezierOne.x, 0f, bezierOne.y), new Vector3(bezierTwo.x, 0f, bezierTwo.y));

                    cultureMesh.AddTriangleUV(new Vector2(0f, 1f), Vector2.zero, Vector2.zero);

                    cultureMesh.AddTriangleColor(cultureColor);
                }

                if (rightCenterContour.Count == 3)
                {
                    Vector2 innerPoint          = Vector2.Lerp(rightCenterContour.Last(), right.AbsolutePositionXZ, RenderConfig.CultureWidthPercent);
                    Vector2 secondToLastContour = rightCenterContour[rightCenterContour.Count - 2];
                    Vector2 lastContour         = rightCenterContour.Last();

                    cultureMesh.AddTriangle(
                        new Vector3(innerPoint.x, 0f, innerPoint.y), new Vector3(secondToLastContour.x, 0f, secondToLastContour.y),
                        new Vector3(lastContour.x, 0f, lastContour.y)
                        );

                    cultureMesh.AddTriangleUV(new Vector2(0f, 0f), new Vector2(0f, 1f), new Vector2(0f, 1f));

                    cultureMesh.AddTriangleColor(cultureColor);
                }
            }
        }