Пример #1
0
        /// <summary>
        /// Updates the ground height below camera.
        /// </summary>
        private void UpdateGroundHeight()
        {
            if (TerrainNode.LocalCameraPosition.z > TerrainNode.TerrainQuadRoot.ZMax)
            {
                return;
            }

            var localCameraPosition = TerrainNode.LocalCameraPosition;

            // If camera has moved update ground height
            if ((localCameraPosition - OldLocalCamera).Magnitude() > 1.0 && CameraQuad != null && CameraQuad.Tile != null && EnableGroundHeightUpdate)
            {
                var slot = CameraQuad.Tile.Slot[0] as GPUTileStorage.GPUSlot;

                if (slot != null)
                {
                    var border   = Producer.GetBorder();
                    var tileSize = Producer.GetTileSizeMinBorder(0);

                    var dx = CameraQuadCoordinates.x * tileSize;
                    var dy = CameraQuadCoordinates.y * tileSize;

                    // x,y are the non-normalized position in the elevations texture where the ground height below the camera is.
                    var x = dx + (float)border;
                    var y = dy + (float)border;

                    // Read the single value from the render texture
                    CBUtility.ReadSingleFromRenderTexture(slot.Texture, x, y, 0, GroundBuffer, GodManager.Instance.ReadData, true);

                    // Get single height value from buffer
                    var height = new Vector4[1];

                    GroundBuffer.GetData(height);

                    TerrainNode.ParentBody.HeightZ = Math.Max(0.0, height[0].x);

                    OldLocalCamera.x = localCameraPosition.x;
                    OldLocalCamera.y = localCameraPosition.y;
                    OldLocalCamera.z = localCameraPosition.z;
                }
            }

            CameraQuad = null;
        }
Пример #2
0
        protected override void GetTiles(QuadTree parent, ref QuadTree tree, TerrainQuad quad)
        {
            if (tree == null)
            {
                tree            = new QuadTreeZ(parent, quad);
                tree.IsNeedTile = NeedTile(quad);
            }

            var treeZ = tree as QuadTreeZ;

            if (treeZ == null)
            {
                Debug.LogError("TileSamplerZ.GetTiles: Can't get provided tree as QuadTreeZ!"); base.GetTiles(parent, ref tree, quad); return;
            }

            // If tile needs elevation data read back add to container
            if (treeZ.Tile != null && treeZ.Tile.Task.IsDone && !treeZ.ReadBack && MaxReadBacksPerFrame > 0)
            {
                if (!NeedsReadBackDictionary.ContainsKey(treeZ.Tile.ID))
                {
                    treeZ.ReadBack = true;
                    NeedsReadBackDictionary.Add(treeZ.Tile.ID, treeZ);
                }
            }

            base.GetTiles(parent, ref tree, quad);

            // Check if this TerrainQuad is below the camera. If so store a reference to it.
            if (CameraQuad == null && treeZ.Tile != null && treeZ.Tile.Task.IsDone)
            {
                var cameraPosition = quad.Owner.LocalCameraPosition;

                var l  = quad.Length;
                var ox = quad.Ox;
                var oy = quad.Oy;

                if (cameraPosition.x >= ox && cameraPosition.x < ox + l && cameraPosition.y >= oy && cameraPosition.y < oy + l)
                {
                    CameraQuadCoordinates = new Vector2((float)((cameraPosition.x - ox) / l), (float)((cameraPosition.y - oy) / l));
                    CameraQuad            = treeZ;
                }
            }
        }
