예제 #1
0
        // Token: 0x06000605 RID: 1541 RVA: 0x0003988C File Offset: 0x00037C8C
        public void AddSpan(uint bottom, uint top, int area, int voxelWalkableClimb)
        {
            VoxelSpan voxelSpan = new VoxelSpan(bottom, top, area);

            if (this.firstSpan == null)
            {
                this.firstSpan = voxelSpan;
                return;
            }
            VoxelSpan voxelSpan2 = null;
            VoxelSpan voxelSpan3 = this.firstSpan;

            while (voxelSpan3 != null)
            {
                if (voxelSpan3.bottom > voxelSpan.top)
                {
                    break;
                }
                if (voxelSpan3.top < voxelSpan.bottom)
                {
                    voxelSpan2 = voxelSpan3;
                    voxelSpan3 = voxelSpan3.next;
                }
                else
                {
                    if (voxelSpan3.bottom < bottom)
                    {
                        voxelSpan.bottom = voxelSpan3.bottom;
                    }
                    if (voxelSpan3.top > top)
                    {
                        voxelSpan.top = voxelSpan3.top;
                    }
                    if (AstarMath.Abs((int)(voxelSpan.top - voxelSpan3.top)) <= voxelWalkableClimb)
                    {
                        voxelSpan.area = AstarMath.Max(voxelSpan.area, voxelSpan3.area);
                    }
                    VoxelSpan next = voxelSpan3.next;
                    if (voxelSpan2 != null)
                    {
                        voxelSpan2.next = next;
                    }
                    else
                    {
                        this.firstSpan = next;
                    }
                    voxelSpan3 = next;
                }
            }
            if (voxelSpan2 != null)
            {
                voxelSpan.next  = voxelSpan2.next;
                voxelSpan2.next = voxelSpan;
            }
            else
            {
                voxelSpan.next = this.firstSpan;
                this.firstSpan = voxelSpan;
            }
        }
예제 #2
0
    protected VInt3 CalculateTargetPoint(VInt3 p, VInt3 a, VInt3 b)
    {
        if (a.x == b.x && a.z == b.z)
        {
            return(a);
        }
        VFactor vFactor = AstarMath.NearestPointFactorXZ(ref a, ref b, ref p);
        long    num     = VInt3.Lerp(a, b, vFactor).XZSqrMagnitude(ref p);
        int     num2    = IntMath.Sqrt(num);
        long    num3    = a.XZSqrMagnitude(ref b);
        int     num4    = IntMath.Sqrt(num3);

        if (num4 == 0)
        {
            return(b);
        }
        int     num5     = Mathf.Clamp(this.forwardLook.i - num2, 0, this.forwardLook.i);
        VFactor vFactor2 = new VFactor((long)num5 * vFactor.den + vFactor.nom * (long)num4, (long)num4 * vFactor.den);

        if (vFactor2 > VFactor.one)
        {
            vFactor2 = VFactor.one;
        }
        else if (vFactor2 < VFactor.zero)
        {
            vFactor2 = VFactor.zero;
        }
        vFactor2.strip();
        return(VInt3.Lerp(a, b, vFactor2));
    }
예제 #3
0
    protected VInt3 CalculateTargetPoint(VInt3 p, VInt3 a, VInt3 b)
    {
        if ((a.x == b.x) && (a.z == b.z))
        {
            return(a);
        }
        VFactor f    = AstarMath.NearestPointFactorXZ(ref a, ref b, ref p);
        int     num3 = IntMath.Sqrt(VInt3.Lerp(a, b, f).XZSqrMagnitude(ref p));
        int     num5 = IntMath.Sqrt(a.XZSqrMagnitude(ref b));

        if (num5 == 0)
        {
            return(b);
        }
        int     num6 = Mathf.Clamp(this.forwardLook.i - num3, 0, this.forwardLook.i);
        VFactor one  = new VFactor((num6 * f.den) + (f.nom * num5), num5 * f.den);

        if (one > VFactor.one)
        {
            one = VFactor.one;
        }
        else if (one < VFactor.zero)
        {
            one = VFactor.zero;
        }
        one.strip();
        return(VInt3.Lerp(a, b, one));
    }
    protected VInt3 CalculateTargetPoint(VInt3 p, VInt3 a, VInt3 b)
    {
        if (a.x == b.x && a.z == b.z)
        {
            return(a);
        }
        VFactor f    = AstarMath.NearestPointFactorXZ(ref a, ref b, ref p);
        long    a2   = VInt3.Lerp(a, b, f).XZSqrMagnitude(ref p);
        int     num  = IntMath.Sqrt(a2);
        long    a3   = a.XZSqrMagnitude(ref b);
        int     num2 = IntMath.Sqrt(a3);

        if (num2 == 0)
        {
            return(b);
        }
        int     num3    = Mathf.Clamp(this.forwardLook.i - num, 0, this.forwardLook.i);
        VFactor vFactor = new VFactor((long)num3 * f.den + f.nom * (long)num2, (long)num2 * f.den);

        if (vFactor > VFactor.one)
        {
            vFactor = VFactor.one;
        }
        else if (vFactor < VFactor.zero)
        {
            vFactor = VFactor.zero;
        }
        vFactor.strip();
        return(VInt3.Lerp(a, b, vFactor));
    }
예제 #5
0
    public void OnPathComplete(Path p)
    {
        StartCoroutine(WaitToRepath());

        //If the path didn't succeed, don't proceed
        if (p.error)
        {
            return;
        }

        //Get the calculated path as a Vector3 array
        path = p.vectorPath.ToArray();

        //Find the segment in the path which is closest to the AI
        //If a closer segment hasn't been found in '6' iterations, break because it is unlikely to find any closer ones then
        float minDist       = Mathf.Infinity;
        int   notCloserHits = 0;

        for (int i = 0; i < path.Length - 1; i++)
        {
            float dist = AstarMath.DistancePointSegmentStrict(path[i], path[i + 1], tr.position);
            if (dist < minDist)
            {
                notCloserHits = 0;
                minDist       = dist;
                pathIndex     = i + 1;
            }
            else if (notCloserHits > 6)
            {
                break;
            }
        }
    }
