void Scene::loadCell (CellStore *cell, Loading::Listener* loadingListener) { std::pair<CellStoreCollection::iterator, bool> result = mActiveCells.insert(cell); if(result.second) { std::cout << "Loading cell " << cell->getCell()->getDescription() << std::endl; float verts = ESM::Land::LAND_SIZE; float worldsize = ESM::Land::REAL_SIZE; // Load terrain physics first... if (cell->getCell()->isExterior()) { ESM::Land* land = MWBase::Environment::get().getWorld()->getStore().get<ESM::Land>().search( cell->getCell()->getGridX(), cell->getCell()->getGridY() ); if (land && land->mDataTypes&ESM::Land::DATA_VHGT) { // Actually only VHGT is needed here, but we'll need the rest for rendering anyway. // Load everything now to reduce IO overhead. const int flags = ESM::Land::DATA_VCLR|ESM::Land::DATA_VHGT|ESM::Land::DATA_VNML|ESM::Land::DATA_VTEX; const ESM::Land::LandData *data = land->getLandData (flags); mPhysics->addHeightField (data->mHeights, cell->getCell()->getGridX(), cell->getCell()->getGridY(), worldsize / (verts-1), verts); } } cell->respawn(); // ... then references. This is important for adjustPosition to work correctly. /// \todo rescale depending on the state of a new GMST insertCell (*cell, true, loadingListener); mRendering.addCell(cell); bool waterEnabled = cell->getCell()->hasWater() || cell->isExterior(); float waterLevel = cell->isExterior() ? -1.f : cell->getWaterLevel(); mRendering.setWaterEnabled(waterEnabled); if (waterEnabled) { mPhysics->enableWater(waterLevel); mRendering.setWaterHeight(waterLevel); } else mPhysics->disableWater(); if (!cell->isExterior() && !(cell->getCell()->mData.mFlags & ESM::Cell::QuasiEx)) mRendering.configureAmbient(cell->getCell()); } // register local scripts // ??? Should this go into the above if block ??? MWBase::Environment::get().getWorld()->getLocalScripts().addCell (cell); }
void GlobalMap::render (Loading::Listener* loadingListener) { const MWWorld::ESMStore &esmStore = MWBase::Environment::get().getWorld()->getStore(); // get the size of the world MWWorld::Store<ESM::Cell>::iterator it = esmStore.get<ESM::Cell>().extBegin(); for (; it != esmStore.get<ESM::Cell>().extEnd(); ++it) { if (it->getGridX() < mMinX) mMinX = it->getGridX(); if (it->getGridX() > mMaxX) mMaxX = it->getGridX(); if (it->getGridY() < mMinY) mMinY = it->getGridY(); if (it->getGridY() > mMaxY) mMaxY = it->getGridY(); } mWidth = mCellSize*(mMaxX-mMinX+1); mHeight = mCellSize*(mMaxY-mMinY+1); loadingListener->loadingOn(); loadingListener->setLabel("Creating map"); loadingListener->setProgressRange((mMaxX-mMinX+1) * (mMaxY-mMinY+1)); loadingListener->setProgress(0); osg::ref_ptr<osg::Image> image = new osg::Image; image->allocateImage(mWidth, mHeight, 1, GL_RGB, GL_UNSIGNED_BYTE); unsigned char* data = image->data(); for (int x = mMinX; x <= mMaxX; ++x) { for (int y = mMinY; y <= mMaxY; ++y) { ESM::Land* land = esmStore.get<ESM::Land>().search (x,y); if (land) { int mask = ESM::Land::DATA_WNAM; if (!land->isDataLoaded(mask)) land->loadData(mask); } const ESM::Land::LandData *landData = land ? land->getLandData (ESM::Land::DATA_WNAM) : 0; for (int cellY=0; cellY<mCellSize; ++cellY) { for (int cellX=0; cellX<mCellSize; ++cellX) { int vertexX = static_cast<int>(float(cellX)/float(mCellSize) * 9); int vertexY = static_cast<int>(float(cellY) / float(mCellSize) * 9); int texelX = (x-mMinX) * mCellSize + cellX; int texelY = (y-mMinY) * mCellSize + cellY; unsigned char r,g,b; float y = 0; if (landData) y = (landData->mWnam[vertexY * 9 + vertexX] << 4) / 2048.f; else y = (SCHAR_MIN << 4) / 2048.f; if (y < 0) { r = static_cast<unsigned char>(14 * y + 38); g = static_cast<unsigned char>(20 * y + 56); b = static_cast<unsigned char>(18 * y + 51); } else if (y < 0.3f) { if (y < 0.1f) y *= 8.f; else { y -= 0.1f; y += 0.8f; } r = static_cast<unsigned char>(66 - 32 * y); g = static_cast<unsigned char>(48 - 23 * y); b = static_cast<unsigned char>(33 - 16 * y); } else { y -= 0.3f; y *= 1.428f; r = static_cast<unsigned char>(34 - 29 * y); g = static_cast<unsigned char>(25 - 20 * y); b = static_cast<unsigned char>(17 - 12 * y); } data[texelY * mWidth * 3 + texelX * 3] = r; data[texelY * mWidth * 3 + texelX * 3+1] = g; data[texelY * mWidth * 3 + texelX * 3+2] = b; } } loadingListener->increaseProgress(); if (land) land->unloadData(); } } mBaseTexture = new osg::Texture2D; mBaseTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); mBaseTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE); mBaseTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR); mBaseTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR); mBaseTexture->setImage(image); mBaseTexture->setResizeNonPowerOfTwoHint(false); clear(); loadingListener->loadingOff(); }