Commit d6d75787 authored by hybrid's avatar hybrid

Added support for standard vertices, if no lightmaps are used. This saves lots...

Added support for standard vertices, if no lightmaps are used. This saves lots of of memory and update times. But it needs some more testing, because I have not enough test files. Moreover, I've added some speedup for the vertex position loading with heavily reduced parsing efforts.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2488 dfc29bdd-3216-0410-991c-e03cc46cb475
parent 701bf011
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include "ISceneManager.h" #include "ISceneManager.h"
#include "IAttributes.h" #include "IAttributes.h"
#include "SAnimatedMesh.h" #include "SAnimatedMesh.h"
#include "SMeshBufferLightMap.h" #include "SSkinMeshBuffer.h"
#include "irrString.h" #include "irrString.h"
#include "irrMath.h" #include "irrMath.h"
#include "dmfsupport.h" #include "dmfsupport.h"
...@@ -98,7 +98,7 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -98,7 +98,7 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
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
SMeshBufferLightMap* buffer = new SMeshBufferLightMap(); SSkinMeshBuffer* buffer = new SSkinMeshBuffer();
buffer->Material.MaterialType = video::EMT_LIGHTMAP_LIGHTING; buffer->Material.MaterialType = video::EMT_LIGHTMAP_LIGHTING;
buffer->Material.Wireframe = false; buffer->Material.Wireframe = false;
buffer->Material.Lighting = true; buffer->Material.Lighting = true;
...@@ -123,24 +123,45 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -123,24 +123,45 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
verts[faces[i].firstVert+1].pos, verts[faces[i].firstVert+1].pos,
verts[faces[i].firstVert+2].pos).getNormal().normalize(); verts[faces[i].firstVert+2].pos).getNormal().normalize();
SMeshBufferLightMap * meshBuffer = (SMeshBufferLightMap*)mesh->getMeshBuffer( SSkinMeshBuffer* meshBuffer = (SSkinMeshBuffer*)mesh->getMeshBuffer(
faces[i].materialID); faces[i].materialID);
const u32 base = meshBuffer->Vertices.size(); const bool use2TCoords = meshBuffer->Vertices_2TCoords.size() ||
materiali[faces[i].materialID].lightmapName.size();
if (use2TCoords && meshBuffer->Vertices_Standard.size())
meshBuffer->MoveTo_2TCoords();
const u32 base = meshBuffer->Vertices_2TCoords.size()?meshBuffer->Vertices_2TCoords.size():meshBuffer->Vertices_Standard.size();
// Add this face's verts // Add this face's verts
u32 v; if (use2TCoords)
for (v = 0; v < faces[i].numVerts; v++)
{ {
const dmfVert& vv = verts[faces[i].firstVert + v]; for (u32 v = 0; v < faces[i].numVerts; 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.X,-vv.tc.Y); 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.X,-vv.tc.Y);
}
meshBuffer->Vertices_2TCoords.push_back(vert);
}
}
else
{
for (u32 v = 0; v < faces[i].numVerts; v++)
{
const dmfVert& vv = verts[faces[i].firstVert + v];
video::S3DVertex vert(vv.pos,
normal, video::SColor(255,255,255,255), vv.tc);
if (materiali[faces[i].materialID].textureBlend==4 &&
SceneMgr->getParameters()->getAttributeAsBool(DMF_FLIP_ALPHA_TEXTURES))
{
vert.TCoords.set(vv.tc.X,-vv.tc.Y);
}
meshBuffer->Vertices_Standard.push_back(vert);
} }
meshBuffer->Vertices.push_back(vert);
} }
// Now add the indices // Now add the indices
...@@ -148,7 +169,7 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -148,7 +169,7 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
// I do it this way instead of a simple fan because it usually // I do it this way instead of a simple fan because it usually
// looks a lot better in wireframe, for example. // looks a lot better in wireframe, for example.
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 (u32 v = 0; v < faces[i].numVerts - 2; v++)
{ {
if (v & 1) // odd if (v & 1) // odd
c = h - 1; c = h - 1;
...@@ -188,7 +209,7 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -188,7 +209,7 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
video::ITexture *lig = 0; video::ITexture *lig = 0;
//current buffer to apply material //current buffer to apply material
SMeshBufferLightMap* buffer = (SMeshBufferLightMap*)mesh->getMeshBuffer(i); video::SMaterial& mat = mesh->getMeshBuffer(i)->getMaterial();
//Primary texture is normal //Primary texture is normal
if (materiali[i].textureFlag==0) if (materiali[i].textureFlag==0)
...@@ -243,8 +264,8 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -243,8 +264,8 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
//to support transparent materials //to support transparent materials
if(color.getAlpha()!=255 && materiali[i].textureBlend==4) if(color.getAlpha()!=255 && materiali[i].textureBlend==4)
{ {
buffer->Material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL; mat.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
buffer->Material.MaterialTypeParam =(((f32) (color.getAlpha()-1))/255.0f); mat.MaterialTypeParam =(((f32) (color.getAlpha()-1))/255.0f);
} }
} }
...@@ -253,15 +274,15 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -253,15 +274,15 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
lig = driver->getTexture((path+materiali[i].lightmapName)); lig = driver->getTexture((path+materiali[i].lightmapName));
else //no lightmap else //no lightmap
{ {
buffer->Material.MaterialType = video::EMT_SOLID; mat.MaterialType = video::EMT_SOLID;
const f32 mult = 100.0f - header.dmfShadow; const f32 mult = 100.0f - header.dmfShadow;
buffer->Material.AmbientColor=header.dmfAmbient.getInterpolated(video::SColor(255,0,0,0),mult/100.f); mat.AmbientColor=header.dmfAmbient.getInterpolated(video::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; mat.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
buffer->Material.MaterialTypeParam = mat.MaterialTypeParam =
SceneMgr->getParameters()->getAttributeAsFloat(DMF_ALPHA_CHANNEL_REF); SceneMgr->getParameters()->getAttributeAsFloat(DMF_ALPHA_CHANNEL_REF);
} }
...@@ -344,8 +365,8 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file) ...@@ -344,8 +365,8 @@ IAnimatedMesh* CDMFLoader::createMesh(io::IReadFile* file)
lig->regenerateMipMapLevels(); lig->regenerateMipMapLevels();
} }
buffer->Material.setTexture(0, tex); mat.setTexture(0, tex);
buffer->Material.setTexture(1, lig); mat.setTexture(1, lig);
} }
delete verts; delete verts;
......
...@@ -59,6 +59,7 @@ struct dmfMaterial ...@@ -59,6 +59,7 @@ struct dmfMaterial
core::stringc pathName;//!<Name of path defined in path element. core::stringc pathName;//!<Name of path defined in path element.
core::stringc textureName;//!<Name of first texture (only file name, no path). core::stringc textureName;//!<Name of first texture (only file name, no path).
core::stringc lightmapName;//!<Name of lightmap (only file name, no path). core::stringc lightmapName;//!<Name of lightmap (only file name, no path).
u32 lightmapBlend;//!<Blend mode used to support alpha maps (not implemented yet).
}; };
...@@ -363,8 +364,8 @@ bool GetDMFMaterials(const StringList& RawFile, ...@@ -363,8 +364,8 @@ bool GetDMFMaterials(const StringList& RawFile,
materials[i].pathName = temp[2]; materials[i].pathName = temp[2];
materials[i].pathName.replace('\\','/'); materials[i].pathName.replace('\\','/');
materials[i].pathName += "/"; materials[i].pathName += "/";
// can be negative! Maybe the wrong field? // temp[3] is reserved, temp[4] is the number of texture layers
materials[i].textureLayers = core::strtol10(temp[3].c_str()); materials[i].textureLayers = core::strtol10(temp[4].c_str());
// Three values are separated by commas // Three values are separated by commas
temp1=SubdivideString(temp[5],","); temp1=SubdivideString(temp[5],",");
...@@ -372,13 +373,13 @@ bool GetDMFMaterials(const StringList& RawFile, ...@@ -372,13 +373,13 @@ bool GetDMFMaterials(const StringList& RawFile,
materials[i].textureName=temp1[1]; materials[i].textureName=temp1[1];
materials[i].textureName.replace('\\','/'); materials[i].textureName.replace('\\','/');
materials[i].textureBlend = atoi(temp1[2].c_str()); materials[i].textureBlend = atoi(temp1[2].c_str());
int a=temp.size(); if(temp.size()>=9)
if(a>=9)
{ {
temp1=SubdivideString(temp[temp.size() - 1],","); temp1=SubdivideString(temp[temp.size() - 1],",");
materials[i].lightmapFlag=atoi(temp1[0].c_str()); materials[i].lightmapFlag=atoi(temp1[0].c_str());
materials[i].lightmapName=temp1[1]; materials[i].lightmapName=temp1[1];
materials[i].lightmapName.replace('\\','/'); materials[i].lightmapName.replace('\\','/');
materials[i].lightmapBlend = atoi(temp1[2].c_str());
} }
else else
{ {
...@@ -466,13 +467,12 @@ bool GetDMFVerticesFaces(const StringList& RawFile/**<StringList representing a ...@@ -466,13 +467,12 @@ bool GetDMFVerticesFaces(const StringList& RawFile/**<StringList representing a
s32 offs = 4 + atoi(RawFile[3].c_str()); s32 offs = 4 + atoi(RawFile[3].c_str());
const s32 objs = atoi(RawFile[offs].c_str()); const s32 objs = atoi(RawFile[offs].c_str());
offs++;
#ifdef _IRR_DMF_DEBUG_ #ifdef _IRR_DMF_DEBUG_
os::Printer::log("Reading objects", core::stringc(objs).c_str()); os::Printer::log("Reading objects", core::stringc(objs).c_str());
#endif #endif
s32 vert=0, tmp_sz=0, vert_cnt=0, face_cnt=0; s32 vert_cnt=0, face_cnt=0;
offs++;
for (int i=0; i<objs; ++i) for (int i=0; i<objs; ++i)
{ {
StringList wat=SubdivideString(RawFile[offs],";"); StringList wat=SubdivideString(RawFile[offs],";");
...@@ -482,10 +482,20 @@ bool GetDMFVerticesFaces(const StringList& RawFile/**<StringList representing a ...@@ -482,10 +482,20 @@ bool GetDMFVerticesFaces(const StringList& RawFile/**<StringList representing a
#endif #endif
offs++; offs++;
const s32 vrtxPos=offs+1; // load vertices
// skip vertices core::array<core::vector3df> pos;
offs += atoi(RawFile[offs].c_str()); const u32 posCount = core::strtol10(RawFile[offs].c_str());
offs++; ++offs;
pos.reallocate(posCount);
for (u32 i=0; i<posCount; ++i)
{
temp1=SubdivideString(RawFile[offs].c_str(),";");
pos.push_back(core::vector3df(core::fast_atof(temp1[0].c_str()),
core::fast_atof(temp1[1].c_str()),
-core::fast_atof(temp1[2].c_str())));
++offs;
}
const s32 numFaces=atoi(RawFile[offs].c_str()); const s32 numFaces=atoi(RawFile[offs].c_str());
offs++; offs++;
if(!(wat1[0]==String("water") && wat[2]==String("0"))) if(!(wat1[0]==String("water") && wat[2]==String("0")))
...@@ -495,7 +505,7 @@ bool GetDMFVerticesFaces(const StringList& RawFile/**<StringList representing a ...@@ -495,7 +505,7 @@ bool GetDMFVerticesFaces(const StringList& RawFile/**<StringList representing a
temp=SubdivideString(RawFile[offs+j],";"); temp=SubdivideString(RawFile[offs+j],";");
//first value is vertices number for this face //first value is vertices number for this face
vert=atoi(temp[0].c_str()); const s32 vert=core::strtol10(temp[0].c_str());
faces[face_cnt].numVerts=vert; faces[face_cnt].numVerts=vert;
//second is material ID //second is material ID
faces[face_cnt].materialID=atoi(temp[1].c_str()); faces[face_cnt].materialID=atoi(temp[1].c_str());
...@@ -505,28 +515,22 @@ bool GetDMFVerticesFaces(const StringList& RawFile/**<StringList representing a ...@@ -505,28 +515,22 @@ bool GetDMFVerticesFaces(const StringList& RawFile/**<StringList representing a
//now we'll create vertices structure //now we'll create vertices structure
for(s32 k=0; k<vert; ++k) for(s32 k=0; k<vert; ++k)
{ {
//get vertex position //copy position
temp1=SubdivideString(RawFile[vrtxPos+atoi(temp[2+k].c_str())],";"); vertices[vert_cnt].pos.set(pos[core::strtol10(temp[2+k].c_str())]);
//copy x,y,z values
vertices[vert_cnt].pos.set((float)atof(temp1[0].c_str()),
(float)atof(temp1[1].c_str()),
(float)-atof(temp1[2].c_str()));
//get uv coords for tex and light if any //get uv coords for tex and light if any
vertices[vert_cnt].tc.set((float)atof(temp[2+vert+(2*k)].c_str()), vertices[vert_cnt].tc.set(core::fast_atof(temp[2+vert+(2*k)].c_str()),
(float)atof(temp[2+vert+(2*k)+1].c_str())); core::fast_atof(temp[2+vert+(2*k)+1].c_str()));
tmp_sz=temp.size(); const u32 tmp_sz=temp.size();
vertices[vert_cnt].lc.set((float)atof(temp[tmp_sz-(2*vert)+(2*k)].c_str()), vertices[vert_cnt].lc.set(core::fast_atof(temp[tmp_sz-(2*vert)+(2*k)].c_str()),
(float)atof(temp[tmp_sz-(2*vert)+(2*k)+1].c_str())); core::fast_atof(temp[tmp_sz-(2*vert)+(2*k)+1].c_str()));
vert_cnt++; vert_cnt++;
temp1.clear();
} }
face_cnt++; face_cnt++;
temp.clear();
} }
} }
offs=offs+numFaces; offs+=numFaces;
} }
return true; return true;
...@@ -759,4 +763,3 @@ bool GetDMFWaterPlanes(const StringList& RawFile/**<StringList representing a DM ...@@ -759,4 +763,3 @@ bool GetDMFWaterPlanes(const StringList& RawFile/**<StringList representing a DM
} // end namespace } // end namespace
#endif /* __DMF_SUPPORT_H__ */ #endif /* __DMF_SUPPORT_H__ */
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