Example #1
0
 /// <summary>
 /// Updates the region rect2D. Needed if points is updated manually.
 /// </summary>
 /// <param name="newPoints">New points.</param>
 /// <param name="inflate">If set to <c>true</c> points will be slightly displaced to prevent polygon clipping floating point issues.</param>
 public void UpdatePointsAndRect(Vector2[] newPoints, bool inflate = false)
 {
     sanitized = false;
     points    = newPoints;
     ComputeBounds();
     if (inflate)
     {
         Vector2 tmp = Misc.Vector2zero;
         for (int k = 0; k < points.Length; k++)
         {
             FastVector.NormalizedDirection(ref center, ref points [k], ref tmp);
             FastVector.Add(ref points [k], ref tmp, 0.00001f);
         }
     }
 }
Example #2
0
        /// <summary>
        /// Returns an optimal route from startPosition to endPosition with options.
        /// </summary>
        /// <returns>The route.</returns>
        /// <param name="startPosition">Start position in map coordinates (-0.5...0.5)</param>
        /// <param name="endPosition">End position in map coordinates (-0.5...0.5)</param>
        /// <param name="totalCost">The total cost of traversing the path</param>
        /// <param name="terrainCapability">Type of terrain that the unit can pass through</param>
        /// <param name="minAltitude">Minimum altitude (0..1)</param>
        /// <param name="maxAltitude">Maximum altutude (0..1)</param>
        /// <param name="maxSearchCost">Maximum search cost for the path finding algorithm. A value of -1 will use the global default defined by pathFindingMaxCost</param>
        public List <Vector2> FindRoute(Vector2 startPosition, Vector2 endPosition, out int totalCost, TERRAIN_CAPABILITY terrainCapability = TERRAIN_CAPABILITY.Any, float minAltitude = 0, float maxAltitude = 1f, int maxSearchCost = -1, int maxSearchSteps = -1)
        {
            ComputeRouteMatrix(terrainCapability, minAltitude, maxAltitude);
            totalCost = 0;
            Point startingPoint = new Point((int)((startPosition.x + 0.5f) * EARTH_ROUTE_SPACE_WIDTH),
                                            (int)((startPosition.y + 0.5f) * EARTH_ROUTE_SPACE_HEIGHT));
            Point endingPoint = new Point((int)((endPosition.x + 0.5f + 0.5f / EARTH_ROUTE_SPACE_WIDTH) * EARTH_ROUTE_SPACE_WIDTH),
                                          (int)((endPosition.y + 0.5f + 0.5f / EARTH_ROUTE_SPACE_HEIGHT) * EARTH_ROUTE_SPACE_HEIGHT));

            endingPoint.X = Mathf.Clamp(endingPoint.X, 0, EARTH_ROUTE_SPACE_WIDTH - 1);
            endingPoint.Y = Mathf.Clamp(endingPoint.Y, 0, EARTH_ROUTE_SPACE_HEIGHT - 1);

            // Helper to find a minimum path in case the destination position is on a different terrain type
            if (terrainCapability == TERRAIN_CAPABILITY.OnlyWater)
            {
                int arrayIndex = endingPoint.Y * EARTH_ROUTE_SPACE_WIDTH + endingPoint.X;
                if ((earthRouteMatrix [arrayIndex] & 4) == 0)
                {
                    int regionIndex  = -1;
                    int countryIndex = GetCountryIndex(endPosition, out regionIndex);
                    if (countryIndex >= 0 && regionIndex >= 0)
                    {
                        List <Vector2> coastPositions      = GetCountryCoastalPoints(countryIndex, regionIndex, 0.001f);
                        float          minDist             = float.MaxValue;
                        Vector2        bestPosition        = Misc.Vector2zero;
                        int            coastPositionsCount = coastPositions.Count;
                        // Get nearest position to the ship which is on water
                        for (int k = 0; k < coastPositionsCount; k++)
                        {
                            Vector2 waterPosition;
                            if (ContainsWater(coastPositions [k], 0.001f, out waterPosition))
                            {
                                float dist = FastVector.SqrDistance(ref endPosition, ref waterPosition);                                  // (endPosition - waterPosition).sqrMagnitude;
                                if (dist < minDist)
                                {
                                    minDist      = dist;
                                    bestPosition = waterPosition;
                                }
                            }
                        }
                        if (minDist < float.MaxValue)
                        {
                            endPosition = bestPosition;
                        }
                        endingPoint = new Point((int)((endPosition.x + 0.5f + 0.5f / EARTH_ROUTE_SPACE_WIDTH) * EARTH_ROUTE_SPACE_WIDTH),
                                                (int)((endPosition.y + 0.5f + 0.5f / EARTH_ROUTE_SPACE_HEIGHT) * EARTH_ROUTE_SPACE_HEIGHT));
                        arrayIndex = endingPoint.Y * EARTH_ROUTE_SPACE_WIDTH + endingPoint.X;
                        if ((earthRouteMatrix [arrayIndex] & 4) == 0)
                        {
                            Vector2 direction = Misc.Vector2zero;
                            for (int k = 1; k <= 10; k++)
                            {
                                if (k == 10 || startPosition == endPosition)
                                {
                                    return(null);
                                }
                                FastVector.NormalizedDirection(ref endPosition, ref startPosition, ref direction);
                                Vector2 p = endPosition + direction * (float)k / EARTH_ROUTE_SPACE_WIDTH;
                                endingPoint = new Point((int)((p.x + 0.5f + 0.5f / EARTH_ROUTE_SPACE_WIDTH) * EARTH_ROUTE_SPACE_WIDTH),
                                                        (int)((p.y + 0.5f + 0.5f / EARTH_ROUTE_SPACE_HEIGHT) * EARTH_ROUTE_SPACE_HEIGHT));
                                arrayIndex = endingPoint.Y * EARTH_ROUTE_SPACE_WIDTH + endingPoint.X;
                                if ((earthRouteMatrix [arrayIndex] & 4) > 0)
                                {
                                    break;
                                }
                            }
                        }
                    }
                }
            }

            List <Vector2> routePoints = null;

            // Minimum distance for routing?
            if (Mathf.Abs(endingPoint.X - startingPoint.X) > 0 || Mathf.Abs(endingPoint.Y - startingPoint.Y) > 0)
            {
                finder.Formula       = _pathFindingHeuristicFormula;
                finder.MaxSearchCost = maxSearchCost < 0 ? _pathFindingMaxCost : maxSearchCost;
                finder.MaxSteps      = maxSearchSteps < 0 ? _pathFindingMaxSteps : maxSearchSteps;
                if (_pathFindingEnableCustomRouteMatrix)
                {
                    finder.OnCellCross = FindRoutePositionValidator;
                }
                else
                {
                    finder.OnCellCross = null;
                }
                List <PathFinderNode> route = finder.FindPath(startingPoint, endingPoint, out totalCost);
                if (route != null)
                {
                    routePoints = new List <Vector2> (route.Count);
                    routePoints.Add(startPosition);
                    for (int r = route.Count - 1; r >= 0; r--)
                    {
                        float   x       = (float)route [r].X / EARTH_ROUTE_SPACE_WIDTH - 0.5f;
                        float   y       = (float)route [r].Y / EARTH_ROUTE_SPACE_HEIGHT - 0.5f;
                        Vector2 stepPos = new Vector2(x, y);

                        // due to grid effect the first step may be farther than the current position, so we skip it in that case.
                        if (r == route.Count - 1 && (endPosition - startPosition).sqrMagnitude < (endPosition - stepPos).sqrMagnitude)
                        {
                            continue;
                        }

                        routePoints.Add(stepPos);
                    }
                }
                else
                {
                    return(null);                       // no route available
                }
            }

            // Add final step if it's appropiate
            bool hasWater = ContainsWater(endPosition);

            if (terrainCapability == TERRAIN_CAPABILITY.Any ||
                (terrainCapability == TERRAIN_CAPABILITY.OnlyWater && hasWater) ||
                (terrainCapability == TERRAIN_CAPABILITY.OnlyGround && !hasWater))
            {
                if (routePoints == null)
                {
                    routePoints = new List <Vector2> ();
                    routePoints.Add(startPosition);
                    routePoints.Add(endPosition);
                }
                else
                {
                    routePoints [routePoints.Count - 1] = endPosition;
                }
            }

            // Check that ground units ends in a position where GetCountryIndex returns a valid index
            if (terrainCapability == TERRAIN_CAPABILITY.OnlyGround)
            {
                int     rr = routePoints.Count - 1;
                Vector2 dd = routePoints [rr - 1] - routePoints [rr];
                dd *= 0.1f;
                while (GetCountryIndex(routePoints [rr]) < 0)
                {
                    routePoints [rr] += dd;
                }
            }

            return(routePoints);
        }
