Fixed reference counting problems due to statically allocated meshbuffers. Bug found by rogerborg.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1447 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2008-08-06 14:45:22 +00:00
parent bcdb49774e
commit d3ccf6335e
13 changed files with 302 additions and 256 deletions

View File

@ -299,25 +299,25 @@ static const SMD2AnimationType MD2AnimationTypeList[21] =
//! constructor //! constructor
CAnimatedMeshMD2::CAnimatedMeshMD2() CAnimatedMeshMD2::CAnimatedMeshMD2()
: FrameList(0), FrameCount(0), TriangleCount(0) : InterpolationBuffer(0), FrameList(0), FrameCount(0), TriangleCount(0)
{ {
#ifdef _DEBUG #ifdef _DEBUG
IAnimatedMesh::setDebugName("CAnimatedMeshMD2 IAnimatedMesh"); IAnimatedMesh::setDebugName("CAnimatedMeshMD2 IAnimatedMesh");
IMesh::setDebugName("CAnimatedMeshMD2 IMesh"); IMesh::setDebugName("CAnimatedMeshMD2 IMesh");
#endif #endif
InterpolationBuffer = new SMeshBuffer;
} }
//! destructor //! destructor
CAnimatedMeshMD2::~CAnimatedMeshMD2() CAnimatedMeshMD2::~CAnimatedMeshMD2()
{ {
if (FrameList)
delete [] FrameList; delete [] FrameList;
if (InterpolationBuffer)
InterpolationBuffer->drop();
} }
//! returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh. //! returns the amount of frames in milliseconds. If the amount is 1, it is a static (=non animated) mesh.
u32 CAnimatedMeshMD2::getFrameCount() const u32 CAnimatedMeshMD2::getFrameCount() const
{ {
@ -325,7 +325,6 @@ u32 CAnimatedMeshMD2::getFrameCount() const
} }
//! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level. //! returns the animated mesh based on a detail level. 0 is the lowest, 255 the highest detail. Note, that some Meshes will ignore the detail level.
IMesh* CAnimatedMeshMD2::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop) IMesh* CAnimatedMeshMD2::getMesh(s32 frame, s32 detailLevel, s32 startFrameLoop, s32 endFrameLoop)
{ {
@ -353,15 +352,15 @@ u32 CAnimatedMeshMD2::getMeshBufferCount() const
//! returns pointer to a mesh buffer //! returns pointer to a mesh buffer
IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(u32 nr) const IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(u32 nr) const
{ {
return const_cast<IMeshBuffer*>(reinterpret_cast<const IMeshBuffer*>(&InterpolationBuffer)); return InterpolationBuffer;
} }
//! Returns pointer to a mesh buffer which fits a material //! Returns pointer to a mesh buffer which fits a material
IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(const video::SMaterial &material) const IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(const video::SMaterial &material) const
{ {
if (InterpolationBuffer.Material == material) if (InterpolationBuffer->Material == material)
return const_cast<IMeshBuffer*>(reinterpret_cast<const IMeshBuffer*>(&InterpolationBuffer)); return InterpolationBuffer;
else else
return 0; return 0;
} }
@ -398,7 +397,7 @@ void CAnimatedMeshMD2::updateInterpolationBuffer(s32 frame, s32 startFrameLoop,
div = frame * MD2_FRAME_SHIFT_RECIPROCAL; div = frame * MD2_FRAME_SHIFT_RECIPROCAL;
} }
video::S3DVertex* target = reinterpret_cast<video::S3DVertex*>(InterpolationBuffer.getVertices()); video::S3DVertex* target = static_cast<video::S3DVertex*>(InterpolationBuffer->getVertices());
video::S3DVertex* first = FrameList[firstFrame].pointer(); video::S3DVertex* first = FrameList[firstFrame].pointer();
video::S3DVertex* second = FrameList[secondFrame].pointer(); video::S3DVertex* second = FrameList[secondFrame].pointer();
@ -415,8 +414,8 @@ void CAnimatedMeshMD2::updateInterpolationBuffer(s32 frame, s32 startFrameLoop,
} }
//update bounding box //update bounding box
InterpolationBuffer.setBoundingBox(BoxList[secondFrame].getInterpolated(BoxList[firstFrame], div)); InterpolationBuffer->setBoundingBox(BoxList[secondFrame].getInterpolated(BoxList[firstFrame], div));
InterpolationBuffer.setDirty(); InterpolationBuffer->setDirty();
} }
@ -618,25 +617,25 @@ bool CAnimatedMeshMD2::loadFile(io::IReadFile* file)
// create indices // create indices
InterpolationBuffer.Indices.reallocate(header.numVertices); InterpolationBuffer->Indices.reallocate(header.numVertices);
s16 count = TriangleCount*3; const u32 count = TriangleCount*3;
for (s16 n=0; n<count; n+=3) for (u32 n=0; n<count; n+=3)
{ {
InterpolationBuffer.Indices.push_back(n); InterpolationBuffer->Indices.push_back(n);
InterpolationBuffer.Indices.push_back(n+1); InterpolationBuffer->Indices.push_back(n+1);
InterpolationBuffer.Indices.push_back(n+2); InterpolationBuffer->Indices.push_back(n+2);
} }
// reallocate interpolate buffer // reallocate interpolate buffer
if (header.numFrames) if (header.numFrames)
{ {
u32 currCount = FrameList[0].size(); const u32 currCount = FrameList[0].size();
InterpolationBuffer.Vertices.set_used(currCount); InterpolationBuffer->Vertices.set_used(currCount);
for (u32 num=0; num<currCount; ++num) for (u32 num=0; num<currCount; ++num)
{ {
InterpolationBuffer.Vertices[num].TCoords = FrameList[0].pointer()[num].TCoords; InterpolationBuffer->Vertices[num].TCoords = FrameList[0].pointer()[num].TCoords;
InterpolationBuffer.Vertices[num].Color = vtx.Color; InterpolationBuffer->Vertices[num].Color = vtx.Color;
} }
} }
@ -658,7 +657,7 @@ bool CAnimatedMeshMD2::loadFile(io::IReadFile* file)
//! calculates the bounding box //! calculates the bounding box
void CAnimatedMeshMD2::calculateBoundingBox() void CAnimatedMeshMD2::calculateBoundingBox()
{ {
InterpolationBuffer.BoundingBox.reset(0,0,0); InterpolationBuffer->BoundingBox.reset(0,0,0);
if (FrameCount) if (FrameCount)
{ {
@ -668,7 +667,7 @@ void CAnimatedMeshMD2::calculateBoundingBox()
defaultFrame = 0; defaultFrame = 0;
for (u32 j=0; j<FrameList[defaultFrame].size(); ++j) for (u32 j=0; j<FrameList[defaultFrame].size(); ++j)
InterpolationBuffer.BoundingBox.addInternalPoint(FrameList[defaultFrame].pointer()[j].Pos); InterpolationBuffer->BoundingBox.addInternalPoint(FrameList[defaultFrame].pointer()[j].Pos);
} }
} }
@ -676,21 +675,21 @@ void CAnimatedMeshMD2::calculateBoundingBox()
//! sets a flag of all contained materials to a new value //! sets a flag of all contained materials to a new value
void CAnimatedMeshMD2::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue) void CAnimatedMeshMD2::setMaterialFlag(video::E_MATERIAL_FLAG flag, bool newvalue)
{ {
InterpolationBuffer.Material.setFlag(flag, newvalue); InterpolationBuffer->Material.setFlag(flag, newvalue);
} }
//! returns an axis aligned bounding box //! returns an axis aligned bounding box
const core::aabbox3d<f32>& CAnimatedMeshMD2::getBoundingBox() const const core::aabbox3d<f32>& CAnimatedMeshMD2::getBoundingBox() const
{ {
return InterpolationBuffer.BoundingBox; return InterpolationBuffer->BoundingBox;
} }
//! set user axis aligned bounding box //! set user axis aligned bounding box
void CAnimatedMeshMD2::setBoundingBox( const core::aabbox3df& box) void CAnimatedMeshMD2::setBoundingBox( const core::aabbox3df& box)
{ {
InterpolationBuffer.BoundingBox = box; InterpolationBuffer->BoundingBox = box;
} }

View File

@ -84,12 +84,9 @@ namespace scene
//! calculates the bounding box //! calculates the bounding box
virtual void calculateBoundingBox(); virtual void calculateBoundingBox();
SMeshBuffer* InterpolationBuffer;
core::array<video::S3DVertex> *FrameList; core::array<video::S3DVertex> *FrameList;
core::array<core::aabbox3d<f32> > BoxList; core::array<core::aabbox3d<f32> > BoxList;
u32 FrameCount;
s32 TriangleCount;
SMeshBuffer InterpolationBuffer;
struct SFrameData struct SFrameData
{ {
@ -100,6 +97,9 @@ namespace scene
}; };
core::array< SFrameData > FrameData; core::array< SFrameData > FrameData;
u32 FrameCount;
s32 TriangleCount;
}; };
} // end namespace scene } // end namespace scene

View File