예제 #6
0
        /** Generates a terrain chunk mesh */
        RasterizationMesh GenerateHeightmapChunk(float[, ] heights, Vector3 sampleSize, Vector3 offset, int x0, int z0, int width, int depth, int stride)
        {
            // Downsample to a smaller mesh (full resolution will take a long time to rasterize)
            // Round up the width to the nearest multiple of terrainSampleSize and then add 1
            // (off by one because there are vertices at the edge of the mesh)
            int resultWidth = CeilDivision(width, terrainSampleSize) + 1;
            int resultDepth = CeilDivision(depth, terrainSampleSize) + 1;

            var heightmapWidth = heights.GetLength(0);
            var heightmapDepth = heights.GetLength(1);

            // Create a mesh from the heightmap
            var terrainVertices = new Vector3[resultWidth * resultDepth];

            // Create lots of vertices
            for (int z = 0; z < resultDepth; z++)
            {
                for (int x = 0; x < resultWidth; x++)
                {
                    int sampleX = Math.Min(x0 + x * stride, heightmapWidth - 1);
                    int sampleZ = Math.Min(z0 + z * stride, heightmapDepth - 1);

                    terrainVertices[z * resultWidth + x] = new Vector3(sampleZ * sampleSize.x, heights[sampleX, sampleZ] * sampleSize.y, sampleX * sampleSize.z) + offset;
                }
            }

            // Create the mesh by creating triangles in a grid like pattern
            var tris          = new int[(resultWidth - 1) * (resultDepth - 1) * 2 * 3];
            int triangleIndex = 0;

            for (int z = 0; z < resultDepth - 1; z++)
            {
                for (int x = 0; x < resultWidth - 1; x++)
                {
                    tris[triangleIndex]     = z * resultWidth + x;
                    tris[triangleIndex + 1] = z * resultWidth + x + 1;
                    tris[triangleIndex + 2] = (z + 1) * resultWidth + x + 1;
                    triangleIndex          += 3;
                    tris[triangleIndex]     = z * resultWidth + x;
                    tris[triangleIndex + 1] = (z + 1) * resultWidth + x + 1;
                    tris[triangleIndex + 2] = (z + 1) * resultWidth + x;
                    triangleIndex          += 3;
                }
            }

#if ASTARDEBUG
            var color = AstarMath.IntToColor(x0 + 7 * z0, 0.7f);
            for (int i = 0; i < tris.Length; i += 3)
            {
                Debug.DrawLine(terrainVertices[tris[i]], terrainVertices[tris[i + 1]], color, 40);
                Debug.DrawLine(terrainVertices[tris[i + 1]], terrainVertices[tris[i + 2]], color, 40);
                Debug.DrawLine(terrainVertices[tris[i + 2]], terrainVertices[tris[i]], color, 40);
            }
#endif

            var mesh = new RasterizationMesh(terrainVertices, tris, new Bounds());
            // Could probably calculate these bounds in a faster way
            mesh.RecalculateBounds();
            return(mesh);
        }
예제 #7
0
    public void OnPathComplete(Path p)
    {
        base.StartCoroutine(this.WaitToRepath());
        if (p.error)
        {
            return;
        }
        this.path = p.vectorPath.ToArray();
        float num  = float.PositiveInfinity;
        int   num2 = 0;

        for (int i = 0; i < this.path.Length - 1; i++)
        {
            float num3 = AstarMath.DistancePointSegmentStrict(this.path[i], this.path[i + 1], this.tr.position);
            if (num3 < num)
            {
                num2           = 0;
                num            = num3;
                this.pathIndex = i + 1;
            }
            else if (num2 > 6)
            {
                break;
            }
        }
    }
예제 #8
0
 public void OnDrawGizmos()
 {
     if (this.points.Length >= 3)
     {
         for (int i = 0; i < this.points.Length; i++)
         {
             if (this.points[i] == null)
             {
                 return;
             }
         }
         for (int j = 0; j < this.points.Length; j++)
         {
             int     num         = this.points.Length;
             Vector3 normalized  = ((this.points[(j + 1) % num].position - this.points[j].position).normalized - (this.points[(j - 1 + num) % num].position - this.points[j].position).normalized).normalized;
             Vector3 normalized2 = ((this.points[(j + 2) % num].position - this.points[(j + 1) % num].position).normalized - (this.points[(j + num) % num].position - this.points[(j + 1) % num].position).normalized).normalized;
             Vector3 from        = this.points[j].position;
             for (int k = 1; k <= 100; k++)
             {
                 Vector3 vector = AstarMath.CubicBezier(this.points[j].position, this.points[j].position + normalized * this.tangentLengths, this.points[(j + 1) % num].position - normalized2 * this.tangentLengths, this.points[(j + 1) % num].position, (float)k / 100f);
                 Gizmos.DrawLine(from, vector);
                 from = vector;
             }
         }
     }
 }
예제 #9
0
    /** Calculates target point from the current line segment.
     * \param p Current position
     * \param a Line segment start
     * \param b Line segment end
     * The returned point will lie somewhere on the line segment.
     * \see #forwardLook
     * \todo This function uses .magnitude quite a lot, can it be optimized?
     */
    protected Vector3 CalculateTargetPoint(Vector3 p, Vector3 a, Vector3 b)
    {
        if (entity == null || entity.MoveState != Pathea.MovementState.Water)
        {
            a.y = p.y;
            b.y = p.y;
        }

        float magn = (a - b).magnitude;

        if (magn == 0)
        {
            return(a);
        }

        float   closest  = AstarMath.Clamp01(AstarMath.NearestPointFactor(a, b, p));
        Vector3 point    = (b - a) * closest + a;
        float   distance = (point - p).magnitude;

        float lookAhead = Mathf.Clamp(forwardLook - distance, 0.0F, forwardLook);

        float offset = lookAhead / magn;

        offset = Mathf.Clamp(offset + closest, 0.0F, 1.0F);
        return((b - a) * offset + a);
    }
