Пример #1
0
 public void GeneratePollutionVertexArray(SurfaceContainer surface, Vector2 position, int xRange, int yRange, VertexArray vA)
 {
     int[] chunkIndices = SurfaceContainer.WorldToChunkCoords(position);
     vA.Clear();
     for (int i = chunkIndices[0] - xRange; i <= chunkIndices[0] + xRange; i++)
     {
         for (int j = chunkIndices[1] - yRange; j <= chunkIndices[1] + yRange; j++)
         {
             byte  val     = Convert.ToByte(surface.GetInterpolatedPollution(i, j) * 255 / Props.maxPollution);
             Color topLeft = new Color(val, 0, 0, (byte)(val / 2));
             val = Convert.ToByte(surface.GetInterpolatedPollution(i + 1, j) * 255 / Props.maxPollution);
             Color topRight = new Color(val, 0, 0, (byte)(val / 2));
             val = Convert.ToByte(surface.GetInterpolatedPollution(i, j + 1) * 255 / Props.maxPollution);
             Color botLeft = new Color(val, 0, 0, (byte)(val / 2));
             val = Convert.ToByte(surface.GetInterpolatedPollution(i + 1, j + 1) * 255 / Props.maxPollution);
             Color botRight = new Color(val, 0, 0, (byte)(val / 2));
             int   oX       = i * Props.chunkSize;
             int   oY       = j * Props.chunkSize;
             vA.Append(new Vertex(new Vector2f(oX, oY), topLeft));
             vA.Append(new Vertex(new Vector2f(oX + Props.chunkSize, oY), topRight));
             vA.Append(new Vertex(new Vector2f(oX, oY + Props.chunkSize), botLeft));
             vA.Append(new Vertex(new Vector2f(oX + Props.chunkSize, oY), topRight));
             vA.Append(new Vertex(new Vector2f(oX + Props.chunkSize, oY + Props.chunkSize), botRight));
             vA.Append(new Vertex(new Vector2f(oX, oY + Props.chunkSize), botLeft));
         }
     }
 }
Пример #2
0
        /// <summary>
        /// Gets minimap textures for a specified surface.  The position is the centered location. The range is the number of chunks x/y away from center to get.
        /// </summary>
        /// <param name="surface"></param>
        /// <param name="position"></param>
        /// <param name="ranges"></param>
        public void GenerateMinimapTextures(SurfaceContainer surface, Vector2 position, int xRange, int yRange, List <VertexArray> vertexArrays)
        {
            int[] chunkIndices = SurfaceContainer.WorldToChunkCoords(position);
            vertexArrays.Clear();
            for (int i = chunkIndices[0] - xRange; i <= chunkIndices[0] + xRange; i++)
            {
                for (int j = chunkIndices[1] - yRange; j <= chunkIndices[1] + yRange; j++)
                {
                    Chunk chunk = surface.GetChunk((i * surface.worldSize) + j, false);
                    if (chunk != null)
                    {
                        VertexArray vA;
                        if (!minimapVertexArrays.TryGetValue(i * surface.worldSize + j, out vA))
                        {
                            vA = tileCollection.GenerateTerrainMinimap(chunk, (i * surface.worldSize) + j, surface.worldSize);
                            minimapVertexArrays.Add(i * surface.worldSize + j, vA);
                        }
                        vertexArrays.Add(vA);
                        //next get entities
                        //This is very dynamic so there is no point caching it
                        List <Entity> entityList  = chunk.entityList;
                        VertexArray   entityArray = new VertexArray(PrimitiveType.Triangles);
                        int           oX          = i * Props.chunkSize;
                        int           oY          = j * Props.chunkSize;
                        for (int l = 0; l < entityList.Count; l++)
                        {
                            EntityPhysical e = entityList[l] as EntityPhysical;
                            if (e == null)
                            {
                                continue;
                            }
                            int[] pos        = surface.WorldToAbsoluteTileCoords(e.position.x, e.position.y);
                            float halfWidth  = e.tileWidth;
                            float halfHeight = e.tileHeight;
                            entityArray.Append(new Vertex(new Vector2f(pos[0] - halfWidth, pos[1] - halfHeight), e.mapColor));
                            entityArray.Append(new Vertex(new Vector2f(pos[0] + halfWidth, pos[1] - halfHeight), e.mapColor));
                            entityArray.Append(new Vertex(new Vector2f(pos[0] - halfWidth, pos[1] + halfHeight), e.mapColor));

                            entityArray.Append(new Vertex(new Vector2f(pos[0] + halfWidth, pos[1] - halfHeight), e.mapColor));
                            entityArray.Append(new Vertex(new Vector2f(pos[0] + halfWidth, pos[1] + halfHeight), e.mapColor));
                            entityArray.Append(new Vertex(new Vector2f(pos[0] - halfWidth, pos[1] + halfHeight), e.mapColor));
                        }
                        if (entityArray.VertexCount > 0)
                        {
                            vertexArrays.Add(entityArray);
                        }
                    }
                }
            }
        }
