/* ============= Q3_LoadBSPFile ============= */ void Q3_LoadBSPFile(struct quakefile_s *qf) { dheader_t *header; // load the file header //LoadFile(filename, (void **)&header, offset, length); // LoadQuakeFile(qf, (void **)&header); // swap the header Q3_SwapBlock( (int *)header, sizeof(*header) ); if ( header->ident != BSP_IDENT ) { Error( "%s is not a 2015 file", qf->filename ); } if ( header->version != BSP_VERSION ) { Error( "%s is version %i, not %i", qf->filename, header->version, BSP_VERSION ); } q3_numShaders = Q3_CopyLump( header, LUMP_SHADERS, (void *) &dshaders, sizeof(dshader_t) ); q3_nummodels = Q3_CopyLump( header, LUMP_MODELS, (void *) &dmodels, sizeof(dmodel_t) ); q3_numplanes = Q3_CopyLump( header, LUMP_PLANES, (void *) &dplanes, sizeof(dplane_t) ); q3_numleafs = Q3_CopyLump( header, LUMP_LEAFS, (void *) &dleafs, sizeof(dleaf_t) ); q3_numnodes = Q3_CopyLump( header, LUMP_NODES, (void *) &dnodes, sizeof(dnode_t) ); q3_numleafsurfaces = Q3_CopyLump( header, LUMP_LEAFSURFACES, (void *) &dleafsurfaces, sizeof(dleafsurfaces[0]) ); q3_numleafbrushes = Q3_CopyLump( header, LUMP_LEAFBRUSHES, (void *) &dleafbrushes, sizeof(dleafbrushes[0]) ); q3_numbrushes = Q3_CopyLump( header, LUMP_BRUSHES, (void *) &dbrushes, sizeof(dbrush_t) ); q3_numbrushsides = Q3_CopyLump( header, LUMP_BRUSHSIDES, (void *) &dbrushsides, sizeof(dbrushside_t) ); q3_numDrawVerts = Q3_CopyLump( header, LUMP_DRAWVERTS, (void *) &drawVerts, sizeof(drawVert_t) ); q3_numDrawSurfaces = Q3_CopyLump( header, LUMP_SURFACES, (void *) &drawSurfaces, sizeof(dsurface_t) ); // q3_numFogs = Q3_CopyLump( header, LUMP_FOGS, (void *) &dfogs, sizeof(dfog_t) ); q3_numDrawIndexes = Q3_CopyLump( header, LUMP_DRAWINDEXES, (void *) &drawIndexes, sizeof(drawIndexes[0]) ); q3_numVisBytes = Q3_CopyLump( header, LUMP_VISIBILITY, (void *) &q3_visBytes, 1 ); q3_numLightBytes = Q3_CopyLump( header, LUMP_LIGHTMAPS, (void *) &q3_lightBytes, 1 ); q3_entdatasize = Q3_CopyLump( header, LUMP_ENTITIES, (void *) &dentdata, 1); // q3_numGridPoints = Q3_CopyLump( header, LUMP_LIGHTGRID, (void *) &q3_gridData, 8 ); CountTriangles(); FreeMemory( header ); // everything has been copied out // swap everything Q3_SwapBSPFile(); Q3_FindVisibleBrushSides(); //Q3_PrintBSPFileSizes(); }
void QuadTreeClass::CreateTreeNode(NodeType* node, float positionX, float positionZ, float width, ID3D10Device* device) { int numTriangles, i, count, vertexCount, index, vertexIndex; float offsetX, offsetZ; VertexType* vertices; unsigned long* indices; bool result; D3D10_BUFFER_DESC vertexBufferDesc, indexBufferDesc; D3D10_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; // Initialize the vertex array to null. node->vertexArray = 0; // 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); // Case 1: If there are no triangles in this node then return as it is empty and requires no processing. if (numTriangles == 0) { return; } // Case 2: If there are too many triangles in this node then split it into four equal sized smaller tree nodes. if (numTriangles > MAX_TRIANGLES) { 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 NodeType; // Extend the tree starting from this new child node now. CreateTreeNode(node->nodes[i], (positionX + offsetX), (positionZ + offsetZ), (width / 2.0f), device); } } return; } // Case 3: 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 VertexType[vertexCount]; // Create the index array. indices = new unsigned long[vertexCount]; // Create the vertex array. node->vertexArray = new VectorType[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 = D3D10_USAGE_DEFAULT; vertexBufferDesc.ByteWidth = sizeof(VertexType) * vertexCount; vertexBufferDesc.BindFlags = D3D10_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 = D3D10_USAGE_DEFAULT; indexBufferDesc.ByteWidth = sizeof(unsigned long) * vertexCount; indexBufferDesc.BindFlags = D3D10_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; return; }
void QuadTree::CreateTreeNode(QuadTreeNode* node,vec2 pos,int width,int numObjs){ float offsetX,offsetZ; node->position.x = pos.x; node->position.y = pos.y; node->size = width; node->culled = false; node->triangleCount = 0; node->indices = NULL; node->objPositions = NULL; node->numObjs = MAX_TREES; for(int child = 0; child < 4; child++) node->nodes[child] = NULL; std::vector<unsigned int> triList; int numTriangles = CountTriangles(pos,width,triList); if(numTriangles == 0) return; if(numTriangles > MAX_TRIANGLES){ for(int child = 0; child < 4; child++){ offsetX = (((child % 2) < 1) ? -1.0f : 1.0f) * (width/4.0f); offsetZ = (((child % 4) < 2) ? -1.0f : 1.0f) * (width/4.0f); node->nodes[child] = new QuadTreeNode(); CreateTreeNode(node->nodes[child],vec2(pos.x + offsetX,pos.y + offsetZ),width/2,numObjs/2); } return; } node->triangleCount = numTriangles; int vertexCount = numTriangles * 3; node->indices = new unsigned int[vertexCount]; int index = 0; int numTris = triList.size(); double startTime2 = glfwGetTime(); for(int triangle = 0; triangle < numTris; triangle++){ int vertIndex = triList[triangle] * 3; node->indices[index++] = vertIndex++; node->indices[index++] = vertIndex++; node->indices[index++] = vertIndex++; } node->objPositions = new vec3[numObjs]; node->numObjs = numObjs; //generate tree coords for(int obj = 0; obj < numObjs; obj++){ int index = (rand() << 3) % vertexCount; float slope = 1.0f - m_normals[node->indices[index]].y; if(slope > 0.7f) continue; node->objPositions[obj] = m_vertices[node->indices[index]]; } }
void CSGPQuadTree::CreateTreeNode(CSGPTerrain* pTerrain, NodeType* node, float positionX, float positionZ, float width) { // 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 children nodes of this node to null. node->nodes[0] = NULL; node->nodes[1] = NULL; node->nodes[2] = NULL; node->nodes[3] = NULL; // Initialize the terrain chunks of this node to null. node->terrainchunks.ensureStorageAllocated(4); // Count the number of triangles that are inside this node. uint32 numTriangles = CountTriangles(pTerrain, positionX, positionZ, width); // Case 1: If there are no triangles in this node then return as it is empty and requires no processing. if(numTriangles == 0) { return; } // Case 2: If there are too many triangles in this node then split it into four equal sized smaller tree nodes. // If QuadNode smaller than one chunk, Do not split! float offsetX, offsetZ; if( (numTriangles > MAX_QUAD_TRIANGLES) && (width > SGPTT_TILE_METER * SGPTT_TILENUM) ) { for(int 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. uint32 count = CountTriangles(pTerrain, (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 NodeType; // Extend the tree starting from this new child node now. CreateTreeNode(pTerrain, node->nodes[i], (positionX + offsetX), (positionZ + offsetZ), (width / 2.0f)); node->NodeBoundingBox += node->nodes[i]->NodeBoundingBox; } } return; } // Case 3: 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 the list of terrain chunks to store in it. node->triangleCount = numTriangles; // Go through all the terrain chunks in this zone uint32 center_x = uint32(positionX / SGPTT_TILE_METER / SGPTT_TILENUM); uint32 center_z = uint32(positionZ / SGPTT_TILE_METER / SGPTT_TILENUM); int32 center_width = int32(width / SGPTT_TILE_METER / SGPTT_TILENUM); uint32 chunk_index = 0; if( center_width == 1 ) { chunk_index = (pTerrain->GetTerrainChunkSize() - 1 - center_z) * pTerrain->GetTerrainChunkSize() + center_x; node->terrainchunks.add( pTerrain->m_TerrainChunks[chunk_index] ); node->NodeBoundingBox += pTerrain->m_TerrainChunks[chunk_index]->m_BoundingBox; } else { for( int32 j = -center_width/2; j<center_width/2; j++ ) { for( int32 i = -center_width/2; i<center_width/2; i++ ) { chunk_index = (pTerrain->GetTerrainChunkSize() - center_z + j) * pTerrain->GetTerrainChunkSize() + (center_x + i); node->terrainchunks.add( pTerrain->m_TerrainChunks[chunk_index] ); node->NodeBoundingBox += pTerrain->m_TerrainChunks[chunk_index]->m_BoundingBox; } } } return; }