예제 #1
0
 /// <summary>
 /// Constructs a Quadtree object
 /// </summary>
 public QuadTree(Game game)
     : base(game)
 {
     _valid = false;
     _root = null;
     _gameComponents = new Collection<QuadTreeGameComponent>();
 }
예제 #2
0
 internal QuadTreeModelInfo(Model model, Vector3 position, float scale, Vector3 rotation)
 {
     _model = model;
     _position = position;
     _rotation = rotation;
     _scale = scale;
     _node = null;
 }
예제 #3
0
        public QuadTreeNode(QuadTreeNode parent)
        {
            m_parent = parent;

            children = new QuadTreeNode[4];

            // TryCull instance variables
            m_corners = new Vector3[8];
            m_projCorners = new Vector4[8];

            // Models and Components collections
            _models = new Collection<QuadTreeModelInfo>();
            _gameComponents = new Collection<QuadTreeGameComponent>();
        }
예제 #4
0
        //-------------------------------------------
        // Build the quadTree using the height data
        //-------------------------------------------
        public bool Buildout(GraphicsDevice gd, float cellSize, int sectorsize, int minX, int minY, int width, int height, float[,] heightData, Vector3[,] normals)
        {
            m_width = width;
            m_height = height;

            if (minX + m_width >= heightData.GetLength(1))
                m_width = heightData.GetLength(1) - minX - 1; // handle end of row case ( sectorsize - 1)
            if (minY + m_height >= heightData.GetLength(0))
                m_height = heightData.GetLength(0) - minY - 1; // handle end of column case (sectorsize - 1)

            m_cellSize = cellSize;

            // set instance variables that define world coords of this sector
            m_startX = cellSize * (float)minX;
            m_startY = cellSize * (float)minY;
            m_endX = cellSize * (float)(minX + m_width);
            m_endY = cellSize * (float)(minY + m_height);

            // now we don't need to do any more if we will delegate to children
            if (m_width > sectorsize || m_height > sectorsize) {
                int halfWidth = m_width / 2;
                if ((m_width & 0x01) == 0x01) {
                    halfWidth++;
                }
                int halfHeight = m_height / 2;
                if ((halfHeight & 0x01) == 0x01) {
                    halfHeight++;
                }

                m_minHeight = 999.0f;
                m_maxHeight = -999.0f;

                if (children[NW] == null) {
                    children[NW] = new QuadTreeNode(this);
                }
                children[NW].Buildout(gd, cellSize, sectorsize, minX, minY, halfWidth, halfHeight, heightData, normals);
                m_minHeight = children[NW].m_minHeight < m_minHeight ? children[NW].m_minHeight : m_minHeight;
                m_maxHeight = children[NW].m_maxHeight > m_maxHeight ? children[NW].m_maxHeight : m_maxHeight;

                if (width > sectorsize) {
                    if (children[NE] == null)
                        children[NE] = new QuadTreeNode(this);
                    children[NE].Buildout(gd, cellSize, sectorsize, minX + halfWidth, minY, halfWidth, halfHeight, heightData, normals);
                    m_minHeight = children[NE].m_minHeight < m_minHeight ? children[NE].m_minHeight : m_minHeight;
                    m_maxHeight = children[NE].m_maxHeight > m_maxHeight ? children[NE].m_maxHeight : m_maxHeight;
                }
                if (height > sectorsize) {
                    if (children[SW] == null)
                        children[SW] = new QuadTreeNode(this);
                    children[SW].Buildout(gd, cellSize, sectorsize, minX, minY + halfHeight, halfWidth, halfHeight, heightData, normals);
                    m_minHeight = children[SW].m_minHeight < m_minHeight ? children[SW].m_minHeight : m_minHeight;
                    m_maxHeight = children[SW].m_maxHeight > m_maxHeight ? children[SW].m_maxHeight : m_maxHeight;
                }

                if (height > sectorsize && width > sectorsize) {
                    if (children[SE] == null)
                        children[SE] = new QuadTreeNode(this);
                    children[SE].Buildout(gd, cellSize, sectorsize, minX + halfWidth, minY + halfHeight, halfWidth, halfHeight, heightData, normals);
                    m_minHeight = children[SE].m_minHeight < m_minHeight ? children[SE].m_minHeight : m_minHeight;
                    m_maxHeight = children[SE].m_maxHeight > m_maxHeight ? children[SE].m_maxHeight : m_maxHeight;
                }

                // find the 4 corners of this node (flat)
                // these are used in TryCull
                ComputeCorners();

                //----------------------------------------
                // we're done here!
                // We will only keep track of children nodes,
                // no data needed for rendering in this node
                //----------------------------------------
                return true;
            }

            //--------------------------------------
            // we are a lowest level child and have
            // arrived at width and height <= sectorsize
            // save the height data for this sector
            // and create the data for rendering
            //--------------------------------------

            // we actually duplicate verts and heightdata on borders of sectors
            // that is, m_width and m_height are the number of cells
            // so the number of vertices is (m_width+1) * (m_height+1).
            // We save the heightdata in an instance variable so that we
            // can compute GetHeightAt(x,y) later.

            m_heightData = new float[m_height + 1, m_width + 1];
            if (m_heightData == null)
                throw new Exception("QuadtreeNode.BuildOut : Out of memory for local heightData");

            m_minHeight = 9999.0f;
            m_maxHeight = -9999.0f;

            for (int y = 0; y <= m_height; y++) {
                for (int x = 0; x <= m_width; x++) {
                    m_heightData[y, x] = heightData[minY + y, minX + x];

                    float data = m_heightData[y, x];

                    if (data > m_maxHeight)
                        m_maxHeight = data;
                    if (data < m_minHeight)
                        m_minHeight = data;
                }
            }

            // find the 4 corners of this node (flat)
            // these are used in TryCull
            ComputeCorners();

            float totalHeight = (float)heightData.GetLength(0);
            float totalWidth = (float)heightData.GetLength(1);

            float ustep = 1.0f / totalWidth;// / (float )m_width;
            float ustart = (float)minX * ustep;
            float vstep = 1.0f / totalHeight;// / (float )m_height;
            float vstart = (float)minY * vstep;

            return CreateMeshFromHeightData(gd, minX, minY, ustart, ustep, vstart, vstep, normals);
        }