Example #3
0
        public static void UpdateDashedLine(MeshFilter meshFilter, List <Vector3> points, float thickness, bool worldSpace, ref Vector3[] meshPoints, ref int[] triPoints, ref Vector2[] uv)
        {
            int max = (points.Count / 2) * 2;

            if (max == 0)
            {
                return;
            }

            int numPoints = 8 * 3 * max / 2;

            if (numPoints > 65000)
            {
                return;
            }

            Mesh mesh         = meshFilter.sharedMesh;
            bool reassignMesh = false;

            if (mesh == null || meshPoints == null || mesh.vertexCount != numPoints)
            {
                meshPoints   = new Vector3[numPoints];
                triPoints    = new int[numPoints];
                uv           = new Vector2[numPoints];
                reassignMesh = true;
            }

            int mp = 0;

            thickness *= 0.5f;
            float   y0     = 0f;          //Mathf.Sin (0.0f * Mathf.Deg2Rad);
            float   x0     = 1f;          //Mathf.Cos (0.0f * Mathf.Deg2Rad);
            float   y1     = 0.8660254f;  //Mathf.Sin (120.0f * Mathf.Deg2Rad);
            float   x1     = -0.5f;       //Mathf.Cos (120.0f * Mathf.Deg2Rad);
            float   y2     = -0.8660254f; //Mathf.Sin (240.0f * Mathf.Deg2Rad);
            float   x2     = -0.5f;       //Mathf.Cos (240.0f * Mathf.Deg2Rad);
            Vector3 up     = WMSK.instance.currentCamera.transform.forward;
            Vector3 axis   = Misc.Vector3zero;
            float   scaleX = worldSpace ? 1f : 0.5f;

            Vector3 tmp = Misc.Vector3zero;

            for (int p = 0; p < max; p += 2)
            {
                Vector3 p0 = points [p];
                Vector3 p1 = points [p + 1];

                FastVector.NormalizedDirection(ref p0, ref p1, ref tmp);

                // Front triangle
                Vector3 right = Vector3.Cross(up, tmp);

//				Vector3 axis = (up * y0 + right * x0).normalized;
                FastVector.CombineAndNormalize(ref up, y0, ref right, x0, ref axis);
                axis.x *= scaleX;
                meshPoints [mp + 0] = p0 + axis * thickness;

//				axis = (up * y2 + right * x2).normalized;
                FastVector.CombineAndNormalize(ref up, y2, ref right, x2, ref axis);
                axis.x *= scaleX;
                meshPoints [mp + 1] = p0 + axis * thickness;

//				axis = (up * y1 + right * x1).normalized;
                FastVector.CombineAndNormalize(ref up, y1, ref right, x1, ref axis);
                axis.x *= scaleX;
                meshPoints [mp + 2] = p0 + axis * thickness;

                triPoints [mp + 0] = mp + 0;
                triPoints [mp + 1] = mp + 1;
                triPoints [mp + 2] = mp + 2;
                uv [mp + 0]        = Misc.Vector2zero;
                uv [mp + 1]        = Misc.Vector2right;
                uv [mp + 2]        = Misc.Vector2up;

                // Back triangle
//				axis =  (up * y0 + right * x0).normalized;
                FastVector.CombineAndNormalize(ref up, y0, ref right, x0, ref axis);
                axis.x *= scaleX;
                meshPoints [mp + 3] = p1 + axis * thickness;

//				axis = (up * y1 + right * x1).normalized;
                FastVector.CombineAndNormalize(ref up, y1, ref right, x1, ref axis);
                axis.x *= scaleX;
                meshPoints [mp + 4] = p1 + axis * thickness;

//				axis = (up * y2 + right * x2).normalized;
                FastVector.CombineAndNormalize(ref up, y2, ref right, x2, ref axis);
                axis.x *= scaleX;
                meshPoints [mp + 5] = p1 + axis * thickness;

                triPoints [mp + 3] = mp + 3;
                triPoints [mp + 4] = mp + 4;
                triPoints [mp + 5] = mp + 5;
                uv [mp + 3]        = Misc.Vector2zero;
                uv [mp + 4]        = Misc.Vector2one;
                uv [mp + 5]        = Misc.Vector2right;

                // One side
                meshPoints [mp + 6] = meshPoints [mp + 0];
                triPoints [mp + 6]  = mp + 6;
                uv [mp + 6]         = Misc.Vector2up;
                meshPoints [mp + 7] = meshPoints [mp + 3];
                triPoints [mp + 7]  = mp + 7;
                uv [mp + 7]         = Misc.Vector2one;
                meshPoints [mp + 8] = meshPoints [mp + 1];
                triPoints [mp + 8]  = mp + 8;
                uv [mp + 8]         = Misc.Vector2zero;

                meshPoints [mp + 9]  = meshPoints [mp + 1];
                triPoints [mp + 9]   = mp + 9;
                uv [mp + 9]          = Misc.Vector2zero;
                meshPoints [mp + 10] = meshPoints [mp + 3];
                triPoints [mp + 10]  = mp + 10;
                uv [mp + 10]         = Misc.Vector2one;
                meshPoints [mp + 11] = meshPoints [mp + 5];
                triPoints [mp + 11]  = mp + 11;
                uv [mp + 11]         = Misc.Vector2zero;

                // Second side
                meshPoints [mp + 12] = meshPoints [mp + 1];
                triPoints [mp + 12]  = mp + 12;
                uv [mp + 12]         = Misc.Vector2zero;
                meshPoints [mp + 13] = meshPoints [mp + 5];
                triPoints [mp + 13]  = mp + 13;
                uv [mp + 13]         = Misc.Vector2right;
                meshPoints [mp + 14] = meshPoints [mp + 2];
                triPoints [mp + 14]  = mp + 14;
                uv [mp + 14]         = Misc.Vector2up;

                meshPoints [mp + 15] = meshPoints [mp + 2];
                triPoints [mp + 15]  = mp + 15;
                uv [mp + 15]         = Misc.Vector2up;
                meshPoints [mp + 16] = meshPoints [mp + 5];
                triPoints [mp + 16]  = mp + 16;
                uv [mp + 16]         = Misc.Vector2right;
                meshPoints [mp + 17] = meshPoints [mp + 4];
                triPoints [mp + 17]  = mp + 17;
                uv [mp + 17]         = Misc.Vector2up;

                // Third side
                meshPoints [mp + 18] = meshPoints [mp + 0];
                triPoints [mp + 18]  = mp + 18;
                uv [mp + 18]         = Misc.Vector2right;
                meshPoints [mp + 19] = meshPoints [mp + 4];
                triPoints [mp + 19]  = mp + 19;
                uv [mp + 19]         = Misc.Vector2up;
                meshPoints [mp + 20] = meshPoints [mp + 3];
                triPoints [mp + 20]  = mp + 20;
                uv [mp + 20]         = Misc.Vector2zero;

                meshPoints [mp + 21] = meshPoints [mp + 0];
                triPoints [mp + 21]  = mp + 21;
                uv [mp + 21]         = Misc.Vector2zero;
                meshPoints [mp + 22] = meshPoints [mp + 2];
                triPoints [mp + 22]  = mp + 22;
                uv [mp + 22]         = Misc.Vector2one;
                meshPoints [mp + 23] = meshPoints [mp + 4];
                triPoints [mp + 23]  = mp + 23;
                uv [mp + 23]         = Misc.Vector2up;

                mp += 24;
            }

            if (mesh == null)
            {
                mesh           = new Mesh();
                mesh.hideFlags = HideFlags.DontSave;
            }
            if (reassignMesh)
            {
                mesh.Clear();
            }
            mesh.vertices  = meshPoints;
            mesh.uv        = uv;
            mesh.triangles = triPoints;
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();
            if (reassignMesh)
            {
                meshFilter.sharedMesh = mesh;
            }
        }
