Work at SourceForge, help us to make it a better place! We have an immediate need for a Support Technician in our San Francisco or Denver office.

Close

#24 Load/Save QuantizedNoLeafTrees

Needs_Feedback
open
nobody
5
2013-11-10
2005-10-23
Jason Perkins
No

From: Simon Barratt
Date: Thu Dec 23 14:30:12 2004
Subject: [ODE] Scenery collision

This isn't a patch or anything as useful as that (of
course not!) but it
should provide a load/save for QuantizedNoLeafTrees in
OPCODE for you.

The code is fairly old and obviously fairly hacked it
was just for a
small couple of hour demo I knocked up.
The way I used this was by constructing a cache
directory of the OPCODE
trees, I added a way to pass in an identifier for each
tree I
constructed so when constructing the terrain AABBTree
I'd pass in
"Terrain" for example. The tree would then be saved out
to that filename
and so next time you run the demo it would check for a
file called
"Terrain" in the cache directory and try to load it
instead of
constructing it (there will be a breakeven between just
constructing
small mesh AABBTree's and loading them by the way). A
better way to do
it would be to store the tree data with your mesh and
precalculate
somewhere in your asset pipeline or whatever suits you.

Hope this helps someone anyways, happy holidays to you all.

--
Simon Barratt, Lead Developer, Pineapple Interactive Ltd
e: barog@pineapple-interactive.com
w: http://www.pineapple-interactive.com
t: +44 (0)1274 480185

--

define OPCODEMODELVERSION 1

bool Model::LoadTreeStream( ctIOStreamSeekable *iostream )
{
if(mTree)
{
DELETESINGLE(mTree);
mTree = NULL;
}

mTree = new AABBQuantizedNoLeafTree;
CHECKALLOC(mTree);

AABBQuantizedNoLeafTree optTree =
(AABBQuantizedNoLeafTree
)mTree;

int ver = 0;
iostream->Read( &ver, sizeof(int) );

if(ver != OPCODEMODELVERSION)
{
ctLog->Fmt("Loaded version %d not equal to current
version %d\n",
ver, OPCODEMODELVERSION);
DELETESINGLE(mTree);
mTree = NULL;
return false;
}

iostream->Read( &optTree->mNbNodes, sizeof(int) );

optTree->mNodes = new AABBQuantizedNoLeafNodemNbNodes">
optTree->mNbNodes
;

iostream->Read( &optTree->mCenterCoeff, sizeof(Point) );
iostream->Read( &optTree->mExtentsCoeff, sizeof(Point) );
iostream->Read( optTree->mNodes,
sizeof(AABBQuantizedNoLeafNode) *
optTree->mNbNodes);

AABBQuantizedNoLeafNode *curnode = optTree->mNodes;

// reconstruct pointers from indices
for(int i = 0; i < optTree->mNbNodes; i++)
{
if(!(curnode->mNegData & 1))
{
curnode->mNegData = (udword)((char
)optTree->mNodes +
((curnode->mNegData>>1)

sizeof(AABBQuantizedNoLeafNode)));
}

if(!(curnode->mPosData & 1))
{
  curnode->mPosData = (udword)((char

)optTree->mNodes +
((curnode->mPosData>>1)

sizeof(AABBQuantizedNoLeafNode)));
}

curnode++;

}

return true;
}

bool Model::SaveTree( char *fileName )
{
if(!mTree) return false;

ctFileBase *file = ctFileSystem->Open( fileName,
CT_IO_ACCESS_WRITE );
if( file == NULL )
{
ctLog->Fmt("Couldn't open file %s\n", fileName );
return false;
}

AABBQuantizedNoLeafTree optTree =
(AABBQuantizedNoLeafTree
)mTree;
unsigned int numNodes = optTree->GetNbNodes();

int ver = OPCODEMODELVERSION;
file->Write( &ver, sizeof(int) );

file->Write( &numNodes, sizeof(int) );
file->Write( &optTree->mCenterCoeff, sizeof(Point) );
file->Write( &optTree->mExtentsCoeff, sizeof(Point) );

// get index for the nodes referenced in posdata and
negdata, we
overwrite the existing values so we don't have to alloc
temp space or
write out
// each one.
AABBQuantizedNoLeafNode curnode = optTree->mNodes;
for(int i = 0; i < numNodes; i++)
{
if(!(curnode->mNegData & 1))
{
int val = (((char
)curnode->mNegData - (char
*)optTree->mNodes) /
sizeof(AABBQuantizedNoLeafNode)) << 1;
curnode->mNegData = val;
}

if(!(curnode->mPosData & 1))
{
  int val = (((char *)curnode->mPosData - (char

*)optTree->mNodes) /
sizeof(AABBQuantizedNoLeafNode)) << 1;
curnode->mPosData = val;
}

curnode++;

}

file->Write( optTree->mNodes,
sizeof(AABBQuantizedNoLeafNode)*
numNodes);

// This reconstructs the data which we just nuked
working out the
indices
curnode = optTree->mNodes;
for(int i = 0; i < numNodes; i++)
{
if(!(curnode->mNegData & 1))
{
curnode->mNegData = (udword)((char
)optTree->mNodes +
((curnode->mNegData>>1)

sizeof(AABBQuantizedNoLeafNode)));
}

if(!(curnode->mPosData & 1))
{
  curnode->mPosData = (udword)((char

)optTree->mNodes +
((curnode->mPosData>>1)

sizeof(AABBQuantizedNoLeafNode)));
}

curnode++;

}

file->Close();

return true;
}

Discussion

  • Jason Perkins
    Jason Perkins
    2005-11-01

    Logged In: YES
    user_id=1683

    Not really a patch, this would need a fair amount of work to
    plug into the ODE core. Also, ODE does not have a concept of
    stream I/O so it would probably have to write to a buffer?
    This would be a nice feature to have though. Perhaps it
    could go into a utility library?