* 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 "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: "<<file->getFileName()<<"\n";
DEBUG(std::cout<<"No such file: "<<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:"<<fileId.c_str()<<"\n";
DEBUG(std::cout << "Header doesn't match, this is no BLP file\n");
DEBUG(std::cout << "Expected:BLP2 Got:"<<fileId.c_str()<<"\n");
return false;
}
}

View File

@ -1,6 +1,11 @@
#include <iostream>
#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;i<header.nVertices;i++)
file->read(&tempM2MVert,sizeof(ModelVertex));
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
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";
logger->log("Using View 0 for all further operations",ELL_INFORMATION);
std::cout<<"This View has "<<M2MViews[0].nSub<<" Submeshes\n";
DEBUG(logger->log("Using View 0 for all further operations",ELL_INFORMATION));
DEBUG(std::cout<<"This View has "<<M2MViews[0].nSub<<" Submeshes\n");
//Vertex indices of a specific view.Local to View 0
if(M2MIndices.size()>0)
@ -93,7 +101,7 @@ for(u32 i =0;i<M2MViews[0].nIndex;i++)
file->read(&tempM2Index,sizeof(u16));
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
@ -107,7 +115,7 @@ for(u32 i =0;i<M2MViews[0].nTris;i++)
file->read(&tempM2Triangle,sizeof(u16));
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
if(M2MSubmeshes.size()>0)
@ -121,7 +129,7 @@ for(u32 i =0;i<M2MViews[0].nSub;i++)
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 << "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
TextureUnit tempM2TexUnit;
@ -135,7 +143,7 @@ for(u32 i=0;i<M2MViews[0].nTex;i++)
file->read(&tempM2TexUnit,sizeof(TextureUnit));
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));
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
TextureDefinition tempM2TexDef;
@ -166,7 +174,7 @@ for(u32 i=0;i<header.nTextures;i++)
file->read(&tempM2TexDef,sizeof(TextureDefinition));
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
RenderFlags tempM2RF;
@ -180,7 +188,7 @@ for(u32 i=0;i<header.nTexFlags;i++)
file->read(&tempM2RF,sizeof(RenderFlags));
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);
file->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<<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()));
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;
if(M2MRenderFlags[i].blending==1)
IMB->getMaterial().MaterialType=video::EMT_TRANSPARENT_ALPHA_CHANNEL;

View File

@ -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<uint32,SceneNodeWithGridPos> _doodads;
};

View File

@ -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<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());
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<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)
{

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.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);

View File

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