[ODE] Scenery collision

Simon Barratt Barog at pineapple-interactive.com
Thu Dec 23 21:41:29 MST 2004


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 at 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 AABBQuantizedNoLeafNode[ 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;
}





More information about the ODE mailing list