예제 #5
0
 public QuadTreeGameComponent(Game game)
     : base(game)
 {
     quadTree = null;
     qNode = null;
 }
예제 #6
0
        /// <summary>
        /// Creates the QuadTree nodes and initializes them for rendering.
        /// This method must be called after content is loaded but before Draw().
        /// </summary>
        /// <param name="cellSize">Width/Height of a cell in the terrain</param>
        /// <param name="sectorsize">Number of cells in x and z that will be rendered or culled as a unit</param>
        /// <param name="heightData">The HeightData to use.</param>
        public bool Create(float cellSize, int sectorSize, float[,] heightData)
        {
            int width = heightData.GetLength(1);
            int height = heightData.GetLength(0);

            _totalWidth = cellSize * width;
            _totalHeight = cellSize * height;
            //m_sectorsize = sectorSize;

            if (height > heightData.GetLength(0))
                _valid = false;
            if (width > heightData.GetLength(1))
                _valid = false;

            Vector3[,] normals = CreateNormals(cellSize, heightData);

            _root = new QuadTreeNode(null);
            _valid = _root.Buildout(GraphicsDevice, cellSize, sectorSize, 0, 0, width, height, heightData, normals);
            if (!_valid)
                _root = null;

            normals = null; // don't need them anymore here

            // if we have QuadTreeGameComponents added to the quadTree already
            // then distribute them to the new nodes
            if (_valid && _root != null) {
                foreach (QuadTreeGameComponent component in _gameComponents) {
                    _root.AddComponent(component);
                }
            }

            return _valid;
        }