예제 #10
0
    public void OnDrawGizmos()
    {
        if (points.Length >= 3)
        {
            for (int i = 0; i < points.Length; i++)
            {
                if (points[i] == null)
                {
                    return;
                }
            }

            for (int pt = 0; pt < points.Length; pt++)
            {
                int     c      = points.Length;
                Vector3 inTang = ((points[(pt + 1) % c].position - points[pt + 0].position).normalized - (points[(pt - 1 + c) % c].position - points[pt + 0].position).normalized).normalized;

                Vector3 outTang = ((points[(pt + 2) % c].position - points[(pt + 1) % c].position).normalized - (points[(pt - 0 + c) % c].position - points[(pt + 1) % c].position).normalized).normalized;

                Vector3 pp = points[pt].position;

                for (int i = 1; i <= 100; i++)
                {
                    Vector3 p = AstarMath.CubicBezier(points[pt].position, points[pt].position + inTang * tangentLengths, points[(pt + 1) % c].position - outTang * tangentLengths, points[(pt + 1) % c].position, i / 100.0f);
                    Gizmos.DrawLine(pp, p);
                    pp = p;
                }
            }
        }
    }
예제 #11
0
        void OnDrawGizmos(int boxi, int depth)
        {
            BBTreeBox box = arr[boxi];

            var min = (Vector3) new Int3(box.rect.xmin, 0, box.rect.ymin);
            var max = (Vector3) new Int3(box.rect.xmax, 0, box.rect.ymax);

            Vector3 center = (min + max) * 0.5F;
            Vector3 size   = (max - center) * 2;

            size      = new Vector3(size.x, 1, size.z);
            center.y += depth * 2;

            Gizmos.color = AstarMath.IntToColor(depth, 1f);             //new Color (0,0,0,0.2F);
            Gizmos.DrawCube(center, size);

            if (box.node != null)
            {
            }
            else
            {
                OnDrawGizmos(box.left, depth + 1);
                OnDrawGizmos(box.right, depth + 1);
            }
        }
예제 #12
0
    /** Finds the closest point on the current path.
     * Sets #currentWaypointIndex and #lerpTime to the appropriate values.
     */
    protected virtual void ConfigureNewPath()
    {
        var points = path.vectorPath;

        var currentPosition = GetFeetPosition();

        float bestFactor = 0;
        float bestDist   = float.PositiveInfinity;
        int   bestIndex  = 0;

        for (int i = 0; i < points.Count - 1; i++)
        {
            float   factor = AstarMath.NearestPointFactor(points[i], points[i + 1], currentPosition);
            Vector3 point  = Vector3.Lerp(points[i], points[i + 1], factor);
            float   dist   = (currentPosition - point).sqrMagnitude;

            if (dist < bestDist)
            {
                bestDist   = dist;
                bestFactor = factor;
                bestIndex  = i + 1;
            }
        }

        currentWaypointIndex = bestIndex;
        lerpTime             = bestFactor;
    }
예제 #13
0
        // Token: 0x0600079F RID: 1951 RVA: 0x00049E78 File Offset: 0x00048278
        public void Update()
        {
            if (this.rvoAgent == null)
            {
                return;
            }
            if (this.lastPosition != this.tr.position)
            {
                this.Teleport(this.tr.position);
            }
            if (this.lockWhenNotMoving)
            {
                this.locked = (this.desiredVelocity == Vector3.zero);
            }
            this.UpdateAgentProperties();
            Vector3 interpolatedPosition = this.rvoAgent.InterpolatedPosition;

            interpolatedPosition.y = this.adjustedY;
            RaycastHit raycastHit;

            if (this.mask != 0 && Physics.Raycast(interpolatedPosition + Vector3.up * this.height * 0.5f, Vector3.down, out raycastHit, float.PositiveInfinity, this.mask))
            {
                this.adjustedY = raycastHit.point.y;
            }
            else
            {
                this.adjustedY = 0f;
            }
            interpolatedPosition.y = this.adjustedY;
            this.rvoAgent.SetYPosition(this.adjustedY);
            Vector3 a = Vector3.zero;

            if (this.wallAvoidFalloff > 0f && this.wallAvoidForce > 0f)
            {
                List <ObstacleVertex> neighbourObstacles = this.rvoAgent.NeighbourObstacles;
                if (neighbourObstacles != null)
                {
                    for (int i = 0; i < neighbourObstacles.Count; i++)
                    {
                        Vector3 position  = neighbourObstacles[i].position;
                        Vector3 position2 = neighbourObstacles[i].next.position;
                        Vector3 vector    = this.position - AstarMath.NearestPointStrict(position, position2, this.position);
                        if (!(vector == position) && !(vector == position2))
                        {
                            float sqrMagnitude = vector.sqrMagnitude;
                            vector /= sqrMagnitude * this.wallAvoidFalloff;
                            a      += vector;
                        }
                    }
                }
            }
            this.rvoAgent.DesiredVelocity = this.desiredVelocity + a * this.wallAvoidForce;
            this.tr.position  = interpolatedPosition + Vector3.up * this.height * 0.5f - this.center;
            this.lastPosition = this.tr.position;
            if (this.enableRotation && this.velocity != Vector3.zero)
            {
                base.transform.rotation = Quaternion.Lerp(base.transform.rotation, Quaternion.LookRotation(this.velocity), Time.deltaTime * this.rotationSpeed * Mathf.Min(this.velocity.magnitude, 0.2f));
            }
        }