Example #4
0
        void UpdateArrowCap(ref GameObject placeholder, ref GameObject obj, GameObject cap, bool flipDirection, Vector3 arrowBasePos, Vector3 arrowTipPos, Vector3 scale, float offset, Material capMaterial)
        {
            if (obj == null)
            {
                placeholder = new GameObject("CapPlaceholder");
                placeholder.transform.SetParent(transform, false);
                if (!usesViewport)
                {
                    placeholder.transform.localScale = new Vector3(1f / transform.lossyScale.x, 1f / transform.lossyScale.y, 1f);
                }
                obj = Instantiate <GameObject>(cap);
                capSpriteRenderer = obj.GetComponent <SpriteRenderer>();
                if (capSpriteRenderer != null)
                {
                    capSpriteRenderer.color = lineMaterial.color;
                    capStartColor           = capSpriteRenderer.color;
                }
                capMeshRenderer = obj.GetComponent <MeshRenderer>();
                if (capMeshRenderer != null)
                {
                    capMeshRenderer.sharedMaterial = capMaterial != null ? capMaterial : lineMaterial;
                    capStartColor = capMeshRenderer.sharedMaterial.color;
                }
                obj.transform.SetParent(placeholder.transform);
                obj.SetActive(false);
            }

            // set position
            Vector3 pos = Misc.Vector3zero;

            if (!usesViewport)
            {
                arrowBasePos = map.transform.TransformPoint(arrowBasePos);
                arrowTipPos  = map.transform.TransformPoint(arrowTipPos);
            }

            // Length of cap based on size
            if (arrowBasePos != arrowTipPos)
            {
                Vector3 dir = Misc.Vector3zero;
                FastVector.NormalizedDirection(ref arrowBasePos, ref arrowTipPos, ref dir);
                pos = arrowTipPos - dir * offset;
                if (!obj.activeSelf)
                {
                    obj.SetActive(true);
                }
                obj.transform.position = pos;

                // look to camera
                if (usesViewport)
                {
                    Vector3 camDir = pos - map.cameraMain.transform.position;
                    obj.transform.LookAt(arrowTipPos + dir * 100f, camDir);
                }
                else
                {
                    Vector3 prdir = Vector3.ProjectOnPlane(dir, map.transform.forward);
                    obj.transform.LookAt(pos + map.transform.forward, prdir);
                    obj.transform.Rotate(obj.transform.forward, 90, Space.Self);
                }

                if (flipDirection)
                {
                    obj.transform.Rotate(180, 0, 0, Space.Self);
                }
            }
            obj.transform.localScale = scale;
        }