Пример #3
0
        protected override void GetTiles(QuadTree parent, ref QuadTree tree, TerrainQuad quad)
        {
            if (tree == null)
            {
                tree          = new QuadTreeZ(parent, quad);
                tree.needTile = NeedTile(quad);
            }

            QuadTreeZ t = tree as QuadTreeZ;

            //If tile needs elevation data read back add to container
            if (t.tile != null && t.tile.GetTask().IsDone() && !t.readBack && m_maxReadBacksPerFrame > 0)
            {
                if (!m_needReadBack.ContainsKey(t.tile.GetId()))
                {
                    t.readBack = true;
                    m_needReadBack.Add(t.tile.GetId(), t);
                }
            }

            base.GetTiles(parent, ref tree, quad);

            //Check if this quad is below the camera. If so store a reference to it.
            if (m_cameraQuad == null && t.tile != null && t.tile.GetTask().IsDone())
            {
                Vector3d2 c = quad.GetOwner().GetLocalCameraPos();

                double l  = quad.GetLength();
                double ox = quad.GetOX();
                double oy = quad.GetOY();

                if (c.x >= ox && c.x < ox + l && c.y >= oy && c.y < oy + l)
                {
                    m_cameraQuadCoords = new Vector2((float)((c.x - ox) / l), (float)((c.y - oy) / l));
                    m_cameraQuad       = t;
                }
            }
        }
Пример #4
0
        /*
         * Updates the ground height below camera.
         */
        void UpdateGroundHeight()
        {
            Vector3d2 localCamPos = GetTerrainNode().GetLocalCameraPos();

            //If camera has moved update ground height
            if ((localCamPos - m_oldLocalCamera).Magnitude() > 1.0 && m_cameraQuad != null && m_cameraQuad.tile != null)
            {
                GPUTileStorage.GPUSlot slot = m_cameraQuad.tile.GetSlot()[0] as GPUTileStorage.GPUSlot;

                if (slot != null)
                {
                    int border   = GetProducer().GetBorder();
                    int tileSize = GetProducer().GetTileSizeMinBorder(0);

                    float dx = m_cameraQuadCoords.x * tileSize;
                    float dy = m_cameraQuadCoords.y * tileSize;

                    //x,y are the non-normalized position in the elevations texture where the
                    //ground height below the camera is.
                    float x = dx + (float)border;
                    float y = dy + (float)border;
                    //Read the single value from the render texture
                    CBUtility.ReadSingleFromRenderTexture(slot.GetTexture(), x, y, 0, m_groundBuffer, m_manager.GetReadData(), true);
                    //Get single height value from buffer
                    float[] height = new float[1];
                    m_groundBuffer.GetData(height);

                    //Update the ground height. Stored as a static value in the TerrainNode script
                    GetView().SetGroundHeight(Math.Max(0.0, height[0]));

                    m_oldLocalCamera.x = localCamPos.x;
                    m_oldLocalCamera.y = localCamPos.y;
                    m_oldLocalCamera.z = localCamPos.z;
                }
            }

            m_cameraQuad = null;
        }