@ -32,12 +32,14 @@ CParticleSystemSceneNode::CParticleSystemSceneNode(bool createDefaultEmitter,
const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& position, const core::vector3df& rotation,
const core::vector3df& scale) const core::vector3df& scale)
: IParticleSystemSceneNode(parent, mgr, id, position, rotation, scale), : IParticleSystemSceneNode(parent, mgr, id, position, rotation, scale),
Emitter(0), LastEmitTime(0), ParticlesAreGlobal(true) Emitter(0), LastEmitTime(0), MaxParticles(0xffff), Buffer(0),
ParticlesAreGlobal(true)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CParticleSystemSceneNode"); setDebugName("CParticleSystemSceneNode");
#endif #endif
Buffer = new SMeshBuffer();
if (createDefaultEmitter) if (createDefaultEmitter)
{ {
IParticleEmitter* e = createBoxEmitter(); IParticleEmitter* e = createBoxEmitter();
@ -49,18 +51,18 @@ CParticleSystemSceneNode::CParticleSystemSceneNode(bool createDefaultEmitter,
} }
//! destructor //! destructor
CParticleSystemSceneNode::~CParticleSystemSceneNode() CParticleSystemSceneNode::~CParticleSystemSceneNode()
{ {
if (Emitter) if (Emitter)
Emitter->drop(); Emitter->drop();
if (Buffer)
Buffer->drop();
removeAllAffectors(); removeAllAffectors();
} }
//! Sets the particle emitter, which creates the particles. //! Sets the particle emitter, which creates the particles.
void CParticleSystemSceneNode::setEmitter(IParticleEmitter* emitter) void CParticleSystemSceneNode::setEmitter(IParticleEmitter* emitter)
{ {
@ -74,7 +76,6 @@ void CParticleSystemSceneNode::setEmitter(IParticleEmitter* emitter)
} }
//! Adds new particle effector to the particle system. //! Adds new particle effector to the particle system.
void CParticleSystemSceneNode::addAffector(IParticleAffector* affector) void CParticleSystemSceneNode::addAffector(IParticleAffector* affector)
{ {
@ -83,7 +84,6 @@ void CParticleSystemSceneNode::addAffector(IParticleAffector* affector)
} }
//! Removes all particle affectors in the particle system. //! Removes all particle affectors in the particle system.
void CParticleSystemSceneNode::removeAllAffectors() void CParticleSystemSceneNode::removeAllAffectors()
{ {
@ -99,7 +99,7 @@ void CParticleSystemSceneNode::removeAllAffectors()
//! Returns the material based on the zero based index i. //! Returns the material based on the zero based index i.
video::SMaterial& CParticleSystemSceneNode::getMaterial(u32 i) video::SMaterial& CParticleSystemSceneNode::getMaterial(u32 i)
{ {
return Buffer.Material; return Buffer->Material;
} }
@ -323,21 +323,21 @@ void CParticleSystemSceneNode::render()
{ {
const SParticle& particle = Particles[i]; const SParticle& particle = Particles[i];
Buffer.Vertices[0+idx].Pos = particle.pos + horizontal + vertical; Buffer->Vertices[0+idx].Pos = particle.pos + horizontal + vertical;
Buffer.Vertices[0+idx].Color = particle.color; Buffer->Vertices[0+idx].Color = particle.color;
Buffer.Vertices[0+idx].Normal = view; Buffer->Vertices[0+idx].Normal = view;
Buffer.Vertices[1+idx].Pos = particle.pos + horizontal - vertical; Buffer->Vertices[1+idx].Pos = particle.pos + horizontal - vertical;
Buffer.Vertices[1+idx].Color = particle.color; Buffer->Vertices[1+idx].Color = particle.color;
Buffer.Vertices[1+idx].Normal = view; Buffer->Vertices[1+idx].Normal = view;
Buffer.Vertices[2+idx].Pos = particle.pos - horizontal - vertical; Buffer->Vertices[2+idx].Pos = particle.pos - horizontal - vertical;
Buffer.Vertices[2+idx].Color = particle.color; Buffer->Vertices[2+idx].Color = particle.color;
Buffer.Vertices[2+idx].Normal = view; Buffer->Vertices[2+idx].Normal = view;
Buffer.Vertices[3+idx].Pos = particle.pos - horizontal + vertical; Buffer->Vertices[3+idx].Pos = particle.pos - horizontal + vertical;
Buffer.Vertices[3+idx].Color = particle.color; Buffer->Vertices[3+idx].Color = particle.color;
Buffer.Vertices[3+idx].Normal = view; Buffer->Vertices[3+idx].Normal = view;
idx +=4; idx +=4;
} }
@ -348,10 +348,10 @@ void CParticleSystemSceneNode::render()
mat.setTranslation(AbsoluteTransformation.getTranslation()); mat.setTranslation(AbsoluteTransformation.getTranslation());
driver->setTransform(video::ETS_WORLD, mat); driver->setTransform(video::ETS_WORLD, mat);
driver->setMaterial(Buffer.Material); driver->setMaterial(Buffer->Material);
driver->drawVertexPrimitiveList(Buffer.getVertices(), Particles.size()*4, driver->drawVertexPrimitiveList(Buffer->getVertices(), Particles.size()*4,
Buffer.getIndices(), Particles.size()*2, video::EVT_STANDARD, EPT_TRIANGLES); Buffer->getIndices(), Particles.size()*2, video::EVT_STANDARD, EPT_TRIANGLES);
// for debug purposes only: // for debug purposes only:
if ( DebugDataVisible & scene::EDS_BBOX ) if ( DebugDataVisible & scene::EDS_BBOX )
@ -360,7 +360,7 @@ void CParticleSystemSceneNode::render()
video::SMaterial deb_m; video::SMaterial deb_m;
deb_m.Lighting = false; deb_m.Lighting = false;
driver->setMaterial(deb_m); driver->setMaterial(deb_m);
driver->draw3DBox(Buffer.BoundingBox, video::SColor(0,255,255,255)); driver->draw3DBox(Buffer->BoundingBox, video::SColor(0,255,255,255));
} }
} }
@ -369,7 +369,7 @@ void CParticleSystemSceneNode::render()
//! returns the axis aligned bounding box of this node //! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CParticleSystemSceneNode::getBoundingBox() const const core::aabbox3d<f32>& CParticleSystemSceneNode::getBoundingBox() const
{ {
return Buffer.getBoundingBox(); return Buffer->getBoundingBox();
} }
@ -415,9 +415,9 @@ void CParticleSystemSceneNode::doParticleSystem(u32 time)
(*ait)->affect(now, Particles.pointer(), Particles.size()); (*ait)->affect(now, Particles.pointer(), Particles.size());
if (ParticlesAreGlobal) if (ParticlesAreGlobal)
Buffer.BoundingBox.reset(AbsoluteTransformation.getTranslation()); Buffer->BoundingBox.reset(AbsoluteTransformation.getTranslation());
else else
Buffer.BoundingBox.reset(core::vector3df(0,0,0)); Buffer->BoundingBox.reset(core::vector3df(0,0,0));
// animate all particles // animate all particles
f32 scale = (f32)timediff; f32 scale = (f32)timediff;
@ -429,26 +429,26 @@ void CParticleSystemSceneNode::doParticleSystem(u32 time)
else else
{ {
Particles[i].pos += (Particles[i].vector * scale); Particles[i].pos += (Particles[i].vector * scale);
Buffer.BoundingBox.addInternalPoint(Particles[i].pos); Buffer->BoundingBox.addInternalPoint(Particles[i].pos);
++i; ++i;
} }
} }
f32 m = ParticleSize.Width > ParticleSize.Height ? ParticleSize.Width : ParticleSize.Height; f32 m = ParticleSize.Width > ParticleSize.Height ? ParticleSize.Width : ParticleSize.Height;
m *= 0.5f; m *= 0.5f;
Buffer.BoundingBox.MaxEdge.X += m; Buffer->BoundingBox.MaxEdge.X += m;
Buffer.BoundingBox.MaxEdge.Y += m; Buffer->BoundingBox.MaxEdge.Y += m;
Buffer.BoundingBox.MaxEdge.Z += m; Buffer->BoundingBox.MaxEdge.Z += m;
Buffer.BoundingBox.MinEdge.X -= m; Buffer->BoundingBox.MinEdge.X -= m;
Buffer.BoundingBox.MinEdge.Y -= m; Buffer->BoundingBox.MinEdge.Y -= m;
Buffer.BoundingBox.MinEdge.Z -= m; Buffer->BoundingBox.MinEdge.Z -= m;
if (ParticlesAreGlobal) if (ParticlesAreGlobal)
{ {
core::matrix4 absinv = AbsoluteTransformation; core::matrix4 absinv = AbsoluteTransformation;
absinv.makeInverse(); absinv.makeInverse();
absinv.transformBox(Buffer.BoundingBox); absinv.transformBox(Buffer->BoundingBox);
} }
} }
@ -472,36 +472,36 @@ void CParticleSystemSceneNode::setParticleSize(const core::dimension2d<f32> &siz
void CParticleSystemSceneNode::reallocateBuffers() void CParticleSystemSceneNode::reallocateBuffers()
{ {
if (Particles.size() * 4 > Buffer.getVertexCount() || if (Particles.size() * 4 > Buffer->getVertexCount() ||
Particles.size() * 6 > Buffer.getIndexCount()) Particles.size() * 6 > Buffer->getIndexCount())
{ {
u32 oldSize = Buffer.getVertexCount(); u32 oldSize = Buffer->getVertexCount();
Buffer.Vertices.set_used(Particles.size() * 4); Buffer->Vertices.set_used(Particles.size() * 4);
u32 i; u32 i;
// fill remaining vertices // fill remaining vertices
for (i=oldSize; i<Buffer.Vertices.size(); i+=4) for (i=oldSize; i<Buffer->Vertices.size(); i+=4)
{ {
Buffer.Vertices[0+i].TCoords.set(0.0f, 0.0f); Buffer->Vertices[0+i].TCoords.set(0.0f, 0.0f);
Buffer.Vertices[1+i].TCoords.set(0.0f, 1.0f); Buffer->Vertices[1+i].TCoords.set(0.0f, 1.0f);
Buffer.Vertices[2+i].TCoords.set(1.0f, 1.0f); Buffer->Vertices[2+i].TCoords.set(1.0f, 1.0f);
Buffer.Vertices[3+i].TCoords.set(1.0f, 0.0f); Buffer->Vertices[3+i].TCoords.set(1.0f, 0.0f);
} }
// fill remaining indices // fill remaining indices
u32 oldIdxSize = Buffer.getIndexCount(); u32 oldIdxSize = Buffer->getIndexCount();
u32 oldvertices = oldSize; u32 oldvertices = oldSize;
Buffer.Indices.set_used(Particles.size() * 6); Buffer->Indices.set_used(Particles.size() * 6);
for (i=oldIdxSize; i<Buffer.Indices.size(); i+=6) for (i=oldIdxSize; i<Buffer->Indices.size(); i+=6)
{ {
Buffer.Indices[0+i] = 0+oldvertices; Buffer->Indices[0+i] = 0+oldvertices;
Buffer.Indices[1+i] = 2+oldvertices; Buffer->Indices[1+i] = 2+oldvertices;
Buffer.Indices[2+i] = 1+oldvertices; Buffer->Indices[2+i] = 1+oldvertices;
Buffer.Indices[3+i] = 0+oldvertices; Buffer->Indices[3+i] = 0+oldvertices;
Buffer.Indices[4+i] = 3+oldvertices; Buffer->Indices[4+i] = 3+oldvertices;
Buffer.Indices[5+i] = 2+oldvertices; Buffer->Indices[5+i] = 2+oldvertices;
oldvertices += 4; oldvertices += 4;
} }
} }

View File

@ -188,7 +188,7 @@ private:
u32 LastEmitTime; u32 LastEmitTime;
s32 MaxParticles; s32 MaxParticles;
SMeshBuffer Buffer; SMeshBuffer* Buffer;
enum E_PARTICLES_PRIMITIVE enum E_PARTICLES_PRIMITIVE
{ {

View File

@ -25,7 +25,8 @@ CQuake3ShaderSceneNode::CQuake3ShaderSceneNode(
scene::ISceneNode* parent, scene::ISceneManager* mgr,s32 id, scene::ISceneNode* parent, scene::ISceneManager* mgr,s32 id,
io::IFileSystem *fileSystem, scene::IMeshBuffer *buffer, io::IFileSystem *fileSystem, scene::IMeshBuffer *buffer,
const quake3::SShader * shader) const quake3::SShader * shader)
: scene::ISceneNode(parent, mgr, id), Shader ( shader ),TimeAbs ( 0.f ) : scene::ISceneNode(parent, mgr, id), MeshBuffer(0), Original(0),
Shader(shader), TimeAbs(0.f)
{ {
#ifdef _DEBUG #ifdef _DEBUG
core::stringc dName = "CQuake3ShaderSceneNode "; core::stringc dName = "CQuake3ShaderSceneNode ";
@ -34,11 +35,14 @@ CQuake3ShaderSceneNode::CQuake3ShaderSceneNode(
setDebugName( dName.c_str() ); setDebugName( dName.c_str() );
#endif #endif
MeshBuffer = new SMeshBuffer();
Original = new SMeshBufferLightMap();
// name the Scene Node // name the Scene Node
this->Name = Shader->name; this->Name = Shader->name;
// clone meshbuffer to modifiable buffer // clone meshbuffer to modifiable buffer
cloneBuffer ( static_cast< scene::SMeshBufferLightMap *> ( buffer ) ); cloneBuffer( static_cast< scene::SMeshBufferLightMap *> ( buffer ) );
// load all Textures in all stages // load all Textures in all stages
loadTextures ( fileSystem ); loadTextures ( fileSystem );
@ -47,58 +51,63 @@ CQuake3ShaderSceneNode::CQuake3ShaderSceneNode(
} }
CQuake3ShaderSceneNode::~CQuake3ShaderSceneNode()
{
if (MeshBuffer)
MeshBuffer->drop();
if (Original)
Original->drop();
}
/* /*
create single copies create single copies
*/ */
void CQuake3ShaderSceneNode::cloneBuffer ( scene::SMeshBufferLightMap * buffer ) void CQuake3ShaderSceneNode::cloneBuffer ( scene::SMeshBufferLightMap * buffer )
{ {
Original.Material = buffer->Material; Original->Material = buffer->Material;
MeshBuffer.Material = buffer->Material; MeshBuffer->Material = buffer->Material;
Original.Indices = buffer->Indices; Original->Indices = buffer->Indices;
MeshBuffer.Indices = buffer->Indices; MeshBuffer->Indices = buffer->Indices;
const u32 vsize = buffer->Vertices.size (); const u32 vsize = buffer->Vertices.size ();
Original.Vertices.reallocate( vsize ); Original->Vertices.reallocate( vsize );
MeshBuffer.Vertices.reallocate( vsize ); MeshBuffer->Vertices.reallocate( vsize );
for ( u32 i = 0; i!= vsize; ++i ) for ( u32 i = 0; i!= vsize; ++i )
{ {
const video::S3DVertex2TCoords& src = buffer->Vertices[i]; const video::S3DVertex2TCoords& src = buffer->Vertices[i];
// Original has same Vertex Format // Original has same Vertex Format
Original.Vertices.push_back(src); Original->Vertices.push_back(src);
// we have a different vertex format // we have a different vertex format
MeshBuffer.Vertices.push_back(src); MeshBuffer->Vertices.push_back(src);
MeshBuffer.Vertices.getLast().Color=0xFFFFFFFF; MeshBuffer->Vertices.getLast().Color=0xFFFFFFFF;
} }
MeshBuffer.recalculateBoundingBox (); MeshBuffer->recalculateBoundingBox ();
#if 1 #if 1
// move the (temp) Mesh // move the (temp) Mesh
{ {
// original bounding box // original bounding box
core::aabbox3df b = MeshBuffer.getBoundingBox(); const core::aabbox3df& b = MeshBuffer->getBoundingBox();
// set Scene Node Position // set Scene Node Position
setPosition ( b.getCenter() ); setPosition( b.getCenter() );
scene::SMesh * mesh = new SMesh ();
mesh->addMeshBuffer ( &Original );
mesh->addMeshBuffer ( &MeshBuffer );
core::matrix4 m; core::matrix4 m;
m.setTranslation ( -b.getCenter() ); m.setTranslation( -b.getCenter() );
SceneManager->getMeshManipulator()->transformMesh ( mesh, m ); SceneManager->getMeshManipulator()->transform( Original, m );
mesh->drop (); SceneManager->getMeshManipulator()->transform( MeshBuffer, m );
MeshBuffer.recalculateBoundingBox (); MeshBuffer->recalculateBoundingBox ();
} }
#endif #endif
// used for sorting // used for sorting
MeshBuffer.Material.setTexture(0, (video::ITexture*) Shader); MeshBuffer->Material.setTexture(0, (video::ITexture*) Shader);
} }
@ -132,7 +141,7 @@ void CQuake3ShaderSceneNode::loadTextures ( io::IFileSystem * fileSystem )
// our lightmap is passed in material.Texture[2] // our lightmap is passed in material.Texture[2]
if ( mapname == "$lightmap" ) if ( mapname == "$lightmap" )
{ {
Q3Texture [i].Texture.push_back ( Original.getMaterial().getTexture(1) ); Q3Texture [i].Texture.push_back( Original->getMaterial().getTexture(1) );
} }
else else
{ {
@ -193,7 +202,7 @@ void CQuake3ShaderSceneNode::OnRegisterSceneNode()
/* /*
is this a transparent node ? is this a transparent node ?
*/ */
bool CQuake3ShaderSceneNode::isTransparent () bool CQuake3ShaderSceneNode::isTransparent () const
{ {
bool ret = false; bool ret = false;
@ -299,7 +308,7 @@ void CQuake3ShaderSceneNode::render()
material.setTextureMatrix ( 0, texture ); material.setTextureMatrix ( 0, texture );
driver->setMaterial( material ); driver->setMaterial( material );
driver->drawMeshBuffer( &MeshBuffer ); driver->drawMeshBuffer( MeshBuffer );
drawCount += 1; drawCount += 1;
} }
@ -322,11 +331,11 @@ void CQuake3ShaderSceneNode::vertextransform_wave ( f32 dt, quake3::SModifierFun
const f32 phase = function.phase; const f32 phase = function.phase;
const u32 vsize = MeshBuffer.Vertices.size(); const u32 vsize = MeshBuffer->Vertices.size();
for ( u32 i = 0; i != vsize; ++i ) for ( u32 i = 0; i != vsize; ++i )
{ {
const video::S3DVertex2TCoords &src = Original.Vertices[i]; const video::S3DVertex2TCoords &src = Original->Vertices[i];
video::S3DVertex &dst = MeshBuffer.Vertices[i]; video::S3DVertex &dst = MeshBuffer->Vertices[i];
f32 wavephase = (src.Pos.X + src.Pos.Y + src.Pos.Z) * function.wave; f32 wavephase = (src.Pos.X + src.Pos.Y + src.Pos.Z) * function.wave;
function.phase = phase + wavephase; function.phase = phase + wavephase;
@ -349,13 +358,13 @@ void CQuake3ShaderSceneNode::vertextransform_bulge ( f32 dt, quake3::SModifierFu
dt *= function.bulgespeed * 0.1f; dt *= function.bulgespeed * 0.1f;
const f32 phase = function.phase; const f32 phase = function.phase;
const u32 vsize = MeshBuffer.Vertices.size(); const u32 vsize = MeshBuffer->Vertices.size();
for ( u32 i = 0; i != vsize; ++i ) for ( u32 i = 0; i != vsize; ++i )
{ {
const video::S3DVertex2TCoords &src = Original.Vertices[i]; const video::S3DVertex2TCoords &src = Original->Vertices[i];
video::S3DVertex &dst = MeshBuffer.Vertices[i]; video::S3DVertex &dst = MeshBuffer->Vertices[i];
f32 wavephase = (Original.Vertices[i].TCoords.X ) * function.wave; f32 wavephase = (Original->Vertices[i].TCoords.X ) * function.wave;
function.phase = phase + wavephase; function.phase = phase + wavephase;
const f32 f = function.evaluate ( dt ); const f32 f = function.evaluate ( dt );
@ -373,7 +382,7 @@ void CQuake3ShaderSceneNode::vertextransform_autosprite ( f32 dt, quake3::SModif
const core::matrix4 &m = SceneManager->getActiveCamera()->getViewFrustum()->Matrices [ video::ETS_VIEW ]; const core::matrix4 &m = SceneManager->getActiveCamera()->getViewFrustum()->Matrices [ video::ETS_VIEW ];
const core::vector3df view ( -m[2], -m[6] , -m[10] ); const core::vector3df view ( -m[2], -m[6] , -m[10] );
const u32 vsize = MeshBuffer.Vertices.size(); const u32 vsize = MeshBuffer->Vertices.size();
core::aabbox3df box; core::aabbox3df box;
u32 g; u32 g;
@ -381,10 +390,10 @@ void CQuake3ShaderSceneNode::vertextransform_autosprite ( f32 dt, quake3::SModif
for ( u32 i = 0; i < vsize; i += 4 ) for ( u32 i = 0; i < vsize; i += 4 )
{ {
// in pairs of 4 // in pairs of 4
box.reset ( Original.Vertices[i].Pos ); box.reset ( Original->Vertices[i].Pos );
for ( g = 1; g != 4; ++g ) for ( g = 1; g != 4; ++g )
{ {
box.addInternalPoint ( Original.Vertices[i + g].Pos ); box.addInternalPoint ( Original->Vertices[i + g].Pos );
} }
core::vector3df c = box.getCenter (); core::vector3df c = box.getCenter ();
@ -394,15 +403,15 @@ void CQuake3ShaderSceneNode::vertextransform_autosprite ( f32 dt, quake3::SModif
const core::vector3df h ( m[0] * sh, m[4] * sh, m[8] * sh ); const core::vector3df h ( m[0] * sh, m[4] * sh, m[8] * sh );
const core::vector3df v ( m[1] * sv, m[5] * sv, m[9] * sv ); const core::vector3df v ( m[1] * sv, m[5] * sv, m[9] * sv );
MeshBuffer.Vertices[ i + 0 ].Pos = c + h + v; MeshBuffer->Vertices[ i + 0 ].Pos = c + h + v;
MeshBuffer.Vertices[ i + 1 ].Pos = c - h - v; MeshBuffer->Vertices[ i + 1 ].Pos = c - h - v;
MeshBuffer.Vertices[ i + 2 ].Pos = c + h - v; MeshBuffer->Vertices[ i + 2 ].Pos = c + h - v;
MeshBuffer.Vertices[ i + 3 ].Pos = c - h + v; MeshBuffer->Vertices[ i + 3 ].Pos = c - h + v;
MeshBuffer.Vertices[ i + 0 ].Normal = view; MeshBuffer->Vertices[ i + 0 ].Normal = view;
MeshBuffer.Vertices[ i + 1 ].Normal = view; MeshBuffer->Vertices[ i + 1 ].Normal = view;
MeshBuffer.Vertices[ i + 2 ].Normal = view; MeshBuffer->Vertices[ i + 2 ].Normal = view;
MeshBuffer.Vertices[ i + 3 ].Normal = view; MeshBuffer->Vertices[ i + 3 ].Normal = view;
} }
} }
@ -412,19 +421,19 @@ void CQuake3ShaderSceneNode::vertextransform_autosprite ( f32 dt, quake3::SModif
void CQuake3ShaderSceneNode::vertextransform_rgbgen ( f32 dt, quake3::SModifierFunction &function ) void CQuake3ShaderSceneNode::vertextransform_rgbgen ( f32 dt, quake3::SModifierFunction &function )
{ {
u32 i; u32 i;
const u32 vsize = MeshBuffer.Vertices.size(); const u32 vsize = MeshBuffer->Vertices.size();
switch ( function.masterfunc1 ) switch ( function.masterfunc1 )
{ {
case 6: case 6:
//identity //identity
for ( i = 0; i != vsize; ++i ) for ( i = 0; i != vsize; ++i )
MeshBuffer.Vertices[i].Color = 0xFFFFFFFF; MeshBuffer->Vertices[i].Color = 0xFFFFFFFF;
break; break;
case 7: case 7:
// vertex // vertex
for ( i = 0; i != vsize; ++i ) for ( i = 0; i != vsize; ++i )
MeshBuffer.Vertices[i].Color = Original.Vertices[i].Color; MeshBuffer->Vertices[i].Color = Original->Vertices[i].Color;
break; break;
case 5: case 5:
{ {
@ -435,7 +444,7 @@ void CQuake3ShaderSceneNode::vertextransform_rgbgen ( f32 dt, quake3::SModifierF
value |= value << 16; value |= value << 16;
for ( i = 0; i != vsize; ++i ) for ( i = 0; i != vsize; ++i )
MeshBuffer.Vertices[i].Color = value; MeshBuffer->Vertices[i].Color = value;
} break; } break;
} }
} }
@ -448,7 +457,7 @@ void CQuake3ShaderSceneNode::vertextransform_rgbgen ( f32 dt, quake3::SModifierF
void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFunction &function ) void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFunction &function )
{ {
u32 i; u32 i;
const u32 vsize = MeshBuffer.Vertices.size(); const u32 vsize = MeshBuffer->Vertices.size();
switch ( function.tcgen ) switch ( function.tcgen )
{ {
@ -461,8 +470,8 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFu
for ( i = 0; i != vsize; ++i ) for ( i = 0; i != vsize; ++i )
{ {
const video::S3DVertex2TCoords &src = Original.Vertices[i]; const video::S3DVertex2TCoords &src = Original->Vertices[i];
video::S3DVertex &dst = MeshBuffer.Vertices[i]; video::S3DVertex &dst = MeshBuffer->Vertices[i];
f32 wavephase = (src.Pos.X + src.Pos.Y + src.Pos.Z) * function.wave; f32 wavephase = (src.Pos.X + src.Pos.Y + src.Pos.Z) * function.wave;
function.phase = phase + wavephase; function.phase = phase + wavephase;
@ -478,12 +487,12 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFu
case 8: case 8:
// tcgen texture // tcgen texture
for ( i = 0; i != vsize; ++i ) for ( i = 0; i != vsize; ++i )
MeshBuffer.Vertices[i].TCoords = Original.Vertices[i].TCoords; MeshBuffer->Vertices[i].TCoords = Original->Vertices[i].TCoords;
break; break;
case 9: case 9:
// tcgen lightmap // tcgen lightmap
for ( i = 0; i != vsize; ++i ) for ( i = 0; i != vsize; ++i )
MeshBuffer.Vertices[i].TCoords = Original.Vertices[i].TCoords2; MeshBuffer->Vertices[i].TCoords = Original->Vertices[i].TCoords2;
break; break;
case 10: case 10:
{ {
@ -508,11 +517,11 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFu
for ( i = 0; i != vsize; ++i ) for ( i = 0; i != vsize; ++i )
{ {
// vertex in eye space // vertex in eye space
view.transformVect ( v, Original.Vertices[i].Pos ); view.transformVect ( v, Original->Vertices[i].Pos );
v.normalize(); v.normalize();
MeshBuffer.Vertices[i].TCoords.X = (1.f + eyePlaneS.dotProduct ( v ) ) * 0.5f; MeshBuffer->Vertices[i].TCoords.X = (1.f + eyePlaneS.dotProduct ( v ) ) * 0.5f;
MeshBuffer.Vertices[i].TCoords.Y = 1.f - ( (1.f + eyePlaneT.dotProduct ( v ) ) * 0.5f ); MeshBuffer->Vertices[i].TCoords.Y = 1.f - ( (1.f + eyePlaneT.dotProduct ( v ) ) * 0.5f );
} }
} break; } break;
@ -528,7 +537,7 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFu
void CQuake3ShaderSceneNode::transformtex ( const core::matrix4 &m, const u32 addressMode ) void CQuake3ShaderSceneNode::transformtex ( const core::matrix4 &m, const u32 addressMode )
{ {
u32 i; u32 i;
const u32 vsize = MeshBuffer.Vertices.size(); const u32 vsize = MeshBuffer->Vertices.size();
f32 tx1; f32 tx1;
f32 ty1; f32 ty1;
@ -537,7 +546,7 @@ void CQuake3ShaderSceneNode::transformtex ( const core::matrix4 &m, const u32 ad
{ {
for ( i = 0; i != vsize; ++i ) for ( i = 0; i != vsize; ++i )
{ {
core::vector2df &tx = MeshBuffer.Vertices[i].TCoords; core::vector2df &tx = MeshBuffer->Vertices[i].TCoords;
tx1 = m[0] * tx.X + m[4] * tx.Y + m[8]; tx1 = m[0] * tx.X + m[4] * tx.Y + m[8];
ty1 = m[1] * tx.X + m[5] * tx.Y + m[9]; ty1 = m[1] * tx.X + m[5] * tx.Y + m[9];
@ -551,7 +560,7 @@ void CQuake3ShaderSceneNode::transformtex ( const core::matrix4 &m, const u32 ad
for ( i = 0; i != vsize; ++i ) for ( i = 0; i != vsize; ++i )
{ {
core::vector2df &tx = MeshBuffer.Vertices[i].TCoords; core::vector2df &tx = MeshBuffer->Vertices[i].TCoords;
tx1 = m[0] * tx.X + m[4] * tx.Y + m[8]; tx1 = m[0] * tx.X + m[4] * tx.Y + m[8];
ty1 = m[1] * tx.X + m[5] * tx.Y + m[9]; ty1 = m[1] * tx.X + m[5] * tx.Y + m[9];
@ -767,7 +776,7 @@ void CQuake3ShaderSceneNode::OnAnimate(u32 timeMs)
const core::aabbox3d<f32>& CQuake3ShaderSceneNode::getBoundingBox() const const core::aabbox3d<f32>& CQuake3ShaderSceneNode::getBoundingBox() const
{ {
return MeshBuffer.getBoundingBox (); return MeshBuffer->getBoundingBox ();
} }
@ -778,7 +787,7 @@ u32 CQuake3ShaderSceneNode::getMaterialCount() const
video::SMaterial& CQuake3ShaderSceneNode::getMaterial(u32 i) video::SMaterial& CQuake3ShaderSceneNode::getMaterial(u32 i)
{ {
video::SMaterial& m = MeshBuffer.getMaterial(); video::SMaterial& m = MeshBuffer->getMaterial();
m.setTexture(0, 0); m.setTexture(0, 0);
if ( Q3Texture [ i ].TextureIndex ) if ( Q3Texture [ i ].TextureIndex )
m.setTexture(0, Q3Texture [ i ].Texture [ Q3Texture [ i ].TextureIndex ]); m.setTexture(0, Q3Texture [ i ].Texture [ Q3Texture [ i ].TextureIndex ]);

View File

@ -23,8 +23,9 @@ public:
CQuake3ShaderSceneNode( ISceneNode* parent, ISceneManager* mgr,s32 id, CQuake3ShaderSceneNode( ISceneNode* parent, ISceneManager* mgr,s32 id,
io::IFileSystem *fileSystem,IMeshBuffer *buffer, io::IFileSystem *fileSystem,IMeshBuffer *buffer,
const quake3::SShader * shader const quake3::SShader * shader);
);
virtual ~CQuake3ShaderSceneNode();
virtual void OnRegisterSceneNode(); virtual void OnRegisterSceneNode();
virtual void render(); virtual void render();
@ -35,9 +36,9 @@ public:
virtual video::SMaterial& getMaterial(u32 i); virtual video::SMaterial& getMaterial(u32 i);
private: private:
SMeshBuffer MeshBuffer; SMeshBuffer* MeshBuffer;
SMeshBufferLightMap Original; SMeshBufferLightMap* Original;
const quake3::SShader * Shader; const quake3::SShader* Shader;
struct SQ3Texture struct SQ3Texture
{ {
@ -69,7 +70,7 @@ private:
f32 TimeAbs; f32 TimeAbs;
void animate( u32 stage, core::matrix4 &texture ); void animate( u32 stage, core::matrix4 &texture );
bool isTransparent (); bool isTransparent() const;
}; };

View File

@ -31,7 +31,7 @@ namespace scene
CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vertRes, CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vertRes,
f64 texturePercentage, f64 spherePercentage, ISceneNode* parent, ISceneManager* mgr, s32 id) f64 texturePercentage, f64 spherePercentage, ISceneNode* parent, ISceneManager* mgr, s32 id)
: ISceneNode(parent, mgr, id) : ISceneNode(parent, mgr, id), Buffer(0)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CSkyDomeSceneNode"); setDebugName("CSkyDomeSceneNode");
@ -46,12 +46,13 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert
AutomaticCullingState = scene::EAC_OFF; AutomaticCullingState = scene::EAC_OFF;
Buffer.Material.Lighting = false; Buffer = new SMeshBuffer();
Buffer.Material.ZBuffer = false; Buffer->Material.Lighting = false;
Buffer.Material.ZWriteEnable = false; Buffer->Material.ZBuffer = false;
Buffer.Material.setTexture(0, sky); Buffer->Material.ZWriteEnable = false;
Buffer.BoundingBox.MaxEdge.set(0,0,0); Buffer->Material.setTexture(0, sky);
Buffer.BoundingBox.MinEdge.set(0,0,0); Buffer->BoundingBox.MaxEdge.set(0,0,0);
Buffer->BoundingBox.MinEdge.set(0,0,0);
azimuth_step = 2.*core::PI64/(f64)horiRes; azimuth_step = 2.*core::PI64/(f64)horiRes;
if (spherePercentage<0.) if (spherePercentage<0.)
@ -60,8 +61,8 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert
spherePercentage=2.; spherePercentage=2.;
elevation_step = spherePercentage*core::PI64/2./(f64)vertRes; elevation_step = spherePercentage*core::PI64/2./(f64)vertRes;
Buffer.Vertices.reallocate((horiRes+1)*(vertRes+1)); Buffer->Vertices.reallocate((horiRes+1)*(vertRes+1));
Buffer.Indices.reallocate(3*(2*vertRes-1)*horiRes); Buffer->Indices.reallocate(3*(2*vertRes-1)*horiRes);
vtx.Color.set(255,255,255,255); vtx.Color.set(255,255,255,255);
vtx.Normal.set(0.0f,0.0f,0.0f); vtx.Normal.set(0.0f,0.0f,0.0f);
@ -82,7 +83,7 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert
vtx.TCoords.set(tcU, (f32)j*tcV); vtx.TCoords.set(tcU, (f32)j*tcV);
Buffer.Vertices.push_back(vtx); Buffer->Vertices.push_back(vtx);
elevation -= elevation_step; elevation -= elevation_step;
} }
azimuth += azimuth_step; azimuth += azimuth_step;
@ -90,24 +91,31 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert
for (k = 0; k < horiRes; ++k) for (k = 0; k < horiRes; ++k)
{ {
Buffer.Indices.push_back(vertRes+2+(vertRes+1)*k); Buffer->Indices.push_back(vertRes+2+(vertRes+1)*k);
Buffer.Indices.push_back(1+(vertRes+1)*k); Buffer->Indices.push_back(1+(vertRes+1)*k);
Buffer.Indices.push_back(0+(vertRes+1)*k); Buffer->Indices.push_back(0+(vertRes+1)*k);
for (u32 j = 1; j < vertRes; ++j) for (u32 j = 1; j < vertRes; ++j)
{ {
Buffer.Indices.push_back(vertRes+2+(vertRes+1)*k+j); Buffer->Indices.push_back(vertRes+2+(vertRes+1)*k+j);
Buffer.Indices.push_back(1+(vertRes+1)*k+j); Buffer->Indices.push_back(1+(vertRes+1)*k+j);
Buffer.Indices.push_back(0+(vertRes+1)*k+j); Buffer->Indices.push_back(0+(vertRes+1)*k+j);
Buffer.Indices.push_back(vertRes+1+(vertRes+1)*k+j); Buffer->Indices.push_back(vertRes+1+(vertRes+1)*k+j);
Buffer.Indices.push_back(vertRes+2+(vertRes+1)*k+j); Buffer->Indices.push_back(vertRes+2+(vertRes+1)*k+j);
Buffer.Indices.push_back(0+(vertRes+1)*k+j); Buffer->Indices.push_back(0+(vertRes+1)*k+j);
} }
} }
} }
CSkyDomeSceneNode::~CSkyDomeSceneNode()
{
if (Buffer)
Buffer->drop();
}
//! renders the node. //! renders the node.
void CSkyDomeSceneNode::render() void CSkyDomeSceneNode::render()
{ {
@ -124,15 +132,16 @@ void CSkyDomeSceneNode::render()
driver->setTransform(video::ETS_WORLD, mat); driver->setTransform(video::ETS_WORLD, mat);
driver->setMaterial(Buffer.Material); driver->setMaterial(Buffer->Material);
driver->drawMeshBuffer(&Buffer); driver->drawMeshBuffer(Buffer);
} }
} }
//! returns the axis aligned bounding box of this node //! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CSkyDomeSceneNode::getBoundingBox() const const core::aabbox3d<f32>& CSkyDomeSceneNode::getBoundingBox() const
{ {
return Buffer.BoundingBox; return Buffer->BoundingBox;
} }
@ -152,7 +161,7 @@ void CSkyDomeSceneNode::OnRegisterSceneNode()
//! to directly modify the material of a scene node. //! to directly modify the material of a scene node.
video::SMaterial& CSkyDomeSceneNode::getMaterial(u32 i) video::SMaterial& CSkyDomeSceneNode::getMaterial(u32 i)
{ {
return Buffer.Material; return Buffer->Material;
} }

View File

@ -18,8 +18,9 @@ class CSkyDomeSceneNode : public ISceneNode
{ {
public: public:
CSkyDomeSceneNode(video::ITexture* texture, u32 horiRes, u32 vertRes, CSkyDomeSceneNode(video::ITexture* texture, u32 horiRes, u32 vertRes,
f64 texturePercentage, f64 spherePercentage, ISceneNode* root, f64 texturePercentage, f64 spherePercentage,
ISceneManager* smgr, s32 id); ISceneNode* root, ISceneManager* smgr, s32 id);
virtual ~CSkyDomeSceneNode();
virtual void OnRegisterSceneNode(); virtual void OnRegisterSceneNode();
virtual void render(); virtual void render();
virtual const core::aabbox3d<f32>& getBoundingBox() const; virtual const core::aabbox3d<f32>& getBoundingBox() const;
@ -28,7 +29,7 @@ class CSkyDomeSceneNode : public ISceneNode
virtual ESCENE_NODE_TYPE getType() const { return ESNT_SKY_BOX; } virtual ESCENE_NODE_TYPE getType() const { return ESNT_SKY_BOX; }
private: private:
SMeshBuffer Buffer; SMeshBuffer* Buffer;
}; };

View File

@ -33,7 +33,7 @@ namespace scene
const core::vector3df& rotation, const core::vector3df& rotation,
const core::vector3df& scale) const core::vector3df& scale)
: ITerrainSceneNode(parent, mgr, id, position, rotation, scale), : ITerrainSceneNode(parent, mgr, id, position, rotation, scale),
TerrainData(patchSize, maxLOD, position, rotation, scale), TerrainData(patchSize, maxLOD, position, rotation, scale), RenderBuffer(0),
VerticesToRender(0), IndicesToRender(0), DynamicSelectorUpdate(false), VerticesToRender(0), IndicesToRender(0), DynamicSelectorUpdate(false),
OverrideDistanceThreshold(false), UseDefaultRotationPivot(true), ForceRecalculation(false), OverrideDistanceThreshold(false), UseDefaultRotationPivot(true), ForceRecalculation(false),
OldCameraPosition(core::vector3df(-99999.9f, -99999.9f, -99999.9f)), OldCameraPosition(core::vector3df(-99999.9f, -99999.9f, -99999.9f)),
@ -45,6 +45,8 @@ namespace scene
setDebugName("CTerrainSceneNode"); setDebugName("CTerrainSceneNode");
#endif #endif
RenderBuffer = new SMeshBufferLightMap();
if (FileSystem) if (FileSystem)
FileSystem->grab(); FileSystem->grab();
@ -61,6 +63,9 @@ namespace scene
if (FileSystem) if (FileSystem)
FileSystem->drop(); FileSystem->drop();
if (RenderBuffer)
RenderBuffer->drop();
} }
@ -161,13 +166,13 @@ namespace scene
const u32 vertexCount = mb->getVertexCount(); const u32 vertexCount = mb->getVertexCount();
// We copy the data to the renderBuffer, after the normals have been calculated. // We copy the data to the renderBuffer, after the normals have been calculated.
RenderBuffer.Vertices.set_used( vertexCount ); RenderBuffer->Vertices.set_used( vertexCount );
for( u32 i = 0; i < vertexCount; ++i ) for( u32 i = 0; i < vertexCount; ++i )
{ {
RenderBuffer.Vertices[i] = mb->Vertices[i]; RenderBuffer->Vertices[i] = mb->Vertices[i];
RenderBuffer.Vertices[i].Pos *= TerrainData.Scale; RenderBuffer->Vertices[i].Pos *= TerrainData.Scale;
RenderBuffer.Vertices[i].Pos += TerrainData.Position; RenderBuffer->Vertices[i].Pos += TerrainData.Position;
} }
// We no longer need the mb // We no longer need the mb
@ -187,10 +192,10 @@ namespace scene
setRotation( TerrainData.Rotation ); setRotation( TerrainData.Rotation );
// Pre-allocate memory for indices // Pre-allocate memory for indices
RenderBuffer.Indices.set_used( TerrainData.PatchCount * TerrainData.PatchCount * RenderBuffer->Indices.set_used( TerrainData.PatchCount * TerrainData.PatchCount *
TerrainData.CalcPatchSize * TerrainData.CalcPatchSize * 6 ); TerrainData.CalcPatchSize * TerrainData.CalcPatchSize * 6 );
RenderBuffer.setDirty(); RenderBuffer->setDirty();
const u32 endTime = os::Timer::getRealTime(); const u32 endTime = os::Timer::getRealTime();
@ -297,13 +302,13 @@ namespace scene
const u32 vertexCount = mb->getVertexCount(); const u32 vertexCount = mb->getVertexCount();
// We copy the data to the renderBuffer, after the normals have been calculated. // We copy the data to the renderBuffer, after the normals have been calculated.
RenderBuffer.Vertices.set_used( vertexCount ); RenderBuffer->Vertices.set_used( vertexCount );
for( u32 i = 0; i < vertexCount; i++ ) for( u32 i = 0; i < vertexCount; i++ )
{ {
RenderBuffer.Vertices[i] = mb->Vertices[i]; RenderBuffer->Vertices[i] = mb->Vertices[i];
RenderBuffer.Vertices[i].Pos *= TerrainData.Scale; RenderBuffer->Vertices[i].Pos *= TerrainData.Scale;
RenderBuffer.Vertices[i].Pos += TerrainData.Position; RenderBuffer->Vertices[i].Pos += TerrainData.Position;
} }
// We no longer need the mb // We no longer need the mb
@ -323,7 +328,7 @@ namespace scene
setRotation( TerrainData.Rotation ); setRotation( TerrainData.Rotation );
// Pre-allocate memory for indices // Pre-allocate memory for indices
RenderBuffer.Indices.set_used( TerrainData.PatchCount * TerrainData.PatchCount * RenderBuffer->Indices.set_used( TerrainData.PatchCount * TerrainData.PatchCount *
TerrainData.CalcPatchSize * TerrainData.CalcPatchSize * 6 ); TerrainData.CalcPatchSize * TerrainData.CalcPatchSize * 6 );
u32 endTime = os::Timer::getTime(); u32 endTime = os::Timer::getTime();
@ -388,17 +393,17 @@ namespace scene
for( s32 i = 0; i < vtxCount; ++i ) for( s32 i = 0; i < vtxCount; ++i )
{ {
RenderBuffer.Vertices[i].Pos = meshVertices[i].Pos * TerrainData.Scale + TerrainData.Position; RenderBuffer->Vertices[i].Pos = meshVertices[i].Pos * TerrainData.Scale + TerrainData.Position;
RenderBuffer.Vertices[i].Pos -= TerrainData.RotationPivot; RenderBuffer->Vertices[i].Pos -= TerrainData.RotationPivot;
rotMatrix.inverseRotateVect( RenderBuffer.Vertices[i].Pos ); rotMatrix.inverseRotateVect( RenderBuffer->Vertices[i].Pos );
RenderBuffer.Vertices[i].Pos += TerrainData.RotationPivot; RenderBuffer->Vertices[i].Pos += TerrainData.RotationPivot;
} }
calculateDistanceThresholds( true ); calculateDistanceThresholds( true );
calculatePatchData(); calculatePatchData();
RenderBuffer.setDirty(EBT_VERTEX); RenderBuffer->setDirty(EBT_VERTEX);
} }
@ -448,7 +453,8 @@ namespace scene
// Determine each patches LOD based on distance from camera ( and whether or not they are in // Determine each patches LOD based on distance from camera ( and whether or not they are in
// the view frustum ). // the view frustum ).
for( s32 j = 0; j < TerrainData.PatchCount * TerrainData.PatchCount; ++j ) const s32 count = TerrainData.PatchCount * TerrainData.PatchCount;
for( s32 j = 0; j < count; ++j )
{ {
if( frustum->getBoundingBox().intersectsWithBox( TerrainData.Patches[j].BoundingBox ) ) if( frustum->getBoundingBox().intersectsWithBox( TerrainData.Patches[j].BoundingBox ) )
{ {
@ -508,12 +514,12 @@ namespace scene
index12 = getIndex( j, i, index, x, z + step ); index12 = getIndex( j, i, index, x, z + step );
index22 = getIndex( j, i, index, x + step, z + step ); index22 = getIndex( j, i, index, x + step, z + step );
RenderBuffer.Indices[IndicesToRender++] = index12; RenderBuffer->Indices[IndicesToRender++] = index12;
RenderBuffer.Indices[IndicesToRender++] = index11; RenderBuffer->Indices[IndicesToRender++] = index11;
RenderBuffer.Indices[IndicesToRender++] = index22; RenderBuffer->Indices[IndicesToRender++] = index22;
RenderBuffer.Indices[IndicesToRender++] = index22; RenderBuffer->Indices[IndicesToRender++] = index22;
RenderBuffer.Indices[IndicesToRender++] = index11; RenderBuffer->Indices[IndicesToRender++] = index11;
RenderBuffer.Indices[IndicesToRender++] = index21; RenderBuffer->Indices[IndicesToRender++] = index21;
// increment index position horizontally // increment index position horizontally
x += step; x += step;
@ -528,7 +534,7 @@ namespace scene
} }
} }
RenderBuffer.setDirty(EBT_INDEX); RenderBuffer->setDirty(EBT_INDEX);
if ( DynamicSelectorUpdate && TriangleSelector ) if ( DynamicSelectorUpdate && TriangleSelector )
{ {
@ -554,12 +560,12 @@ namespace scene
driver->setMaterial(Mesh.getMeshBuffer(0)->getMaterial()); driver->setMaterial(Mesh.getMeshBuffer(0)->getMaterial());
RenderBuffer.Indices.set_used(IndicesToRender); RenderBuffer->Indices.set_used(IndicesToRender);
// For use with geomorphing // For use with geomorphing
driver->drawMeshBuffer(&RenderBuffer); driver->drawMeshBuffer(RenderBuffer);
RenderBuffer.Indices.set_used( RenderBuffer.Indices.allocated_size() ); RenderBuffer->Indices.set_used( RenderBuffer->Indices.allocated_size() );
// for debug purposes only: // for debug purposes only:
if (DebugDataVisible) if (DebugDataVisible)
@ -759,7 +765,8 @@ namespace scene
s32 numLODs; s32 numLODs;
LODs.clear ( ); LODs.clear ( );
for ( numLODs = 0; numLODs < TerrainData.PatchCount * TerrainData.PatchCount; numLODs++ ) const s32 count = TerrainData.PatchCount * TerrainData.PatchCount;
for ( numLODs = 0; numLODs < count; numLODs++ )
LODs.push_back ( TerrainData.Patches[numLODs].CurrentLOD ); LODs.push_back ( TerrainData.Patches[numLODs].CurrentLOD );
return LODs.size(); return LODs.size();
@ -808,17 +815,17 @@ namespace scene
zval=z2val=0; zval=z2val=0;
for (s32 z=0; z<TerrainData.Size; ++z) for (s32 z=0; z<TerrainData.Size; ++z)
{ {
RenderBuffer.Vertices[index].TCoords.X = xval; RenderBuffer->Vertices[index].TCoords.X = xval;
RenderBuffer.Vertices[index].TCoords.Y = zval; RenderBuffer->Vertices[index].TCoords.Y = zval;
if ( resolution2 == 0 ) if ( resolution2 == 0 )
{ {
RenderBuffer.Vertices[index].TCoords2 = RenderBuffer.Vertices[index].TCoords; RenderBuffer->Vertices[index].TCoords2 = RenderBuffer->Vertices[index].TCoords;
} }
else else
{ {
RenderBuffer.Vertices[index].TCoords2.X = x2val; RenderBuffer->Vertices[index].TCoords2.X = x2val;
RenderBuffer.Vertices[index].TCoords2.Y = z2val; RenderBuffer->Vertices[index].TCoords2.Y = z2val;
} }
++index; ++index;
zval += resBySize; zval += resBySize;
@ -828,7 +835,7 @@ namespace scene
x2val += res2BySize; x2val += res2BySize;
} }
RenderBuffer.setDirty(EBT_VERTEX); RenderBuffer->setDirty(EBT_VERTEX);
} }
//! used to get the indices when generating index data for patches at varying levels of detail. //! used to get the indices when generating index data for patches at varying levels of detail.
@ -1061,7 +1068,7 @@ namespace scene
for( s32 xx = x*(TerrainData.CalcPatchSize); xx <= ( x + 1 ) * TerrainData.CalcPatchSize; ++xx ) for( s32 xx = x*(TerrainData.CalcPatchSize); xx <= ( x + 1 ) * TerrainData.CalcPatchSize; ++xx )
for( s32 zz = z*(TerrainData.CalcPatchSize); zz <= ( z + 1 ) * TerrainData.CalcPatchSize; ++zz ) for( s32 zz = z*(TerrainData.CalcPatchSize); zz <= ( z + 1 ) * TerrainData.CalcPatchSize; ++zz )
TerrainData.Patches[index].BoundingBox.addInternalPoint( RenderBuffer.Vertices[xx * TerrainData.Size + zz].Pos ); TerrainData.Patches[index].BoundingBox.addInternalPoint( RenderBuffer->Vertices[xx * TerrainData.Size + zz].Pos );
// Reconfigure the bounding box of the terrain as a whole // Reconfigure the bounding box of the terrain as a whole
TerrainData.BoundingBox.addInternalBox( TerrainData.Patches[index].BoundingBox ); TerrainData.BoundingBox.addInternalBox( TerrainData.Patches[index].BoundingBox );
@ -1133,13 +1140,15 @@ namespace scene
void CTerrainSceneNode::setCurrentLODOfPatches(s32 lod) void CTerrainSceneNode::setCurrentLODOfPatches(s32 lod)
{ {
for (s32 i=0; i< TerrainData.PatchCount * TerrainData.PatchCount; ++i) const s32 count = TerrainData.PatchCount * TerrainData.PatchCount;
for (s32 i=0; i< count; ++i)
TerrainData.Patches[i].CurrentLOD = lod; TerrainData.Patches[i].CurrentLOD = lod;
} }
void CTerrainSceneNode::setCurrentLODOfPatches(const core::array<s32>& lodarray) void CTerrainSceneNode::setCurrentLODOfPatches(const core::array<s32>& lodarray)
{ {
for (s32 i=0; i<TerrainData.PatchCount * TerrainData.PatchCount; ++i) const s32 count = TerrainData.PatchCount * TerrainData.PatchCount;
for (s32 i=0; i<count; ++i)
TerrainData.Patches[i].CurrentLOD = lodarray[i]; TerrainData.Patches[i].CurrentLOD = lodarray[i];
} }
@ -1283,7 +1292,7 @@ namespace scene
} }
} }
nb->RenderBuffer.Material = RenderBuffer.Material; nb->RenderBuffer->Material = RenderBuffer->Material;
// finish // finish

View File

@ -137,8 +137,7 @@ namespace scene
virtual IMesh* getMesh() { return &Mesh; } virtual IMesh* getMesh() { return &Mesh; }
//! Returns a pointer to the buffer used by the terrain (most users will not need this) //! Returns a pointer to the buffer used by the terrain (most users will not need this)
virtual IMeshBuffer* getRenderBuffer() { return &RenderBuffer; } virtual IMeshBuffer* getRenderBuffer() { return RenderBuffer; }
//! Gets the meshbuffer data based on a specified Level of Detail. //! Gets the meshbuffer data based on a specified Level of Detail.
//! \param mb: A reference to an SMeshBufferLightMap object //! \param mb: A reference to an SMeshBufferLightMap object
@ -308,7 +307,7 @@ namespace scene
STerrainData TerrainData; STerrainData TerrainData;
SMesh Mesh; SMesh Mesh;
SMeshBufferLightMap RenderBuffer; SMeshBufferLightMap* RenderBuffer;
u32 VerticesToRender; u32 VerticesToRender;
u32 IndicesToRender; u32 IndicesToRender;

View File

@ -14,47 +14,49 @@ namespace scene
//! constructor //! constructor
CTerrainTriangleSelector::CTerrainTriangleSelector ( ITerrainSceneNode* node, s32 LOD ) CTerrainTriangleSelector::CTerrainTriangleSelector ( ITerrainSceneNode* node, s32 LOD )
: SceneNode ( node ) : SceneNode(node)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName ("CTerrainTriangleSelector"); setDebugName ("CTerrainTriangleSelector");
#endif #endif
setTriangleData ( node, LOD ); setTriangleData(node, LOD);
} }
//! destructor //! destructor
CTerrainTriangleSelector::~CTerrainTriangleSelector() CTerrainTriangleSelector::~CTerrainTriangleSelector()
{ {
TrianglePatches.TrianglePatchArray.clear ( ); TrianglePatches.TrianglePatchArray.clear();
} }
//! Clears and sets triangle data //! Clears and sets triangle data
void CTerrainTriangleSelector::setTriangleData(ITerrainSceneNode* node, s32 LOD) void CTerrainTriangleSelector::setTriangleData(ITerrainSceneNode* node, s32 LOD)
{ {
core::triangle3df tri; core::triangle3df tri;
core::array<u32> indices; core::array<u32> indices;
CTerrainSceneNode* terrainNode = (CTerrainSceneNode*)node;
// Get pointer to the GeoMipMaps vertices // Get pointer to the GeoMipMaps vertices
video::S3DVertex2TCoords* vertices = (video::S3DVertex2TCoords*)terrainNode->RenderBuffer.getVertices(); video::S3DVertex2TCoords* vertices = static_cast<video::S3DVertex2TCoords*>(node->getRenderBuffer()->getVertices());
// Clear current data // Clear current data
const s32 count = (static_cast<CTerrainSceneNode*>(node))->TerrainData.PatchCount;
TrianglePatches.TotalTriangles = 0; TrianglePatches.TotalTriangles = 0;
TrianglePatches.NumPatches = terrainNode->TerrainData.PatchCount * terrainNode->TerrainData.PatchCount; TrianglePatches.NumPatches = count*count;
TrianglePatches.TrianglePatchArray.reallocate(TrianglePatches.NumPatches); TrianglePatches.TrianglePatchArray.reallocate(TrianglePatches.NumPatches);
for (int o=0; o<TrianglePatches.NumPatches; ++o) for (s32 o=0; o<TrianglePatches.NumPatches; ++o)
TrianglePatches.TrianglePatchArray.push_back(SGeoMipMapTrianglePatch()); TrianglePatches.TrianglePatchArray.push_back(SGeoMipMapTrianglePatch());
s32 tIndex = 0; s32 tIndex = 0;
for(s32 x = 0; x < terrainNode->TerrainData.PatchCount; ++x ) for(s32 x = 0; x < count; ++x )
{ {
for(s32 z = 0; z < terrainNode->TerrainData.PatchCount; ++z ) for(s32 z = 0; z < count; ++z )
{ {
TrianglePatches.TrianglePatchArray[tIndex].NumTriangles = 0; TrianglePatches.TrianglePatchArray[tIndex].NumTriangles = 0;
TrianglePatches.TrianglePatchArray[tIndex].Box = terrainNode->getBoundingBox( x, z ); TrianglePatches.TrianglePatchArray[tIndex].Box = node->getBoundingBox( x, z );
u32 indexCount = terrainNode->getIndicesForPatch( indices, x, z, LOD ); u32 indexCount = node->getIndicesForPatch( indices, x, z, LOD );
TrianglePatches.TrianglePatchArray[tIndex].Triangles.reallocate(indexCount/3); TrianglePatches.TrianglePatchArray[tIndex].Triangles.reallocate(indexCount/3);
for(u32 i = 0; i < indexCount; i += 3 ) for(u32 i = 0; i < indexCount; i += 3 )
@ -106,6 +108,7 @@ void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32
outTriangleCount = tIndex; outTriangleCount = tIndex;
} }
//! Gets all triangles which lie within a specific bounding box. //! Gets all triangles which lie within a specific bounding box.
void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32 arraySize, void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::aabbox3d<f32>& box, s32& outTriangleCount, const core::aabbox3d<f32>& box,

View File

@ -31,22 +31,33 @@ CVolumeLightSceneNode::CVolumeLightSceneNode(ISceneNode* parent, ISceneManager*
setDebugName("CVolumeLightSceneNode"); setDebugName("CVolumeLightSceneNode");
#endif #endif
Buffer.setHardwareMappingHint(EHM_STATIC); Buffer = new SMeshBuffer();
if (Buffer)
{
Buffer->setHardwareMappingHint(EHM_STATIC);
constructLight(); constructLight();
}
}
CVolumeLightSceneNode::~CVolumeLightSceneNode()
{
if (Buffer)
Buffer->drop();
} }
void CVolumeLightSceneNode::addToBuffer(video::S3DVertex v) void CVolumeLightSceneNode::addToBuffer(video::S3DVertex v)
{ {
const s32 tnidx = Buffer.Vertices.linear_reverse_search(v); const s32 tnidx = Buffer->Vertices.linear_reverse_search(v);
const bool alreadyIn = (tnidx != -1); const bool alreadyIn = (tnidx != -1);
u16 nidx = (u16)tnidx; u16 nidx = (u16)tnidx;
if (!alreadyIn) { if (!alreadyIn) {
nidx = Buffer.Vertices.size(); nidx = Buffer->Vertices.size();
Buffer.Indices.push_back(nidx); Buffer->Indices.push_back(nidx);
Buffer.Vertices.push_back(v); Buffer->Vertices.push_back(v);
} else } else
Buffer.Indices.push_back(nidx); Buffer->Indices.push_back(nidx);
} }
@ -56,10 +67,10 @@ void CVolumeLightSceneNode::constructLight()
const f32 ax = LightDimensions.X * 0.5f; // X Axis const f32 ax = LightDimensions.X * 0.5f; // X Axis
const f32 az = LightDimensions.Z * 0.5f; // Z Axis const f32 az = LightDimensions.Z * 0.5f; // Z Axis
Buffer.Vertices.clear(); Buffer->Vertices.clear();
Buffer.Vertices.reallocate(6+12*(SubdivideU+SubdivideV)); Buffer->Vertices.reallocate(6+12*(SubdivideU+SubdivideV));
Buffer.Indices.clear(); Buffer->Indices.clear();
Buffer.Indices.reallocate(6+12*(SubdivideU+SubdivideV)); Buffer->Indices.reallocate(6+12*(SubdivideU+SubdivideV));
//draw the bottom foot.. the glowing region //draw the bottom foot.. the glowing region
addToBuffer(video::S3DVertex(-ax, 0, az, 0,0,0, FootColour, 0, 1)); addToBuffer(video::S3DVertex(-ax, 0, az, 0,0,0, FootColour, 0, 1));
addToBuffer(video::S3DVertex(ax , 0, az, 0,0,0, FootColour, 1, 1)); addToBuffer(video::S3DVertex(ax , 0, az, 0,0,0, FootColour, 1, 1));
@ -161,33 +172,36 @@ void CVolumeLightSceneNode::constructLight()
bz += bzStep; bz += bzStep;
} }
Buffer.recalculateBoundingBox(); Buffer->recalculateBoundingBox();
Buffer.Material.MaterialType = video::EMT_ONETEXTURE_BLEND; Buffer->Material.MaterialType = video::EMT_ONETEXTURE_BLEND;
Buffer.Material.MaterialTypeParam = pack_texureBlendFunc( video::EBF_SRC_COLOR, video::EBF_SRC_ALPHA, video::EMFN_MODULATE_1X ); Buffer->Material.MaterialTypeParam = pack_texureBlendFunc( video::EBF_SRC_COLOR, video::EBF_SRC_ALPHA, video::EMFN_MODULATE_1X );
Buffer.Material.Lighting = false; Buffer->Material.Lighting = false;
Buffer.Material.ZWriteEnable = false; Buffer->Material.ZWriteEnable = false;
Buffer.setDirty(EBT_VERTEX_AND_INDEX); Buffer->setDirty(EBT_VERTEX_AND_INDEX);
} }
//! renders the node. //! renders the node.
void CVolumeLightSceneNode::render() void CVolumeLightSceneNode::render()
{ {
if (!Buffer)
return;
video::IVideoDriver* driver = SceneManager->getVideoDriver(); video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->setMaterial(Buffer.Material); driver->setMaterial(Buffer->Material);
driver->drawMeshBuffer(&Buffer); driver->drawMeshBuffer(Buffer);
} }
//! returns the axis aligned bounding box of this node //! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CVolumeLightSceneNode::getBoundingBox() const const core::aabbox3d<f32>& CVolumeLightSceneNode::getBoundingBox() const
{ {
return Buffer.BoundingBox; return Buffer->BoundingBox;
} }
@ -208,7 +222,7 @@ void CVolumeLightSceneNode::OnRegisterSceneNode()
//! to directly modify the material of a scene node. //! to directly modify the material of a scene node.
video::SMaterial& CVolumeLightSceneNode::getMaterial(u32 i) video::SMaterial& CVolumeLightSceneNode::getMaterial(u32 i)
{ {
return Buffer.Material; return Buffer->Material;
} }
@ -298,7 +312,7 @@ ISceneNode* CVolumeLightSceneNode::clone(ISceneNode* newParent, ISceneManager* n
newManager, ID, SubdivideU, SubdivideV, FootColour, TailColour, RelativeTranslation); newManager, ID, SubdivideU, SubdivideV, FootColour, TailColour, RelativeTranslation);
nb->cloneMembers(this, newManager); nb->cloneMembers(this, newManager);
nb->Buffer.Material = Buffer.Material; nb->Buffer->Material = Buffer->Material;
nb->drop(); nb->drop();
return nb; return nb;

View File

@ -27,6 +27,8 @@ namespace scene
const core::vector3df& rotation = core::vector3df(0,0,0), const core::vector3df& rotation = core::vector3df(0,0,0),
const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f)); const core::vector3df& scale = core::vector3df(1.0f, 1.0f, 1.0f));
virtual ~CVolumeLightSceneNode();
virtual void OnRegisterSceneNode(); virtual void OnRegisterSceneNode();
//! renders the node. //! renders the node.
@ -73,7 +75,7 @@ namespace scene
void addToBuffer(video::S3DVertex v); void addToBuffer(video::S3DVertex v);
void constructLight(); void constructLight();
SMeshBuffer Buffer; SMeshBuffer* Buffer;
f32 LPDistance; // Distance to hypothetical lightsource point -- affects fov angle f32 LPDistance; // Distance to hypothetical lightsource point -- affects fov angle