예제 #14
0
    private void Update()
    {
        Vector3 a = this.PointToGraphSpace(this.graph.center);
        Vector3 b = this.PointToGraphSpace(this.target.position);

        if (AstarMath.SqrMagnitudeXZ(a, b) > this.updateDistance * this.updateDistance)
        {
            this.UpdateGraph();
        }
    }
예제 #15
0
 // Update is called once per frame
 void Update()
 {
     // Check the distance along the XZ plane
     // we only move the graph in the X and Z directions so
     // checking for if the Y coordinate has changed is
     // not something we want to do
     if (AstarMath.SqrMagnitudeXZ(target.position, graph.center) > updateDistance * updateDistance)
     {
         UpdateGraph();
     }
 }
예제 #16
0
    private Vector3 Plot(float t)
    {
        int     num         = this.points.Length;
        int     num2        = Mathf.FloorToInt(t);
        Vector3 normalized  = ((this.points[(num2 + 1) % num].position - this.points[num2 % num].position).normalized - (this.points[(num2 - 1 + num) % num].position - this.points[num2 % num].position).normalized).normalized;
        Vector3 normalized2 = ((this.points[(num2 + 2) % num].position - this.points[(num2 + 1) % num].position).normalized - (this.points[(num2 + num) % num].position - this.points[(num2 + 1) % num].position).normalized).normalized;

        Debug.DrawLine(this.points[num2 % num].position, this.points[num2 % num].position + normalized * this.tangentLengths, Color.red);
        Debug.DrawLine(this.points[(num2 + 1) % num].position - normalized2 * this.tangentLengths, this.points[(num2 + 1) % num].position, Color.green);
        return(AstarMath.CubicBezier(this.points[num2 % num].position, this.points[num2 % num].position + normalized * this.tangentLengths, this.points[(num2 + 1) % num].position - normalized2 * this.tangentLengths, this.points[(num2 + 1) % num].position, t - (float)num2));
    }
    /** Update is called once per frame */
    void Update()
    {
        // Calculate where the graph center and the target position is in graph space
        var graphCenterInGraphSpace    = PointToGraphSpace(graph.center);
        var targetPositionInGraphSpace = PointToGraphSpace(target.position);

        // Check the distance in graph space
        // We only care about the X and Z axes since the Y axis is the "height" coordinate of the nodes (in graph space)
        // We only care about the plane that the nodes are placed in
        if (AstarMath.SqrMagnitudeXZ(graphCenterInGraphSpace, targetPositionInGraphSpace) > updateDistance * updateDistance)
        {
            UpdateGraph();
        }
    }
예제 #18
0
        //public System.Object lockObject;
        public void AddSpan(uint bottom, uint top, int area, int voxelWalkableClimb)
        {
            VoxelSpan span = new VoxelSpan (bottom,top,area);

            if (firstSpan == null) {
                firstSpan = span;
                return;
            }

            VoxelSpan prev = null;
            VoxelSpan cSpan = firstSpan;

            while (cSpan != null) {
                if (cSpan.bottom > span.top) {
                    break;

                } else if (cSpan.top < span.bottom) {
                    prev = cSpan;
                    cSpan = cSpan.next;
                } else {
                    if (cSpan.bottom < bottom) {
                        span.bottom = cSpan.bottom;
                    }
                    if (cSpan.top > top) {
                        span.top = cSpan.top;
                    }

                    //1 is flagMergeDistance, when a walkable flag is favored before an unwalkable one
                    if (AstarMath.Abs ((int)span.top - (int)cSpan.top) <= voxelWalkableClimb) {
                        span.area = AstarMath.Max (span.area,cSpan.area);
                    }

                    VoxelSpan next = cSpan.next;
                    if (prev != null) {
                        prev.next = next;
                    } else {
                        firstSpan = next;
                    }
                    cSpan = next;
                }
            }

            if (prev != null) {
                span.next = prev.next;
                prev.next = span;
            } else {
                span.next = firstSpan;
                firstSpan = span;
            }
        }
예제 #19
0
    Vector3 Plot(float t)
    {
        Vector3 inTang, outTang;


        int c  = points.Length;
        int pt = Mathf.FloorToInt(t);

        inTang = ((points[(pt + 1) % c].position - points[(pt + 0) % c].position).normalized - (points[(pt - 1 + c) % c].position - points[(pt + 0) % c].position).normalized).normalized;

        outTang = ((points[(pt + 2) % c].position - points[(pt + 1) % c].position).normalized - (points[(pt - 0 + c) % c].position - points[(pt + 1) % c].position).normalized).normalized;

        Debug.DrawLine(points[pt % c].position, points[pt % c].position + inTang * tangentLengths, Color.red);
        Debug.DrawLine(points[(pt + 1) % c].position - outTang * tangentLengths, points[(pt + 1) % c].position, Color.green);

        return(AstarMath.CubicBezier(points[pt % c].position, points[pt % c].position + inTang * tangentLengths, points[(pt + 1) % c].position - outTang * tangentLengths, points[(pt + 1) % c].position, t - pt));
    }
	protected Vector3 CalculateTargetPoint(Vector3 p, Vector3 a, Vector3 b)
	{
		a.y = p.y;
		b.y = p.y;
		
		float magn = (a - b).magnitude;
		if (magn == 0) return a;
		
		float closest = AstarMath.Clamp01(AstarMath.NearestPointFactor(a, b, p));
		Vector3 point = (b - a) * closest + a;
		float distance = (point - p).magnitude;
		
		float lookAhead = Mathf.Clamp(forwardLook - distance, 0.0F, forwardLook);
		
		float offset = lookAhead / magn;
		offset = Mathf.Clamp(offset + closest, 0.0F, 1.0F);
		return (b - a) * offset + a;
	}
