Introduced VolumeResourcePtr as a wrapper around Volume.

This commit is contained in:
David Williams 2008-01-31 20:27:33 +00:00
parent 05c5d1dbce
commit 9e9537a9ee
9 changed files with 665 additions and 10 deletions

View File

@ -13,6 +13,7 @@ SET(SRC_FILES
source/Volume.cpp
source/VolumeIterator.cpp
source/VolumeManager.cpp
source/VolumeResource.cpp
source/VolumeSerializer.cpp
)
@ -34,6 +35,7 @@ SET(INC_FILES
include/Volume.h
include/VolumeIterator.h
include/VolumeManager.h
include/VolumeResource.h
include/VolumeSerializer.h
)

View File

@ -31,6 +31,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "Volume.h"
#include "SurfaceVertex.h"
#include "RegionGeometry.h"
#include "VolumeResource.h"
#include <set>
@ -100,7 +101,8 @@ namespace Ogre
NormalGenerationMethod m_normalGenerationMethod;
VolumePtr volumeData;
VolumeResourcePtr volumeResource;
Volume* volumeData;
bool m_bHaveGeneratedMeshes;

68
include/Volume.h Normal file
View File

@ -0,0 +1,68 @@
/******************************************************************************
This file is part of a voxel plugin for OGRE
Copyright (C) 2006 David Williams
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
******************************************************************************/
#ifndef __Volume_H__
#define __Volume_H__
#include "OgrePrerequisites.h"
#include "OgreSharedPtr.h"
#include "Block.h"
#include "Constants.h"
#include "TypeDef.h"
#include "IntegralVector3.h"
#include <OgreResourceManager.h>
namespace Ogre
{
class VOXEL_SCENE_MANAGER_API Volume
{
//Make VolumeIterator a friend
friend class VolumeIterator;
friend class VolumeResource;
//Volume interface
public:
Volume();
Volume(const Volume& rhs);
~Volume();
Volume& operator=(const Volume& rhs);
//uchar getVoxelAt(const uint xPosition, const uint yPosition, const uint zPosition) const;
//void setVoxelAt(const uint xPosition, const uint yPosition, const uint zPosition, const uchar value);
bool containsPoint(Vector3 pos, float boundary);
bool containsPoint(IntVector3 pos, uint boundary);
bool loadFromFile(const std::string& sFilename);
bool saveToFile(const std::string& sFilename);
void regionGrow(uint xStart, uint yStart, uint zStart, uchar value);
void tidy(void);
private:
static SharedPtr<Block> mHomogeneousBlocks[256];
SharedPtr<Block> mBlocks[OGRE_NO_OF_BLOCKS_IN_VOLUME];
};
VOXEL_SCENE_MANAGER_API Volume createDilatedCopy(Volume& volInput, uchar value);
}
#endif

View File

@ -2,7 +2,7 @@
#define __VOLUMEMANAGER_H__
#include <OgreResourceManager.h>
#include "Volume.h"
#include "VolumeResource.h"
namespace Ogre
{
@ -20,7 +20,7 @@ namespace Ogre
VolumeManager ();
virtual ~VolumeManager ();
virtual VolumePtr load (const Ogre::String &name, const Ogre::String &group);
virtual VolumeResourcePtr load (const Ogre::String &name, const Ogre::String &group);
static VolumeManager &getSingleton ();
static VolumeManager *getSingletonPtr ();

92
include/VolumeResource.h Normal file
View File

@ -0,0 +1,92 @@
/******************************************************************************
This file is part of a voxel plugin for OGRE
Copyright (C) 2006 David Williams
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
******************************************************************************/
#ifndef __VolumeResource_H__
#define __VolumeResource_H__
#include "OgrePrerequisites.h"
#include "OgreSharedPtr.h"
#include "Block.h"
#include "Constants.h"
#include "TypeDef.h"
#include "IntegralVector3.h"
#include "Volume.h"
#include <OgreResourceManager.h>
namespace Ogre
{
class VOXEL_SCENE_MANAGER_API VolumeResource : public Ogre::Resource
{
public:
VolumeResource (Ogre::ResourceManager *creator, const Ogre::String &name,
Ogre::ResourceHandle handle, const Ogre::String &group, bool isManual = false,
Ogre::ManualResourceLoader *loader = 0);
~VolumeResource();
Volume* volume;
protected:
// must implement these from the Ogre::Resource interface
void loadImpl ();
void unloadImpl ();
size_t calculateSize () const;
};
class VolumeResourcePtr : public Ogre::SharedPtr<VolumeResource>
{
public:
VolumeResourcePtr () : Ogre::SharedPtr<VolumeResource> () {}
explicit VolumeResourcePtr (VolumeResource *rep) : Ogre::SharedPtr<VolumeResource> (rep) {}
VolumeResourcePtr (const VolumeResourcePtr &r) : Ogre::SharedPtr<VolumeResource> (r) {}
VolumeResourcePtr (const Ogre::ResourcePtr &r) : Ogre::SharedPtr<VolumeResource> ()
{
// lock & copy other mutex pointer
OGRE_LOCK_MUTEX (*r.OGRE_AUTO_MUTEX_NAME)
OGRE_COPY_AUTO_SHARED_MUTEX (r.OGRE_AUTO_MUTEX_NAME)
pRep = static_cast<VolumeResource*> (r.getPointer ());
pUseCount = r.useCountPointer ();
if (pUseCount)
{
++ (*pUseCount);
}
}
/// Operator used to convert a ResourcePtr to a VolumeResourcePtr
VolumeResourcePtr& operator=(const Ogre::ResourcePtr& r)
{
if (pRep == static_cast<VolumeResource*> (r.getPointer ()))
return *this;
release ();
// lock & copy other mutex pointer
OGRE_LOCK_MUTEX (*r.OGRE_AUTO_MUTEX_NAME)
OGRE_COPY_AUTO_SHARED_MUTEX(r.OGRE_AUTO_MUTEX_NAME)
pRep = static_cast<VolumeResource*> (r.getPointer());
pUseCount = r.useCountPointer ();
if (pUseCount)
{
++ (*pUseCount);
}
return *this;
}
};
}
#endif

View File

@ -37,7 +37,8 @@ namespace Ogre
// PolyVoxSceneManager
//////////////////////////////////////////////////////////////////////////
PolyVoxSceneManager::PolyVoxSceneManager()
:volumeData(0)
:volumeResource(0)
,volumeData(0)
,useNormalSmoothing(false)
,normalSmoothingFilterSize(1)
,m_normalGenerationMethod(SOBEL)
@ -52,14 +53,16 @@ namespace Ogre
bool PolyVoxSceneManager::loadScene(const String& filename)
{
volumeData = VolumeManager::getSingletonPtr()->load(filename + ".volume", "General");
if(volumeData.isNull())
volumeResource = VolumeManager::getSingletonPtr()->load(filename + ".volume", "General");
if(volumeResource.isNull())
{
LogManager::getSingleton().logMessage("Generating default volume");
generateLevelVolume();
LogManager::getSingleton().logMessage("Done generating default volume");
}
volumeData = volumeResource->volume;
volumeData->tidy();
@ -177,7 +180,8 @@ namespace Ogre
void PolyVoxSceneManager::generateLevelVolume(void)
{
volumeData = VolumePtr(new Volume);
//volumeData = VolumePtr(new Volume);
volumeData = new Volume();
VolumeIterator volIter(*volumeData);
for(uint z = 0; z < OGRE_VOLUME_SIDE_LENGTH; ++z)
{

394
source/Volume.cpp Normal file
View File

@ -0,0 +1,394 @@
/******************************************************************************
This file is part of a voxel plugin for OGRE
Copyright (C) 2006 David Williams
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
******************************************************************************/
#include "IntegralVector3.h"
#include "Volume.h"
#include "VolumeIterator.h"
#include "VolumeSerializer.h"
#include "OgreVector3.h"
#include "OgreLogManager.h"
#include "OgreStringConverter.h"
#include <iostream> //FIXME - remove this...
namespace Ogre
{
SharedPtr<Block> Volume::mHomogeneousBlocks[256];
Volume::Volume()
{
//FIXME - Add checking...
SharedPtr<Block>& homogeneousBlock = mHomogeneousBlocks[0];
if(homogeneousBlock.isNull())
{
homogeneousBlock = SharedPtr<Block>(new Block);
homogeneousBlock->fillWithValue(0);
}
for(uint i = 0; i < OGRE_NO_OF_BLOCKS_IN_VOLUME; ++i)
{
mBlocks[i] = mHomogeneousBlocks[0];
}
}
Volume::Volume(const Volume& rhs)
{
std::cout << "Warning - Copying Volume" << std::endl;
*this = rhs;
}
Volume::~Volume()
{
}
Volume& Volume::operator=(const Volume& rhs)
{
std::cout << "Warning - Assigning Volume" << std::endl;
if (this == &rhs)
{
return *this;
}
/*for(uint i = 0; i < OGRE_NO_OF_BLOCKS_IN_VOLUME; ++i)
{
//FIXME - Add checking...
mBlocks[i] = SharedPtr<Block>(new Block);
}*/
for(uint i = 0; i < OGRE_NO_OF_BLOCKS_IN_VOLUME; ++i)
{
//I think this is OK... If a block is in the homogeneous array it's ref count will be greater
//than 1 as there will be the pointer in the volume and the pointer in the static homogeneous array.
if(rhs.mBlocks[i].unique())
{
mBlocks[i] = SharedPtr<Block>(new Block(*(rhs.mBlocks[i])));
}
else
{
//we have a block in the homogeneous array - just copy the pointer.
mBlocks[i] = rhs.mBlocks[i];
}
}
return *this;
}
/*uchar Volume::getVoxelAt(const uint xPosition, const uint yPosition, const uint zPosition) const
{
const uint blockX = xPosition >> OGRE_BLOCK_SIDE_LENGTH_POWER;
const uint blockY = yPosition >> OGRE_BLOCK_SIDE_LENGTH_POWER;
const uint blockZ = zPosition >> OGRE_BLOCK_SIDE_LENGTH_POWER;
const uint xOffset = xPosition - (blockX << OGRE_BLOCK_SIDE_LENGTH_POWER);
const uint yOffset = yPosition - (blockY << OGRE_BLOCK_SIDE_LENGTH_POWER);
const uint zOffset = zPosition - (blockZ << OGRE_BLOCK_SIDE_LENGTH_POWER);
Block* block = mBlocks
[
blockX +
blockY * OGRE_VOLUME_SIDE_LENGTH_IN_BLOCKS +
blockZ * OGRE_VOLUME_SIDE_LENGTH_IN_BLOCKS * OGRE_VOLUME_SIDE_LENGTH_IN_BLOCKS
];
return block->getVoxelAt(xOffset,yOffset,zOffset);
}*/
/*void Volume::setVoxelAt(const uint xPosition, const uint yPosition, const uint zPosition, const uchar value)
{
const uint blockX = xPosition >> OGRE_BLOCK_SIDE_LENGTH_POWER;
const uint blockY = yPosition >> OGRE_BLOCK_SIDE_LENGTH_POWER;
const uint blockZ = zPosition >> OGRE_BLOCK_SIDE_LENGTH_POWER;
const uint xOffset = xPosition - (blockX << OGRE_BLOCK_SIDE_LENGTH_POWER);
const uint yOffset = yPosition - (blockY << OGRE_BLOCK_SIDE_LENGTH_POWER);
const uint zOffset = zPosition - (blockZ << OGRE_BLOCK_SIDE_LENGTH_POWER);
Block* block = mBlocks
[
blockX +
blockY * OGRE_VOLUME_SIDE_LENGTH_IN_BLOCKS +
blockZ * OGRE_VOLUME_SIDE_LENGTH_IN_BLOCKS * OGRE_VOLUME_SIDE_LENGTH_IN_BLOCKS
];
block->setVoxelAt(xOffset,yOffset,zOffset, value);
}*/
bool Volume::containsPoint(Vector3 pos, float boundary)
{
return (pos.x < OGRE_VOLUME_SIDE_LENGTH - 1 - boundary)
&& (pos.y < OGRE_VOLUME_SIDE_LENGTH - 1 - boundary)
&& (pos.z < OGRE_VOLUME_SIDE_LENGTH - 1 - boundary)
&& (pos.x > boundary)
&& (pos.y > boundary)
&& (pos.z > boundary);
}
bool Volume::containsPoint(IntVector3 pos, uint boundary)
{
return (pos.x < OGRE_VOLUME_SIDE_LENGTH - 1 - boundary)
&& (pos.y < OGRE_VOLUME_SIDE_LENGTH - 1 - boundary)
&& (pos.z < OGRE_VOLUME_SIDE_LENGTH - 1 - boundary)
&& (pos.x > boundary)
&& (pos.y > boundary)
&& (pos.z > boundary);
}
bool Volume::loadFromFile(const std::string& sFilename)
{
//Open the file
std::ifstream file;
file.open(sFilename.c_str(), std::ios::in | std::ios::binary);
if(!file.is_open())
{
LogManager::getSingleton().logMessage("Failed to open volume file " + sFilename);
return false;
}
//Read volume dimensions
uchar volumeWidth = 0;
uchar volumeHeight = 0;
uchar volumeDepth = 0;
file.read(reinterpret_cast<char*>(&volumeWidth), sizeof(volumeWidth));
file.read(reinterpret_cast<char*>(&volumeHeight), sizeof(volumeHeight));
file.read(reinterpret_cast<char*>(&volumeDepth), sizeof(volumeDepth));
if(file.fail())
{
LogManager::getSingleton().logMessage("Failed to read dimentions");
return false;
}
//Read data
VolumeIterator volIter(*this);
for(uint z = 0; z < OGRE_VOLUME_SIDE_LENGTH; ++z)
{
for(uint y = 0; y < OGRE_VOLUME_SIDE_LENGTH; ++y)
{
for(uint x = 0; x < OGRE_VOLUME_SIDE_LENGTH; ++x)
{
uchar value;
file.read(reinterpret_cast<char*>(&value), sizeof(value)); //FIXME - check for error here
volIter.setVoxelAt(x,y,z,value);
}
}
//Periodically see if we can tidy the memory to avoid excessive usage during loading.
if(z%OGRE_BLOCK_SIDE_LENGTH == OGRE_BLOCK_SIDE_LENGTH-1)
{
tidy(); //FIXME - we don't actually have to tidy the whole volume here - just the part we loaded since the last call to tidy.
}
}
return true;
}
bool Volume::saveToFile(const std::string& sFilename)
{
//Open the file
std::ofstream file;
file.open(sFilename.c_str(), std::ios::out | std::ios::binary);
if(!file.is_open())
{
LogManager::getSingleton().logMessage("Failed to open file for saving volume");
return false;
}
//Read volume dimensions
uchar volumeWidth = 0;
uchar volumeHeight = 0;
uchar volumeDepth = 0;
file.write(reinterpret_cast<char*>(&volumeWidth), sizeof(volumeWidth));
file.write(reinterpret_cast<char*>(&volumeHeight), sizeof(volumeHeight));
file.write(reinterpret_cast<char*>(&volumeDepth), sizeof(volumeDepth));
if(file.fail())
{
LogManager::getSingleton().logMessage("Failed to write dimensions");
return false;
}
//Write data
VolumeIterator volIter(*this);
for(uint z = 0; z < OGRE_VOLUME_SIDE_LENGTH; ++z)
{
for(uint y = 0; y < OGRE_VOLUME_SIDE_LENGTH; ++y)
{
for(uint x = 0; x < OGRE_VOLUME_SIDE_LENGTH; ++x)
{
uchar value = volIter.getVoxelAt(x,y,z);
file.write(reinterpret_cast<char*>(&value), sizeof(value)); //FIXME - check for error here
}
}
}
return true;
}
void Volume::regionGrow(uint xStart, uint yStart, uint zStart, uchar value)
{
//FIXME - introduce integrer 'isInVolume' function
if((xStart > OGRE_VOLUME_SIDE_LENGTH-1) || (yStart > OGRE_VOLUME_SIDE_LENGTH-1) || (zStart > OGRE_VOLUME_SIDE_LENGTH-1)
|| (xStart < 0) || (yStart < 0) || (zStart < 0))
{
//FIXME - error message..
return;
}
VolumeIterator volIter(*this);
const uchar uSeedValue = volIter.getVoxelAt(xStart,yStart,zStart);
if(value == uSeedValue)
{
return; //FIXME - Error message? Exception?
}
std::queue<UIntVector3> seeds;
seeds.push(UIntVector3(xStart,yStart,zStart));
while(!seeds.empty())
{
UIntVector3 currentSeed = seeds.front();
seeds.pop();
//std::cout << "x = " << currentSeed.x << " y = " << currentSeed.y << " z = " << currentSeed.z << std::endl;
//FIXME - introduce 'safe' function which tests this?
if((currentSeed.x > OGRE_VOLUME_SIDE_LENGTH-2) || (currentSeed.y > OGRE_VOLUME_SIDE_LENGTH-2) || (currentSeed.z > OGRE_VOLUME_SIDE_LENGTH-2)
|| (currentSeed.x < 1) || (currentSeed.y < 1) || (currentSeed.z < 1))
{
continue;
}
if(volIter.getVoxelAt(currentSeed.x, currentSeed.y, currentSeed.z+1) == uSeedValue)
{
volIter.setVoxelAt(currentSeed.x, currentSeed.y, currentSeed.z+1, value);
seeds.push(UIntVector3(currentSeed.x, currentSeed.y, currentSeed.z+1));
}
if(volIter.getVoxelAt(currentSeed.x, currentSeed.y, currentSeed.z-1) == uSeedValue)
{
volIter.setVoxelAt(currentSeed.x, currentSeed.y, currentSeed.z-1, value);
seeds.push(UIntVector3(currentSeed.x, currentSeed.y, currentSeed.z-1));
}
if(volIter.getVoxelAt(currentSeed.x, currentSeed.y+1, currentSeed.z) == uSeedValue)
{
volIter.setVoxelAt(currentSeed.x, currentSeed.y+1, currentSeed.z, value);
seeds.push(UIntVector3(currentSeed.x, currentSeed.y+1, currentSeed.z));
}
if(volIter.getVoxelAt(currentSeed.x, currentSeed.y-1, currentSeed.z) == uSeedValue)
{
volIter.setVoxelAt(currentSeed.x, currentSeed.y-1, currentSeed.z, value);
seeds.push(UIntVector3(currentSeed.x, currentSeed.y-1, currentSeed.z));
}
if(volIter.getVoxelAt(currentSeed.x+1, currentSeed.y, currentSeed.z) == uSeedValue)
{
volIter.setVoxelAt(currentSeed.x+1, currentSeed.y, currentSeed.z, value);
seeds.push(UIntVector3(currentSeed.x+1, currentSeed.y, currentSeed.z));
}
if(volIter.getVoxelAt(currentSeed.x-1, currentSeed.y, currentSeed.z) == uSeedValue)
{
volIter.setVoxelAt(currentSeed.x-1, currentSeed.y, currentSeed.z, value);
seeds.push(UIntVector3(currentSeed.x-1, currentSeed.y, currentSeed.z));
}
}
}
void Volume::tidy(void)
{
//Check for homogeneous blocks
for(ulong ct = 0; ct < OGRE_NO_OF_BLOCKS_IN_VOLUME; ++ct)
{
if(mBlocks[ct]->isHomogeneous())
{
//LogManager::getSingleton().logMessage("Got homogeneous block with value " + StringConverter::toString(mBlocks[ct]->getVoxelAt(0,0,0)));
const uchar homogeneousValue = mBlocks[ct]->getVoxelAt(0,0,0);
SharedPtr<Block>& homogeneousBlock = mHomogeneousBlocks[homogeneousValue];
if(homogeneousBlock.isNull())
{
homogeneousBlock = SharedPtr<Block>(new Block);
homogeneousBlock->fillWithValue(homogeneousValue);
}
mBlocks[ct] = homogeneousBlock;
}
}
}
Volume createDilatedCopy(Volume& volInput, uchar value)
{
Volume volResult = volInput;
VolumeIterator iterResult(volResult);
VolumeIterator iterInput(volInput);
//FIXME - use looping over region thing...
for(uint z = 1; z < OGRE_VOLUME_SIDE_LENGTH-1; z++)
{
//std::cout << "z = " << z << std::endl;
for(uint y = 1; y < OGRE_VOLUME_SIDE_LENGTH-1; y++)
{
for(uint x = 1; x < OGRE_VOLUME_SIDE_LENGTH-1; x++)
{
iterInput.setPosition(x,y,z);
if
(
(iterInput.peekVoxel1nx1ny1nz() == value) ||
(iterInput.peekVoxel1nx1ny0pz() == value) ||
(iterInput.peekVoxel1nx1ny1pz() == value) ||
(iterInput.peekVoxel1nx0py1nz() == value) ||
(iterInput.peekVoxel1nx0py0pz() == value) ||
(iterInput.peekVoxel1nx0py1pz() == value) ||
(iterInput.peekVoxel1nx1py1nz() == value) ||
(iterInput.peekVoxel1nx1py0pz() == value) ||
(iterInput.peekVoxel1nx1py1pz() == value) ||
(iterInput.peekVoxel0px1ny1nz() == value) ||
(iterInput.peekVoxel0px1ny0pz() == value) ||
(iterInput.peekVoxel0px1ny1pz() == value) ||
(iterInput.peekVoxel0px0py1nz() == value) ||
//(iterInput.peekVoxel0px0py0pz() == value) ||
(iterInput.peekVoxel0px0py1pz() == value) ||
(iterInput.peekVoxel0px1py1nz() == value) ||
(iterInput.peekVoxel0px1py0pz() == value) ||
(iterInput.peekVoxel0px1py1pz() == value) ||
(iterInput.peekVoxel1px1ny1nz() == value) ||
(iterInput.peekVoxel1px1ny0pz() == value) ||
(iterInput.peekVoxel1px1ny1pz() == value) ||
(iterInput.peekVoxel1px0py1nz() == value) ||
(iterInput.peekVoxel1px0py0pz() == value) ||
(iterInput.peekVoxel1px0py1pz() == value) ||
(iterInput.peekVoxel1px1py1nz() == value) ||
(iterInput.peekVoxel1px1py0pz() == value) ||
(iterInput.peekVoxel1px1py1pz() == value)
)
{
iterResult.setVoxelAt(x,y,z,value);
}
}
}
}
return volResult;
}
}

View File

@ -34,10 +34,10 @@ namespace Ogre
Ogre::ResourceGroupManager::getSingleton ()._unregisterResourceManager (mResourceType);
}
VolumePtr VolumeManager::load (const Ogre::String &name, const Ogre::String &group)
VolumeResourcePtr VolumeManager::load (const Ogre::String &name, const Ogre::String &group)
{
Ogre::LogManager::getSingleton().logMessage("DAVID - calling getByName");
VolumePtr textf = getByName (name);
VolumeResourcePtr textf = getByName (name);
Ogre::LogManager::getSingleton().logMessage("DAVID - done getByName");
if (textf.isNull ())
@ -54,6 +54,6 @@ namespace Ogre
const Ogre::String &group, bool isManual, Ogre::ManualResourceLoader *loader,
const Ogre::NameValuePairList *createParams)
{
return new Volume (this, name, handle, group, isManual, loader);
return new VolumeResource (this, name, handle, group, isManual, loader);
}
}

93
source/VolumeResource.cpp Normal file
View File

@ -0,0 +1,93 @@
/******************************************************************************
This file is part of a voxel plugin for OGRE
Copyright (C) 2006 David Williams
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
******************************************************************************/
#include "IntegralVector3.h"
#include "VolumeResource.h"
#include "VolumeIterator.h"
#include "VolumeSerializer.h"
#include "OgreVector3.h"
#include "OgreLogManager.h"
#include "OgreStringConverter.h"
#include <iostream> //FIXME - remove this...
namespace Ogre
{
VolumeResource::VolumeResource (Ogre::ResourceManager* creator, const Ogre::String &name,
Ogre::ResourceHandle handle, const Ogre::String &group, bool isManual,
Ogre::ManualResourceLoader *loader) :
Ogre::Resource (creator, name, handle, group, isManual, loader)
{
/* If you were storing a pointer to an object, then you would set that pointer to NULL here.
*/
/* For consistency with StringInterface, but we don't add any parameters here
That's because the Resource implementation of StringInterface is to
list all the options that need to be set before loading, of which
we have none as such. Full details can be set through scripts.
*/
createParamDictionary ("Volume");
volume = new Volume();
}
VolumeResource::~VolumeResource()
{
unload ();
}
// farm out to VolumeSerializer
void VolumeResource::loadImpl ()
{
/* If you were storing a pointer to an object, then you would create that object with 'new' here.
*/
VolumeSerializer serializer;
Ogre::DataStreamPtr stream = Ogre::ResourceGroupManager::getSingleton ().openResource (mName, mGroup, true, this);
serializer.importVolume (stream, this->volume);
}
void VolumeResource::unloadImpl ()
{
/* If you were storing a pointer to an object, then you would check the pointer here,
and if it is not NULL, you would destruct the object and set its pointer to NULL again.
*/
//mString.clear ();
}
size_t VolumeResource::calculateSize () const
{
//NOTE - I don't really know what this function is for, so am therefore
//a bit vague on how to implement it. But here's my best guess...
ulong uNonHomogeneousBlocks = 0;
for(uint i = 0; i < OGRE_NO_OF_BLOCKS_IN_VOLUME; ++i)
{
//I think this is OK... If a block is in the homogeneous array it's ref count will be greater
//than 1 as there will be the pointer in the volume and the pointer in the static homogeneous array.
if(volume->mBlocks[i].unique())
{
++uNonHomogeneousBlocks;
}
}
return uNonHomogeneousBlocks * OGRE_NO_OF_VOXELS_IN_BLOCK;
}
}