Commit bf5890e8 authored by cutealien's avatar cutealien

- Add support for bsp brush entities. Written by Hendu.


git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@3991 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 99cfad9d
Changes in 1.8 (??.??.2011) Changes in 1.8 (??.??.2011)
- Add support for bsp brush entities. Written by Hendu.
- Add IGUIComboBox::setMaxSelectionRows and IGUIComboBox::getMaxSelectionRows - Add IGUIComboBox::setMaxSelectionRows and IGUIComboBox::getMaxSelectionRows
- Scenemanager switches from type ESNT_UNKNOWN to type ESNT_SCENE_MANAGER. - Scenemanager switches from type ESNT_UNKNOWN to type ESNT_SCENE_MANAGER.
......
...@@ -13,9 +13,7 @@ namespace irr ...@@ -13,9 +13,7 @@ namespace irr
namespace scene namespace scene
{ {
//! Interface for a Mesh which can be loaded directly from a Quake3 .bsp-file. //! Interface for a Mesh which can be loaded directly from a Quake3 .bsp-file.
/** The Mesh tries to load all textures of the map. There are currently /** The Mesh tries to load all textures of the map.*/
no additional methods in this class, but maybe there will be some in later
releases if there are feature requests. */
class IQ3LevelMesh : public IAnimatedMesh class IQ3LevelMesh : public IAnimatedMesh
{ {
public: public:
...@@ -31,6 +29,14 @@ namespace scene ...@@ -31,6 +29,14 @@ namespace scene
//! get's an interface to the entities //! get's an interface to the entities
virtual quake3::tQ3EntityList& getEntityList() = 0; virtual quake3::tQ3EntityList& getEntityList() = 0;
//! returns the requested brush entity
/** \param num The number from the model key of the entity.
Use this interface if you parse the entities yourself.*/
virtual IMesh* getBrushEntityMesh(s32 num) const = 0;
//! returns the requested brush entity
virtual IMesh* getBrushEntityMesh(quake3::IEntity &ent) const = 0;
}; };
} // end namespace scene } // end namespace scene
......
...@@ -28,9 +28,10 @@ namespace scene ...@@ -28,9 +28,10 @@ namespace scene
CQ3LevelMesh::CQ3LevelMesh(io::IFileSystem* fs, scene::ISceneManager* smgr, CQ3LevelMesh::CQ3LevelMesh(io::IFileSystem* fs, scene::ISceneManager* smgr,
const Q3LevelLoadParameter &loadParam) const Q3LevelLoadParameter &loadParam)
: LoadParam(loadParam), Textures(0), NumTextures(0), LightMaps(0), NumLightMaps(0), : LoadParam(loadParam), Textures(0), NumTextures(0), LightMaps(0), NumLightMaps(0),
Vertices(0), NumVertices(0), Faces(0), NumFaces(0), Planes(0), NumPlanes(0), Vertices(0), NumVertices(0), Faces(0), NumFaces(0), Models(0), NumModels(0),
Nodes(0), NumNodes(0), Leafs(0), NumLeafs(0), LeafFaces(0), NumLeafFaces(0), Planes(0), NumPlanes(0), Nodes(0), NumNodes(0), Leafs(0), NumLeafs(0),
MeshVerts(0), NumMeshVerts(0), Brushes(0), NumBrushes(0), FileSystem(fs), SceneManager(smgr) LeafFaces(0), NumLeafFaces(0), MeshVerts(0), NumMeshVerts(0),
Brushes(0), NumBrushes(0), BrushEntities(0), FileSystem(fs), SceneManager(smgr)
{ {
#ifdef _DEBUG #ifdef _DEBUG
IReferenceCounted::setDebugName("CQ3LevelMesh"); IReferenceCounted::setDebugName("CQ3LevelMesh");
...@@ -64,7 +65,9 @@ CQ3LevelMesh::~CQ3LevelMesh() ...@@ -64,7 +65,9 @@ CQ3LevelMesh::~CQ3LevelMesh()
if (FileSystem) if (FileSystem)
FileSystem->drop(); FileSystem->drop();
for ( s32 i = 0; i!= E_Q3_MESH_SIZE; ++i ) s32 i;
for ( i = 0; i!= E_Q3_MESH_SIZE; ++i )
{ {
if ( Mesh[i] ) if ( Mesh[i] )
{ {
...@@ -73,6 +76,12 @@ CQ3LevelMesh::~CQ3LevelMesh() ...@@ -73,6 +76,12 @@ CQ3LevelMesh::~CQ3LevelMesh()
} }
} }
for ( i = 1; i < NumModels; i++ )
{
BrushEntities[i]->drop();
}
delete [] BrushEntities; BrushEntities = 0;
ReleaseShader(); ReleaseShader();
ReleaseEntity(); ReleaseEntity();
} }
...@@ -126,11 +135,6 @@ bool CQ3LevelMesh::loadFile(io::IReadFile* file) ...@@ -126,11 +135,6 @@ bool CQ3LevelMesh::loadFile(io::IReadFile* file)
} }
} }
for ( i = 0; i!= E_Q3_MESH_SIZE; ++i )
{
Mesh[i] = new SMesh();
}
ReleaseEntity(); ReleaseEntity();
// load everything // load everything
...@@ -170,6 +174,7 @@ void CQ3LevelMesh::cleanLoader () ...@@ -170,6 +174,7 @@ void CQ3LevelMesh::cleanLoader ()
delete [] LightMaps; LightMaps = 0; delete [] LightMaps; LightMaps = 0;
delete [] Vertices; Vertices = 0; delete [] Vertices; Vertices = 0;
delete [] Faces; Faces = 0; delete [] Faces; Faces = 0;
delete [] Models; Models = 0;
delete [] Planes; Planes = 0; delete [] Planes; Planes = 0;
delete [] Nodes; Nodes = 0; delete [] Nodes; Nodes = 0;
delete [] Leafs; Leafs = 0; delete [] Leafs; Leafs = 0;
...@@ -388,15 +393,31 @@ void CQ3LevelMesh::loadFogs(tBSPLump* l, io::IReadFile* file) ...@@ -388,15 +393,31 @@ void CQ3LevelMesh::loadFogs(tBSPLump* l, io::IReadFile* file)
*/ */
void CQ3LevelMesh::loadModels(tBSPLump* l, io::IReadFile* file) void CQ3LevelMesh::loadModels(tBSPLump* l, io::IReadFile* file)
{ {
u32 files = l->length / sizeof(tBSPModel); NumModels = l->length / sizeof(tBSPModel);
Models = new tBSPModel[NumModels];
file->seek( l->offset ); file->seek( l->offset );
file->read(Models, l->length);
tBSPModel def; if ( LoadParam.swapHeader )
for ( u32 i = 0; i!= files; ++i )
{ {
file->read( &def, sizeof( def ) ); for ( s32 i = 0; i < NumModels; i++)
{
Models[i].min[0] = os::Byteswap::byteswap(Models[i].min[0]);
Models[i].min[1] = os::Byteswap::byteswap(Models[i].min[1]);
Models[i].min[2] = os::Byteswap::byteswap(Models[i].min[2]);
Models[i].max[0] = os::Byteswap::byteswap(Models[i].max[0]);
Models[i].max[1] = os::Byteswap::byteswap(Models[i].max[1]);
Models[i].max[2] = os::Byteswap::byteswap(Models[i].max[2]);
Models[i].faceIndex = os::Byteswap::byteswap(Models[i].faceIndex);
Models[i].numOfFaces = os::Byteswap::byteswap(Models[i].numOfFaces);
Models[i].brushIndex = os::Byteswap::byteswap(Models[i].brushIndex);
Models[i].numOfBrushes = os::Byteswap::byteswap(Models[i].numOfBrushes);
}
} }
BrushEntities = new SMesh*[NumModels];
} }
/*! /*!
...@@ -818,37 +839,20 @@ s32 CQ3LevelMesh::setShaderMaterial( video::SMaterial &material, const tBSPFace ...@@ -818,37 +839,20 @@ s32 CQ3LevelMesh::setShaderMaterial( video::SMaterial &material, const tBSPFace
#endif #endif
} }
/*!
*/
void CQ3LevelMesh::solveTJunction()
{
}
/*! /*!
constructs a mesh from the quake 3 level file. Internal function to build a mesh.
*/ */
void CQ3LevelMesh::constructMesh() scene::SMesh** CQ3LevelMesh::buildMesh(s32 num)
{ {
if ( LoadParam.verbose > 0 ) scene::SMesh** newmesh = new SMesh *[quake3::E_Q3_MESH_SIZE];
{
LoadParam.startTime = os::Timer::getRealTime();
if ( LoadParam.verbose > 1 ) s32 i, j, k,s;
{
snprintf( buf, sizeof ( buf ),
"quake3::constructMesh start to create %d faces, %d vertices,%d mesh vertices",
NumFaces,
NumVertices,
NumMeshVerts
);
os::Printer::log(buf, ELL_INFORMATION);
}
for (i = 0; i < E_Q3_MESH_SIZE; i++)
{
newmesh[i] = new SMesh();
} }
s32 i, j, k,s;
s32 *index; s32 *index;
video::S3DVertex2TCoords temp[3]; video::S3DVertex2TCoords temp[3];
...@@ -858,7 +862,7 @@ void CQ3LevelMesh::constructMesh() ...@@ -858,7 +862,7 @@ void CQ3LevelMesh::constructMesh()
SToBuffer item [ E_Q3_MESH_SIZE ]; SToBuffer item [ E_Q3_MESH_SIZE ];
u32 itemSize; u32 itemSize;
for ( i=0; i < NumFaces; ++i) for (i = Models[num].faceIndex; i < Models[num].numOfFaces + Models[num].faceIndex; ++i)
{ {
const tBSPFace * face = Faces + i; const tBSPFace * face = Faces + i;
...@@ -880,36 +884,34 @@ void CQ3LevelMesh::constructMesh() ...@@ -880,36 +884,34 @@ void CQ3LevelMesh::constructMesh()
case 1: // normal polygons case 1: // normal polygons
case 2: // patches case 2: // patches
case 3: // meshes case 3: // meshes
if ( 0 == shader )
{ {
if ( 0 == shader ) if ( LoadParam.cleanUnResolvedMeshes || material.getTexture(0) )
{ {
if ( LoadParam.cleanUnResolvedMeshes || material.getTexture(0) ) item[itemSize].takeVertexColor = 1;
{ item[itemSize].index = E_Q3_MESH_GEOMETRY;
item[itemSize].takeVertexColor = 1; itemSize += 1;
item[itemSize].index = E_Q3_MESH_GEOMETRY;
itemSize += 1;
}
else
{
item[itemSize].takeVertexColor = 1;
item[itemSize].index = E_Q3_MESH_UNRESOLVED;
itemSize += 1;
}
} }
else else
{ {
item[itemSize].takeVertexColor = 1; item[itemSize].takeVertexColor = 1;
item[itemSize].index = E_Q3_MESH_ITEMS; item[itemSize].index = E_Q3_MESH_UNRESOLVED;
itemSize += 1; itemSize += 1;
} }
}
} break; else
{
item[itemSize].takeVertexColor = 1;
item[itemSize].index = E_Q3_MESH_ITEMS;
itemSize += 1;
}
break;
case 4: // billboards case 4: // billboards
//item[itemSize].takeVertexColor = 1; //item[itemSize].takeVertexColor = 1;
//item[itemSize].index = E_Q3_MESH_ITEMS; //item[itemSize].index = E_Q3_MESH_ITEMS;
//itemSize += 1; //itemSize += 1;
break; break;
} }
...@@ -932,7 +934,7 @@ void CQ3LevelMesh::constructMesh() ...@@ -932,7 +934,7 @@ void CQ3LevelMesh::constructMesh()
#if 0 #if 0
// there are lightmapsids and textureid with -1 // there are lightmapsids and textureid with -1
const s32 tmp_index = ((Faces[i].lightmapID+1) * (NumTextures+1)) + (Faces[i].textureID+1); const s32 tmp_index = ((Faces[i].lightmapID+1) * (NumTextures+1)) + (Faces[i].textureID+1);
buffer = (SMeshBufferLightMap*) Mesh[E_Q3_MESH_GEOMETRY]->getMeshBuffer(tmp_index); buffer = (SMeshBufferLightMap*) newmesh[E_Q3_MESH_GEOMETRY]->getMeshBuffer(tmp_index);
buffer->setHardwareMappingHint ( EHM_STATIC ); buffer->setHardwareMappingHint ( EHM_STATIC );
buffer->getMaterial() = material; buffer->getMaterial() = material;
#endif #endif
...@@ -945,7 +947,7 @@ void CQ3LevelMesh::constructMesh() ...@@ -945,7 +947,7 @@ void CQ3LevelMesh::constructMesh()
if ( LoadParam.mergeShaderBuffer == 1 ) if ( LoadParam.mergeShaderBuffer == 1 )
{ {
// combine // combine
buffer = (SMeshBufferLightMap*) Mesh[ item[g].index ]->getMeshBuffer( buffer = (SMeshBufferLightMap*) newmesh[ item[g].index ]->getMeshBuffer(
item[g].index != E_Q3_MESH_FOG ? material : material2 ); item[g].index != E_Q3_MESH_FOG ? material : material2 );
} }
...@@ -953,7 +955,7 @@ void CQ3LevelMesh::constructMesh() ...@@ -953,7 +955,7 @@ void CQ3LevelMesh::constructMesh()
if ( 0 == buffer ) if ( 0 == buffer )
{ {
buffer = new scene::SMeshBufferLightMap(); buffer = new scene::SMeshBufferLightMap();
Mesh[ item[g].index ]->addMeshBuffer( buffer ); newmesh[ item[g].index ]->addMeshBuffer( buffer );
buffer->drop(); buffer->drop();
buffer->getMaterial() = item[g].index != E_Q3_MESH_FOG ? material : material2; buffer->getMaterial() = item[g].index != E_Q3_MESH_FOG ? material : material2;
if ( item[g].index == E_Q3_MESH_GEOMETRY ) if ( item[g].index == E_Q3_MESH_GEOMETRY )
...@@ -967,10 +969,10 @@ void CQ3LevelMesh::constructMesh() ...@@ -967,10 +969,10 @@ void CQ3LevelMesh::constructMesh()
case 4: // billboards case 4: // billboards
break; break;
case 2: // patches case 2: // patches
createCurvedSurface_bezier( buffer, i, createCurvedSurface_bezier( buffer, i,
LoadParam.patchTesselation, LoadParam.patchTesselation,
item[g].takeVertexColor item[g].takeVertexColor
); );
break; break;
case 1: // normal polygons case 1: // normal polygons
...@@ -1018,6 +1020,63 @@ void CQ3LevelMesh::constructMesh() ...@@ -1018,6 +1020,63 @@ void CQ3LevelMesh::constructMesh()
} }
} }
return newmesh;
}
/*!
*/
void CQ3LevelMesh::solveTJunction()
{
}
/*!
constructs a mesh from the quake 3 level file.
*/
void CQ3LevelMesh::constructMesh()
{
if ( LoadParam.verbose > 0 )
{
LoadParam.startTime = os::Timer::getRealTime();
if ( LoadParam.verbose > 1 )
{
snprintf( buf, sizeof ( buf ),
"quake3::constructMesh start to create %d faces, %d vertices,%d mesh vertices",
NumFaces,
NumVertices,
NumMeshVerts
);
os::Printer::log(buf, ELL_INFORMATION);
}
}
s32 i, j;
// First the main level
SMesh **tmp = buildMesh(0);
for (i = 0; i < E_Q3_MESH_SIZE; i++)
{
Mesh[i] = tmp[i];
}
delete [] tmp;
// Then the brush entities
for (i = 1; i < NumModels; i++)
{
tmp = buildMesh(i);
BrushEntities[i] = tmp[0];
// We only care about the main geometry here
for (j = 1; j < E_Q3_MESH_SIZE; j++)
{
tmp[j]->drop();
}
delete [] tmp;
}
if ( LoadParam.verbose > 0 ) if ( LoadParam.verbose > 0 )
{ {
LoadParam.endTime = os::Timer::getRealTime(); LoadParam.endTime = os::Timer::getRealTime();
...@@ -1401,6 +1460,35 @@ tQ3EntityList & CQ3LevelMesh::getEntityList() ...@@ -1401,6 +1460,35 @@ tQ3EntityList & CQ3LevelMesh::getEntityList()
return Entity; return Entity;
} }
//! returns the requested brush entity
IMesh* CQ3LevelMesh::getBrushEntityMesh(s32 num) const
{
if (num < 1 || num >= NumModels)
return 0;
return BrushEntities[num];
}
//! returns the requested brush entity
IMesh* CQ3LevelMesh::getBrushEntityMesh(quake3::IEntity &ent) const
{
// This is a helper function to parse the entity,
// so you don't have to.
s32 num;
const quake3::SVarGroup* group = ent.getGroup(1);
const core::stringc& modnum = group->get("model");
if (!group->isDefined("model"))
return 0;
const char *temp = modnum.c_str() + 1; // We skip the first character.
num = core::strtol10(temp);
return getBrushEntityMesh(num);
}
/*! /*!
*/ */
...@@ -1681,94 +1769,105 @@ void CQ3LevelMesh::cleanMeshes() ...@@ -1681,94 +1769,105 @@ void CQ3LevelMesh::cleanMeshes()
if ( 0 == LoadParam.cleanUnResolvedMeshes ) if ( 0 == LoadParam.cleanUnResolvedMeshes )
return; return;
s32 i;
// First the main level
for (i = 0; i < E_Q3_MESH_SIZE; i++)
{
bool texture0important = ( i == 0 );
cleanMesh(Mesh[i], texture0important);
}
// Then the brush entities
for (i = 1; i < NumModels; i++)
{
cleanMesh(BrushEntities[i], true);
}
}
void CQ3LevelMesh::cleanMesh(SMesh *m, const bool texture0important)
{
// delete all buffers without geometry in it. // delete all buffers without geometry in it.
u32 run = 0; u32 run = 0;
u32 remove = 0; u32 remove = 0;
irr::scene::SMesh *m;
IMeshBuffer *b; IMeshBuffer *b;
for ( u32 g = 0; g < E_Q3_MESH_SIZE; ++g )
{
bool texture0important = ( g == 0 );
run = 0; run = 0;
remove = 0; remove = 0;
m = Mesh[g];
if ( LoadParam.verbose > 0 ) if ( LoadParam.verbose > 0 )
{
LoadParam.startTime = os::Timer::getRealTime();
if ( LoadParam.verbose > 1 )
{ {
LoadParam.startTime = os::Timer::getRealTime(); snprintf( buf, sizeof ( buf ),
if ( LoadParam.verbose > 1 ) "quake3::cleanMeshes start for %d meshes",
{ m->MeshBuffers.size()
snprintf( buf, sizeof ( buf ), );
"quake3::cleanMeshes%d start for %d meshes", os::Printer::log(buf, ELL_INFORMATION);
g,
m->MeshBuffers.size()
);
os::Printer::log(buf, ELL_INFORMATION);
}
} }
}
u32 i = 0; u32 i = 0;
s32 blockstart = -1; s32 blockstart = -1;
s32 blockcount; s32 blockcount;
while( i < m->MeshBuffers.size()) while( i < m->MeshBuffers.size())
{ {
run += 1; run += 1;
b = m->MeshBuffers[i]; b = m->MeshBuffers[i];
if ( b->getVertexCount() == 0 || b->getIndexCount() == 0 || if ( b->getVertexCount() == 0 || b->getIndexCount() == 0 ||
( texture0important && b->getMaterial().getTexture(0) == 0 ) ( texture0important && b->getMaterial().getTexture(0) == 0 )
) )
{
if ( blockstart < 0 )
{ {
if ( blockstart < 0 ) blockstart = i;
{ blockcount = 0;
blockstart = i;
blockcount = 0;
}
blockcount += 1;
i += 1;
// delete Meshbuffer
i -= 1;
remove += 1;
b->drop();
m->MeshBuffers.erase(i);
} }
else blockcount += 1;
i += 1;
// delete Meshbuffer
i -= 1;
remove += 1;
b->drop();
m->MeshBuffers.erase(i);
}
else
{
// clean blockwise
if ( blockstart >= 0 )
{ {
// clean blockwise if ( LoadParam.verbose > 1 )
if ( blockstart >= 0 )
{ {
if ( LoadParam.verbose > 1 ) snprintf( buf, sizeof ( buf ),
{ "quake3::cleanMeshes cleaning mesh %d %d size",
snprintf( buf, sizeof ( buf ), blockstart,
"quake3::cleanMeshes%d cleaning mesh %d %d size", blockcount
g, );
blockstart, os::Printer::log(buf, ELL_INFORMATION);
blockcount
);
os::Printer::log(buf, ELL_INFORMATION);
}
blockstart = -1;
} }
i += 1; blockstart = -1;
} }
i += 1;
} }
}
if ( LoadParam.verbose > 0 ) if ( LoadParam.verbose > 0 )
{ {
LoadParam.endTime = os::Timer::getRealTime(); LoadParam.endTime = os::Timer::getRealTime();
snprintf( buf, sizeof ( buf ), snprintf( buf, sizeof ( buf ),
"quake3::cleanMeshes%d needed %04d ms to clean %d of %d meshes", "quake3::cleanMeshes needed %04d ms to clean %d of %d meshes",
g, LoadParam.endTime - LoadParam.startTime,
LoadParam.endTime - LoadParam.startTime, remove,
remove, run
run );
); os::Printer::log(buf, ELL_INFORMATION);
os::Printer::log(buf, ELL_INFORMATION);
}
} }
} }
...@@ -1791,8 +1890,10 @@ void CQ3LevelMesh::calcBoundingBoxes() ...@@ -1791,8 +1890,10 @@ void CQ3LevelMesh::calcBoundingBoxes()
} }
} }
s32 g;
// create bounding box // create bounding box
for ( u32 g = 0; g != E_Q3_MESH_SIZE; ++g ) for ( g = 0; g != E_Q3_MESH_SIZE; ++g )
{ {
for ( u32 j=0; j < Mesh[g]->MeshBuffers.size(); ++j) for ( u32 j=0; j < Mesh[g]->MeshBuffers.size(); ++j)
{ {
...@@ -1805,6 +1906,17 @@ void CQ3LevelMesh::calcBoundingBoxes() ...@@ -1805,6 +1906,17 @@ void CQ3LevelMesh::calcBoundingBoxes()
Mesh[0]->BoundingBox.addInternalBox(Mesh[g]->getBoundingBox()); Mesh[0]->BoundingBox.addInternalBox(Mesh[g]->getBoundingBox());
} }
for (g = 1; g < NumModels; g++)
{
for ( u32 j=0; j < BrushEntities[g]->MeshBuffers.size(); ++j)
{
((SMeshBufferLightMap*)BrushEntities[g]->MeshBuffers[j])->
recalculateBoundingBox();
}
BrushEntities[g]->recalculateBoundingBox();
}
if ( LoadParam.verbose > 0 ) if ( LoadParam.verbose > 0 )
{ {
LoadParam.endTime = os::Timer::getRealTime(); LoadParam.endTime = os::Timer::getRealTime();
......
...@@ -69,6 +69,11 @@ namespace scene ...@@ -69,6 +69,11 @@ namespace scene
//! get's an interface to the entities //! get's an interface to the entities
virtual quake3::tQ3EntityList & getEntityList(); virtual quake3::tQ3EntityList & getEntityList();
//! returns the requested brush entity
virtual IMesh* getBrushEntityMesh(s32 num) const;
//! returns the requested brush entity
virtual IMesh* getBrushEntityMesh(quake3::IEntity &ent) const;
//Link to held meshes? ... //Link to held meshes? ...
...@@ -116,6 +121,7 @@ namespace scene ...@@ -116,6 +121,7 @@ namespace scene
void constructMesh(); void constructMesh();
void solveTJunction(); void solveTJunction();
void loadTextures(); void loadTextures();
scene::SMesh** buildMesh(s32 num);
struct STexShader struct STexShader
{ {
...@@ -372,6 +378,9 @@ namespace scene ...@@ -372,6 +378,9 @@ namespace scene
tBSPFace* Faces; tBSPFace* Faces;
s32 NumFaces; s32 NumFaces;
tBSPModel* Models;
s32 NumModels;
tBSPPlane* Planes; tBSPPlane* Planes;
s32 NumPlanes; s32 NumPlanes;
...@@ -390,6 +399,8 @@ namespace scene ...@@ -390,6 +399,8 @@ namespace scene
tBSPBrush* Brushes; tBSPBrush* Brushes;
s32 NumBrushes; s32 NumBrushes;
scene::SMesh** BrushEntities;
scene::SMesh* Mesh[quake3::E_Q3_MESH_SIZE]; scene::SMesh* Mesh[quake3::E_Q3_MESH_SIZE];
video::IVideoDriver* Driver; video::IVideoDriver* Driver;
core::stringc LevelName; core::stringc LevelName;
...@@ -452,6 +463,7 @@ namespace scene ...@@ -452,6 +463,7 @@ namespace scene
}; };
void cleanMeshes(); void cleanMeshes();
void cleanMesh(SMesh *m, const bool texture0important = false);
void cleanLoader (); void cleanLoader ();
void calcBoundingBoxes(); void calcBoundingBoxes();
c8 buf[128]; c8 buf[128];
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment