예제 #1
0
        public override bool Equals(object obj)
        {
            if (!(obj is PlaneVector))
            {
                return(false);
            }

            return(PlaneVector.SqrMagnitude((PlaneVector)obj - this) < 9.99999944E-11f);
        }
예제 #2
0
        /// <summary>
        /// Returns a normalized <see cref="PlaneVector"/> (divided by its Magnitude)
        /// </summary>
        /// <param name="value">The <see cref="PlaneVector"/> to normalize.</param>
        /// <returns></returns>
        public static PlaneVector Normalize(PlaneVector value)
        {
            float single = PlaneVector.Magnitude(value);

            if (single <= 1E-05f)
            {
                return(PlaneVector.zero);
            }

            return(value / single);
        }
 /// <summary>
 /// Gets the squared magnitude of the vector
 /// </summary>
 /// <param name="a">The vector</param>
 /// <returns>The squared magnitude</returns>
 public static float SqrMagnitude(PlaneVector a)
 {
     return (a.x * a.x) + (a.z * a.z);
 }
 /// <summary>
 /// Returns the magnitude of a <see cref="PlaneVector"/>.
 /// </summary>
 /// <param name="a"></param>
 /// <returns></returns>
 public static float Magnitude(PlaneVector a)
 {
     return Mathf.Sqrt((a.x * a.x) + (a.z * a.z));
 }
        /// <summary>
        /// Returns a normalized <see cref="PlaneVector"/> (divided by its Magnitude)
        /// </summary>
        /// <param name="value">The <see cref="PlaneVector"/> to normalize.</param>
        /// <returns></returns>
        public static PlaneVector Normalize(PlaneVector value)
        {
            float single = PlaneVector.Magnitude(value);
            if (single <= 1E-05f)
            {
                return PlaneVector.zero;
            }

            return value / single;
        }
예제 #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VectorFieldCell"/> struct.
 /// </summary>
 /// <param name="portalIndex">Index of the portal.</param>
 /// The plane vector defaults to a PlaneVector.zero (0f, 0f) in this case.
 public VectorFieldCell(int portalIndex)
 {
     this.direction = PlaneVector.zero;
     this.pathPortalIndex = portalIndex;
 }
예제 #7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VectorFieldCell"/> struct.
 /// </summary>
 /// <param name="direction">The direction.</param>
 /// The path portal index defaults to -1 in this case.
 public VectorFieldCell(PlaneVector direction)
 {
     this.direction = direction;
     this.pathPortalIndex = -1;
 }
예제 #8
0
 /// <summary>
 /// Initializes a new instance of the <see cref="VectorFieldCell"/> struct.
 /// </summary>
 /// <param name="direction">The direction.</param>
 /// <param name="portalIndex">Index of the portal.</param>
 public VectorFieldCell(PlaneVector direction, int portalIndex)
 {
     this.direction = direction;
     this.pathPortalIndex = portalIndex;
 }
        private void FunnelMethod(Cell currentCell, Cell destinationCell)
        {
            // prepare local variables
            // the previous path node is either the actual previous path node, or in the case of portalling where we might receive a path with only 1 point - the destination - then we use the group's center of gravity in place of the previous path node
            Vector3 cellPos = currentCell.position;
            Vector3 currentPathNode = _currentPath[_currentPathStep].position;
            Vector3 previousPathNode = _currentPathStep > 0 ? _currentPath[_currentPathStep - 1].position : this.group.centerOfGravity;
            
            // get all walkable cell neighbours
            GetWalkableCellNeighbours(currentCell, _tempWalkableNeighbours, !_allowDiagonals);
            int neighboursCount = _tempWalkableNeighbours.count;
            for (int i = 0; i < neighboursCount; i++)
            {
                var neighbour = _tempWalkableNeighbours[i];
                Vector3 neighbourPos = neighbour.position;

                // check whether the neighbour cell we are visiting has unwalkable neighbours
                Vector3 directionVector = Vector3.zero;
                bool noUnwalkables = GetCellNeighboursAndUnwalkability(neighbour, _extraTempWalkableNeighbours, !_allowDiagonals);
                if (noUnwalkables && (neighbourPos - destinationCell.position).sqrMagnitude > _funnelWidthSqr)
                {
                    // if cell has no unwalkable neighbours...
                    // Sum up a vector comprised of 3 vectors: 1) fast marching direction (avoid obstacles), 2) goal direction (point to next node path), 3) path direction (point in path's direction)
                    Vector3 fastMarchVector = neighbourPos.DirToXZ(cellPos).normalized;
                    Vector3 goalVector = neighbourPos.DirToXZ(currentPathNode).normalized;
                    Vector3 pathVector = previousPathNode.DirToXZ(currentPathNode).normalized;
                    directionVector = (fastMarchVector + goalVector + pathVector) / 3f;
                }
                else
                {
                    // if this cell has unwalkable neighbours, then just use fast marching direction and multiply the magnitude with the obstacle strength factor
                    directionVector = neighbourPos.DirToXZ(cellPos).normalized * _obstacleStrengthFactor;
                }

                _fastMarchedCellsSet[neighbourPos] = new PlaneVector(directionVector);

                Vector3 closestPos = GetClosestPositionOnLine(previousPathNode, currentPathNode, neighbourPos);
                if ((closestPos - neighbourPos).sqrMagnitude > _funnelWidthSqr)
                {
                    // only add neighbour cells within the defined funnel area around the path
                    continue;
                }

                _openSet.Enqueue(neighbour);
            }

            // check whether we need to move backwards along the path (we start at the destination)
            // Basically, if we reach a cell that is less than one cell size away from our previous path node, then move on to the next path nodes (decrementally)
            if (_currentPathStep > 0 && (previousPathNode - cellPos).sqrMagnitude < (_grid.cellSize * _grid.cellSize))
            {
                if (_currentPath[_currentPathStep - 1] is IPortalNode)
                {
                    // never move past portal nodes, we never want to remove them because we want to force units to go through the portal
                    return;
                }

                _currentPathStep -= 1;
            }
        }
예제 #10
0
 public static float SqrMagnitude(PlaneVector a)
 {
     return((a.x * a.x) + (a.z * a.z));
 }
예제 #11
0
 /// <summary>
 /// Returns the magnitude of a <see cref="PlaneVector"/>.
 /// </summary>
 /// <param name="a"></param>
 /// <returns></returns>
 public static float Magnitude(PlaneVector a)
 {
     return(Mathf.Sqrt((a.x * a.x) + (a.z * a.z)));
 }
예제 #12
0
 public static bool operator !=(PlaneVector lhs, PlaneVector rhs)
 {
     return(PlaneVector.SqrMagnitude(lhs - rhs) >= 9.99999944E-11f);
 }