Пример #5
0
        /// <summary>
        /// Updates the terrainQuads min and max values. Used to create a better fitting bounding box.
        /// Is not essental and can be disabled if retriving the heights data from the GPU is causing  performance issues.
        /// </summary>
        private void UpdateMinMax()
        {
            // If no quads need read back or if disabled return
            if (NeedsReadBackDictionary.Count == 0 || !EnableReadBack)
            {
                return;
            }

            // Make a copy of all the keys of the tiles that need to be read back
            var ids = new Tile.Id[NeedsReadBackDictionary.Count];

            NeedsReadBackDictionary.Keys.CopyTo(ids, 0);

            // Sort the keys by there level, lowest -> highest
            Array.Sort(ids, new Tile.ComparerID());

            var count = 0;

            // Foreach key read back the tiles data until the maxReadBacksPerFrame limit is reached
            foreach (var id in ids)
            {
                QuadTreeZ treeZ = NeedsReadBackDictionary[id];

                // If elevations container already contains key then data has been read back before so just reapply the [min, max] values to TerranQuad
                if (ElevationsDicionary.ContainsKey(id))
                {
                    ElevationInfo info = ElevationsDicionary.Get(id);

                    treeZ.TerrainQuad.ZMin = info.Min;
                    treeZ.TerrainQuad.ZMax = info.Max;

                    NeedsReadBackDictionary.Remove(id);
                }
                else
                {
                    // If for some reason the tile is null remove from container and continue
                    if (treeZ.Tile == null)
                    {
                        NeedsReadBackDictionary.Remove(id);

                        continue;
                    }

                    var slot = treeZ.Tile.Slot[0] as GPUTileStorage.GPUSlot;

                    // If for some reason this is not a GPUSlot remove and continue
                    if (slot == null)
                    {
                        NeedsReadBackDictionary.Remove(id);

                        continue;
                    }

                    var texture = slot.Texture;
                    var size    = texture.width * texture.height;

                    var elevationInfo = new ElevationInfo();
                    elevationInfo.Elevations = new float[size];

                    // Read back heights data from texture
                    CBUtility.ReadFromRenderTexture(texture, 1, ElevationsBuffer, GodManager.Instance.ReadData);

                    // Copy into elevations info
                    ElevationsBuffer.GetData(elevationInfo.Elevations);

                    // Find the min/max values
                    for (int i = 0; i < size; i++)
                    {
                        if (elevationInfo.Elevations[i] < elevationInfo.Min)
                        {
                            elevationInfo.Min = elevationInfo.Elevations[i];
                        }
                        if (elevationInfo.Elevations[i] > elevationInfo.Max)
                        {
                            elevationInfo.Max = elevationInfo.Elevations[i];
                        }
                    }

                    // Update TerrainQuad
                    treeZ.TerrainQuad.ZMin = elevationInfo.Min;
                    treeZ.TerrainQuad.ZMax = elevationInfo.Max;

                    // Store elevations to prevent having to read back again soon
                    // Add to end of container
                    ElevationsDicionary.AddLast(id, elevationInfo);
                    NeedsReadBackDictionary.Remove(id);

                    count++;

                    // If the number of rad back to do per frame has hit the limit stop loop.
                    if (count >= MaxReadBacksPerFrame)
                    {
                        break;
                    }
                }
            }

            // If the number of elevation info to store has exceded limit remove from start of container
            while (ElevationsDicionary.Count() > MaxStoredElevations)
            {
                ElevationsDicionary.RemoveFirst();
            }
        }
Пример #6
0
		protected override void GetTiles(QuadTree parent, ref QuadTree tree, TerrainQuad quad)
		{
			if (tree == null) 
			{
				tree = new QuadTreeZ(parent, quad);
				tree.needTile = NeedTile(quad);
			}
			
			QuadTreeZ t = tree as QuadTreeZ;
			
			//If tile needs elevation data read back add to container
			if(t.tile != null && t.tile.GetTask().IsDone() && !t.readBack && m_maxReadBacksPerFrame > 0)
			{
				if(!m_needReadBack.ContainsKey(t.tile.GetId()))
				{
					t.readBack = true;
					m_needReadBack.Add(t.tile.GetId(), t);
				}
			}
			
			base.GetTiles(parent, ref tree, quad);
			
			//Check if this quad is below the camera. If so store a reference to it.
			if (m_cameraQuad == null && t.tile != null && t.tile.GetTask().IsDone()) 
			{
				Vector3d2 c = quad.GetOwner().GetLocalCameraPos();
				
				double l = quad.GetLength();
				double ox = quad.GetOX();
				double oy = quad.GetOY();
				
				if (c.x >= ox && c.x < ox + l && c.y >= oy && c.y < oy + l) 
				{
					m_cameraQuadCoords = new Vector2((float)((c.x - ox) / l), (float)((c.y - oy) / l));
					m_cameraQuad = t;
				}
			}
		}
