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 @@
#include "IrrCompileConfig.h"
#ifdef _IRR_COMPILE_WITH_DMF_LOADER_
#ifdef _DEBUG
#define _IRR_DMF_DEBUG_
#include "os.h"
#endif
#include "CDMFLoader.h"
#include "ISceneManager.h"
#include "IAttributes.h"
......@@ -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.
\return Pointer to the created mesh. Returns 0 if loading failed.
If you no longer need the mesh, you should call IAnimatedMesh::drop().
......@@ -101,20 +75,28 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
SceneMgr->setAmbientLight(header.dmfAmbient);
//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];
dmfFace *faces=new dmfFace[header.numFaces];
//let's get the materials
bool use_mat_dirs=false;
use_mat_dirs=SceneMgr->getParameters()->getAttributeAsBool(DMF_USE_MATERIALS_DIRS);
const bool 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
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
#ifdef _IRR_DMF_DEBUG_
os::Printer::log("Creating meshbuffers.");
#endif
for (i=0; i<header.numMaterials; i++)
{
//create a new SMeshBufferLightMap for each material
......@@ -127,38 +109,38 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
}
// Build the mesh buffers
#ifdef _IRR_DMF_DEBUG_
os::Printer::log("Adding geometry to mesh.");
#endif
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)
continue;
f32 normal[3];
GetFaceNormal(verts[faces[i].firstVert].pos,
verts[faces[i].firstVert+1].pos, verts[faces[i].firstVert+2].pos, normal);
const core::vector3df normal =
core::triangle3df(verts[faces[i].firstVert].pos,
verts[faces[i].firstVert+1].pos,
verts[faces[i].firstVert+2].pos).getNormal().normalize();
SMeshBufferLightMap * meshBuffer = (SMeshBufferLightMap*)mesh->getMeshBuffer(
faces[i].materialID);
u32 base = meshBuffer->Vertices.size();
const u32 base = meshBuffer->Vertices.size();
// Add this face's verts
u32 v;
for (v = 0; v < faces[i].numVerts; v++)
{
dmfVert * vv = &verts[faces[i].firstVert + v];
video::S3DVertex2TCoords vert(vv->pos[0], vv->pos[1], vv->pos[2],
normal[0], normal[1], normal[2], video::SColor(0,255,255,255), 0.0f, 0.0f);
if ( materiali[faces[i].materialID].textureBlend==4 &&
const dmfVert& vv = verts[faces[i].firstVert + v];
video::S3DVertex2TCoords vert(vv.pos,
normal, video::SColor(255,255,255,255), vv.tc, vv.lc);
if (materiali[faces[i].materialID].textureBlend==4 &&
SceneMgr->getParameters()->getAttributeAsBool(DMF_FLIP_ALPHA_TEXTURES))
{
vert.TCoords.set(vv->tc[0],-vv->tc[1]);
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]);
vert.TCoords.set(vv.tc.X,-vv.tc.Y);
}
meshBuffer->Vertices.push_back(vert);
}
......@@ -170,18 +152,18 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
u32 h = faces[i].numVerts - 1, l = 0, c; // High, Low, Center
for (v = 0; v < faces[i].numVerts - 2; v++)
{
if (v & 1)
if (v & 1) // odd
c = h - 1;
else
else // even
c = l + 1;
meshBuffer->Indices.push_back(base + h);
meshBuffer->Indices.push_back(base + l);
meshBuffer->Indices.push_back(base + c);
if (v & 1)
if (v & 1) // odd
h--;
else
else // even
l++;
}
}
......@@ -189,6 +171,9 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
//load textures and lightmaps in materials.
//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.
#ifdef _IRR_DMF_DEBUG_
os::Printer::log("Loading textures.");
#endif
for (i=0; i<header.numMaterials; i++)
{
core::stringc path;
......@@ -207,27 +192,14 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
//Primary texture is normal
if ((materiali[i].textureFlag==0) || (materiali[i].textureBlend==4))
{
driver->setTextureCreationFlag(ETCF_ALWAYS_32_BIT,true);
tex = driver->getTexture((path+materiali[i].textureName).c_str());
}
//Primary texture is just a colour
if(materiali[i].textureFlag==1)
else if(materiali[i].textureFlag==1)
{
String colour(materiali[i].textureName);
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()));
SColor color(axtoi(materiali[i].textureName.c_str()));
//just for compatibility with older Irrlicht versions
//to support transparent materials
......@@ -246,7 +218,6 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
buffer->Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
buffer->Material.MaterialTypeParam =(((f32) (color.getAlpha()-1))/255.0f);
}
immagine->drop();
}
//Lightmap is present
......@@ -260,28 +231,21 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
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.MaterialTypeParam =SceneMgr->getParameters()->getAttributeAsFloat(DMF_ALPHA_CHANNEL_REF);
buffer->Material.MaterialTypeParam =
SceneMgr->getParameters()->getAttributeAsFloat(DMF_ALPHA_CHANNEL_REF);
}
core::dimension2d<s32> texsize;
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 texture is present mirror vertically owing to DeleD representation
if (tex && header.dmfVersion<1.1)
{
const core::dimension2d<s32> texsize = tex->getSize();
void* pp = tex->lock();
if (pp)
{
video::ECOLOR_FORMAT format = tex->getColorFormat();
const video::ECOLOR_FORMAT format = tex->getColorFormat();
if (format == video::ECF_A1R5G5B5)
{
s16* p = (s16*)pp;
......@@ -308,10 +272,6 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
}
}
}
}
if(tex && header.dmfVersion<1.1)
{
tex->unlock();
tex->regenerateMipMapLevels();
}
......@@ -319,6 +279,7 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
//if lightmap is present mirror vertically owing to DeleD rapresentation
if (lig && header.dmfVersion<1.1)
{
const core::dimension2d<s32> ligsize=lig->getSize();
void* pp = lig->lock();
if (pp)
{
......@@ -352,10 +313,6 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
}
}
}
}
if (lig && header.dmfVersion<1.1)
{
lig->unlock();
lig->regenerateMipMapLevels();
}
......@@ -366,16 +323,17 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
delete verts;
delete faces;
delete materiali;
}
// delete all buffers without geometry in it.
#ifdef _IRR_DMF_DEBUG_
os::Printer::log("Cleaning meshbuffers.");
#endif
i = 0;
while(i < mesh->MeshBuffers.size())
{
if (mesh->MeshBuffers[i]->getVertexCount() == 0 ||
mesh->MeshBuffers[i]->getIndexCount() == 0 ||
mesh->MeshBuffers[i]->getMaterial().getTexture(0) == 0)
mesh->MeshBuffers[i]->getIndexCount() == 0)
{
// Meshbuffer is empty -- drop it
mesh->MeshBuffers[i]->drop();
......
......@@ -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).
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.*/
int loadWaterPlains ( const c8 *filename,
int loadWaterPlains(const c8 *filename,
ISceneManager* smgr,
ISceneNode * parent = 0,
s32 base_id = 2000,
bool mode = true);
private:
void GetFaceNormal(f32 a[3], f32 b[3], f32 c[3], f32 out[3]);
ISceneManager* SceneMgr;
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