예제 #21
0
    private void OnDrawGizmos()
    {
        List <Vector3>[] paths = drawPaths;

        for (int i = 0; i < paths.Length; i++)
        {
            List <Vector3> pt = paths[i];

            if (pt == null)
            {
                Debug.LogWarning("Path Number " + i + " cound not be found");
                continue;
            }
            for (int j = 0; j < pt.Count - 1; j++)
            {
                Debug.DrawLine(pt[j], pt[j + 1], AstarMath.IntToColor(i, 0.5f));
            }
        }
    }
예제 #22
0
        public void OnPathComplete(Path p)
        {
            Debug.Log("Got Callback");

            if (p.error)
            {
                Debug.Log("Ouch, the path returned an error");
                Debug.LogError(p.errorLog);
                return;
            }

            List <Vector3> path = p.vectorPath;

            for (int j = 0; j < path.Count - 1; j++)
            {
                // Plot segment j to j+1 with a nice color got from Pathfinding.AstarMath.IntToColor
                Debug.DrawLine(path[j], path[j + 1], AstarMath.IntToColor(1, 0.5F), 1);
            }
        }
예제 #23
0
        public void InsertObstacleNeighbour(ObstacleVertex ob1, float rangeSq)
        {
            ObstacleVertex obstacleVertex = ob1.next;
            float          num            = AstarMath.DistancePointSegmentStrict(ob1.position, obstacleVertex.position, this.Position);

            if (num < rangeSq)
            {
                this.obstacles.Add(ob1);
                this.obstacleDists.Add(num);
                int num2 = this.obstacles.Count - 1;
                while (num2 != 0 && num < this.obstacleDists[num2 - 1])
                {
                    this.obstacles[num2]     = this.obstacles[num2 - 1];
                    this.obstacleDists[num2] = this.obstacleDists[num2 - 1];
                    num2--;
                }
                this.obstacles[num2]     = ob1;
                this.obstacleDists[num2] = num;
            }
        }
예제 #24
0
        /*public void UpdateNeighbours () {
         *      neighbours.Clear ();
         *      float sqrDist = neighbourDistance*neighbourDistance;
         *      for ( int i = 0; i < simulator.agents.Count; i++ ) {
         *              float dist = (simulator.agents[i].position - position).sqrMagnitude;
         *              if ( dist <= sqrDist ) {
         *                      neighbours.Add ( simulator.agents[i] );
         *              }
         *      }
         * }*/

        public void InsertObstacleNeighbour(ObstacleVertex ob1, float rangeSq)
        {
            ObstacleVertex ob2 = ob1.next;

            float dist = AstarMath.DistancePointSegmentStrict(ob1.position, ob2.position, Position);

            if (dist < rangeSq)
            {
                obstacles.Add(ob1);
                obstacleDists.Add(dist);

                int i = obstacles.Count - 1;
                while (i != 0 && dist < obstacleDists[i - 1])
                {
                    obstacles[i]     = obstacles[i - 1];
                    obstacleDists[i] = obstacleDists[i - 1];
                    i--;
                }
                obstacles[i]     = ob1;
                obstacleDists[i] = dist;
            }
        }
예제 #25
0
    protected Vector3 CalculateTargetPoint(Vector3 p, Vector3 a, Vector3 b, bool canGoDirectly)
    {
        if (canGoDirectly && (b - this.target.position).sqrMagnitude < 16f)
        {
            return(this.target.position);
        }
        a.y = p.y;
        b.y = p.y;
        float magnitude = (a - b).magnitude;

        if (magnitude == 0f)
        {
            return(a);
        }
        float   num        = AstarMath.Clamp01(AstarMath.NearestPointFactor(a, b, p));
        Vector3 vector     = (b - a) * num + a;
        float   magnitude2 = (vector - p).magnitude;
        float   num2       = Mathf.Clamp(this.forwardLook - magnitude2, 0f, this.forwardLook);
        float   num3       = num2 / magnitude;

        num3 = Mathf.Clamp(num3 + num, 0f, 1f);
        return((b - a) * num3 + a);
    }
