//-------------------------------------------------------------------- // return true if all neighbors in memory BOOL ChunkWorld::loadNeighbors( ChunkObj* chunk) { ChunkObj* xmin = createChunk(chunk->m_originX - CHUNK_SIZE, chunk->m_originZ); if (xmin->m_status == CHUNK_UNLOADED) requestChunk(xmin); ChunkObj* xmax = createChunk(chunk->m_originX + CHUNK_SIZE, chunk->m_originZ); if (xmax->m_status == CHUNK_UNLOADED) requestChunk(xmax); ChunkObj* zmin = createChunk(chunk->m_originX, chunk->m_originZ - CHUNK_SIZE); if (zmin->m_status == CHUNK_UNLOADED) requestChunk(zmin); ChunkObj* zmax = createChunk(chunk->m_originX, chunk->m_originZ + CHUNK_SIZE); if (zmax->m_status == CHUNK_UNLOADED) requestChunk(zmax); if (xmin->m_status == CHUNK_UNLOADED || xmax->m_status == CHUNK_UNLOADED || zmin->m_status == CHUNK_UNLOADED || zmax->m_status == CHUNK_UNLOADED) return false; return true; }
void CubeWorld::createWorldChunks (void) { //std::vector<int> VertexArray; Ogre::MaterialPtr mat = Ogre::MaterialManager::getSingleton().create("BoxColor", "General", true ); Ogre::Technique* tech = mat->getTechnique(0); Ogre::Pass* pass = tech->getPass(0); Ogre::TextureUnitState* tex = pass->createTextureUnitState(); tex->setColourOperationEx(Ogre::LBX_MODULATE, Ogre::LBS_MANUAL, Ogre::LBS_CURRENT, Ogre::ColourValue(0, 0.5, 0)); Ogre::ManualObject* MeshChunk = new Ogre::ManualObject("MeshMatChunk"); MeshChunk->begin("TerrainImage"); for (int z = 0; z < WORLD_SIZE; z += CHUNK_SIZE) { for (int y = 0; y < WORLD_SIZE; y += CHUNK_SIZE) { for (int x = 0; x < WORLD_SIZE; x += CHUNK_SIZE) { createChunk(MeshChunk, x,y,z); /* WFaces or not */ //createChunkWater(x, y, z); } } } }
char readChunk(Chunk *chunk, FILE *in) { RLE_BlockData buf; BlockData data; int count = 0, size, i = 0; Block *block; while (count < CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE) { size = fread(&buf, sizeof(buf), 1, in); if (!size) { // file too short fprintf(stderr, "Error reading world file"); if (feof(in)) fputs("; file too short", stderr); else if (ferror(in)) fputs("; an error occured", stderr); fputs("\n", stderr); return 0; } // printf("read %d blocks\n", buf.count); count += buf.count; data = buf.data; while (buf.count > 0 && i < CHUNK_SIZE * CHUNK_SIZE * CHUNK_SIZE) { block = &chunk->blocks_lin[i]; if (data.logic) { block->logic = calloc(1, sizeof(Logic)); block->logic->type = data.logic_type; block->logic->roll = data.logic_roll; block->logic->pitch = data.logic_pitch; block->logic->yaw = data.logic_yaw; updateLogicModel(block); } if (data.data) { block->data = createModel(); block->data->chunk = createChunk(0, 0, 0); block->active = 1; if (!readChunk(block->data->chunk, in)) return 0; renderModel(block->data); } block->color = data.color; if (data.color.all) { block->active = 1; } i++; buf.count--; } } renderChunk(chunk); return 1; }
OctreeChunk* CubeWorld::findChunk( const Point& p, bool createIfNotFound ) { OctreeChunk* chunk = m_chunks[ chunkOffset(p) ]; if ( createIfNotFound && chunk == NULL ) { chunk = createChunk( p ); } return chunk; }
// **************************************************************************** // __declspec(dllexport) int GetBlock(float _fX, float _fY, float _fZ) { int x = (int)_fX; int y = (int)_fY; int z = (int)_fZ; uint16 Type = Map.Get(x,y,z); if(Type == 65535)//not in RAM { if(!loadChunk(x-(x%ChunkLength), y-(y%ChunkLength), z-(z%ChunkLength)))//generate createChunk(x-(x%ChunkLength), y-(y%ChunkLength), z-(z%ChunkLength)); Type = Map.Get(x,y,z); } return Type; }
void CubeWorld::set( const CubeData& value, const Point& pt ) { // sanity checkPointBounds( pt ); // Find the chunk that holds the cube OctreeChunk * chunk = m_chunks[ chunkOffset(pt) ]; if ( chunk == NULL ) { chunk = createChunk( pt ); } // Assign the value assert( chunk != NULL ); chunk->set( value, calcRelativeChunkPoint(pt) ); }
// **************************************************************************** // // Load a map a generate a new one if file does not exists __declspec(dllexport) bool LoadBlockMap(wchar_t* _pcFileName) { ConcatpwChar(_pcFileName, L"\\"); Map.Dir = (wchar_t*) malloc(wss.str().length()+1); wcscpy(Map.Dir, wss.str().c_str()); CreateDirectoryW(_pcFileName, NULL); Map.IndexHigh = 0; Map.Ini();//inizialise, pointers get NULLed if(!loadChunk(0,0,0)) //ini map with 1 chunk loaded so that pChunkArray[0] is spezified createChunk( 0, 0, 0); Map.pChunkArray[0] = Map.pChunkArray[1]; // Errors are not supported! // Try open ConcatpwChar(Map.Dir,_pcFileName, L".map"); FILE* pFile = _wfopen(sss, L"rb"); if(!pFile) { // Seed random to file name uint32 dwSeed = 0; while(*_pcFileName) { dwSeed += *_pcFileName; // Only remark the real file not the path if(*_pcFileName == '/' || *_pcFileName == '\\') dwSeed = 0; ++_pcFileName; } PerlinObject2D.SetSeed(dwSeed); PerlinObject3D.SetSeed(dwSeed*1009 + 71); return false; } else { // Read and check for version... FileHeader FH; fread(&FH, sizeof(FileHeader), 1, pFile); if(FH.uiFileSignature != *(unsigned int*)FILE_SIGNATURE) return false; PerlinObject2D.SetSeed(FH.uiSeed2D); PerlinObject3D.SetSeed(FH.uiSeed3D); fclose(pFile); return true; } }
Chunk* ChunkPillar::getChunkLocal(wCoord y) { size_t index = getChunkIndex(y); Chunk* curChunk = mChunks[index]; if (curChunk == 0) { wCoord yAbs = (y > ChunksAboveZero ? y - ChunksPerPillar : y); curChunk = mWRegion.loadChunk(*this, mX, yAbs, mZ); if (curChunk == 0) { if (maxY > yAbs * ChunkSizeY) { // Chunk has blocks curChunk = createChunk(yAbs); mWRegion.getTerraGen().fillChunk(*this, *static_cast<ChunkBase*>(curChunk)); } else { // Chunk is empty curChunk = createChunkEmpty(yAbs); } } mChunks[index] = curChunk; } return curChunk; };
World * createWorld(unsigned int size) { World *world = malloc(sizeof(World)); world->size = size; world->num_chunks = size * size * size; world->chunks = calloc(world->num_chunks, sizeof(Chunk*)); int x, y, z; for (x = 0; x < world->size; x++) { for (y = 0; y < world->size; y++) { for (z = 0; z < world->size; z++) { getChunk(world, x, y, z) = createChunk(x, y, z); } } } unsigned int world_block_width = world->size * CHUNK_SIZE; // link neighbors in the world for (x = 0; x < world_block_width; x++) { for (y = 0; y < world_block_width; y++) { for (z = 0; z < world_block_width; z++) { Block *block = worldBlock(world, x, y, z); block->nb_pos_x = worldBlock(world, x+1, y, z); block->nb_neg_x = worldBlock(world, x-1, y, z); block->nb_pos_y = worldBlock(world, x, y+1, z); block->nb_neg_y = worldBlock(world, x, y-1, z); block->nb_pos_z = worldBlock(world, x, y, z+1); block->nb_neg_z = worldBlock(world, x, y, z-1); } } } return world; }
//-------------------------------------------------------------- // update animation BOOL ChunkWorld::animate( double now, // current time (ms) double since) // milliseconds since last pass { BOOL viewChanged = false; m_chunkLock->lock(); // keep memory use under limits checkMemory(); resetRequestList(); // figure which chunk we are in int viewX = (int) floor(m_eyePt.x / CHUNK_SIZE); int viewZ = (int) floor(m_eyePt.z / CHUNK_SIZE); // for all coordinates in view list for (int i = m_viewListCount-1; i >= 0; i--) { ChunkOrigin* origin = &m_viewList[i]; int chunkX = CHUNK_SIZE*(viewX + origin->x); int chunkZ = CHUNK_SIZE*(viewZ + origin->z); // find/create chunk ChunkObj* chunk = createChunk(chunkX, chunkZ); // if chunk within view if (chunk->withinFrustum()) { switch (chunk->m_status) { case CHUNK_UNLOADED: // request the chunk (loads in memory) requestChunk(chunk); // request the neighbors loadNeighbors(chunk); break; case CHUNK_INMEMORY: // if all neighbors loaded, update chunk edges if (loadNeighbors(chunk)) { updateEdges(chunk); // request the chunk (loads in display) requestChunk(chunk); } break; case CHUNK_INDISPLAY: // if we have an update, use it if (!chunk->m_active && chunk->m_hasUpdate) { // mgDebug("use update on (%d, %d)", chunk->m_originX, chunk->m_originZ); int oldSize = chunk->getDisplayMemUsed(); chunk->useUpdate(); int size = chunk->getDisplayMemUsed(); m_displayMemUsed += size-oldSize; chunk->m_hasUpdate = false; } // if it needs an update, flag it if (!chunk->m_active && chunk->needsUpdate(m_eyePt)) { // mgDebug("wants update on (%d, %d)", chunk->m_originX, chunk->m_originZ); chunk->m_status = CHUNK_NEEDSUPDATE; chunk->m_eyePt = m_eyePt; m_requestList.addToTail(chunk); } // if still in display, animate it, since we will draw it if (chunk->m_status == CHUNK_INDISPLAY || chunk->m_status == CHUNK_NEEDSUPDATE) chunk->animate(now, since); break; case CHUNK_NEEDSUPDATE: // if needed update last pass, and not being processed, still needs update if (!chunk->m_active) { // mgDebug("still needs update on (%d, %d)", chunk->m_originX, chunk->m_originZ); m_requestList.addToTail(chunk); chunk->animate(now, since); } break; } // push to bottom of LRU list ChunkListNode* node = m_LRUList.find(chunk); if (node != NULL) m_LRUList.removeNode(node); m_LRUList.addToTail(chunk); } } if (m_chunksChanged) { viewChanged = true; m_chunksChanged = false; } m_chunkLock->unlock(); // if we requested chunks, activate worker threads if (!m_requestList.isEmpty()) { if (m_chunkThreads != NULL) { // signal the threads to look at requestList m_chunkEvent->signal(); } else { // process one request in this thread (no worker threads) ChunkObj* found = dequeueRequest(); if (found != NULL) processRequest(found); } } return viewChanged; }
void createWaitFreePool(int m, int n, int c, int C, int blkSize) { LOG_PROLOG(); memory = (Memory*)my_malloc(sizeof(Memory)); int numOfThreads = n; int numOfBlocksPerChunk = c; int numOfChunks = m/c; int numOfChunksPerThread = numOfChunks/numOfThreads; //numOfThreads = n + 1; globalHPStructure = (HPStructure*)my_malloc(sizeof(HPStructure)); hpStructureCreate(globalHPStructure, n, 5); //LOG_INFO("globalHPStructure is %u", globalHPStructure); memory->fullPool = createFullPool(numOfThreads); memory->localPool = createLocalPool(numOfThreads); memory->freePoolUC = createFreePoolUC(numOfThreads); memory->freePoolC = createFreePoolC(numOfThreads); LOG_INFO("created freePoolC\n"); memory->sharedQueuePools = createSharedQueuePools(numOfThreads); LOG_INFO("created SQP\n"); numOfThreads = n; memory->m = m; memory->n = n; memory->c = c; memory->C = C; Chunk *chunk; BLOCK_MEM block; // Set-up of initial local pools for(int j = 0; j < numOfThreads ; j++) { for(int i = 0; i < 1; i++) { chunk = createChunk(numOfBlocksPerChunk); for(int k = 0; k < numOfBlocksPerChunk; k++) { block = createBlock(blkSize); //set the owner of the block to be -1 initially putInChunkUncontended(chunk, block); } putInLocalPool(memory->localPool,j,chunk); } } //LOG_INFO("set up localPool with chunk\n"); // Set-up of initial full pools for(int j = 0; j < numOfThreads ; j++) { for(int i = 0; i < numOfChunksPerThread - 1; i++) { chunk = createChunk(numOfBlocksPerChunk); for(int k = 0; k < numOfBlocksPerChunk; k++) { block = createBlock(blkSize); putInChunkUncontended(chunk, block); } //LOG_INFO("created the chunk for FP\n"); putInOwnFullPool(memory->fullPool,j,chunk); //LOG_INFO("fullPoolEmpty[%d] %u %u\n",j, isFullPoolEmpty(memory->fullPool,j), flag); } } //LOG_INFO("set up FullPools with chunks\n"); //numOfThreads = n + 1; memory->announce = (Announce*)my_malloc(sizeof(Announce)); memory->announce->helpers = (AtomicStampedReference*) my_malloc(sizeof(AtomicStampedReference)*numOfThreads); for(int i = 0; i < numOfThreads; i++) { AtomicStampedReference* helperEntry = getHelperEntry(i); bool* tempBoolObj = (bool*)my_malloc(sizeof(bool)); *tempBoolObj = false; createAtomicStampedReference(helperEntry,tempBoolObj,0); } // Set up initial info array memory->info = (Info*)my_malloc(sizeof(Info)); memory->info->donors = (Donor*) my_malloc(sizeof(Donor)*numOfThreads); memory->info->numOfDonors = numOfThreads; for(int i = 0; i < numOfThreads; i++) { Donor* donorEntry = getDonorEntry(i); donorEntry->lastDonated = i; donorEntry->noOfOps = 0; donorEntry->numOfPassed = 0; donorEntry->addInFreePoolC = false; } LOG_EPILOG(); }