Пример #3
0
        /// <summary>
        /// Gets the chunks the entity is possibly present in chunk indices
        /// </summary>
        /// <param name="self"></param>
        /// <param name="selfPos"></param>
        /// <returns></returns>
        public static int[] GetChunkBounds(BoundingBox self, Vector2 posSelf, SurfaceContainer surface)
        {
            float xMin = posSelf.x - self.radiusApproximation - Props.tileCollisionFactor * Props.tileSize;
            float xMax = posSelf.x + self.radiusApproximation + Props.tileCollisionFactor * Props.tileSize;
            float yMin = posSelf.y - self.radiusApproximation - Props.tileCollisionFactor * Props.tileSize;
            float yMax = posSelf.y + self.radiusApproximation + Props.tileCollisionFactor * Props.tileSize;

            int[] top    = surface.WorldToChunkCoords(xMin, yMin);
            int[] bot    = surface.WorldToChunkCoords(xMax, yMax);
            int   yRange = (bot[1] - top[1]) + 1;
            int   xRange = (bot[0] - top[0]) + 1;

            int[] ret = new int[xRange * yRange];
            int   k   = 0;

            for (int i = top[0]; i <= bot[0]; i++)
            {
                for (int j = top[1]; j <= bot[1]; j++)
                {
                    ret[k] = i * surface.worldSize + j;
                    k++;
                }
            }
            return(ret);

            #region more complex chunk bound code

            /*if(self.rotation == 0)
             * {
             *  int[] top = SurfaceContainer.WorldToChunkCoords(selfPos.x + self.topLeftR.x, selfPos.y + self.topLeftR.y);
             *  int[] bot = SurfaceContainer.WorldToChunkCoords(selfPos.x + self.botLeftR.y, selfPos.y + self.botLeftR.y);
             *  int yRange = (bot[1] - top[1]);
             *  int xRange = (bot[0] - top[0]);
             *  int[] ret = new int[xRange * yRange];
             *  int k = 0;
             *  for(int i = top[0]; i <= bot[0]; i++)
             *  {
             *      for(int j = top[1]; j <= bot[1]; j++)
             *      {
             *          ret[k] = i * Props.worldSize + j;
             *          k++;
             *      }
             *  }
             *  return ret;
             * }
             * int[][] coords = new int[4][];
             * coords[0] = SurfaceContainer.WorldToChunkCoords(selfPos.VAdd(self.topLeftR));
             * coords[1] = SurfaceContainer.WorldToChunkCoords(selfPos.VAdd(self.topRightR));
             * coords[2] = SurfaceContainer.WorldToChunkCoords(selfPos.VAdd(self.botLeftR));
             * coords[3] = SurfaceContainer.WorldToChunkCoords(selfPos.VAdd(self.botRightR));
             * int[] min = new int[] { coords[0][0], coords[0][1] };
             * int[] max = new int[] { coords[3][0], coords[3][1] };
             * for (int i = 0; i < 4; i++)
             * {
             *  if(coords[i][0] <= min[0])
             *  {
             *      min[0] = coords[i][0];
             *  }
             *  if(coords[i][0] >= max[0])
             *  {
             *      max[0] = coords[i][0];
             *  }
             *  if(coords[i][1] <= min[1])
             *  {
             *      min[1] = coords[i][1];
             *  }
             *  if(coords[i][1] >= max[1])
             *  {
             *      max[1] = coords[i][1];
             *  }
             * }*/
            #endregion more complex chunk bound code
        }