예제 #26
0
        /** Builds a polygon mesh from a contour set.
         * \param nvp Maximum allowed vertices per polygon. \note Currently locked to 3
         */
        public void BuildPolyMesh(VoxelContourSet cset, int nvp, out VoxelMesh mesh)
        {
            AstarProfiler.StartProfile("Build Poly Mesh");

            nvp = 3;

            int maxVertices     = 0;
            int maxTris         = 0;
            int maxVertsPerCont = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                // Skip null contours.
                if (cset.conts[i].nverts < 3)
                {
                    continue;
                }

                maxVertices    += cset.conts[i].nverts;
                maxTris        += cset.conts[i].nverts - 2;
                maxVertsPerCont = AstarMath.Max(maxVertsPerCont, cset.conts[i].nverts);
            }

            if (maxVertices >= 65534)
            {
                Debug.LogWarning("To many vertices for unity to render - Unity might screw up rendering, but hopefully the navmesh will work ok");
                //mesh = new VoxelMesh ();
                //yield break;
                //return;
            }

            //int[] vflags = new int[maxVertices];

            /** \todo Could be cached to avoid allocations */
            Int3[] verts = new Int3[maxVertices];
            /** \todo Could be cached to avoid allocations */
            int[] polys = new int[maxTris * nvp];

            //int[] regs = new int[maxTris];

            //int[] areas = new int[maxTris];

            Pathfinding.Util.Memory.MemSet <int> (polys, 0xff, sizeof(int));
            //for (int i=0;i<polys.Length;i++) {
            //	polys[i] = 0xff;
            //}

            //int[] nexVert = new int[maxVertices];

            //int[] firstVert = new int[VERTEX_BUCKET_COUNT];

            int[] indices = new int[maxVertsPerCont];

            int[] tris = new int[maxVertsPerCont * 3];

            //ushort[] polys

            int vertexIndex = 0;
            int polyIndex   = 0;

            for (int i = 0; i < cset.conts.Count; i++)
            {
                VoxelContour cont = cset.conts[i];

                //Skip null contours
                if (cont.nverts < 3)
                {
                    continue;
                }

                for (int j = 0; j < cont.nverts; j++)
                {
                    indices[j]             = j;
                    cont.verts[j * 4 + 2] /= voxelArea.width;
                }

                //yield return (GameObject.FindObjectOfType (typeof(MonoBehaviour)) as MonoBehaviour).StartCoroutine (
                //Triangulate (cont.nverts, cont.verts, indices, tris);
                int ntris = Triangulate(cont.nverts, cont.verts, ref indices, ref tris);

                /*if (ntris > cont.nverts-2) {
                 *      Debug.LogError (ntris + " "+cont.nverts+" "+cont.verts.Length+" "+(cont.nverts-2));
                 * }
                 *
                 * if (ntris > maxVertsPerCont) {
                 *      Debug.LogError (ntris*3 + " "+maxVertsPerCont);
                 * }
                 *
                 * int tmp = polyIndex;
                 *
                 * Debug.Log (maxTris + " "+polyIndex+" "+polys.Length+" "+ntris+" "+(ntris*3) + " " + cont.nverts);*/
                int startIndex = vertexIndex;
                for (int j = 0; j < ntris * 3; polyIndex++, j++)
                {
                    //@Error sometimes
                    polys[polyIndex] = tris[j] + startIndex;
                }

                /*int tmp2 = polyIndex;
                 * if (tmp+ntris*3 != tmp2) {
                 *      Debug.LogWarning (tmp+" "+(tmp+ntris*3)+" "+tmp2+" "+ntris*3);
                 * }*/

                for (int j = 0; j < cont.nverts; vertexIndex++, j++)
                {
                    verts[vertexIndex] = new Int3(cont.verts[j * 4], cont.verts[j * 4 + 1], cont.verts[j * 4 + 2]);
                }
            }

            mesh = new VoxelMesh();
            //yield break;
            Int3[] trimmedVerts = new Int3[vertexIndex];
            for (int i = 0; i < vertexIndex; i++)
            {
                trimmedVerts[i] = verts[i];
            }

            int[] trimmedTris = new int[polyIndex];

            System.Buffer.BlockCopy(polys, 0, trimmedTris, 0, polyIndex * sizeof(int));
            //for (int i=0;i<polyIndex;i++) {
            //	trimmedTris[i] = polys[i];
            //}


            mesh.verts = trimmedVerts;
            mesh.tris  = trimmedTris;

            /*for (int i=0;i<mesh.tris.Length/3;i++) {
             *
             *      int p = i*3;
             *
             *      int p1 = mesh.tris[p];
             *      int p2 = mesh.tris[p+1];
             *      int p3 = mesh.tris[p+2];
             *
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p1].x,mesh.verts[p1].y,mesh.verts[p1].z),ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),Color.yellow);
             *      //Debug.DrawLine (ConvertPosCorrZ (mesh.verts[p3].x,mesh.verts[p3].y,mesh.verts[p3].z),ConvertPosCorrZ (mesh.verts[p2].x,mesh.verts[p2].y,mesh.verts[p2].z),Color.yellow);
             *
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p2],0,verts[p2+2]),Color.blue);
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p1],0,verts[p1+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
             *      //Debug.DrawLine (ConvertPosCorrZ (verts[p2],0,verts[p2+2]),ConvertPosCorrZ (verts[p3],0,verts[p3+2]),Color.blue);
             *
             * }*/

            AstarProfiler.EndProfile("Build Poly Mesh");
        }
예제 #27
0
 /** Color from an angle */
 public Color GetColor(float angle)
 {
     return(AstarMath.HSVToRGB(angle * rad2Deg, 0.8f, 0.6f));
 }
