#ifndef __DMF_SUPPORT_H_INCLUDED__
#define __DMF_SUPPORT_H_INCLUDED__
#include "irrString.h"
#include "fast_atof.h"
namespace irr
{
namespace scene
{
namespace
{
struct dmfHeader
{
core::stringc dmfName;
f32 dmfVersion;
video::SColor dmfAmbient;
f32 dmfShadow;
u32 numObjects;
u32 numMaterials;
u32 numVertices;
u32 numFaces;
u32 numLights;
u32 numWatVertices;
u32 numWatFaces;
};
struct dmfMaterial
{
u32 materialID;
u32 textureLayers;
u32 textureFlag;
u32 lightmapFlag;
u32 textureBlend;
core::stringc pathName;
core::stringc textureName;
core::stringc lightmapName;
u32 lightmapBlend;
};
struct dmfFace
{
u32 firstVert;
u32 numVerts;
u32 materialID;
};
struct dmfVert
{
core::vector3df pos;
core::vector2df tc;
core::vector2df lc;
};
struct dmfLight
{
core::vector3df pos;
video::SColorf diffuseColor;
video::SColorf specularColor;
f32 radius;
};
struct dmfWaterPlane
{
u32 waterID;
u32 numFaces;
u32 firstFace;
core::dimension2d<u32> tileNum;
f32 waveHeight;
f32 waveSpeed;
f32 waveLength;
};
int axtoi(const char *hexStg)
{
unsigned int intValue = 0;
sscanf(hexStg, "%x", &intValue);
return (intValue);
}
typedef core::array<core::stringc> StringList;
void LoadFromFile(io::IReadFile* file, StringList& strlist)
{
const long sz = file->getSize();
char* buf = new char[sz+1];
file->read(buf, sz);
buf[sz] = 0;
char* p = buf;
char* start = p;
while(*p)
{
if (*p == '\n')
{
core::stringc str(start, (u32)(p - start - 1));
str.trim();
strlist.push_back(str);
start = p+1;
}
++p;
}
if (p - start > 1)
{
core::stringc str(start, (u32)(p - start - 1));
str.trim();
strlist.push_back(str);
}
delete [] buf;
};
StringList SubdivideString(const core::stringc& str, const core::stringc& divider)
{
StringList strings;
strings.clear();
int c=0;
int l=str.size();
while(c<l)
{
core::stringc resultstr;
resultstr = "";
while((str[c]!=divider[0]) && c<l)
{
resultstr += str[c];
++c;
}
resultstr.trim();
strings.push_back(resultstr);
++c;
}
return strings;
}
bool GetDMFHeader(const StringList& RawFile, dmfHeader& header)
{
StringList temp;
RawFile[0].split(temp, ";");
if ( temp[0] != "DeleD Map File" )
return false;
temp.clear();
temp = SubdivideString(RawFile[1]," ");
StringList temp1=SubdivideString(temp[1],";");
header.dmfVersion = (float)atof(temp1[0].c_str());
if (header.dmfVersion < 0.91)
return false;
temp.clear();
temp = SubdivideString(RawFile[2],";");
header.dmfName=temp[0];
header.dmfAmbient.set(axtoi(temp[1].c_str()));
header.dmfShadow = (float)atof(temp[2].c_str());
int offs=3;
header.numMaterials=atoi(RawFile[offs].c_str());
offs+=header.numMaterials;
++offs;
header.numObjects=atoi(RawFile[offs].c_str());
header.numVertices=0;
header.numFaces=0;
header.numWatFaces=0;
header.numWatVertices=0;
offs++;
s32 fac;
int i;
for(i=0; i < (int)header.numObjects; i++)
{
StringList wat=SubdivideString(RawFile[offs],";");
StringList wat1=SubdivideString(wat[0],"_");
++offs;
offs += atoi(RawFile[offs].c_str());
++offs;
fac=atoi(RawFile[offs].c_str());
if(!(wat1[0]=="water" && wat[2]=="0"))
header.numFaces = header.numFaces + fac;
else
header.numWatFaces = header.numWatFaces + fac;
offs++;
for(int j=0; j<fac; j++)
{
if(!(wat1[0] == "water" && wat[2] == "0"))
header.numVertices=header.numVertices + atoi(RawFile[offs+j].c_str());
else
header.numWatVertices=header.numWatVertices + atoi(RawFile[offs + j].c_str());
}
offs = offs + fac;
}
header.numLights=0;
temp.clear();
temp1.clear();
s32 lit = atoi(RawFile[offs].c_str());
for (i=0; i<lit; i++)
{
offs++;
temp=SubdivideString(RawFile[offs],";");
if(atoi(temp[0].c_str())==1)
{
temp1=SubdivideString(temp[18],"_");
if(temp1[0]=="dynamic")
header.numLights++;
}
temp.clear();
temp1.clear();
}
return true;
}
bool GetDMFMaterials(const StringList& RawFile,
core::array<dmfMaterial>& materials,
int num_material)
{
const int offs=4;
StringList temp;
StringList temp1;
materials.reallocate(num_material);
for(int i=0; i<num_material; ++i)
{
materials.push_back(dmfMaterial());
temp=SubdivideString(RawFile[offs+i],";");
materials[i].materialID = i;
materials[i].pathName = temp[2];
materials[i].pathName.replace('\\','/');
materials[i].pathName += "/";
materials[i].textureLayers = core::strtol10(temp[4].c_str());
temp1=SubdivideString(temp[5],",");
materials[i].textureFlag = atoi(temp1[0].c_str());
materials[i].textureName=temp1[1];
materials[i].textureName.replace('\\','/');
materials[i].textureBlend = atoi(temp1[2].c_str());
if(temp.size()>=9)
{
temp1=SubdivideString(temp[temp.size() - 1],",");
materials[i].lightmapFlag=atoi(temp1[0].c_str());
materials[i].lightmapName=temp1[1];
materials[i].lightmapName.replace('\\','/');
materials[i].lightmapBlend = atoi(temp1[2].c_str());
}
else
{
materials[i].lightmapFlag=1;
materials[i].lightmapName="";
}
}
return true;
}
bool GetDMFWaterMaterials(const StringList& RawFile ,
core::array<dmfMaterial>& materials,
int num_material
)
{
int offs=4;
StringList temp;
StringList temp1;
StringList temp2;
temp=SubdivideString(RawFile[0],";");
if ( temp[0] != "DeleD Map File" )
return false;
temp.clear();
temp=SubdivideString(RawFile[1]," ");
temp1=SubdivideString(temp[1],";");
if (atof(temp1[0].c_str()) < 0.91)
return false;
temp.clear();
temp1.clear();
for(int i=0;i<num_material;i++)
{
temp = SubdivideString(RawFile[offs+i],";");
materials[i].materialID=i;
temp1 = SubdivideString(temp[5],",");
materials[i].textureFlag=atoi(temp1[0].c_str());
temp2 = SubdivideString(temp1[1],"\\");
materials[i].textureName=temp2.getLast();
temp1.clear();
temp2.clear();
int a=temp.size();
if(a==7)
{
temp1=SubdivideString(temp[6],",");
materials[i].lightmapFlag=atoi(temp1[0].c_str());
temp2=SubdivideString(temp1[1],"\\");
materials[i].lightmapName=temp2.getLast();
}
else
{
materials[i].lightmapFlag=1;
materials[i].lightmapName="FFFFFFFF";
}
temp1.clear();
temp2.clear();
}
return true;
}
bool GetDMFVerticesFaces(const StringList& RawFile,
dmfVert vertices[],
dmfFace faces[]
)
{
StringList temp,temp1;
s32 offs = 4 + atoi(RawFile[3].c_str());
const s32 objs = atoi(RawFile[offs].c_str());
offs++;
#ifdef _IRR_DMF_DEBUG_
os::Printer::log("Reading objects", core::stringc(objs).c_str());
#endif
s32 vert_cnt=0, face_cnt=0;
for (int i=0; i<objs; ++i)
{
StringList wat=SubdivideString(RawFile[offs],";");
StringList wat1=SubdivideString(wat[0],"_");
#ifdef _IRR_DMF_DEBUG_
os::Printer::log("Reading object", wat[0].c_str());
#endif
offs++;
core::array<core::vector3df> pos;
const u32 posCount = core::strtol10(RawFile[offs].c_str());
++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());
offs++;
if(!(wat1[0]=="water" && wat[2]=="0"))
{
for(s32 j=0; j<numFaces; ++j)
{
temp=SubdivideString(RawFile[offs+j],";");
const s32 vert=core::strtol10(temp[0].c_str());
faces[face_cnt].numVerts=vert;
faces[face_cnt].materialID=atoi(temp[1].c_str());
faces[face_cnt].firstVert=vert_cnt;
for(s32 k=0; k<vert; ++k)
{
vertices[vert_cnt].pos.set(pos[core::strtol10(temp[2+k].c_str())]);
vertices[vert_cnt].tc.set(core::fast_atof(temp[2+vert+(2*k)].c_str()),
core::fast_atof(temp[2+vert+(2*k)+1].c_str()));
const u32 tmp_sz=temp.size();
vertices[vert_cnt].lc.set(core::fast_atof(temp[tmp_sz-(2*vert)+(2*k)].c_str()),
core::fast_atof(temp[tmp_sz-(2*vert)+(2*k)+1].c_str()));
vert_cnt++;
}
face_cnt++;
}
}
offs+=numFaces;
}
return true;
}
bool GetDMFLights(const StringList& RawFile,
dmfLight lights[]
)
{
int offs=3;
StringList temp,temp1;
temp=SubdivideString(RawFile[0],";");
if ( temp[0] != "DeleD Map File" )
return false;
temp.clear();
temp=SubdivideString(RawFile[1]," ");
temp1=SubdivideString(temp[1],";");
if (atof(temp1[0].c_str()) < 0.91)
return false;
temp.clear();
temp1.clear();
offs=offs + atoi(RawFile[offs].c_str());
offs++;
s32 objs = atoi(RawFile[offs].c_str());
s32 lit=0;
s32 d_lit=0;
offs++;
int i;
for(i=0;i<objs;i++)
{
offs++;
offs = offs + atoi(RawFile[offs].c_str());
offs++;
offs = offs + atoi(RawFile[offs].c_str());
offs++;
}
lit = atoi(RawFile[offs].c_str());
for(i=0;i<lit;i++)
{
offs++;
temp=SubdivideString(RawFile[offs],";");
if(atoi(temp[0].c_str())==1)
{
temp1=SubdivideString(temp[18],"_");
if(temp1[0]=="dynamic")
{
lights[d_lit].radius = (float)atof(temp[4].c_str());
lights[d_lit].pos.set((float)atof(temp[5].c_str()),
(float)atof(temp[6].c_str()),
(float)-atof(temp[7].c_str()));
lights[d_lit].diffuseColor = video::SColorf(
video::SColor(255, atoi(temp[10].c_str()), atoi(temp[11].c_str()),
atoi(temp[12].c_str())));
lights[d_lit].specularColor = video::SColorf(
video::SColor(255, atoi(temp[13].c_str()), atoi(temp[14].c_str()),
atoi(temp[15].c_str())));
d_lit++;
}
}
temp.clear();
temp1.clear();
}
return true;
}
bool GetDMFWaterPlanes(const StringList& RawFile,
dmfWaterPlane wat_planes[],
dmfVert vertices[],
dmfFace faces[]
)
{
int offs=3;
int offs1=0;
StringList temp,temp1;
temp=SubdivideString(RawFile[0],";");
if ( temp[0] != "DeleD Map File" )
return false;
temp.clear();
temp=SubdivideString(RawFile[1]," ");
temp1=SubdivideString(temp[1],";");
if (atof(temp1[0].c_str()) < 0.91)
return false;
temp.clear();
temp1.clear();
offs=offs+atoi(RawFile[offs].c_str());
offs++;
s32 objs=atoi(RawFile[offs].c_str());
s32 fac=0,vert=0,tmp_sz=0,vert_cnt=0,face_cnt=0,wat_id=0;
core::dimension2d<u32> tilenum(40,40);
f32 waveheight=3.0f;
f32 wavespeed=300.0f;
f32 wavelength=80.0f;
offs++;
for(int i=0;i<objs;i++)
{
StringList wat=SubdivideString(RawFile[offs],";");
StringList wat1=SubdivideString(wat[0],"_");
offs++;
offs1=offs;
offs=offs+atoi(RawFile[offs].c_str());
offs++;
offs1++;
fac=atoi(RawFile[offs].c_str());
offs++;
if(wat1[0]=="water" && wat[2]=="0")
{
StringList userinfo=SubdivideString(wat[7],",");
int j;
for (j=0; j<(int)userinfo.size(); j++)
{
switch(j)
{
case 0:
if(atoi(userinfo[0].c_str()))
tilenum.Width = atoi(userinfo[0].c_str());
break;
case 1:
if(atoi(userinfo[1].c_str()))
tilenum.Height = atoi(userinfo[1].c_str());
break;
case 2:
if(atof(userinfo[2].c_str()))
waveheight = (float)atof(userinfo[2].c_str());
break;
case 3:
if(atof(userinfo[3].c_str()))
wavespeed = (float)atof(userinfo[3].c_str());
break;
case 4:
if(atof(userinfo[4].c_str()))
wavelength = (float)atof(userinfo[4].c_str());
break;
}
}
wat_planes[wat_id].waterID=wat_id;
wat_planes[wat_id].numFaces=fac;
wat_planes[wat_id].firstFace=face_cnt;
wat_planes[wat_id].tileNum=tilenum;
wat_planes[wat_id].waveHeight=waveheight;
wat_planes[wat_id].waveSpeed=wavespeed;
wat_planes[wat_id].waveLength=wavelength;
for(j=0;j<fac;j++)
{
temp=SubdivideString(RawFile[offs+j],";");
faces[face_cnt].numVerts=atoi(temp[0].c_str());
vert=faces[face_cnt].numVerts;
faces[face_cnt].materialID=atoi(temp[1].c_str());
faces[face_cnt].firstVert=vert_cnt;
for(int k=0;k<vert;k++)
{
temp1=SubdivideString(RawFile[offs1+atoi(temp[2+k].c_str())], ";");
vertices[vert_cnt].pos.set((float)atof(temp1[0].c_str()),
(float)atof(temp1[1].c_str()),
(float)-atof(temp1[2].c_str()));
vertices[vert_cnt].tc.set((float)atof(temp[2+vert+(2*k)].c_str()),
(float)atof(temp[2+vert+(2*k)+1].c_str()));
tmp_sz=temp.size();
vertices[vert_cnt].lc.set((float)atof(temp[tmp_sz-(2*vert)+(2*k)].c_str()),
(float)atof(temp[tmp_sz-(2*vert)+(2*k)+1].c_str()));
++vert_cnt;
temp1.clear();
}
++face_cnt;
temp.clear();
}
}
offs=offs+fac;
}
return true;
}
}
}
}
#endif