Пример #4
0
        public void RenderWorld(RenderWindow window, Camera camera, SurfaceContainer surface)
        {
            window.SetView(camera.GetGameView()); //Set view
            Vector2f origin = window.MapPixelToCoords(new Vector2i(0, 0), camera.GetGameView());
            Vector2f extent = window.MapPixelToCoords(new Vector2i((int)window.Size.X, (int)window.Size.Y), camera.GetGameView());

            int[] begPos = surface.WorldToChunkCoords(origin.X, origin.Y);
            int[] endPos = surface.WorldToChunkCoords(extent.X, extent.Y);
            windowBox = new BoundingBox(0, 0, extent.X - origin.X, extent.Y - origin.Y);
            #region terrain drawing
            for (int i = begPos[0]; i <= endPos[0]; i++)
            {
                for (int j = begPos[1]; j <= endPos[1]; j++)
                {
                    int key = (i) * surface.worldSize + j;
                    if (terrainVertexArrays.TryGetValue(key, out _) == false)
                    {
                        terrainVertexArrays.Add(key, tileCollection.GenerateTerrainVertices(surface, new int[] { i, j }));
                    }
                    VertexArray[] vArr;
                    if (terrainVertexArrays.TryGetValue(key, out vArr))
                    {
                        for (int k = 0; k < vArr.Length; k++)
                        {
                            window.Draw(vArr[k], terrainRenderStates[k]);
                        }
                    }
                }
            }
            #endregion terrain drawing

            #region entity drawing
            renderedEntityCount = 0;
            renderedSpriteCount = 0;
            for (int i = begPos[0]; i <= endPos[0] + 1; i++)
            {
                for (int j = begPos[1]; j <= endPos[1] + 1; j++)
                {
                    Chunk chunk = surface.GetChunk(i, j);
                    if (chunk == null)
                    {
                        continue;
                    }
                    List <Entity> entityList = chunk.entityList;
                    for (int k = 0; k < entityList.Count; k++)
                    {
                        if (entityList[k].drawArray != null && BoundingBox.CheckCollision(windowBox, entityList[k].drawingBox, new Vector2(origin), entityList[k].position))
                        {
                            drawList.Add(entityList[k]);
                        }
                    }
                }
            }
            drawList.Sort(delegate(Entity a, Entity b)
            {
                int ydiff = a.position.y.CompareTo(b.position.y);
                if (ydiff != 0)
                {
                    return(ydiff);
                }
                else
                {
                    return(a.position.x.CompareTo(b.position.x));
                }
            });
            for (int i = 0; i < entityBatch.Length; i++)
            {
                entityBatch[i].Initialize(camera.GetGameView(), Color.Transparent);
            }
            foreach (Entity e in drawList)
            {
                renderedEntityCount++;
                for (int i = 0; i < e.drawArray.Length; i++)
                {
                    if (e.drawArray[i].drawLayer != Drawable.DrawLayer.None)
                    {
                        e.drawArray[i].Draw(entityBatch[(int)e.drawArray[i].drawLayer - 1], e.position.internalVector);
                        renderedSpriteCount++;
                    }
                }
            }
            window.SetView(camera.GetGUIView());
            for (int i = 0; i < entityBatch.Length; i++)
            {
                Sprite sprite = entityBatch[i].Finalize();
                window.Draw(sprite);
            }
            window.SetView(camera.GetGameView());
            drawList.Clear();
            #endregion entity drawing

            #region lighting drawing
            lightingBatch.Initialize(camera.GetGameView(), new Color(0, 0, 0, surface.GetDarkness()));
            for (int i = begPos[0]; i <= endPos[0]; i++)
            {
                for (int j = begPos[1]; j <= endPos[1]; j++)
                {
                    Chunk chunk = surface.GetChunk(i, j);
                    List <LightSource> lightSources = chunk.lightSources;
                    for (int k = 0; k < lightSources.Count; k++)
                    {
                        if (lightSources[k].on == true)
                        {
                            lightSources[k].Draw(lightingBatch);
                        }
                    }
                }
            }
            Sprite lightingSprite = lightingBatch.Finalize();
            window.SetView(camera.GetGUIView());
            window.Draw(lightingSprite);
            window.SetView(camera.GetGameView());
            #endregion

            #region bounding box drawing
            if (drawBoundingBoxes == true)
            {
                for (int i = begPos[0]; i <= endPos[0]; i++)
                {
                    for (int j = begPos[1]; j <= endPos[1]; j++)
                    {
                        Chunk chunk = surface.GetChunk(i, j);
                        #region Tile bounding box drawing

                        int         chunkIndex = i * surface.worldSize + j;
                        float[]     pointsTile = surface.tileBox.GetPoints();
                        VertexArray vA;
                        if (!tileBoundingBoxVertexArray.TryGetValue(chunkIndex, out vA))
                        {
                            vA = tileCollection.GenerateTerrainBoundingBoxArray(surface, chunk, chunkIndex, pointsTile);
                            tileBoundingBoxVertexArray.Add(chunkIndex, vA);
                        }
                        window.Draw(vA);
                        #endregion Tile bounding box drawing

                        #region Entity bounding box drawing
                        List <Entity> entityList = chunk.entityList;
                        for (int k = 0; k < entityList.Count; k++)
                        {
                            float[] pointsEntity        = entityList[k].collisionBox.GetPoints();
                            float[] drawingPointsEntity = entityList[k].drawingBox.GetPoints();
                            Vector2 position            = entityList[k].position;
                            for (int l = 0; l < pointsEntity.Length; l += 2)
                            {
                                entityBoundingBoxArray.Append(new Vertex(new Vector2f(pointsEntity[l] + position.x, pointsEntity[l + 1] + position.y), Color.Red));
                                entityBoundingBoxArray.Append(new Vertex(new Vector2f(pointsEntity[(l + 2) % 8] + position.x, pointsEntity[(l + 3) % 8] + position.y), Color.Red));
                            }
                            for (int l = 0; l < drawingPointsEntity.Length; l += 2)
                            {
                                drawingBoundingBoxArray.Append(new Vertex(new Vector2f(drawingPointsEntity[l] + position.x, drawingPointsEntity[l + 1] + position.y), Color.Blue));
                                drawingBoundingBoxArray.Append(new Vertex(new Vector2f(drawingPointsEntity[(l + 2) % 8] + position.x, drawingPointsEntity[(l + 3) % 8] + position.y), Color.Blue));
                            }
                        }
                        #endregion Entity bounding box drawing
                    }
                }
                window.Draw(entityBoundingBoxArray);
                window.Draw(drawingBoundingBoxArray);
                entityBoundingBoxArray.Clear();
                drawingBoundingBoxArray.Clear();
                VertexArray windowBoxArray = new VertexArray(PrimitiveType.Lines);
                float[]     pointsWindow   = windowBox.GetPoints();
                for (int l = 0; l < pointsWindow.Length; l += 2)
                {
                    windowBoxArray.Append(new Vertex(new Vector2f(pointsWindow[l] + origin.X, pointsWindow[l + 1] + origin.Y), Color.Magenta));
                    windowBoxArray.Append(new Vertex(new Vector2f(pointsWindow[(l + 2) % 8] + origin.X, pointsWindow[(l + 3) % 8] + origin.Y), Color.Magenta));
                }
                window.Draw(windowBoxArray);
                windowBoxArray.Clear();
            }
            #endregion bounding box drawing
        }