예제 #28
0
        //Code almost completely ripped from Recast
        public void FilterLedges(uint voxelWalkableHeight, int voxelWalkableClimb, float cs, float ch, Vector3 min)
        {
            int wd = voxelArea.width * voxelArea.depth;

#if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST
            LinkedVoxelSpan[] spans      = voxelArea.linkedSpans;
            int[]             DirectionX = voxelArea.DirectionX;
            int[]             DirectionZ = voxelArea.DirectionZ;
#endif
            int width = voxelArea.width;

            //Filter all ledges
            for (int z = 0, pz = 0; z < wd; z += width, pz++)
            {
                for (int x = 0; x < width; x++)
                {
#if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST
                    if (spans[x + z].bottom == VoxelArea.InvalidSpanValue)
                    {
                        continue;
                    }

                    for (int s = x + z; s != -1; s = spans[s].next)
                    {
                        //Skip non-walkable spans
                        if (spans[s].area == UnwalkableArea)
                        {
                            continue;
                        }

                        int bottom = (int)spans[s].top;
                        int top    = spans[s].next != -1 ? (int)spans[spans[s].next].bottom : VoxelArea.MaxHeightInt;

                        int minHeight = VoxelArea.MaxHeightInt;

                        int aMinHeight = (int)spans[s].top;
                        int aMaxHeight = aMinHeight;

                        for (int d = 0; d < 4; d++)
                        {
                            int nx = x + DirectionX[d];
                            int nz = z + DirectionZ[d];

                            //Skip out-of-bounds points
                            if (nx < 0 || nz < 0 || nz >= wd || nx >= width)
                            {
                                spans[s].area = UnwalkableArea;
                                break;
                            }

                            int nsx = nx + nz;

                            int nbottom = -voxelWalkableClimb;

                            int ntop = spans[nsx].bottom != VoxelArea.InvalidSpanValue ? (int)spans[nsx].bottom : VoxelArea.MaxHeightInt;

                            if (System.Math.Min(top, ntop) - System.Math.Max(bottom, nbottom) > voxelWalkableHeight)
                            {
                                minHeight = System.Math.Min(minHeight, nbottom - bottom);
                            }

                            //Loop through spans
                            if (spans[nsx].bottom != VoxelArea.InvalidSpanValue)
                            {
                                for (int ns = nsx; ns != -1; ns = spans[ns].next)
                                {
                                    nbottom = (int)spans[ns].top;
                                    ntop    = spans[ns].next != -1 ? (int)spans[spans[ns].next].bottom : VoxelArea.MaxHeightInt;

                                    if (System.Math.Min(top, ntop) - System.Math.Max(bottom, nbottom) > voxelWalkableHeight)
                                    {
                                        minHeight = System.Math.Min(minHeight, nbottom - bottom);

                                        if (System.Math.Abs(nbottom - bottom) <= voxelWalkableClimb)
                                        {
                                            if (nbottom < aMinHeight)
                                            {
                                                aMinHeight = nbottom;
                                            }
                                            if (nbottom > aMaxHeight)
                                            {
                                                aMaxHeight = nbottom;
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        if (minHeight < -voxelWalkableClimb || (aMaxHeight - aMinHeight) > voxelWalkableClimb)
                        {
                            spans[s].area = UnwalkableArea;
                        }
                    }
#else
                    for (VoxelSpan s = voxelArea.cells[z + x].firstSpan; s != null; s = s.next)
                    {
                        //Skip non-walkable spans
                        if (s.area == UnwalkableArea)
                        {
                            continue;
                        }

                        int bottom = (int)s.top;
                        int top    = s.next != null ? (int)s.next.bottom : VoxelArea.MaxHeightInt;

                        int minHeight = VoxelArea.MaxHeightInt;

                        int aMinHeight = (int)s.top;
                        int aMaxHeight = (int)s.top;

                        for (int d = 0; d < 4; d++)
                        {
                            int nx = x + voxelArea.DirectionX[d];
                            int nz = z + voxelArea.DirectionZ[d];

                            //Skip out-of-bounds points
                            if (nx < 0 || nz < 0 || nz >= wd || nx >= voxelArea.width)
                            {
                                s.area = UnwalkableArea;
                                break;
                            }

                            VoxelSpan nsx = voxelArea.cells[nx + nz].firstSpan;

                            int nbottom = -voxelWalkableClimb;

                            int ntop = nsx != null ? (int)nsx.bottom : VoxelArea.MaxHeightInt;

                            if (AstarMath.Min(top, ntop) - AstarMath.Max(bottom, nbottom) > voxelWalkableHeight)
                            {
                                minHeight = AstarMath.Min(minHeight, nbottom - bottom);
                            }

                            //Loop through spans
                            for (VoxelSpan ns = nsx; ns != null; ns = ns.next)
                            {
                                nbottom = (int)ns.top;
                                ntop    = ns.next != null ? (int)ns.next.bottom : VoxelArea.MaxHeightInt;

                                if (AstarMath.Min(top, ntop) - AstarMath.Max(bottom, nbottom) > voxelWalkableHeight)
                                {
                                    minHeight = AstarMath.Min(minHeight, nbottom - bottom);

                                    if (AstarMath.Abs(nbottom - bottom) <= voxelWalkableClimb)
                                    {
                                        if (nbottom < aMinHeight)
                                        {
                                            aMinHeight = nbottom;
                                        }
                                        if (nbottom > aMaxHeight)
                                        {
                                            aMaxHeight = nbottom;
                                        }
                                    }
                                }
                            }
                        }

                        if (minHeight < -voxelWalkableClimb || (aMaxHeight - aMinHeight) > voxelWalkableClimb)
                        {
                            s.area = UnwalkableArea;
                        }
                    }
#endif
                }
            }
        }
예제 #29
0
        public void BuildCompactField()
        {
            AstarProfiler.StartProfile("Build Compact Voxel Field");

            //Build compact representation
            int spanCount = voxelArea.GetSpanCount();

            voxelArea.compactSpanCount = spanCount;
            if (voxelArea.compactSpans == null || voxelArea.compactSpans.Length < spanCount)
            {
                voxelArea.compactSpans = new CompactVoxelSpan[spanCount];
                voxelArea.areaTypes    = new int[spanCount];
            }

            uint idx = 0;

            int w  = voxelArea.width;
            int d  = voxelArea.depth;
            int wd = w * d;

            if (this.voxelWalkableHeight >= 0xFFFF)
            {
                Debug.LogWarning("Too high walkable height to guarantee correctness. Increase voxel height or lower walkable height.");
            }

#if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST
            LinkedVoxelSpan[] spans = voxelArea.linkedSpans;
#endif

            //Parallel.For (0, voxelArea.depth, delegate (int pz) {
            for (int z = 0, pz = 0; z < wd; z += w, pz++)
            {
                for (int x = 0; x < w; x++)
                {
#if !ASTAR_RECAST_CLASS_BASED_LINKED_LIST
                    int spanIndex = x + z;
                    if (spans[spanIndex].bottom == VoxelArea.InvalidSpanValue)
                    {
                        voxelArea.compactCells[x + z] = new CompactVoxelCell(0, 0);
                        continue;
                    }

                    uint index = idx;
                    uint count = 0;

                    //Vector3 p = new Vector3(x,0,pz)*cellSize+voxelOffset;

                    while (spanIndex != -1)
                    {
                        if (spans[spanIndex].area != UnwalkableArea)
                        {
                            int bottom = (int)spans[spanIndex].top;
                            int next   = spans[spanIndex].next;
                            int top    = next != -1 ? (int)spans[next].bottom : VoxelArea.MaxHeightInt;

                            voxelArea.compactSpans[idx] = new CompactVoxelSpan((ushort)(bottom > 0xFFFF ? 0xFFFF : bottom), (uint)(top - bottom > 0xFFFF ? 0xFFFF : top - bottom));
                            voxelArea.areaTypes[idx]    = spans[spanIndex].area;
                            idx++;
                            count++;
                        }
                        spanIndex = spans[spanIndex].next;
                    }

                    voxelArea.compactCells[x + z] = new CompactVoxelCell(index, count);
#else
                    VoxelSpan s = voxelArea.cells[x + z].firstSpan;

                    if (s == null)
                    {
                        voxelArea.compactCells[x + z] = new CompactVoxelCell(0, 0);
                        continue;
                    }

                    uint index = idx;
                    uint count = 0;

                    //Vector3 p = new Vector3(x,0,pz)*cellSize+voxelOffset;

                    while (s != null)
                    {
                        if (s.area != UnwalkableArea)
                        {
                            int bottom = (int)s.top;
                            int top    = s.next != null ? (int)s.next.bottom : VoxelArea.MaxHeightInt;

                            voxelArea.compactSpans[idx] = new CompactVoxelSpan((ushort)AstarMath.Clamp(bottom, 0, 0xffff), (uint)AstarMath.Clamp(top - bottom, 0, 0xffff));
                            voxelArea.areaTypes[idx]    = s.area;
                            idx++;
                            count++;
                        }
                        s = s.next;
                    }

                    voxelArea.compactCells[x + z] = new CompactVoxelCell(index, count);
#endif
                }
            }

            AstarProfiler.EndProfile("Build Compact Voxel Field");
        }
예제 #30
0
        /// <summary>Create a number of agents in circle and restart simulation</summary>
        public void CreateAgents(int num)
        {
            this.agentCount = num;

            agents = new List <IAgent>(agentCount);
            goals  = new List <Vector3>(agentCount);
            colors = new List <Color>(agentCount);

            sim.ClearAgents();

            if (type == RVOExampleType.Circle)
            {
                float circleRad = Mathf.Sqrt(agentCount * radius * radius * 4 / Mathf.PI) * exampleScale * 0.05f;

                for (int i = 0; i < agentCount; i++)
                {
                    Vector3 pos   = new Vector3(Mathf.Cos(i * Mathf.PI * 2.0f / agentCount), 0, Mathf.Sin(i * Mathf.PI * 2.0f / agentCount)) * circleRad * (1 + Random.value * 0.01f);
                    IAgent  agent = sim.AddAgent(new Vector2(pos.x, pos.z), pos.y);
                    agents.Add(agent);
                    goals.Add(-pos);
                    colors.Add(AstarMath.HSVToRGB(i * 360.0f / agentCount, 0.8f, 0.6f));
                }
            }
            else if (type == RVOExampleType.Line)
            {
                for (int i = 0; i < agentCount; i++)
                {
                    Vector3 pos   = new Vector3((i % 2 == 0 ? 1 : -1) * exampleScale, 0, (i / 2) * radius * 2.5f);
                    IAgent  agent = sim.AddAgent(new Vector2(pos.x, pos.z), pos.y);
                    agents.Add(agent);
                    goals.Add(new Vector3(-pos.x, pos.y, pos.z));
                    colors.Add(i % 2 == 0 ? Color.red : Color.blue);
                }
            }
            else if (type == RVOExampleType.Point)
            {
                for (int i = 0; i < agentCount; i++)
                {
                    Vector3 pos   = new Vector3(Mathf.Cos(i * Mathf.PI * 2.0f / agentCount), 0, Mathf.Sin(i * Mathf.PI * 2.0f / agentCount)) * exampleScale;
                    IAgent  agent = sim.AddAgent(new Vector2(pos.x, pos.z), pos.y);
                    agents.Add(agent);
                    goals.Add(new Vector3(0, pos.y, 0));
                    colors.Add(AstarMath.HSVToRGB(i * 360.0f / agentCount, 0.8f, 0.6f));
                }
            }
            else if (type == RVOExampleType.RandomStreams)
            {
                float circleRad = Mathf.Sqrt(agentCount * radius * radius * 4 / Mathf.PI) * exampleScale * 0.05f;

                for (int i = 0; i < agentCount; i++)
                {
                    float   angle       = Random.value * Mathf.PI * 2.0f;
                    float   targetAngle = Random.value * Mathf.PI * 2.0f;
                    Vector3 pos         = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * uniformDistance(circleRad);
                    IAgent  agent       = sim.AddAgent(new Vector2(pos.x, pos.z), pos.y);
                    agents.Add(agent);
                    goals.Add(new Vector3(Mathf.Cos(targetAngle), 0, Mathf.Sin(targetAngle)) * uniformDistance(circleRad));
                    colors.Add(AstarMath.HSVToRGB(targetAngle * Mathf.Rad2Deg, 0.8f, 0.6f));
                }
            }
            else if (type == RVOExampleType.Crossing)
            {
                float distanceBetweenGroups = exampleScale * radius * 0.5f;
                int   directions            = (int)Mathf.Sqrt(agentCount / 25f);
                directions = Mathf.Max(directions, 2);

                const int AgentsPerDistance = 10;
                for (int i = 0; i < agentCount; i++)
                {
                    float   angle = ((i % directions) / (float)directions) * Mathf.PI * 2.0f;
                    var     dist  = distanceBetweenGroups * ((i / (directions * AgentsPerDistance) + 1) + 0.3f * Random.value);
                    Vector3 pos   = new Vector3(Mathf.Cos(angle), 0, Mathf.Sin(angle)) * dist;
                    IAgent  agent = sim.AddAgent(new Vector2(pos.x, pos.z), pos.y);
                    agent.Priority = (i % directions) == 0 ? 1 : 0.01f;
                    agents.Add(agent);
                    goals.Add(-pos.normalized * distanceBetweenGroups * 3);
                    colors.Add(AstarMath.HSVToRGB(angle * Mathf.Rad2Deg, 0.8f, 0.6f));
                }
            }

            SetAgentSettings();

            verts      = new Vector3[4 * agents.Count];
            uv         = new Vector2[verts.Length];
            tris       = new int[agents.Count * 2 * 3];
            meshColors = new Color[verts.Length];
        }