bool Region::containsPoint(const Vector3DInt32& pos, uint8_t boundary) const { return (pos.getX() <= m_v3dUpperCorner.getX() - boundary) && (pos.getY() <= m_v3dUpperCorner.getY() - boundary) && (pos.getZ() <= m_v3dUpperCorner.getZ() - boundary) && (pos.getX() >= m_v3dLowerCorner.getX() + boundary) && (pos.getY() >= m_v3dLowerCorner.getY() + boundary) && (pos.getZ() >= m_v3dLowerCorner.getZ() + boundary); }
void createCubeInVolume(LargeVolume<MaterialDensityPair44>& volData, Vector3DInt32 lowerCorner, Vector3DInt32 upperCorner, uint8_t uValue) { uint8_t maxDen = MaterialDensityPair44::getMaxDensity(); uint8_t minDen = MaterialDensityPair44::getMinDensity(); //This three-level for loop iterates over every voxel between the specified corners for (int z = lowerCorner.getZ(); z <= upperCorner.getZ(); z++) { for (int y = lowerCorner.getY(); y <= upperCorner.getY(); y++) { for (int x = lowerCorner.getX() ; x <= upperCorner.getX(); x++) { volData.setVoxelAt(x,y,z, MaterialDensityPair44(uValue, uValue > 0 ? maxDen : minDen)); } } } }
void PhysicsManager::UpdateChunkRange(Vector3DInt32 &start, Vector3DInt32 &end) { if(start.getX() > end.getX() || start.getY() > end.getY() || start.getZ() > end.getZ()) return; //start needs to be lower than end GameTimer timer; double totalElapsed = 0.f; for(int i = start.getX(); i <= end.getX(); i++) for(int j = start.getY(); j <= end.getY(); j++) for(int k = start.getZ(); k <= end.getZ(); k++) { totalElapsed += timer.getElapsedTimeSec(); if(totalElapsed >= .5f) { totalElapsed = 0; float progress = (float)(i * end.getY() + j) / (float)(end.getX() * end.getY()); graphMan->UpdatePhysicsProgress(progress); } UpdateChunk(Vector3DInt32(i, j, k)); } }
void PhysicsManager::UpdateChunk(Vector3DInt32 &chunk) { //Determines if the player is in this chunk or not hkVector4 playerPos = GetPlayerPosition(); Vector3DInt32 playerPosPoly(playerPos(0) / chunkSize, playerPos(1) / chunkSize, playerPos(2) / chunkSize); bool playerInChunk = false; if(playerPosPoly.getX() == chunk.getX() && playerPosPoly.getY() == chunk.getY() && playerPosPoly.getZ() == chunk.getZ()) playerInChunk = true; if(threadNum > 5 && !playerInChunk) return;//TOO MANY THREADS int upperX = polyVolume->getWidth() / chunkSize; int upperY = polyVolume->getHeight() / chunkSize; int upperZ = polyVolume->getDepth() / chunkSize; if(chunk.getX() < 0 || chunk.getY() < 0 || chunk.getZ() < 0) return;//Lower bounds check if(chunk.getX() > upperX || chunk.getY() > upperY || chunk.getZ() > upperZ) return;//Upper bounds check mu.lock(); if(pageQueue.getSize() >= maxPageSize)//Need to delete the LRU chunk { Vector3DInt32 LRUchunk = pageQueue[0]; pageQueue.removeAtAndCopy(0);//Pop the front chunk hkpRigidBody* body = physicsMap[LRUchunk]; physicsMap.erase(LRUchunk);//delete the rigid body from the physics map if(body && body->getWorld())//Ignore NULL values { world->lock(); world->removeEntity(body); world->unlock(); } } bool isPaged = false; int queuePos = -1; for(int i = 0; i < pageQueue.getSize(); i++) if(pageQueue[i] == chunk) { isPaged = true; pageQueue.removeAtAndCopy(i);//Remove the element and shift the array queuePos = i; break; } pageQueue.pushBack(chunk);//put chunk at the back of the queue //The chunk is still in memory if(isPaged) { if(queuePos < maxPageSize - maxRender)//This chunk currently isn't in the world { hkpRigidBody *body = physicsMap[chunk]; if(body && !body->getWorld())//Make sure the body isn't null and hasn't been added to the world yet { readyRigidBodies.enqueue(body); } } mu.unlock(); return; } mu.unlock(); Vector3DInt32* chunkPtr = new Vector3DInt32(chunk.getX(), chunk.getY(), chunk.getZ()); boost::thread t(&PhysicsManager::Thread_UpdateChunk, this, chunkPtr); #ifdef _DEBUG t.join(); #else //If the player is in this chunk, we need to block while loading if(playerInChunk) t.join(); else t.detach(); #endif }