Пример #5
0
        /// <summary>
        /// Culls vertex arrays that are too far away based on camera variables.
        /// </summary>
        public void CullVertexCache(Camera camera, SurfaceContainer surface)
        {
            int[]      cameraChunkCoords = surface.WorldToChunkCoords(camera.GetGameView().Center.X, camera.GetGameView().Center.Y);
            List <int> keysToRemove      = new List <int>();

            foreach (int key in terrainVertexArrays.Keys)
            {
                int[] chunkIndices = surface.ChunkIndexToChunkCoords(key);
                if (Math.Abs(chunkIndices[0] - cameraChunkCoords[0]) > Props.vertexArrayCullingDistance ||
                    Math.Abs(chunkIndices[1] - cameraChunkCoords[1]) > Props.vertexArrayCullingDistance)
                {
                    keysToRemove.Add(key);
                }
            }
            foreach (int key in keysToRemove)
            {
                VertexArray[] vA;
                if (terrainVertexArrays.TryGetValue(key, out vA))
                {
                    foreach (VertexArray v in vA)
                    {
                        v.Dispose();
                    }
                }
                terrainVertexArrays.Remove(key);
            }
            keysToRemove.Clear();

            foreach (int key in tileBoundingBoxVertexArray.Keys)
            {
                int[] chunkIndices = surface.ChunkIndexToChunkCoords(key);
                if (Math.Abs(chunkIndices[0] - cameraChunkCoords[0]) > Props.vertexArrayCullingDistance ||
                    Math.Abs(chunkIndices[1] - cameraChunkCoords[1]) > Props.vertexArrayCullingDistance)
                {
                    keysToRemove.Add(key);
                }
            }
            foreach (int key in keysToRemove)
            {
                VertexArray vA;
                if (tileBoundingBoxVertexArray.TryGetValue(key, out vA))
                {
                    vA.Dispose();
                }
                tileBoundingBoxVertexArray.Remove(key);
            }
            keysToRemove.Clear();

            if (cullMinimap)
            {
                foreach (int key in minimapVertexArrays.Keys)
                {
                    int[] chunkIndices = surface.ChunkIndexToChunkCoords(key);
                    if (Math.Abs(chunkIndices[0] - cameraChunkCoords[0]) > Props.vertexArrayCullingDistance ||
                        Math.Abs(chunkIndices[1] - cameraChunkCoords[1]) > Props.vertexArrayCullingDistance)
                    {
                        keysToRemove.Add(key);
                    }
                }
                foreach (int key in keysToRemove)
                {
                    VertexArray vA;
                    if (minimapVertexArrays.TryGetValue(key, out vA))
                    {
                        vA.Dispose();
                    }
                    minimapVertexArrays.Remove(key);
                }
            }
        }