Code: Select all
class CProgressSceneUserDataReader : public ISceneUserDataSerializer
{
IFileSystem* FileSystem;
void (*RdCallbackFn)(void*, s32, s32);
void* RdCallbackP;
s32 TotalSceneNodes;
s32 ReadSceneNodes;
public:
CProgressSceneUserDataReader(IFileSystem* fileSystem)
: FileSystem(fileSystem)
, RdCallbackFn(0)
, RdCallbackP(0)
, TotalSceneNodes(0)
, ReadSceneNodes(0)
{
FileSystem->grab();
}
virtual ~CProgressSceneUserDataReader()
{
FileSystem->drop();
}
void setProgressCb(void (*cb)(void*, s32, s32), void* param)
{
RdCallbackFn = cb;
RdCallbackP = param;
}
//! Called when the scene manager read a scene node while loading a file.
virtual void OnReadUserData(ISceneNode* forSceneNode, io::IAttributes* userData)
{
// if we've never read total scene nodes, then we assume this is the top level
// scene node. there is no nice way to identify the root scene node.
if (!TotalSceneNodes)
{
TotalSceneNodes = userData->getAttributeAsInt("NodeCount");
ReadSceneNodes = 0;
}
++ReadSceneNodes;
if (RdCallbackFn && (TotalSceneNodes != 0))
(*RdCallbackFn)(RdCallbackP, ReadSceneNodes, TotalSceneNodes);
}
//! Called when the scene manager is writing a scene node to an xml file for example.
virtual io::IAttributes* createUserData(ISceneNode* forSceneNode)
{
// no-op. this class is for reading only.
return 0;
}
};
class CProgressSceneUserDataWriter : public ISceneUserDataSerializer
{
IFileSystem* FileSystem;
void (*WrCallbackFn)(void*, s32, s32);
void* WrCallbackP;
s32 TotalSceneNodes;
s32 WrittenSceneNodes;
public:
CProgressSceneUserDataWriter(IFileSystem* fileSystem)
: FileSystem(fileSystem)
, WrCallbackFn(0)
, WrCallbackP(0)
, TotalSceneNodes(0)
, WrittenSceneNodes(0)
{
FileSystem->grab();
}
virtual ~CProgressSceneUserDataWriter()
{
FileSystem->drop();
}
void setProgressCb(void (*cb)(void*, s32, s32), void* param)
{
WrCallbackFn = cb;
WrCallbackP = param;
}
//! Called when the scene manager read a scene node while loading a file.
virtual void OnReadUserData(ISceneNode* forSceneNode, IAttributes* userData)
{
// no-op. this class is for writing only
}
//! Called when the scene manager is writing a scene node to an xml file for example.
virtual IAttributes* createUserData(ISceneNode* forSceneNode)
{
IAttributes* newAttributes = 0;
// if TotalSceneNodes is 0 then this is the first call
if (!TotalSceneNodes)
{
// get count of all scene nodes including this one
getNodeCount(forSceneNode, TotalSceneNodes);
WrittenSceneNodes = 0;
newAttributes = FileSystem->createEmptyAttributes();
if (!newAttributes)
return 0;
// add the node count to the attributes
newAttributes->addInt("NodeCount", TotalSceneNodes);
}
else
{
// this is necessary so that our read callback gets notified
// of a new node.
newAttributes = FileSystem->createEmptyAttributes();
}
++WrittenSceneNodes;
if (WrCallbackFn && (TotalSceneNodes != 0))
(*WrCallbackFn)(WrCallbackP, WrittenSceneNodes, TotalSceneNodes);
return newAttributes;
}
protected:
void getNodeCount(ISceneNode* node, s32& nodeCount)
{
core::list<ISceneNode*>::Iterator head = node->getChildren().begin();
core::list<ISceneNode*>::Iterator tail = node->getChildren().end();
for (; head != tail; ++head)
getNodeCount(*head, nodeCount);
nodeCount += 1;
}
};
Code: Select all
void testProgressCb(void*, s32 n, s32 t)
{
printf("%0.2f%%\n", 100.f * n / t);
}
int main(int argc, char* argv[])
{
//...
// to write out a scene
CProgressSceneUserDataWriter writer(device->getFileSystem());
writer.setProgressCb(testProgressCb, 0);
smgr->saveScene("../../media/example2.irr", &writer);
// to read back a scene
CProgressSceneUserDataReader reader(device->getFileSystem());
reader.setProgressCb(testProgressCb, 0);
smgr->loadScene("../../media/example2.irr", &reader);
//...
}
Here is the output of loading the converted example.irr.
Code: Select all
Irrlicht Engine version 1.1
Microsoft Windows XP Professional Service Pack 2 (Build 2600)
Using renderer: Direct3D 9.0
NVIDIA GeForce 6200 TurboCache(TM) nv4_disp.dll 6.14.10.8421
Loaded texture: #DefaultFont
12.50%
Loaded mesh: ../../media/room.3ds
Loaded texture: ../../media/wall.jpg
25.00%
37.50%
Loaded texture: ../../media/particlewhite.bmp
50.00%
62.50%
Loaded texture: ../../media/rockwall.bmp
75.00%
87.50%
Loaded texture: ../../media/particlered.bmp
100.00%
Finished loading scene: ../../media/example2.irr