//-------------------------------------------------------------- // create updated display buffers void BrickBlob::createUpdate( const mgPoint3& eyePt) { if (m_bricksChanged) countTriangles(m_buffers2); else { m_buffers2.m_cubeCount = m_buffers.m_cubeCount; m_buffers2.m_shapeCount = m_buffers.m_shapeCount; m_buffers2.m_transCount = m_buffers.m_transCount; } if (m_bricksChanged || sortRequired(eyePt)) { m_buffers2.m_sortEyePt = eyePt; createTransBrickBuffers(m_buffers2); createTransTriangles(m_buffers2); } if (m_bricksChanged) { createSolidBrickBuffers(m_buffers2); createSolidTriangles(m_buffers2); } m_bricksChanged = false; }
//-------------------------------------------------------------- // create buffers, ready to send to display void BrickBlob::createBuffers( const mgPoint3& eyePt) { countTriangles(m_buffers); m_buffers.m_sortEyePt = eyePt; createTransBrickBuffers(m_buffers); createTransTriangles(m_buffers); createSolidBrickBuffers(m_buffers); createSolidTriangles(m_buffers); m_bricksChanged = false; // create selection buffer }
// ---|> NodeVisitor NodeVisitor::status enter(Node * node) override { NodeInfo * info=r.getNodeInfo(node); info->setActualSubtreeComplexity(0); // the current subtree is completely inside the frustum, so we need not to test inside this subtree if(insideFrustum>0){ info->setActualFrustumStatus(Geometry::Frustum::INSIDE); insideFrustum++; }else{ int i=camera->testBoxFrustumIntersection( node->getWorldBB()); info->setActualFrustumStatus(i); if(i==Geometry::Frustum::OUTSIDE){ return NodeVisitor::BREAK_TRAVERSAL; }else if(i==Geometry::Frustum::INSIDE){ insideFrustum++; } } if(node->isClosed() && node!=rootNode){ unsigned int c = insideFrustum > 0 ? countTriangles(node) : countTrianglesInFrustum(node, camera->getFrustum()); info->increaseActualSubtreeComplexity( c ); return BREAK_TRAVERSAL; } return CONTINUE_TRAVERSAL; }
//createTreeNode- creates the node for the tree //positionX- the x position of the node //positionZ- the z position of the node //width- the width of the node //device- the device to use void TerrainQuadTree::createTreeNode(Node* node, float positionX, float positionZ, float width, ID3D11Device* device) { int numTriangles, i, count, vertexCount, index, vertexIndex; float offsetX, offsetZ; Vertex* vertices; unsigned long* indices; bool result; D3D11_BUFFER_DESC vertexBufferDesc, indexBufferDesc; D3D11_SUBRESOURCE_DATA vertexData, indexData; // Store the node position and size. node->positionX = positionX; node->positionZ = positionZ; node->width = width; // Initialize the triangle count to zero for the node. node->triangleCount = 0; // Initialize the vertex and index buffer to null. node->vertexBuffer = 0; node->indexBuffer = 0; //init the vertex array to null node->vertexArray = NULL; // Initialize the children nodes of this node to null. node->nodes[0] = 0; node->nodes[1] = 0; node->nodes[2] = 0; node->nodes[3] = 0; // Count the number of triangles that are inside this node. numTriangles = countTriangles(positionX, positionZ, width); // If there are no triangles in this node then return as it is empty and requires no processing. if (numTriangles == 0) { return; } // If there are too many triangles in this node then split it into four equal sized smaller tree nodes. if (numTriangles > m_maxTriangles) { for (i = 0; i<4; i++) { // Calculate the position offsets for the new child node. offsetX = (((i % 2) < 1) ? -1.0f : 1.0f) * (width / 4.0f); offsetZ = (((i % 4) < 2) ? -1.0f : 1.0f) * (width / 4.0f); // See if there are any triangles in the new node. count = countTriangles((positionX + offsetX), (positionZ + offsetZ), (width / 2.0f)); if (count > 0) { // If there are triangles inside where this new node would be then create the child node. node->nodes[i] = new Node; // Extend the tree starting from this new child node now. createTreeNode(node->nodes[i], (positionX + offsetX), (positionZ + offsetZ), (width / 2.0f), device); } } return; } // If this node is not empty and the triangle count for it is less than the max then // this node is at the bottom of the tree so create the list of triangles to store in it. node->triangleCount = numTriangles; // Calculate the number of vertices. vertexCount = numTriangles * 3; // Create the vertex array. vertices = new Vertex[vertexCount]; // Create the index array. indices = new unsigned long[vertexCount]; //Create the vertex array node->vertexArray = new Vector[vertexCount]; // Initialize the index for this new vertex and index array. index = 0; // Go through all the triangles in the vertex list. for (i = 0; i<m_triangleCount; i++) { // If the triangle is inside this node then add it to the vertex array. result = isTriangleContained(i, positionX, positionZ, width); if (result == true) { // Calculate the index into the terrain vertex list. vertexIndex = i * 3; // Get the three vertices of this triangle from the vertex list. vertices[index].position = m_vertexList[vertexIndex].position; vertices[index].texture = m_vertexList[vertexIndex].texture; vertices[index].normal = m_vertexList[vertexIndex].normal; indices[index] = index; // Also store the vertex position information in the node vertex array. node->vertexArray[index].x = m_vertexList[vertexIndex].position.x; node->vertexArray[index].y = m_vertexList[vertexIndex].position.y; node->vertexArray[index].z = m_vertexList[vertexIndex].position.z; // Increment the indexes. index++; vertexIndex++; // Do the same for the next point. vertices[index].position = m_vertexList[vertexIndex].position; vertices[index].texture = m_vertexList[vertexIndex].texture; vertices[index].normal = m_vertexList[vertexIndex].normal; indices[index] = index; node->vertexArray[index].x = m_vertexList[vertexIndex].position.x; node->vertexArray[index].y = m_vertexList[vertexIndex].position.y; node->vertexArray[index].z = m_vertexList[vertexIndex].position.z; index++; vertexIndex++; // Do the same for the next point also. vertices[index].position = m_vertexList[vertexIndex].position; vertices[index].texture = m_vertexList[vertexIndex].texture; vertices[index].normal = m_vertexList[vertexIndex].normal; indices[index] = index; node->vertexArray[index].x = m_vertexList[vertexIndex].position.x; node->vertexArray[index].y = m_vertexList[vertexIndex].position.y; node->vertexArray[index].z = m_vertexList[vertexIndex].position.z; index++; } } // Set up the description of the vertex buffer. vertexBufferDesc.Usage = D3D11_USAGE_DEFAULT; vertexBufferDesc.ByteWidth = sizeof(Vertex) * vertexCount; vertexBufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; vertexBufferDesc.CPUAccessFlags = 0; vertexBufferDesc.MiscFlags = 0; vertexBufferDesc.StructureByteStride = 0; // Give the subresource structure a pointer to the vertex data. vertexData.pSysMem = vertices; vertexData.SysMemPitch = 0; vertexData.SysMemSlicePitch = 0; // Now finally create the vertex buffer. device->CreateBuffer(&vertexBufferDesc, &vertexData, &node->vertexBuffer); // Set up the description of the index buffer. indexBufferDesc.Usage = D3D11_USAGE_DEFAULT; indexBufferDesc.ByteWidth = sizeof(unsigned long) * vertexCount; indexBufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; indexBufferDesc.CPUAccessFlags = 0; indexBufferDesc.MiscFlags = 0; indexBufferDesc.StructureByteStride = 0; // Give the subresource structure a pointer to the index data. indexData.pSysMem = indices; indexData.SysMemPitch = 0; indexData.SysMemSlicePitch = 0; // Create the index buffer. device->CreateBuffer(&indexBufferDesc, &indexData, &node->indexBuffer); // Release the vertex and index arrays now that the data is stored in the buffers in the node. delete[] vertices; vertices = 0; delete[] indices; indices = 0; }