1
// Copyright (C) 2002-2011 Nikolaus Gebhardt
2
// This file is part of the "Irrlicht Engine".
3
// For conditions of distribution and use, see copyright notice in irrlicht.h
5
// This file was written by Saurav Mohapatra and modified by Nikolaus Gebhardt.
6
// See CCSMLoader.h for details.
8
#include "IrrCompileConfig.h"
9
#ifdef _IRR_COMPILE_WITH_CSM_LOADER_
11
#include "CCSMLoader.h"
13
#include "IFileSystem.h"
14
#include "IReadFile.h"
15
#include "ISceneManager.h"
16
#include "IAttributes.h"
18
#include "IVideoDriver.h"
19
#include "SAnimatedMesh.h"
20
#include "SMeshBufferLightMap.h"
23
#define _IRR_DEBUG_CSM_LOADER_
39
color_rgb_t() : red(0), green(0), blue(0) {}
40
void clear() { red=0; green=0; blue=0; }
41
video::SColor toSColor() const { return video::SColor(255, red, green, blue); }
46
// A Binary File Reader
48
struct BinaryFileReader
50
BinaryFileReader(io::IReadFile* pFile) : file(pFile) { }
52
s32 readBuffer(void* buffer, s32 len)
54
return file->read(buffer,len);
60
void readString(core::stringc &str);
61
void readVec3f(core::vector3df* v);
62
void readVec2f(core::vector2df* v);
63
void readColorRGB(color_rgb_t* color);
83
s32 getVersion() const { return version; }
84
void clear(){ version = 0; }
85
void load(BinaryFileReader* pReader)
87
version = pReader->readLong();
107
void load(BinaryFileReader* pReader);
109
s32 getFlags() const { return flags; }
110
s32 getParentGroupID() const { return parentGroup; }
111
const core::stringc& getProperties() const { return props; }
112
video::SColor getColor() const { return color.toSColor(); }
130
VisGroup(){ clear(); }
131
~VisGroup(){ clear(); }
133
void load(BinaryFileReader* pReader);
135
s32 getFlags() const{ return flags; }
136
const core::stringc& getName() const{ return name; }
137
video::SColor getColor() const{ return color.toSColor(); }
154
LightMap() : pixelData(0){ clear(); }
155
~LightMap(){ clear(); }
157
void load(BinaryFileReader* pReader);
158
s32 getWidth() const{ return width; }
159
s32 getHeight() const{ return height; }
160
s32* getPixelData() const{ return pixelData; }
186
~Vertex(){ clear(); }
188
void load(BinaryFileReader* pReader);
190
const core::vector3df& getPosition() const { return position; }
191
const core::vector3df& getNormal() const { return normal; }
192
video::SColor getColor() const { return color.toSColor(); }
193
const core::vector3df& getTextureCoordinates() const { return texCoords; }
194
const core::vector3df& getLightMapCoordinates() const { return lmapCoords; }
198
core::vector3df position;
199
core::vector3df normal;
201
core::vector3df texCoords;
202
core::vector3df lmapCoords;
210
Surface() { clear(); }
211
~Surface(){ clear(); }
214
void load(BinaryFileReader *pReader);
216
s32 getFlags() const{ return flags; }
217
const core::stringc& getTextureName() const{ return textureName; }
218
s32 getLightMapId() const{ return lightMapId; }
219
const core::vector2df* getUVOffset() const{ return &uvOffset; }
220
const core::vector2df* getUVScale() const{ return &uvScale; }
221
f32 getUVRotation() const{ return uvRotation; }
223
u32 getVertexCount() const{ return vertices.size(); }
224
const Vertex& getVertexAt(const s32 index) const{ return vertices[index]; }
226
u32 getTriangleCount() const{ return triangles.size(); }
227
const Triangle& getTriangleAt(const s32 index) const{ return triangles[index]; }
232
core::stringc textureName;
234
core::vector2df uvOffset;
235
core::vector2df uvScale;
237
core::array<Vertex> vertices;
238
core::array<Triangle> triangles;
239
core::array<Line> lines;
250
void load(BinaryFileReader* pReader, bool bReadVisGroups);
252
s32 getFlags() const { return flags; }
253
s32 getGroupID() const { return groupId; }
254
const core::stringc& getProperties() const { return props; }
255
video::SColor getColor() const { return color.toSColor(); }
256
const core::vector3df* getPosition() const { return &position; }
257
s32 getVisgroupID() const { return visgroupId; }
258
s32 getSurfaceCount() const { return surfaces.size(); }
259
const Surface* getSurfaceAt(const s32 index) const { return surfaces[index]; }
267
core::vector3df position;
270
core::array<Surface*> surfaces;
277
Entity() { clear(); }
278
~Entity() { clear(); }
281
void load(BinaryFileReader* pReader);
282
s32 getVisgroupID() const { return visgroupId; }
283
s32 getGroupID() const { return groupId; }
284
const core::stringc& getProperties() const { return props; }
285
const core::vector3df* getPosition() const { return &position; }
292
core::vector3df position;
300
CameraData(){ clear(); }
301
~CameraData(){ clear(); }
304
void load(BinaryFileReader* pReader);
306
const core::vector3df* getPosition(){ return &position; }
307
f32 getPitch(){ return pitch; }
308
f32 getYaw(){ return yaw; }
312
core::vector3df position;
324
CSMFile(){ clear(); }
325
~CSMFile(){ clear(); }
327
void load(BinaryFileReader* pReader);
329
const Header* getHeader() const{ return &header; }
331
u32 getGroupCount() const{ return groups.size(); }
332
const Group* getGroupAt(const s32 index) const{ return groups[index]; }
334
u32 getVisGroupCount() const{ return visgroups.size(); }
335
const VisGroup* getVisGroupAt(const s32 index) const{ return visgroups[index]; }
337
u32 getLightMapCount() const{ return lightmaps.size(); }
338
const LightMap* getLightMapAt(const s32 index) const { return lightmaps[index]; }
340
u32 getMeshCount() const{ return meshes.size(); }
341
const Mesh* getMeshAt(const s32 index) const{ return meshes[index]; }
343
u32 getEntityCount() const{ return entities.size(); }
344
const Entity* getEntityAt(const s32 index) const{ return entities[index]; }
346
const CameraData* getCameraData() const{ return &cameraData; }
351
core::array<Group*> groups;
352
core::array<VisGroup*> visgroups;
353
core::array<LightMap*> lightmaps;
354
core::array<Mesh*> meshes;
355
core::array<Entity*> entities;
356
CameraData cameraData;
359
CCSMLoader::CCSMLoader(scene::ISceneManager* manager, io::IFileSystem* fs)
360
: FileSystem(fs), SceneManager(manager)
364
setDebugName("CCSMLoader");
369
//! returns true if the file maybe is able to be loaded by this class
370
//! based on the file extension (e.g. ".bsp")
371
bool CCSMLoader::isALoadableFileExtension(const io::path& filename) const
373
return core::hasFileExtension ( filename, "csm" );
377
//! creates/loads an animated mesh from the file.
378
IAnimatedMesh* CCSMLoader::createMesh(io::IReadFile* file)
380
scene::IMesh* m = createCSMMesh(file);
385
SAnimatedMesh* am = new SAnimatedMesh();
390
am->recalculateBoundingBox();
394
scene::IMesh* CCSMLoader::createCSMMesh(io::IReadFile* file)
399
BinaryFileReader reader(file);
401
csmFile.load(&reader);
403
return createIrrlichtMesh(&csmFile,
404
SceneManager->getParameters()->getAttributeAsString(CSM_TEXTURE_PATH),
405
file->getFileName());
409
scene::IMesh* CCSMLoader::createIrrlichtMesh(const CSMFile* csmFile,
410
const core::stringc& textureRoot, const io::path& lmprefix)
412
scene::SMesh *pMesh = new scene::SMesh();
413
video::IVideoDriver* driver = SceneManager->getVideoDriver();
415
for(u32 l = 0; l<csmFile->getLightMapCount(); l++)
417
const LightMap* lmap = csmFile->getLightMapAt(l);
419
io::path lmapName = lmprefix;
421
lmapName += io::path(l+1);
422
os::Printer::log("CCSMLoader loading light map", lmapName.c_str());
424
video::IImage* lmapImg = driver->createImageFromData(
426
core::dimension2d<u32>(lmap->getWidth(),lmap->getHeight()),
427
lmap->getPixelData());
429
driver->addTexture(lmapName.c_str(), lmapImg);
433
for(u32 m = 0; m<csmFile->getMeshCount(); m++)
435
const Mesh* mshPtr = csmFile->getMeshAt(m);
437
for(s32 s = 0; s < mshPtr->getSurfaceCount(); s++)
439
const Surface* surface = mshPtr->getSurfaceAt(s);
441
core::stringc texName;
442
if (textureRoot.size())
444
texName += textureRoot;
447
texName+= surface->getTextureName();
449
video::ITexture* texture = 0;
452
if (FileSystem->existFile(texName))
453
texture = driver->getTexture(texName);
454
else if (FileSystem->existFile(surface->getTextureName()))
455
texture = driver->getTexture(surface->getTextureName());
456
else if (FileSystem->existFile(FileSystem->getFileBasename(surface->getTextureName())))
457
texture = driver->getTexture(FileSystem->getFileBasename(surface->getTextureName()));
458
else if (FileSystem->existFile(FileSystem->getFileDir(lmprefix)+"/"+surface->getTextureName()))
459
texture = driver->getTexture(FileSystem->getFileDir(lmprefix)+"/"+surface->getTextureName());
461
texture = driver->getTexture(FileSystem->getFileDir(lmprefix)+"/"+FileSystem->getFileBasename(surface->getTextureName()));
465
io::path lmapName = lmprefix;
467
lmapName += io::path(surface->getLightMapId());
469
scene::SMeshBufferLightMap *buffer = new scene::SMeshBufferLightMap();
470
buffer->Material.setTexture(0, texture);
471
if (surface->getLightMapId())
473
buffer->Material.setTexture(1, driver->getTexture(lmapName));
474
buffer->Material.Lighting = false;
475
buffer->Material.MaterialType = video::EMT_LIGHTMAP_ADD;
478
buffer->Vertices.reallocate(surface->getVertexCount());
479
for(u32 v = 0; v < surface->getVertexCount(); ++v)
481
const Vertex& vtxPtr = surface->getVertexAt(v);
482
video::S3DVertex2TCoords vtx;
483
vtx.Pos = vtxPtr.getPosition();
484
vtx.Normal = vtxPtr.getPosition();
485
vtx.Color=vtxPtr.getColor();
486
vtx.TCoords.set(vtxPtr.getTextureCoordinates().X, 1.f-vtxPtr.getTextureCoordinates().Y);
487
vtx.TCoords2.set(vtxPtr.getLightMapCoordinates().X, 1.f-vtxPtr.getLightMapCoordinates().Y);
489
buffer->Vertices.push_back(vtx);
492
buffer->Indices.reallocate(surface->getTriangleCount()*3);
493
for(u32 t = 0; t < surface->getTriangleCount(); ++t)
495
const Triangle& tri = surface->getTriangleAt(t);
496
buffer->Indices.push_back(tri.c);
497
buffer->Indices.push_back(tri.b);
498
buffer->Indices.push_back(tri.a);
501
buffer->recalculateBoundingBox();
502
pMesh->addMeshBuffer(buffer);
507
pMesh->recalculateBoundingBox();
519
void Group::load(BinaryFileReader* pReader)
521
flags = pReader->readLong();
522
parentGroup = pReader->readLong();
523
pReader->readString(props);
524
pReader->readColorRGB(&color);
527
void VisGroup::clear()
534
void VisGroup::load(BinaryFileReader* pReader)
536
pReader->readString(name);
537
flags = pReader->readLong();
538
pReader->readColorRGB(&color);
541
void LightMap::clear()
548
void LightMap::load(BinaryFileReader* pReader)
550
width = pReader->readLong();
551
height = pReader->readLong();
552
pixelData = new s32[width * height];
553
pReader->readBuffer(pixelData, width * height * sizeof(s32));
565
for(u32 s = 0; s < surfaces.size(); s++)
572
void Mesh::load(BinaryFileReader* pReader, bool bReadVisGroups)
574
flags = pReader->readLong();
575
groupId = pReader->readLong();
576
pReader->readString(props);
577
pReader->readColorRGB(&color);
578
pReader->readVec3f(&position);
580
visgroupId = pReader->readLong();
584
s32 count = pReader->readLong();
586
for(s32 i = 0; i < count; i++)
588
Surface* surf = new Surface();
590
surfaces.push_back(surf);
594
void Surface::clear()
599
uvOffset.set(0.0f,0.0f);
600
uvScale.set(0.0f,0.0f);
607
void Surface::load(BinaryFileReader* pReader)
609
flags = pReader->readLong();
610
pReader->readString(textureName);
611
textureName.replace('\\', '/');
613
lightMapId = pReader->readLong();
614
pReader->readVec2f(&uvOffset);
615
pReader->readVec2f(&uvScale);
616
uvRotation = pReader->readFloat();
617
s32 vtxCount = pReader->readLong();
618
s32 triCount = pReader->readLong();
619
s32 lineCount = pReader->readLong();
621
for(s32 v = 0; v < vtxCount; v++)
623
vertices.push_back(Vertex());
624
vertices.getLast().load(pReader);
627
for(s32 t = 0; t < triCount; t++)
630
pReader->readBuffer(&tri, sizeof(tri));
631
triangles.push_back(tri);
634
for(s32 l = 0; l < lineCount; l++)
637
pReader->readBuffer(&line,sizeof(line));
638
lines.push_back(line);
649
texCoords.set(0,0,0);
650
lmapCoords.set(0,0,0);
653
void Vertex::load(BinaryFileReader* pReader)
655
pReader->readVec3f(&position);
656
pReader->readVec3f(&normal);
657
pReader->readColorRGB(&color);
658
pReader->readVec3f(&texCoords);
659
pReader->readVec3f(&lmapCoords);
664
visgroupId = groupId = 0;
669
void Entity::load(BinaryFileReader* pReader)
671
visgroupId = pReader->readLong();
672
groupId = pReader->readLong();
673
pReader->readString(props);
674
pReader->readVec3f(&position);
677
void CameraData::clear()
684
void CameraData::load(BinaryFileReader* pReader)
686
pReader->readVec3f(&position);
687
pitch = pReader->readFloat();
688
yaw = pReader->readFloat();
691
void CSMFile::clear()
697
for( x= 0; x < groups.size(); x++)
702
for(x= 0; x < visgroups.size(); x++)
707
for(x= 0; x < lightmaps.size(); x++)
712
for(x= 0; x < meshes.size(); x++)
717
for(x= 0; x < entities.size(); x++)
723
void CSMFile::load(BinaryFileReader* pReader)
727
header.load(pReader);
731
const s32 count = pReader->readLong();
732
#ifdef _IRR_DEBUG_CSM_LOADER_
733
os::Printer::log("CSM Version", core::stringc(header.getVersion()).c_str());
734
os::Printer::log("Loading groups. Count", core::stringc(count));
737
groups.reallocate(count);
738
for (s32 i = 0; i < count; i++)
740
Group* grp = new Group();
742
groups.push_back(grp);
745
const bool bHasVGroups = (header.getVersion() == Header::VERSION_4_1);
750
const s32 count = pReader->readLong();
751
#ifdef _IRR_DEBUG_CSM_LOADER_
752
os::Printer::log("Loading visgroups. Count", core::stringc(count));
755
visgroups.reallocate(count);
756
for (s32 i = 0; i < count; i++)
758
VisGroup* grp = new VisGroup();
760
visgroups.push_back(grp);
766
const s32 count = pReader->readLong();
767
#ifdef _IRR_DEBUG_CSM_LOADER_
768
os::Printer::log("Loading lightmaps. Count", core::stringc(count));
771
lightmaps.reallocate(count);
772
for(s32 i = 0; i < count; i++)
774
LightMap* lm = new LightMap();
776
lightmaps.push_back(lm);
782
const s32 count = pReader->readLong();
783
#ifdef _IRR_DEBUG_CSM_LOADER_
784
os::Printer::log("Loading meshes. Count", core::stringc(count));
787
meshes.reallocate(count);
788
for(s32 i = 0; i < count; i++)
790
Mesh* mesh = new Mesh();
791
mesh->load(pReader,bHasVGroups);
792
meshes.push_back(mesh);
798
const s32 count = pReader->readLong();
799
#ifdef _IRR_DEBUG_CSM_LOADER_
800
os::Printer::log("Loading entitites. Count", core::stringc(count));
803
entities.reallocate(count);
804
for(s32 i = 0; i < count; i++)
806
Entity* ent = new Entity();
808
entities.push_back(ent);
813
#ifdef _IRR_DEBUG_CSM_LOADER_
814
os::Printer::log("Loading camera data.");
816
cameraData.load(pReader);
819
s32 BinaryFileReader::readLong()
822
readBuffer(&ret,sizeof(int));
823
#ifdef __BIG_ENDIAN__
824
ret = os::Byteswap::byteswap(ret);
829
f32 BinaryFileReader::readFloat()
832
readBuffer(&ret,sizeof(float));
833
#ifdef __BIG_ENDIAN__
834
ret = os::Byteswap::byteswap(ret);
839
void BinaryFileReader::readString(core::stringc &str)
843
readBuffer(&c,sizeof(char));
847
readBuffer(&c,sizeof(char));
851
void BinaryFileReader::readVec3f(core::vector3df* v)
858
void BinaryFileReader::readVec2f(core::vector2df* v)
864
void BinaryFileReader::readColorRGB(color_rgb_t* color)
866
readBuffer(color,sizeof(color_rgb_t));
872
#endif // _IRR_COMPILE_WITH_CSM_LOADER_