diff --git a/src/Client/GUI/CImageLoaderBLP.cpp b/src/Client/GUI/CImageLoaderBLP.cpp index 13ec549..668b530 100644 --- a/src/Client/GUI/CImageLoaderBLP.cpp +++ b/src/Client/GUI/CImageLoaderBLP.cpp @@ -4,6 +4,12 @@ #include "SImage.h" #include "CImageLoaderBLP.h" +#ifdef _DEBUG +#define DEBUG(code) code; +#else +#define DEBUG(code) ; +#endif + namespace irr { namespace video @@ -24,26 +30,26 @@ bool CImageLoaderBLP::isALoadableFileFormat(io::IReadFile* file) const // std::cout <<"Checking if file is a BLP file\n"; if (!file) { - std::cout<<"No such file: "<getFileName()<<"\n"; + DEBUG(std::cout<<"No such file: "<getFileName()<<"\n"); return false; } std::string fileId; // Read the first few bytes of the BLP file if (file->read(&fileId[0], 4) != 4) { - std::cout << "Cannot read BLP file header\n"; + DEBUG(std::cout << "Cannot read BLP file header\n"); return false; } if(fileId[0]=='B' && fileId[1]=='L' && fileId[2]=='P' && fileId[3]=='2') { - std::cout << "Header is BLP2, file should be loadable\n"; + DEBUG(std::cout << "Header is BLP2, file should be loadable\n"); return true; } else { - std::cout << "Header doesn't match, this is no BLP file\n"; - std::cout << "Expected:BLP2 Got:"< #include "CM2MeshFileLoader.h" +#ifdef _DEBUG +#define DEBUG(code) code; +#else +#define DEBUG(code) ; +#endif namespace irr @@ -34,7 +39,7 @@ IAnimatedMesh* CM2MeshFileLoader::createMesh(io::IReadFile* file) { ILogger* logger =Device->getLogger(); -logger->log("Trying to open file",file->getFileName(),ELL_INFORMATION); +DEBUG(logger->log("Trying to open file",file->getFileName(),ELL_INFORMATION)); file->read(&header,sizeof(ModelHeader)); @@ -42,9 +47,12 @@ file->read(&header,sizeof(ModelHeader)); logger->log("Something wrong!",ELL_ERROR); return 0; } - else logger->log(L"header okay",ELL_INFORMATION); + else + { + DEBUG(logger->log(L"header okay",ELL_INFORMATION)); + } //Name -> not very important I think, but save it nontheless; -std::cout << "Name offset:" << header.nameOfs << "Name length:" << header.nameLength << "\n"; +DEBUG(std::cout << "Name offset:" << header.nameOfs << "Name length:" << header.nameLength << "\n"); //M2MeshName.clear(); //M2MeshName.reserve(header.nameLength); file->seek(header.nameOfs); @@ -65,7 +73,7 @@ for(u32 i =0;iread(&tempM2MVert,sizeof(ModelVertex)); M2MVertices.push_back(tempM2MVert); } -std::cout << "Read "<0) @@ -79,8 +87,8 @@ for(u32 i =0;ilog("Using View 0 for all further operations",ELL_INFORMATION); -std::cout<<"This View has "<log("Using View 0 for all further operations",ELL_INFORMATION)); +DEBUG(std::cout<<"This View has "<0) @@ -93,7 +101,7 @@ for(u32 i =0;iread(&tempM2Index,sizeof(u16)); M2MIndices.push_back(tempM2Index); } -std::cout << "Read "<read(&tempM2Triangle,sizeof(u16)); M2MTriangles.push_back(tempM2Triangle); } -std::cout << "Read "<0) @@ -121,7 +129,7 @@ for(u32 i =0;iread(&tempM2TexUnit,sizeof(TextureUnit)); M2MTextureUnit.push_back(tempM2TexUnit); } -std::cout << "Read "<read(&tempM2TexLookup,sizeof(u16)); M2MTextureLookup.push_back(tempM2TexLookup); } -std::cout << "Read "<read(&tempM2TexDef,sizeof(TextureDefinition)); M2MTextureDef.push_back(tempM2TexDef); } -std::cout << "Read "<read(&tempM2RF,sizeof(RenderFlags)); M2MRenderFlags.push_back(tempM2RF); } -std::cout << "Read "<seek(M2MTextureDef[i].texFileOfs); file->read((void*)tempTexFileName.c_str(),M2MTextureDef[i].texFileLen); - std::cout << "texture: '" << tempTexFileName << "'\n"; + DEBUG(std::cout << "texture: '" << tempTexFileName << "'\n"); M2MTextureFiles.push_back(tempTexFileName.c_str()); std::cout<getMaterial().setTexture(0,Device->getVideoDriver()->getTexture(TexName.c_str())); if(igetMaterial().BackfaceCulling=(M2MRenderFlags[i].flags & 0x04)?false:true; if(M2MRenderFlags[i].blending==1) IMB->getMaterial().MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL; diff --git a/src/Client/GUI/Scene.h b/src/Client/GUI/Scene.h index 84e365f..d387b4b 100644 --- a/src/Client/GUI/Scene.h +++ b/src/Client/GUI/Scene.h @@ -57,6 +57,12 @@ class WorldSession; class SceneWorld : public Scene { + struct SceneNodeWithGridPos + { + scene::ISceneNode *scenenode; + uint32 gx,gy; + }; + public: SceneWorld(PseuGUI *gui); void OnDraw(void); @@ -65,6 +71,7 @@ public: void UpdateTerrain(void); void InitTerrain(void); void RelocateCamera(void); + void UpdateDoodads(void); WorldPosition GetWorldPosition(void); @@ -82,6 +89,7 @@ private: MapMgr *mapmgr; IGUIStaticText *debugText; bool debugmode; + std::map _doodads; }; diff --git a/src/Client/GUI/SceneWorld.cpp b/src/Client/GUI/SceneWorld.cpp index 2c95c4a..566357e 100644 --- a/src/Client/GUI/SceneWorld.cpp +++ b/src/Client/GUI/SceneWorld.cpp @@ -170,8 +170,11 @@ void SceneWorld::OnUpdate(s32 timediff) eventrecv->mouse.wheel = 2; camera->setHeight( eventrecv->mouse.wheel + terrain->getHeight(camera->getPosition()) ); + core::stringw str = L""; + + DEBUG( WorldPosition wp = GetWorldPosition(); - core::stringw str = L"Camera: pitch:"; + str += L"Camera: pitch:"; str += camera->getPitch(); str += L" c pos:"; str += camera->getPosition().X; @@ -189,10 +192,24 @@ void SceneWorld::OnUpdate(s32 timediff) str += L" / "; str += (int)terrain->getSectorCount(); str += L"\n"; - str += device->getCursorControl()->isVisible() ? L"Cursor: VISIBLE" : L"Cursor: HIDDEN"; + + + const core::list& nodelist = smgr->getRootSceneNode()->getChildren(); + str += L"Scene nodes: total: "; + str += nodelist.getSize(); + str += L" visible: "; + u32 vis = 0; + for(core::list::ConstIterator it = nodelist.begin(); it != nodelist.end(); it++) + if((*it)->isVisible()) + vis++; + str += vis; + ); // END DEBUG; + + debugText->setText(str.c_str()); + gui->domgr.Update(); // iterate over DrawObjects, draw them and clean up } @@ -260,11 +277,27 @@ void SceneWorld::UpdateTerrain(void) return; } - // something is not good here. we have terrain, but the chunks are read incorrectly. - // need to find out where which formula is wrong - // the current terrain renderer code is just a test to see if ADT files are read correctly. - // EDIT: it seems to display fine now, but i am still not sure if the way it is done is correct... - mutex.acquire(); // prevent other threads from deleting the maptile + UpdateDoodads(); // drop doodads on maps not loaded anymore. no maptile pointers are dereferenced here, so it can be done before acquiring the mutex + + mutex.acquire(); // prevent other threads from deleting maptiles + + // to set the correct position of the terrain, we have to use the top-left tile's coords as terrain base pos + MapTile *maptile = mapmgr->GetNearTile(-1, -1); + vector3df tpos(0,0,0); // height already managed when building up terrain (-> Y = always 0) + if(maptile) + { + tpos.X = -maptile->GetBaseX(); + tpos.Z = -maptile->GetBaseY(); + } + else if(maptile = mapmgr->GetCurrentTile()) // this is tile (0, 0) in relative coords + { + logdebug("SceneWorld: Using alternative coords due to missing MapTile"); + tpos.X = -(maptile->GetBaseX() + TILESIZE); + tpos.Y = -(maptile->GetBaseY() + TILESIZE); + } + logdebug("SceneWorld: Setting position of terrain (x:%.2f y:%.2f z:%.2f)", tpos.X, tpos.Y, tpos.Z); + terrain->setPosition(tpos); + logdebug("SceneWorld: Displaying MapTiles near grids x:%u y:%u",mapmgr->GetGridX(),mapmgr->GetGridY()); logdebug("Loaded maps: %u: %s",mapmgr->GetLoadedMapsCount(), mapmgr->GetLoadedTilesString().c_str()); for(s32 tiley = 0; tiley < 3; tiley++) @@ -296,14 +329,23 @@ void SceneWorld::UpdateTerrain(void) for(uint32 i = 0; i < maptile->GetDoodadCount(); i++) { Doodad *d = maptile->GetDoodad(i); - scene::IAnimatedMesh *mesh = smgr->getMesh(d->model.c_str()); - if(mesh) + if(_doodads.find(d->uniqueid) == _doodads.end()) // only add doodads that dont exist yet { - scene::ISceneNode *doodad = smgr->addAnimatedMeshSceneNode(mesh); - if(doodad) + scene::IAnimatedMesh *mesh = smgr->getMesh(d->model.c_str()); + if(mesh) { - doodad->setPosition(core::vector3df(-d->x, d->z, -d->y)); - doodad->setRotation(core::vector3df(-d->ox, -d->oy-90, -d->oz)); // +270 solves M2 models lying on the side + scene::ISceneNode *doodad = smgr->addAnimatedMeshSceneNode(mesh); + if(doodad) + { + doodad->setAutomaticCulling(EAC_BOX); + doodad->setPosition(core::vector3df(-d->x, d->z, -d->y)); + doodad->setRotation(core::vector3df(-d->ox, -d->oy-90, -d->oz)); + SceneNodeWithGridPos gp; + gp.gx = mapmgr->GetGridX() + tilex - 1; + gp.gy = mapmgr->GetGridY() + tiley - 1; + gp.scenenode = doodad; + _doodads[d->uniqueid] = gp; + } } } } @@ -341,23 +383,6 @@ void SceneWorld::UpdateTerrain(void) terrain->setColor(i,j, video::SColor(255,r,g,b)); } - // to set the correct position of the terrain, we have to use the top-left tile's coords as terrain base pos - MapTile *maptile = mapmgr->GetNearTile(-1, -1); - vector3df tpos(0,0,0); // height already managed when building up terrain (-> Y = always 0) - if(maptile) - { - tpos.X = -maptile->GetBaseX(); - tpos.Z = -maptile->GetBaseY(); - } - else if(maptile = mapmgr->GetCurrentTile()) // this is tile (0, 0) in relative coords - { - logdebug("SceneWorld: Using alternative coords due to missing MapTile"); - tpos.X = -(maptile->GetBaseX() + TILESIZE); - tpos.Y = -(maptile->GetBaseY() + TILESIZE); - } - logdebug("SceneWorld: Setting position of terrain (x:%.2f y:%.2f z:%.2f)", tpos.X, tpos.Y, tpos.Z); - terrain->setPosition(tpos); - logdebug("SceneWorld: Smoothing terrain normals..."); terrain->smoothNormals(); @@ -366,6 +391,24 @@ void SceneWorld::UpdateTerrain(void) RelocateCamera(); } +// drop unneeded doodads from the map +void SceneWorld::UpdateDoodads(void) +{ + uint32 s = _doodads.size(); + std::set tmp; // temporary storage for all doodad unique ids + // too bad erasing from a map causes pointer invalidation, so first store all unique ids, and then erase + for(std::map::iterator it = _doodads.begin(); it != _doodads.end(); it++ ) + if(!mapmgr->GetTile(it->second.gx, it->second.gy)) + tmp.insert(it->first); + for(std::set::iterator it = tmp.begin(); it != tmp.end(); it++) + { + _doodads[*it].scenenode->remove(); + _doodads.erase(*it); + } + logdebug("SceneWorld: Doodads cleaned up, before: %u, after: %u, dropped: %u", s, _doodads.size(), s - _doodads.size()); +} + + void SceneWorld::RelocateCamera(void) { diff --git a/src/shared/MapTile.cpp b/src/shared/MapTile.cpp index db24bee..e20b379 100644 --- a/src/shared/MapTile.cpp +++ b/src/shared/MapTile.cpp @@ -83,6 +83,7 @@ void MapTile::ImportFromADT(ADTFile *adt) d.oy = mddf.b - 90.0f; // wowdev states Y=B-90, but this doesnt really look as expected... d.oz = -mddf.a; d.flags = mddf.flags; + d.uniqueid = mddf.uniqueid; d.model = std::string("./data/model/") + NormalizeFilename(_PathToFileName(adt->_models[mddf.id])); // this .mdx -> .m2 transformation is annoying >.< - replace "mdx" and end of string with "m2\0" memcpy(&d.model[0] + d.model.size() - 3, "m2\0", 3); diff --git a/src/shared/MapTile.h b/src/shared/MapTile.h index a0d9865..57ff75e 100644 --- a/src/shared/MapTile.h +++ b/src/shared/MapTile.h @@ -27,6 +27,7 @@ public: struct Doodad { + uint32 uniqueid; float x,y,z,ox,oy,oz,scale; uint16 flags; std::string model;