Commit be924b27 authored by hybrid's avatar hybrid

Fixed core dumps and loading errors. Some speedup and simplifications.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1629 dfc29bdd-3216-0410-991c-e03cc46cb475
parent f180825e
...@@ -16,6 +16,11 @@ ...@@ -16,6 +16,11 @@
#include "IrrCompileConfig.h" #include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_DMF_LOADER_ #ifdef _IRR_COMPILE_WITH_DMF_LOADER_
#ifdef _DEBUG
#define _IRR_DMF_DEBUG_
#include "os.h"
#endif
#include "CDMFLoader.h" #include "CDMFLoader.h"
#include "ISceneManager.h" #include "ISceneManager.h"
#include "IAttributes.h" #include "IAttributes.h"
...@@ -41,37 +46,6 @@ CDMFLoader::CDMFLoader(ISceneManager* smgr, io::IFileSystem* filesys) ...@@ -41,37 +46,6 @@ CDMFLoader::CDMFLoader(ISceneManager* smgr, io::IFileSystem* filesys)
} }
/** Given first three points of a face, returns a face normal*/
void CDMFLoader::GetFaceNormal( f32 a[3], //First point
f32 b[3], //Second point
f32 c[3], //Third point
f32 out[3]) //Normal computed
{
f32 v1[3], v2[3];
v1[0] = a[0] - b[0];
v1[1] = a[1] - b[1];
v1[2] = a[2] - b[2];
v2[0] = b[0] - c[0];
v2[1] = b[1] - c[1];
v2[2] = b[2] - c[2];
out[0] = (v1[1] * v2[2]) - (v1[2] * v2[1]);
out[1] = (v1[2] * v2[0]) - (v1[0] * v2[2]);
out[2] = (v1[0] * v2[1]) - (v1[1] * v2[0]);
f32 dist = (f32)sqrtf((out[0] * out[0]) + (out[1] * out[1]) + (out[2] * out[2]));
if (dist == 0.0f)
dist = 0.001f;
out[0] /= dist;
out[1] /= dist;
out[2] /= dist;
}
/**Creates/loads an animated mesh from the file. /**Creates/loads an animated mesh from the file.
\return Pointer to the created mesh. Returns 0 if loading failed. \return Pointer to the created mesh. Returns 0 if loading failed.
If you no longer need the mesh, you should call IAnimatedMesh::drop(). If you no longer need the mesh, you should call IAnimatedMesh::drop().
...@@ -101,20 +75,28 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -101,20 +75,28 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
SceneMgr->setAmbientLight(header.dmfAmbient); SceneMgr->setAmbientLight(header.dmfAmbient);
//let's create the correct number of materials, vertices and faces //let's create the correct number of materials, vertices and faces
dmfMaterial *materiali=new dmfMaterial[header.numMaterials]; core::array<dmfMaterial> materiali;
dmfVert *verts=new dmfVert[header.numVertices]; dmfVert *verts=new dmfVert[header.numVertices];
dmfFace *faces=new dmfFace[header.numFaces]; dmfFace *faces=new dmfFace[header.numFaces];
//let's get the materials //let's get the materials
bool use_mat_dirs=false; const bool use_mat_dirs=SceneMgr->getParameters()->getAttributeAsBool(DMF_USE_MATERIALS_DIRS);
use_mat_dirs=SceneMgr->getParameters()->getAttributeAsBool(DMF_USE_MATERIALS_DIRS);
GetDMFMaterials(dmfRawFile , materiali,header.numMaterials,use_mat_dirs); #ifdef _IRR_DMF_DEBUG_
os::Printer::log("Loading materials", core::stringc(header.numMaterials).c_str());
#endif
GetDMFMaterials(dmfRawFile, materiali, header.numMaterials, use_mat_dirs);
//let's get vertices and faces //let's get vertices and faces
GetDMFVerticesFaces(dmfRawFile, verts,faces); #ifdef _IRR_DMF_DEBUG_
os::Printer::log("Loading geometry");
#endif
GetDMFVerticesFaces(dmfRawFile, verts, faces);
//create a meshbuffer for each material, then we'll remove empty ones //create a meshbuffer for each material, then we'll remove empty ones
#ifdef _IRR_DMF_DEBUG_
os::Printer::log("Creating meshbuffers.");
#endif
for (i=0; i<header.numMaterials; i++) for (i=0; i<header.numMaterials; i++)
{ {
//create a new SMeshBufferLightMap for each material //create a new SMeshBufferLightMap for each material
...@@ -127,38 +109,38 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -127,38 +109,38 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
} }
// Build the mesh buffers // Build the mesh buffers
#ifdef _IRR_DMF_DEBUG_
os::Printer::log("Adding geometry to mesh.");
#endif
for (i = 0; i < header.numFaces; i++) for (i = 0; i < header.numFaces; i++)
{ {
#ifdef _IRR_DMF_DEBUG_
os::Printer::log("Polygon with #vertices", core::stringc(faces[i].numVerts).c_str());
#endif
if (faces[i].numVerts < 3) if (faces[i].numVerts < 3)
continue; continue;
f32 normal[3]; const core::vector3df normal =
core::triangle3df(verts[faces[i].firstVert].pos,
GetFaceNormal(verts[faces[i].firstVert].pos, verts[faces[i].firstVert+1].pos,
verts[faces[i].firstVert+1].pos, verts[faces[i].firstVert+2].pos, normal); verts[faces[i].firstVert+2].pos).getNormal().normalize();
SMeshBufferLightMap * meshBuffer = (SMeshBufferLightMap*)mesh->getMeshBuffer( SMeshBufferLightMap * meshBuffer = (SMeshBufferLightMap*)mesh->getMeshBuffer(
faces[i].materialID); faces[i].materialID);
u32 base = meshBuffer->Vertices.size(); const u32 base = meshBuffer->Vertices.size();
// Add this face's verts // Add this face's verts
u32 v; u32 v;
for (v = 0; v < faces[i].numVerts; v++) for (v = 0; v < faces[i].numVerts; v++)
{ {
dmfVert * vv = &verts[faces[i].firstVert + v]; const dmfVert& vv = verts[faces[i].firstVert + v];
video::S3DVertex2TCoords vert(vv->pos[0], vv->pos[1], vv->pos[2], video::S3DVertex2TCoords vert(vv.pos,
normal[0], normal[1], normal[2], video::SColor(0,255,255,255), 0.0f, 0.0f); normal, video::SColor(255,255,255,255), vv.tc, vv.lc);
if ( materiali[faces[i].materialID].textureBlend==4 && if (materiali[faces[i].materialID].textureBlend==4 &&
SceneMgr->getParameters()->getAttributeAsBool(DMF_FLIP_ALPHA_TEXTURES)) SceneMgr->getParameters()->getAttributeAsBool(DMF_FLIP_ALPHA_TEXTURES))
{ {
vert.TCoords.set(vv->tc[0],-vv->tc[1]); vert.TCoords.set(vv.tc.X,-vv.tc.Y);
vert.TCoords2.set(vv->lc[0],vv->lc[1]);
}
else
{
vert.TCoords.set(vv->tc[0], vv->tc[1]);
vert.TCoords2.set(vv->lc[0], vv->lc[1]);
} }
meshBuffer->Vertices.push_back(vert); meshBuffer->Vertices.push_back(vert);
} }
...@@ -170,18 +152,18 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -170,18 +152,18 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
u32 h = faces[i].numVerts - 1, l = 0, c; // High, Low, Center u32 h = faces[i].numVerts - 1, l = 0, c; // High, Low, Center
for (v = 0; v < faces[i].numVerts - 2; v++) for (v = 0; v < faces[i].numVerts - 2; v++)
{ {
if (v & 1) if (v & 1) // odd
c = h - 1; c = h - 1;
else else // even
c = l + 1; c = l + 1;
meshBuffer->Indices.push_back(base + h); meshBuffer->Indices.push_back(base + h);
meshBuffer->Indices.push_back(base + l); meshBuffer->Indices.push_back(base + l);
meshBuffer->Indices.push_back(base + c); meshBuffer->Indices.push_back(base + c);
if (v & 1) if (v & 1) // odd
h--; h--;
else else // even
l++; l++;
} }
} }
...@@ -189,6 +171,9 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -189,6 +171,9 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
//load textures and lightmaps in materials. //load textures and lightmaps in materials.
//don't worry if you receive a could not load texture, cause if you don't need //don't worry if you receive a could not load texture, cause if you don't need
//a particular material in your scene it will be loaded and then destroyed. //a particular material in your scene it will be loaded and then destroyed.
#ifdef _IRR_DMF_DEBUG_
os::Printer::log("Loading textures.");
#endif
for (i=0; i<header.numMaterials; i++) for (i=0; i<header.numMaterials; i++)
{ {
core::stringc path; core::stringc path;
...@@ -207,27 +192,14 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -207,27 +192,14 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
//Primary texture is normal //Primary texture is normal
if ((materiali[i].textureFlag==0) || (materiali[i].textureBlend==4)) if ((materiali[i].textureFlag==0) || (materiali[i].textureBlend==4))
{
driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT,true); driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT,true);
tex = driver->getTexture((path+materiali[i].textureName).c_str()); tex = driver->getTexture((path+materiali[i].textureName).c_str());
}
//Primary texture is just a colour //Primary texture is just a colour
if(materiali[i].textureFlag==1) else if(materiali[i].textureFlag==1)
{ {
String colour(materiali[i].textureName); SColor color(axtoi(materiali[i].textureName.c_str()));
String alpha,red,green,blue;
alpha.append((char*)&colour[0]);
alpha.append((char*)&colour[1]);
blue.append((char*)&colour[2]);
blue.append((char*)&colour[3]);
green.append((char*)&colour[4]);
green.append((char*)&colour[5]);
red.append((char*)&colour[6]);
red.append((char*)&colour[7]);
SColor color(axtoi(alpha.c_str()),
axtoi(red.c_str()),axtoi(green.c_str()),
axtoi(blue.c_str()));
//just for compatibility with older Irrlicht versions //just for compatibility with older Irrlicht versions
//to support transparent materials //to support transparent materials
...@@ -246,7 +218,6 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -246,7 +218,6 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
buffer->Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; buffer->Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
buffer->Material.MaterialTypeParam =(((f32) (color.getAlpha()-1))/255.0f); buffer->Material.MaterialTypeParam =(((f32) (color.getAlpha()-1))/255.0f);
} }
immagine->drop();
} }
//Lightmap is present //Lightmap is present
...@@ -260,28 +231,21 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -260,28 +231,21 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
buffer->Material.AmbientColor=header.dmfAmbient.getInterpolated(SColor(255,0,0,0),mult/100.f); buffer->Material.AmbientColor=header.dmfAmbient.getInterpolated(SColor(255,0,0,0),mult/100.f);
} }
if(materiali[i].textureBlend==4) if (materiali[i].textureBlend==4)
{ {
buffer->Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; buffer->Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
buffer->Material.MaterialTypeParam =SceneMgr->getParameters()->getAttributeAsFloat(DMF_ALPHA_CHANNEL_REF); buffer->Material.MaterialTypeParam =
SceneMgr->getParameters()->getAttributeAsFloat(DMF_ALPHA_CHANNEL_REF);
} }
core::dimension2d<s32> texsize; //if texture is present mirror vertically owing to DeleD representation
core::dimension2d<s32> ligsize;
if (tex && header.dmfVersion<1.1)
texsize=tex->getSize();
if (lig && header.dmfVersion<1.1)
ligsize=lig->getSize();
//if texture is present mirror vertically owing to DeleD rapresentation
if (tex && header.dmfVersion<1.1) if (tex && header.dmfVersion<1.1)
{ {
const core::dimension2d<s32> texsize = tex->getSize();
void* pp = tex->lock(); void* pp = tex->lock();
if (pp) if (pp)
{ {
video::ECOLOR_FORMAT format = tex->getColorFormat(); const video::ECOLOR_FORMAT format = tex->getColorFormat();
if (format == video::ECF_A1R5G5B5) if (format == video::ECF_A1R5G5B5)
{ {
s16* p = (s16*)pp; s16* p = (s16*)pp;
...@@ -308,10 +272,6 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -308,10 +272,6 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
} }
} }
} }
}
if(tex && header.dmfVersion<1.1)
{
tex->unlock(); tex->unlock();
tex->regenerateMipMapLevels(); tex->regenerateMipMapLevels();
} }
...@@ -319,6 +279,7 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -319,6 +279,7 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
//if lightmap is present mirror vertically owing to DeleD rapresentation //if lightmap is present mirror vertically owing to DeleD rapresentation
if (lig && header.dmfVersion<1.1) if (lig && header.dmfVersion<1.1)
{ {
const core::dimension2d<s32> ligsize=lig->getSize();
void* pp = lig->lock(); void* pp = lig->lock();
if (pp) if (pp)
{ {
...@@ -352,10 +313,6 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -352,10 +313,6 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
} }
} }
} }
}
if (lig && header.dmfVersion<1.1)
{
lig->unlock(); lig->unlock();
lig->regenerateMipMapLevels(); lig->regenerateMipMapLevels();
} }
...@@ -366,16 +323,17 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -366,16 +323,17 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
delete verts; delete verts;
delete faces; delete faces;
delete materiali;
} }
// delete all buffers without geometry in it. // delete all buffers without geometry in it.
#ifdef _IRR_DMF_DEBUG_
os::Printer::log("Cleaning meshbuffers.");
#endif
i = 0; i = 0;
while(i < mesh->MeshBuffers.size()) while(i < mesh->MeshBuffers.size())
{ {
if (mesh->MeshBuffers[i]->getVertexCount() == 0 || if (mesh->MeshBuffers[i]->getVertexCount() == 0 ||
mesh->MeshBuffers[i]->getIndexCount() == 0 || mesh->MeshBuffers[i]->getIndexCount() == 0)
mesh->MeshBuffers[i]->getMaterial().getTexture(0) == 0)
{ {
// Meshbuffer is empty -- drop it // Meshbuffer is empty -- drop it
mesh->MeshBuffers[i]->drop(); mesh->MeshBuffers[i]->drop();
......
...@@ -71,16 +71,13 @@ namespace scene ...@@ -71,16 +71,13 @@ namespace scene
Note that loaded water plains from DeleD must have the suffix \b water_ and must be \b rectangle (with just 1 rectangular face). Note that loaded water plains from DeleD must have the suffix \b water_ and must be \b rectangle (with just 1 rectangular face).
Irrlicht correctly loads position and rotation of water plain as well as texture layers. Irrlicht correctly loads position and rotation of water plain as well as texture layers.
\return number of water plains loaded or 0 if loading failed.*/ \return number of water plains loaded or 0 if loading failed.*/
int loadWaterPlains ( const c8 *filename, int loadWaterPlains(const c8 *filename,
ISceneManager* smgr, ISceneManager* smgr,
ISceneNode * parent = 0, ISceneNode * parent = 0,
s32 base_id = 2000, s32 base_id = 2000,
bool mode = true); bool mode = true);
private: private:
void GetFaceNormal(f32 a[3], f32 b[3], f32 c[3], f32 out[3]);
ISceneManager* SceneMgr; ISceneManager* SceneMgr;
io::IFileSystem* FileSystem; io::IFileSystem* FileSystem;
}; };
......
This diff is collapsed.
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