* output text in .blp and .m2 loader only in debug mode

* remove doodads from unused map tiles (after teleport or so)
* some render speedups (enabled automatic culling, but thats not enough. more optimizations must be done)
This commit is contained in:
false_genesis 2008-04-07 15:18:52 +00:00
parent a05dfe613e
commit cc4283f18f
6 changed files with 117 additions and 50 deletions

View File

@ -4,6 +4,12 @@
#include "SImage.h" #include "SImage.h"
#include "CImageLoaderBLP.h" #include "CImageLoaderBLP.h"
#ifdef _DEBUG
#define DEBUG(code) code;
#else
#define DEBUG(code) ;
#endif
namespace irr namespace irr
{ {
namespace video namespace video
@ -24,26 +30,26 @@ bool CImageLoaderBLP::isALoadableFileFormat(io::IReadFile* file) const
// std::cout <<"Checking if file is a BLP file\n"; // std::cout <<"Checking if file is a BLP file\n";
if (!file) if (!file)
{ {
std::cout<<"No such file: "<<file->getFileName()<<"\n"; DEBUG(std::cout<<"No such file: "<<file->getFileName()<<"\n");
return false; return false;
} }
std::string fileId; std::string fileId;
// Read the first few bytes of the BLP file // Read the first few bytes of the BLP file
if (file->read(&fileId[0], 4) != 4) 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; return false;
} }
if(fileId[0]=='B' && fileId[1]=='L' && fileId[2]=='P' && fileId[3]=='2') 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; return true;
} }
else else
{ {
std::cout << "Header doesn't match, this is no BLP file\n"; DEBUG(std::cout << "Header doesn't match, this is no BLP file\n");
std::cout << "Expected:BLP2 Got:"<<fileId.c_str()<<"\n"; DEBUG(std::cout << "Expected:BLP2 Got:"<<fileId.c_str()<<"\n");
return false; return false;
} }
} }

View File