Пример #7
0
		/*
		 * Updates the ground height below camera.
		 */
		void UpdateGroundHeight()
		{
			Vector3d2 localCamPos = GetTerrainNode().GetLocalCameraPos();
			
			//If camera has moved update ground height
			if ((localCamPos - m_oldLocalCamera).Magnitude() > 1.0 && m_cameraQuad != null && m_cameraQuad.tile != null) 
			{
				GPUTileStorage.GPUSlot slot = m_cameraQuad.tile.GetSlot()[0] as GPUTileStorage.GPUSlot;
				
				if(slot != null)
				{
					int border = GetProducer().GetBorder();
					int tileSize = GetProducer().GetTileSizeMinBorder(0);
					
					float dx = m_cameraQuadCoords.x * tileSize;
					float dy = m_cameraQuadCoords.y * tileSize;
					
					//x,y are the non-normalized position in the elevations texture where the 
					//ground height below the camera is.
					float x = dx + (float)border;
					float y = dy + (float)border;
					//Read the single value from the render texture
					CBUtility.ReadSingleFromRenderTexture(slot.GetTexture(), x, y, 0, m_groundBuffer, m_manager.GetReadData(), true);
					//Get single height value from buffer
					float[] height = new float[1];
					m_groundBuffer.GetData(height);
					
					//Update the ground height. Stored as a static value in the TerrainNode script
					GetView().SetGroundHeight(Math.Max(0.0, height[0]));
					
					m_oldLocalCamera.x = localCamPos.x;
					m_oldLocalCamera.y = localCamPos.y;
					m_oldLocalCamera.z = localCamPos.z;
					
				}
			}
			
			m_cameraQuad = null;
			
		}
Пример #8
0
        /*
         * Updates the terrainQuads min and max values. Used to create a better fitting bounding box.
         * Is not essental and can be disabled if retriving the heights data from the GPU is causing
         * performance issues.
         */
        void UpdateMinMax()
        {
            //if no quads need read back or if disabled return
            if (m_needReadBack.Count == 0 || !m_enableMinMaxReadBack)
            {
                return;
            }

            //Make a copy of all the keys of the tiles that need to be read back
            Tile.Id[] ids = new Tile.Id[m_needReadBack.Count];
            m_needReadBack.Keys.CopyTo(ids, 0);
            //Sort the keys by there level, lowest -> highest
            System.Array.Sort(ids, new Tile.ComparerID());

            int count = 0;

            //foreach key read back the tiles data until the maxReadBacksPerFrame limit is reached
            foreach (Tile.Id id in ids)
            {
                QuadTreeZ t = m_needReadBack[id];

                //If elevations container already contains key then data has been
                //read back before so just reapply the min/max values to TerranQuad
                if (m_elevations.ContainsKey(id))
                {
                    ElevationInfo info = m_elevations.Get(id);

                    t.quad.SetZMin(info.min);
                    t.quad.SetZMax(info.max);

                    m_needReadBack.Remove(id);
                }
                else
                {
                    //if for some reason the tile is null remove from container and continue
                    if (t.tile == null)
                    {
                        m_needReadBack.Remove(id);
                        continue;
                    }

                    GPUTileStorage.GPUSlot slot = t.tile.GetSlot()[0] as GPUTileStorage.GPUSlot;

                    //If for some reason this is not a GPUSlot remove and continue
                    if (slot == null)
                    {
                        m_needReadBack.Remove(id);
                        continue;
                    }

                    RenderTexture tex = slot.GetTexture();

                    int size = tex.width * tex.height;

                    ElevationInfo info = new ElevationInfo();
                    info.elevations = new float[size];
                    //Read back heights data from texture
                    CBUtility.ReadFromRenderTexture(tex, 1, m_elevationsBuffer, m_manager.GetReadData());
                    //Copy into elevations info
                    m_elevationsBuffer.GetData(info.elevations);
                    //Find the min/max values
                    for (int i = 0; i < size; i++)
                    {
                        if (info.elevations[i] < info.min)
                        {
                            info.min = info.elevations[i];
                        }
                        if (info.elevations[i] > info.max)
                        {
                            info.max = info.elevations[i];
                        }
                    }
                    //Update quad
                    t.quad.SetZMin(info.min);
                    t.quad.SetZMax(info.max);
                    //Store elevations to prevent having to read back again soon
                    //Add to end of container
                    m_elevations.AddLast(id, info);

                    m_needReadBack.Remove(id);

                    count++;
                    //If the number of rad back to do per frame has hit the limit stop loop.
                    if (count >= m_maxReadBacksPerFrame)
                    {
                        break;
                    }
                }
            }

            //If the number of elevation info to store has exceded limit remove from start of container
            while (m_elevations.Count() > m_maxStoredElevations)
            {
                m_elevations.RemoveFirst();
            }
        }