@ -1,6 +1,11 @@
#include <iostream> #include <iostream>
#include "CM2MeshFileLoader.h" #include "CM2MeshFileLoader.h"
#ifdef _DEBUG
#define DEBUG(code) code;
#else
#define DEBUG(code) ;
#endif
namespace irr namespace irr
@ -34,7 +39,7 @@ IAnimatedMesh* CM2MeshFileLoader::createMesh(io::IReadFile* file)
{ {
ILogger* logger =Device->getLogger(); 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)); file->read(&header,sizeof(ModelHeader));
@ -42,9 +47,12 @@ file->read(&header,sizeof(ModelHeader));
logger->log("Something wrong!",ELL_ERROR); logger->log("Something wrong!",ELL_ERROR);
return 0; 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; //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.clear();
//M2MeshName.reserve(header.nameLength); //M2MeshName.reserve(header.nameLength);
file->seek(header.nameOfs); file->seek(header.nameOfs);
@ -65,7 +73,7 @@ for(u32 i =0;i<header.nVertices;i++)
file->read(&tempM2MVert,sizeof(ModelVertex)); file->read(&tempM2MVert,sizeof(ModelVertex));
M2MVertices.push_back(tempM2MVert); M2MVertices.push_back(tempM2MVert);
} }
std::cout << "Read "<<M2MVertices.size()<<"/"<<header.nVertices<<" Vertices\n"; DEBUG(std::cout << "Read "<<M2MVertices.size()<<"/"<<header.nVertices<<" Vertices\n");
//Views == Sets of vertices. Usage yet unknown. Global data //Views == Sets of vertices. Usage yet unknown. Global data
if(M2MViews.size()>0) if(M2MViews.size()>0)
@ -79,8 +87,8 @@ for(u32 i =0;i<header.nViews;i++)
} }
//std::cout << "Read "<<M2MViews.size()<<"/"<<header.nViews<<" Views\n"; //std::cout << "Read "<<M2MViews.size()<<"/"<<header.nViews<<" Views\n";
logger->log("Using View 0 for all further operations",ELL_INFORMATION); DEBUG(logger->log("Using View 0 for all further operations",ELL_INFORMATION));
std::cout<<"This View has "<<M2MViews[0].nSub<<" Submeshes\n"; DEBUG(std::cout<<"This View has "<<M2MViews[0].nSub<<" Submeshes\n");
//Vertex indices of a specific view.Local to View 0 //Vertex indices of a specific view.Local to View 0
if(M2MIndices.size()>0) if(M2MIndices.size()>0)
@ -93,7 +101,7 @@ for(u32 i =0;i<M2MViews[0].nIndex;i++)
file->read(&tempM2Index,sizeof(u16)); file->read(&tempM2Index,sizeof(u16));
M2MIndices.push_back(tempM2Index); M2MIndices.push_back(tempM2Index);
} }
std::cout << "Read "<<M2MIndices.size()<<"/"<<M2MViews[0].nIndex<<" Indices\n"; DEBUG(std::cout << "Read "<<M2MIndices.size()<<"/"<<M2MViews[0].nIndex<<" Indices\n");
//Triangles. Data Points point to the Vertex Indices, not the vertices themself. 3 Points = 1 Triangle, Local to View 0 //Triangles. Data Points point to the Vertex Indices, not the vertices themself. 3 Points = 1 Triangle, Local to View 0
@ -107,7 +115,7 @@ for(u32 i =0;i<M2MViews[0].nTris;i++)
file->read(&tempM2Triangle,sizeof(u16)); file->read(&tempM2Triangle,sizeof(u16));
M2MTriangles.push_back(tempM2Triangle); M2MTriangles.push_back(tempM2Triangle);
} }
std::cout << "Read "<<M2MTriangles.size()<<"/"<<M2MViews[0].nTris<<" Triangle Indices\n"; DEBUG(std::cout << "Read "<<M2MTriangles.size()<<"/"<<M2MViews[0].nTris<<" Triangle Indices\n");
//Submeshes, Local to View 0 //Submeshes, Local to View 0
if(M2MSubmeshes.size()>0) if(M2MSubmeshes.size()>0)
@ -121,7 +129,7 @@ for(u32 i =0;i<M2MViews[0].nSub;i++)
M2MSubmeshes.push_back(tempM2Submesh); M2MSubmeshes.push_back(tempM2Submesh);
// std::cout<< "Submesh " <<i<<" ID "<<tempM2Submesh.meshpartId<<" starts at V/T "<<tempM2Submesh.ofsVertex<<"/"<<tempM2Submesh.ofsTris<<" and has "<<tempM2Submesh.nVertex<<"/"<<tempM2Submesh.nTris<<" V/T\n"; // std::cout<< "Submesh " <<i<<" ID "<<tempM2Submesh.meshpartId<<" starts at V/T "<<tempM2Submesh.ofsVertex<<"/"<<tempM2Submesh.ofsTris<<" and has "<<tempM2Submesh.nVertex<<"/"<<tempM2Submesh.nTris<<" V/T\n";
} }
std::cout << "Read "<<M2MSubmeshes.size()<<"/"<<M2MViews[0].nSub<<" Submeshes\n"; DEBUG(std::cout << "Read "<<M2MSubmeshes.size()<<"/"<<M2MViews[0].nSub<<" Submeshes\n");
//Texture units. Local to view 0 //Texture units. Local to view 0
TextureUnit tempM2TexUnit; TextureUnit tempM2TexUnit;
@ -135,7 +143,7 @@ for(u32 i=0;i<M2MViews[0].nTex;i++)
file->read(&tempM2TexUnit,sizeof(TextureUnit)); file->read(&tempM2TexUnit,sizeof(TextureUnit));
M2MTextureUnit.push_back(tempM2TexUnit); M2MTextureUnit.push_back(tempM2TexUnit);
} }
std::cout << "Read "<<M2MTextureUnit.size()<<" Texture Unit entries for View 0\n"; DEBUG(std::cout << "Read "<<M2MTextureUnit.size()<<" Texture Unit entries for View 0\n");
@ -152,7 +160,7 @@ for(u32 i=0;i<header.nTexLookup;i++)
file->read(&tempM2TexLookup,sizeof(u16)); file->read(&tempM2TexLookup,sizeof(u16));
M2MTextureLookup.push_back(tempM2TexLookup); M2MTextureLookup.push_back(tempM2TexLookup);
} }
std::cout << "Read "<<M2MTextureLookup.size()<<" Texture lookup entries\n"; DEBUG(std::cout << "Read "<<M2MTextureLookup.size()<<" Texture lookup entries\n");
//Texture Definitions table. This is global data //Texture Definitions table. This is global data
TextureDefinition tempM2TexDef; TextureDefinition tempM2TexDef;
@ -166,7 +174,7 @@ for(u32 i=0;i<header.nTextures;i++)
file->read(&tempM2TexDef,sizeof(TextureDefinition)); file->read(&tempM2TexDef,sizeof(TextureDefinition));
M2MTextureDef.push_back(tempM2TexDef); M2MTextureDef.push_back(tempM2TexDef);
} }
std::cout << "Read "<<M2MTextureDef.size()<<" Texture Definition entries\n"; DEBUG(std::cout << "Read "<<M2MTextureDef.size()<<" Texture Definition entries\n");
//Render Flags table. This is global data //Render Flags table. This is global data
RenderFlags tempM2RF; RenderFlags tempM2RF;
@ -180,7 +188,7 @@ for(u32 i=0;i<header.nTexFlags;i++)
file->read(&tempM2RF,sizeof(RenderFlags)); file->read(&tempM2RF,sizeof(RenderFlags));
M2MRenderFlags.push_back(tempM2RF); M2MRenderFlags.push_back(tempM2RF);
} }
std::cout << "Read "<<M2MRenderFlags.size()<<" Render Flags\n"; DEBUG(std::cout << "Read "<<M2MRenderFlags.size()<<" Render Flags\n");
@ -196,7 +204,7 @@ for(u32 i=0; i<M2MTextureDef.size(); i++)
tempTexFileName.reserve(M2MTextureDef[i].texFileLen + 1); tempTexFileName.reserve(M2MTextureDef[i].texFileLen + 1);
file->seek(M2MTextureDef[i].texFileOfs); file->seek(M2MTextureDef[i].texFileOfs);
file->read((void*)tempTexFileName.c_str(),M2MTextureDef[i].texFileLen); 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()); M2MTextureFiles.push_back(tempTexFileName.c_str());
std::cout<<M2MTextureFiles.size()<<"-"<<M2MTextureFiles[i].c_str()<<"\n"; std::cout<<M2MTextureFiles.size()<<"-"<<M2MTextureFiles[i].c_str()<<"\n";
} }
@ -269,7 +277,7 @@ std::transform(TexName.begin(), TexName.end(), TexName.begin(), tolower);
IMB->getMaterial().setTexture(0,Device->getVideoDriver()->getTexture(TexName.c_str())); IMB->getMaterial().setTexture(0,Device->getVideoDriver()->getTexture(TexName.c_str()));
if(i<M2MRenderFlags.size()) if(i<M2MRenderFlags.size())
{ {
std::cout<<M2MRenderFlags[i].flags<<"--"<<M2MRenderFlags[i].blending<<"\n"; DEBUG(std::cout<<M2MRenderFlags[i].flags<<"--"<<M2MRenderFlags[i].blending<<"\n");
IMB->getMaterial().BackfaceCulling=(M2MRenderFlags[i].flags & 0x04)?false:true; IMB->getMaterial().BackfaceCulling=(M2MRenderFlags[i].flags & 0x04)?false:true;
if(M2MRenderFlags[i].blending==1) if(M2MRenderFlags[i].blending==1)
IMB->getMaterial().MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL; IMB->getMaterial().MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL;

View File

@ -57,6 +57,12 @@ class WorldSession;
class SceneWorld : public Scene class SceneWorld : public Scene
{ {
struct SceneNodeWithGridPos
{
scene::ISceneNode *scenenode;
uint32 gx,gy;
};
public: public:
SceneWorld(PseuGUI *gui); SceneWorld(PseuGUI *gui);
void OnDraw(void); void OnDraw(void);
@ -65,6 +71,7 @@ public:
void UpdateTerrain(void); void UpdateTerrain(void);
void InitTerrain(void); void InitTerrain(void);
void RelocateCamera(void); void RelocateCamera(void);
void UpdateDoodads(void);
WorldPosition GetWorldPosition(void); WorldPosition GetWorldPosition(void);
@ -82,6 +89,7 @@ private:
MapMgr *mapmgr; MapMgr *mapmgr;
IGUIStaticText *debugText; IGUIStaticText *debugText;
bool debugmode; bool debugmode;
std::map<uint32,SceneNodeWithGridPos> _doodads;
}; };

View File

@ -170,8 +170,11 @@ void SceneWorld::OnUpdate(s32 timediff)
eventrecv->mouse.wheel = 2; eventrecv->mouse.wheel = 2;
camera->setHeight( eventrecv->mouse.wheel + terrain->getHeight(camera->getPosition()) ); camera->setHeight( eventrecv->mouse.wheel + terrain->getHeight(camera->getPosition()) );
core::stringw str = L"";
DEBUG(
WorldPosition wp = GetWorldPosition(); WorldPosition wp = GetWorldPosition();
core::stringw str = L"Camera: pitch:"; str += L"Camera: pitch:";
str += camera->getPitch(); str += camera->getPitch();
str += L" c pos:"; str += L" c pos:";
str += camera->getPosition().X; str += camera->getPosition().X;
@ -189,10 +192,24 @@ void SceneWorld::OnUpdate(s32 timediff)
str += L" / "; str += L" / ";
str += (int)terrain->getSectorCount(); str += (int)terrain->getSectorCount();
str += L"\n"; str += L"\n";
str += device->getCursorControl()->isVisible() ? L"Cursor: VISIBLE" : L"Cursor: HIDDEN";
const core::list<scene::ISceneNode*>& nodelist = smgr->getRootSceneNode()->getChildren();
str += L"Scene nodes: total: ";
str += nodelist.getSize();
str += L" visible: ";
u32 vis = 0;
for(core::list<scene::ISceneNode*>::ConstIterator it = nodelist.begin(); it != nodelist.end(); it++)
if((*it)->isVisible())
vis++;
str += vis;
); // END DEBUG;
debugText->setText(str.c_str()); debugText->setText(str.c_str());
gui->domgr.Update(); // iterate over DrawObjects, draw them and clean up gui->domgr.Update(); // iterate over DrawObjects, draw them and clean up
} }
@ -260,11 +277,27 @@ void SceneWorld::UpdateTerrain(void)
return; return;
} }
// something is not good here. we have terrain, but the chunks are read incorrectly. UpdateDoodads(); // drop doodads on maps not loaded anymore. no maptile pointers are dereferenced here, so it can be done before acquiring the mutex
// 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. mutex.acquire(); // prevent other threads from deleting maptiles
// 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 // 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("SceneWorld: Displaying MapTiles near grids x:%u y:%u",mapmgr->GetGridX(),mapmgr->GetGridY());
logdebug("Loaded maps: %u: %s",mapmgr->GetLoadedMapsCount(), mapmgr->GetLoadedTilesString().c_str()); logdebug("Loaded maps: %u: %s",mapmgr->GetLoadedMapsCount(), mapmgr->GetLoadedTilesString().c_str());
for(s32 tiley = 0; tiley < 3; tiley++) for(s32 tiley = 0; tiley < 3; tiley++)
@ -296,14 +329,23 @@ void SceneWorld::UpdateTerrain(void)
for(uint32 i = 0; i < maptile->GetDoodadCount(); i++) for(uint32 i = 0; i < maptile->GetDoodadCount(); i++)
{ {
Doodad *d = maptile->GetDoodad(i); Doodad *d = maptile->GetDoodad(i);
scene::IAnimatedMesh *mesh = smgr->getMesh(d->model.c_str()); if(_doodads.find(d->uniqueid) == _doodads.end()) // only add doodads that dont exist yet
if(mesh)
{ {
scene::ISceneNode *doodad = smgr->addAnimatedMeshSceneNode(mesh); scene::IAnimatedMesh *mesh = smgr->getMesh(d->model.c_str());
if(doodad) if(mesh)
{ {
doodad->setPosition(core::vector3df(-d->x, d->z, -d->y)); scene::ISceneNode *doodad = smgr->addAnimatedMeshSceneNode(mesh);
doodad->setRotation(core::vector3df(-d->ox, -d->oy-90, -d->oz)); // +270 solves M2 models lying on the side 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)); 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..."); logdebug("SceneWorld: Smoothing terrain normals...");
terrain->smoothNormals(); terrain->smoothNormals();
@ -366,6 +391,24 @@ void SceneWorld::UpdateTerrain(void)
RelocateCamera(); RelocateCamera();
} }
// drop unneeded doodads from the map
void SceneWorld::UpdateDoodads(void)
{
uint32 s = _doodads.size();
std::set<uint32> 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<uint32,SceneNodeWithGridPos>::iterator it = _doodads.begin(); it != _doodads.end(); it++ )
if(!mapmgr->GetTile(it->second.gx, it->second.gy))
tmp.insert(it->first);
for(std::set<uint32>::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) void SceneWorld::RelocateCamera(void)
{ {

View File

@ -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.oy = mddf.b - 90.0f; // wowdev states Y=B-90, but this doesnt really look as expected...
d.oz = -mddf.a; d.oz = -mddf.a;
d.flags = mddf.flags; d.flags = mddf.flags;
d.uniqueid = mddf.uniqueid;
d.model = std::string("./data/model/") + NormalizeFilename(_PathToFileName(adt->_models[mddf.id])); 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" // 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); memcpy(&d.model[0] + d.model.size() - 3, "m2\0", 3);

View File

@ -27,6 +27,7 @@ public:
struct Doodad struct Doodad
{ {
uint32 uniqueid;
float x,y,z,ox,oy,oz,scale; float x,y,z,ox,oy,oz,scale;
uint16 flags; uint16 flags;
std::string model; std::string model;