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
CAnimatedMeshMD2::CAnimatedMeshMD2()
: FrameList(0), FrameCount(0), TriangleCount(0)
: InterpolationBuffer(0), FrameList(0), FrameCount(0), TriangleCount(0)
{
#ifdef _DEBUG
IAnimatedMesh::setDebugName("CAnimatedMeshMD2 IAnimatedMesh");
IMesh::setDebugName("CAnimatedMeshMD2 IMesh");
#endif
InterpolationBuffer = new SMeshBuffer;
}
//! destructor
CAnimatedMeshMD2::~CAnimatedMeshMD2()
{
if (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.
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.
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
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
IMeshBuffer* CAnimatedMeshMD2::getMeshBuffer(const video::SMaterial &material) const
{
if (InterpolationBuffer.Material == material)
return const_cast<IMeshBuffer*>(reinterpret_cast<const IMeshBuffer*>(&InterpolationBuffer));
if (InterpolationBuffer->Material == material)
return InterpolationBuffer;
else
return 0;
}
@ -398,7 +397,7 @@ void CAnimatedMeshMD2::updateInterpolationBuffer(s32 frame, s32 startFrameLoop,
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* second = FrameList[secondFrame].pointer();
@ -415,8 +414,8 @@ void CAnimatedMeshMD2::updateInterpolationBuffer(s32 frame, s32 startFrameLoop,
}
//update bounding box
InterpolationBuffer.setBoundingBox(BoxList[secondFrame].getInterpolated(BoxList[firstFrame], div));
InterpolationBuffer.setDirty();
InterpolationBuffer->setBoundingBox(BoxList[secondFrame].getInterpolated(BoxList[firstFrame], div));
InterpolationBuffer->setDirty();
}
@ -618,25 +617,25 @@ bool CAnimatedMeshMD2::loadFile(io::IReadFile* file)
// create indices
InterpolationBuffer.Indices.reallocate(header.numVertices);
s16 count = TriangleCount*3;
for (s16 n=0; n<count; n+=3)
InterpolationBuffer->Indices.reallocate(header.numVertices);
const u32 count = TriangleCount*3;
for (u32 n=0; n<count; n+=3)
{
InterpolationBuffer.Indices.push_back(n);
InterpolationBuffer.Indices.push_back(n+1);
InterpolationBuffer.Indices.push_back(n+2);
InterpolationBuffer->Indices.push_back(n);
InterpolationBuffer->Indices.push_back(n+1);
InterpolationBuffer->Indices.push_back(n+2);
}
// reallocate interpolate buffer
if (header.numFrames)
{
u32 currCount = FrameList[0].size();
InterpolationBuffer.Vertices.set_used(currCount);
const u32 currCount = FrameList[0].size();
InterpolationBuffer->Vertices.set_used(currCount);
for (u32 num=0; num<currCount; ++num)
{
InterpolationBuffer.Vertices[num].TCoords = FrameList[0].pointer()[num].TCoords;
InterpolationBuffer.Vertices[num].Color = vtx.Color;
InterpolationBuffer->Vertices[num].TCoords = FrameList[0].pointer()[num].TCoords;
InterpolationBuffer->Vertices[num].Color = vtx.Color;
}
}
@ -658,7 +657,7 @@ bool CAnimatedMeshMD2::loadFile(io::IReadFile* file)
//! calculates the bounding box
void CAnimatedMeshMD2::calculateBoundingBox()
{
InterpolationBuffer.BoundingBox.reset(0,0,0);
InterpolationBuffer->BoundingBox.reset(0,0,0);
if (FrameCount)
{
@ -668,7 +667,7 @@ void CAnimatedMeshMD2::calculateBoundingBox()
defaultFrame = 0;
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
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
const core::aabbox3d<f32>& CAnimatedMeshMD2::getBoundingBox() const
{
return InterpolationBuffer.BoundingBox;
return InterpolationBuffer->BoundingBox;
}
//! set user axis aligned bounding 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
virtual void calculateBoundingBox();
SMeshBuffer* InterpolationBuffer;
core::array<video::S3DVertex> *FrameList;
core::array<core::aabbox3d<f32> > BoxList;
u32 FrameCount;
s32 TriangleCount;
SMeshBuffer InterpolationBuffer;
struct SFrameData
{
@ -100,6 +97,9 @@ namespace scene
};
core::array< SFrameData > FrameData;
u32 FrameCount;
s32 TriangleCount;
};
} // end namespace scene

View File

@ -32,12 +32,14 @@ CParticleSystemSceneNode::CParticleSystemSceneNode(bool createDefaultEmitter,
const core::vector3df& position, const core::vector3df& rotation,
const core::vector3df& 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
setDebugName("CParticleSystemSceneNode");
#endif
Buffer = new SMeshBuffer();
if (createDefaultEmitter)
{
IParticleEmitter* e = createBoxEmitter();
@ -49,18 +51,18 @@ CParticleSystemSceneNode::CParticleSystemSceneNode(bool createDefaultEmitter,
}
//! destructor
CParticleSystemSceneNode::~CParticleSystemSceneNode()
{
if (Emitter)
Emitter->drop();
if (Buffer)
Buffer->drop();
removeAllAffectors();
}
//! Sets the particle emitter, which creates the particles.
void CParticleSystemSceneNode::setEmitter(IParticleEmitter* emitter)
{
@ -74,7 +76,6 @@ void CParticleSystemSceneNode::setEmitter(IParticleEmitter* emitter)
}
//! Adds new particle effector to the particle system.
void CParticleSystemSceneNode::addAffector(IParticleAffector* affector)
{
@ -83,7 +84,6 @@ void CParticleSystemSceneNode::addAffector(IParticleAffector* affector)
}
//! Removes all particle affectors in the particle system.
void CParticleSystemSceneNode::removeAllAffectors()
{
@ -99,7 +99,7 @@ void CParticleSystemSceneNode::removeAllAffectors()
//! Returns the material based on the zero based index 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];
Buffer.Vertices[0+idx].Pos = particle.pos + horizontal + vertical;
Buffer.Vertices[0+idx].Color = particle.color;
Buffer.Vertices[0+idx].Normal = view;
Buffer->Vertices[0+idx].Pos = particle.pos + horizontal + vertical;
Buffer->Vertices[0+idx].Color = particle.color;
Buffer->Vertices[0+idx].Normal = view;
Buffer.Vertices[1+idx].Pos = particle.pos + horizontal - vertical;
Buffer.Vertices[1+idx].Color = particle.color;
Buffer.Vertices[1+idx].Normal = view;
Buffer->Vertices[1+idx].Pos = particle.pos + horizontal - vertical;
Buffer->Vertices[1+idx].Color = particle.color;
Buffer->Vertices[1+idx].Normal = view;
Buffer.Vertices[2+idx].Pos = particle.pos - horizontal - vertical;
Buffer.Vertices[2+idx].Color = particle.color;
Buffer.Vertices[2+idx].Normal = view;
Buffer->Vertices[2+idx].Pos = particle.pos - horizontal - vertical;
Buffer->Vertices[2+idx].Color = particle.color;
Buffer->Vertices[2+idx].Normal = view;
Buffer.Vertices[3+idx].Pos = particle.pos - horizontal + vertical;
Buffer.Vertices[3+idx].Color = particle.color;
Buffer.Vertices[3+idx].Normal = view;
Buffer->Vertices[3+idx].Pos = particle.pos - horizontal + vertical;
Buffer->Vertices[3+idx].Color = particle.color;
Buffer->Vertices[3+idx].Normal = view;
idx +=4;
}
@ -348,10 +348,10 @@ void CParticleSystemSceneNode::render()
mat.setTranslation(AbsoluteTransformation.getTranslation());
driver->setTransform(video::ETS_WORLD, mat);
driver->setMaterial(Buffer.Material);
driver->setMaterial(Buffer->Material);
driver->drawVertexPrimitiveList(Buffer.getVertices(), Particles.size()*4,
Buffer.getIndices(), Particles.size()*2, video::EVT_STANDARD, EPT_TRIANGLES);
driver->drawVertexPrimitiveList(Buffer->getVertices(), Particles.size()*4,
Buffer->getIndices(), Particles.size()*2, video::EVT_STANDARD, EPT_TRIANGLES);
// for debug purposes only:
if ( DebugDataVisible & scene::EDS_BBOX )
@ -360,7 +360,7 @@ void CParticleSystemSceneNode::render()
video::SMaterial deb_m;
deb_m.Lighting = false;
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
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());
if (ParticlesAreGlobal)
Buffer.BoundingBox.reset(AbsoluteTransformation.getTranslation());
Buffer->BoundingBox.reset(AbsoluteTransformation.getTranslation());
else
Buffer.BoundingBox.reset(core::vector3df(0,0,0));
Buffer->BoundingBox.reset(core::vector3df(0,0,0));
// animate all particles
f32 scale = (f32)timediff;
@ -429,26 +429,26 @@ void CParticleSystemSceneNode::doParticleSystem(u32 time)
else
{
Particles[i].pos += (Particles[i].vector * scale);
Buffer.BoundingBox.addInternalPoint(Particles[i].pos);
Buffer->BoundingBox.addInternalPoint(Particles[i].pos);
++i;
}
}
f32 m = ParticleSize.Width > ParticleSize.Height ? ParticleSize.Width : ParticleSize.Height;
m *= 0.5f;
Buffer.BoundingBox.MaxEdge.X += m;
Buffer.BoundingBox.MaxEdge.Y += m;
Buffer.BoundingBox.MaxEdge.Z += m;
Buffer->BoundingBox.MaxEdge.X += m;
Buffer->BoundingBox.MaxEdge.Y += m;
Buffer->BoundingBox.MaxEdge.Z += m;
Buffer.BoundingBox.MinEdge.X -= m;
Buffer.BoundingBox.MinEdge.Y -= m;
Buffer.BoundingBox.MinEdge.Z -= m;
Buffer->BoundingBox.MinEdge.X -= m;
Buffer->BoundingBox.MinEdge.Y -= m;
Buffer->BoundingBox.MinEdge.Z -= m;
if (ParticlesAreGlobal)
{
core::matrix4 absinv = AbsoluteTransformation;
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()
{
if (Particles.size() * 4 > Buffer.getVertexCount() ||
Particles.size() * 6 > Buffer.getIndexCount())
if (Particles.size() * 4 > Buffer->getVertexCount() ||
Particles.size() * 6 > Buffer->getIndexCount())
{
u32 oldSize = Buffer.getVertexCount();
Buffer.Vertices.set_used(Particles.size() * 4);
u32 oldSize = Buffer->getVertexCount();
Buffer->Vertices.set_used(Particles.size() * 4);
u32 i;
// 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[1+i].TCoords.set(0.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[0+i].TCoords.set(0.0f, 0.0f);
Buffer->Vertices[1+i].TCoords.set(0.0f, 1.0f);
Buffer->Vertices[2+i].TCoords.set(1.0f, 1.0f);
Buffer->Vertices[3+i].TCoords.set(1.0f, 0.0f);
}
// fill remaining indices
u32 oldIdxSize = Buffer.getIndexCount();
u32 oldIdxSize = Buffer->getIndexCount();
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[1+i] = 2+oldvertices;
Buffer.Indices[2+i] = 1+oldvertices;
Buffer.Indices[3+i] = 0+oldvertices;
Buffer.Indices[4+i] = 3+oldvertices;
Buffer.Indices[5+i] = 2+oldvertices;
Buffer->Indices[0+i] = 0+oldvertices;
Buffer->Indices[1+i] = 2+oldvertices;
Buffer->Indices[2+i] = 1+oldvertices;
Buffer->Indices[3+i] = 0+oldvertices;
Buffer->Indices[4+i] = 3+oldvertices;
Buffer->Indices[5+i] = 2+oldvertices;
oldvertices += 4;
}
}

View File

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

View File

@ -25,7 +25,8 @@ CQuake3ShaderSceneNode::CQuake3ShaderSceneNode(
scene::ISceneNode* parent, scene::ISceneManager* mgr,s32 id,
io::IFileSystem *fileSystem, scene::IMeshBuffer *buffer,
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
core::stringc dName = "CQuake3ShaderSceneNode ";
@ -34,6 +35,9 @@ CQuake3ShaderSceneNode::CQuake3ShaderSceneNode(
setDebugName( dName.c_str() );
#endif
MeshBuffer = new SMeshBuffer();
Original = new SMeshBufferLightMap();
// name the Scene Node
this->Name = Shader->name;
@ -47,58 +51,63 @@ CQuake3ShaderSceneNode::CQuake3ShaderSceneNode(
}
CQuake3ShaderSceneNode::~CQuake3ShaderSceneNode()
{
if (MeshBuffer)
MeshBuffer->drop();
if (Original)
Original->drop();
}
/*
create single copies
*/
void CQuake3ShaderSceneNode::cloneBuffer ( scene::SMeshBufferLightMap * buffer )
{
Original.Material = buffer->Material;
MeshBuffer.Material = buffer->Material;
Original->Material = buffer->Material;
MeshBuffer->Material = buffer->Material;
Original.Indices = buffer->Indices;
MeshBuffer.Indices = buffer->Indices;
Original->Indices = buffer->Indices;
MeshBuffer->Indices = buffer->Indices;
const u32 vsize = buffer->Vertices.size ();
Original.Vertices.reallocate( vsize );
MeshBuffer.Vertices.reallocate( vsize );
Original->Vertices.reallocate( vsize );
MeshBuffer->Vertices.reallocate( vsize );
for ( u32 i = 0; i!= vsize; ++i )
{
const video::S3DVertex2TCoords& src = buffer->Vertices[i];
// Original has same Vertex Format
Original.Vertices.push_back(src);
Original->Vertices.push_back(src);
// we have a different vertex format
MeshBuffer.Vertices.push_back(src);
MeshBuffer.Vertices.getLast().Color=0xFFFFFFFF;
MeshBuffer->Vertices.push_back(src);
MeshBuffer->Vertices.getLast().Color=0xFFFFFFFF;
}
MeshBuffer.recalculateBoundingBox ();
MeshBuffer->recalculateBoundingBox ();
#if 1
// move the (temp) Mesh
{
// original bounding box
core::aabbox3df b = MeshBuffer.getBoundingBox();
const core::aabbox3df& b = MeshBuffer->getBoundingBox();
// set Scene Node Position
setPosition( b.getCenter() );
scene::SMesh * mesh = new SMesh ();
mesh->addMeshBuffer ( &Original );
mesh->addMeshBuffer ( &MeshBuffer );
core::matrix4 m;
m.setTranslation( -b.getCenter() );
SceneManager->getMeshManipulator()->transformMesh ( mesh, m );
mesh->drop ();
SceneManager->getMeshManipulator()->transform( Original, m );
SceneManager->getMeshManipulator()->transform( MeshBuffer, m );
MeshBuffer.recalculateBoundingBox ();
MeshBuffer->recalculateBoundingBox ();
}
#endif
// 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]
if ( mapname == "$lightmap" )
{
Q3Texture [i].Texture.push_back ( Original.getMaterial().getTexture(1) );
Q3Texture [i].Texture.push_back( Original->getMaterial().getTexture(1) );
}
else
{
@ -193,7 +202,7 @@ void CQuake3ShaderSceneNode::OnRegisterSceneNode()
/*
is this a transparent node ?
*/
bool CQuake3ShaderSceneNode::isTransparent ()
bool CQuake3ShaderSceneNode::isTransparent () const
{
bool ret = false;
@ -299,7 +308,7 @@ void CQuake3ShaderSceneNode::render()
material.setTextureMatrix ( 0, texture );
driver->setMaterial( material );
driver->drawMeshBuffer( &MeshBuffer );
driver->drawMeshBuffer( MeshBuffer );
drawCount += 1;
}
@ -322,11 +331,11 @@ void CQuake3ShaderSceneNode::vertextransform_wave ( f32 dt, quake3::SModifierFun
const f32 phase = function.phase;
const u32 vsize = MeshBuffer.Vertices.size();
const u32 vsize = MeshBuffer->Vertices.size();
for ( u32 i = 0; i != vsize; ++i )
{
const video::S3DVertex2TCoords &src = Original.Vertices[i];
video::S3DVertex &dst = MeshBuffer.Vertices[i];
const video::S3DVertex2TCoords &src = Original->Vertices[i];
video::S3DVertex &dst = MeshBuffer->Vertices[i];
f32 wavephase = (src.Pos.X + src.Pos.Y + src.Pos.Z) * function.wave;
function.phase = phase + wavephase;
@ -349,13 +358,13 @@ void CQuake3ShaderSceneNode::vertextransform_bulge ( f32 dt, quake3::SModifierFu
dt *= function.bulgespeed * 0.1f;
const f32 phase = function.phase;
const u32 vsize = MeshBuffer.Vertices.size();
const u32 vsize = MeshBuffer->Vertices.size();
for ( u32 i = 0; i != vsize; ++i )
{
const video::S3DVertex2TCoords &src = Original.Vertices[i];
video::S3DVertex &dst = MeshBuffer.Vertices[i];
const video::S3DVertex2TCoords &src = Original->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;
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::vector3df view ( -m[2], -m[6] , -m[10] );
const u32 vsize = MeshBuffer.Vertices.size();
const u32 vsize = MeshBuffer->Vertices.size();
core::aabbox3df box;
u32 g;
@ -381,10 +390,10 @@ void CQuake3ShaderSceneNode::vertextransform_autosprite ( f32 dt, quake3::SModif
for ( u32 i = 0; i < vsize; i += 4 )
{
// in pairs of 4
box.reset ( Original.Vertices[i].Pos );
box.reset ( Original->Vertices[i].Pos );
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 ();
@ -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 v ( m[1] * sv, m[5] * sv, m[9] * sv );
MeshBuffer.Vertices[ i + 0 ].Pos = c + h + v;
MeshBuffer.Vertices[ i + 1 ].Pos = c - h - v;
MeshBuffer.Vertices[ i + 2 ].Pos = c + h - v;
MeshBuffer.Vertices[ i + 3 ].Pos = c - h + v;
MeshBuffer->Vertices[ i + 0 ].Pos = c + h + v;
MeshBuffer->Vertices[ i + 1 ].Pos = c - h - v;
MeshBuffer->Vertices[ i + 2 ].Pos = c + h - v;
MeshBuffer->Vertices[ i + 3 ].Pos = c - h + v;
MeshBuffer.Vertices[ i + 0 ].Normal = view;
MeshBuffer.Vertices[ i + 1 ].Normal = view;
MeshBuffer.Vertices[ i + 2 ].Normal = view;
MeshBuffer.Vertices[ i + 3 ].Normal = view;
MeshBuffer->Vertices[ i + 0 ].Normal = view;
MeshBuffer->Vertices[ i + 1 ].Normal = view;
MeshBuffer->Vertices[ i + 2 ].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 )
{
u32 i;
const u32 vsize = MeshBuffer.Vertices.size();
const u32 vsize = MeshBuffer->Vertices.size();
switch ( function.masterfunc1 )
{
case 6:
//identity
for ( i = 0; i != vsize; ++i )
MeshBuffer.Vertices[i].Color = 0xFFFFFFFF;
MeshBuffer->Vertices[i].Color = 0xFFFFFFFF;
break;
case 7:
// vertex
for ( i = 0; i != vsize; ++i )
MeshBuffer.Vertices[i].Color = Original.Vertices[i].Color;
MeshBuffer->Vertices[i].Color = Original->Vertices[i].Color;
break;
case 5:
{
@ -435,7 +444,7 @@ void CQuake3ShaderSceneNode::vertextransform_rgbgen ( f32 dt, quake3::SModifierF
value |= value << 16;
for ( i = 0; i != vsize; ++i )
MeshBuffer.Vertices[i].Color = value;
MeshBuffer->Vertices[i].Color = value;
} break;
}
}
@ -448,7 +457,7 @@ void CQuake3ShaderSceneNode::vertextransform_rgbgen ( f32 dt, quake3::SModifierF
void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFunction &function )
{
u32 i;
const u32 vsize = MeshBuffer.Vertices.size();
const u32 vsize = MeshBuffer->Vertices.size();
switch ( function.tcgen )
{
@ -461,8 +470,8 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFu
for ( i = 0; i != vsize; ++i )
{
const video::S3DVertex2TCoords &src = Original.Vertices[i];
video::S3DVertex &dst = MeshBuffer.Vertices[i];
const video::S3DVertex2TCoords &src = Original->Vertices[i];
video::S3DVertex &dst = MeshBuffer->Vertices[i];
f32 wavephase = (src.Pos.X + src.Pos.Y + src.Pos.Z) * function.wave;
function.phase = phase + wavephase;
@ -478,12 +487,12 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFu
case 8:
// tcgen texture
for ( i = 0; i != vsize; ++i )
MeshBuffer.Vertices[i].TCoords = Original.Vertices[i].TCoords;
MeshBuffer->Vertices[i].TCoords = Original->Vertices[i].TCoords;
break;
case 9:
// tcgen lightmap
for ( i = 0; i != vsize; ++i )
MeshBuffer.Vertices[i].TCoords = Original.Vertices[i].TCoords2;
MeshBuffer->Vertices[i].TCoords = Original->Vertices[i].TCoords2;
break;
case 10:
{
@ -508,11 +517,11 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFu
for ( i = 0; i != vsize; ++i )
{
// vertex in eye space
view.transformVect ( v, Original.Vertices[i].Pos );
view.transformVect ( v, Original->Vertices[i].Pos );
v.normalize();
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.X = (1.f + eyePlaneS.dotProduct ( v ) ) * 0.5f;
MeshBuffer->Vertices[i].TCoords.Y = 1.f - ( (1.f + eyePlaneT.dotProduct ( v ) ) * 0.5f );
}
} break;
@ -528,7 +537,7 @@ void CQuake3ShaderSceneNode::vertextransform_tcgen ( f32 dt, quake3::SModifierFu
void CQuake3ShaderSceneNode::transformtex ( const core::matrix4 &m, const u32 addressMode )
{
u32 i;
const u32 vsize = MeshBuffer.Vertices.size();
const u32 vsize = MeshBuffer->Vertices.size();
f32 tx1;
f32 ty1;
@ -537,7 +546,7 @@ void CQuake3ShaderSceneNode::transformtex ( const core::matrix4 &m, const u32 ad
{
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];
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 )
{
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];
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
{
return MeshBuffer.getBoundingBox ();
return MeshBuffer->getBoundingBox ();
}
@ -778,7 +787,7 @@ u32 CQuake3ShaderSceneNode::getMaterialCount() const
video::SMaterial& CQuake3ShaderSceneNode::getMaterial(u32 i)
{
video::SMaterial& m = MeshBuffer.getMaterial();
video::SMaterial& m = MeshBuffer->getMaterial();
m.setTexture(0, 0);
if ( 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,
io::IFileSystem *fileSystem,IMeshBuffer *buffer,
const quake3::SShader * shader
);
const quake3::SShader * shader);
virtual ~CQuake3ShaderSceneNode();
virtual void OnRegisterSceneNode();
virtual void render();
@ -35,8 +36,8 @@ public:
virtual video::SMaterial& getMaterial(u32 i);
private:
SMeshBuffer MeshBuffer;
SMeshBufferLightMap Original;
SMeshBuffer* MeshBuffer;
SMeshBufferLightMap* Original;
const quake3::SShader* Shader;
struct SQ3Texture
@ -69,7 +70,7 @@ private:
f32 TimeAbs;
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,
f64 texturePercentage, f64 spherePercentage, ISceneNode* parent, ISceneManager* mgr, s32 id)
: ISceneNode(parent, mgr, id)
: ISceneNode(parent, mgr, id), Buffer(0)
{
#ifdef _DEBUG
setDebugName("CSkyDomeSceneNode");
@ -46,12 +46,13 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert
AutomaticCullingState = scene::EAC_OFF;
Buffer.Material.Lighting = false;
Buffer.Material.ZBuffer = false;
Buffer.Material.ZWriteEnable = false;
Buffer.Material.setTexture(0, sky);
Buffer.BoundingBox.MaxEdge.set(0,0,0);
Buffer.BoundingBox.MinEdge.set(0,0,0);
Buffer = new SMeshBuffer();
Buffer->Material.Lighting = false;
Buffer->Material.ZBuffer = false;
Buffer->Material.ZWriteEnable = false;
Buffer->Material.setTexture(0, sky);
Buffer->BoundingBox.MaxEdge.set(0,0,0);
Buffer->BoundingBox.MinEdge.set(0,0,0);
azimuth_step = 2.*core::PI64/(f64)horiRes;
if (spherePercentage<0.)
@ -60,8 +61,8 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert
spherePercentage=2.;
elevation_step = spherePercentage*core::PI64/2./(f64)vertRes;
Buffer.Vertices.reallocate((horiRes+1)*(vertRes+1));
Buffer.Indices.reallocate(3*(2*vertRes-1)*horiRes);
Buffer->Vertices.reallocate((horiRes+1)*(vertRes+1));
Buffer->Indices.reallocate(3*(2*vertRes-1)*horiRes);
vtx.Color.set(255,255,255,255);
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);
Buffer.Vertices.push_back(vtx);
Buffer->Vertices.push_back(vtx);
elevation -= elevation_step;
}
azimuth += azimuth_step;
@ -90,24 +91,31 @@ CSkyDomeSceneNode::CSkyDomeSceneNode(video::ITexture* sky, u32 horiRes, u32 vert
for (k = 0; k < horiRes; ++k)
{
Buffer.Indices.push_back(vertRes+2+(vertRes+1)*k);
Buffer.Indices.push_back(1+(vertRes+1)*k);
Buffer.Indices.push_back(0+(vertRes+1)*k);
Buffer->Indices.push_back(vertRes+2+(vertRes+1)*k);
Buffer->Indices.push_back(1+(vertRes+1)*k);
Buffer->Indices.push_back(0+(vertRes+1)*k);
for (u32 j = 1; j < vertRes; ++j)
{
Buffer.Indices.push_back(vertRes+2+(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(vertRes+2+(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(vertRes+1+(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(vertRes+1+(vertRes+1)*k+j);
Buffer->Indices.push_back(vertRes+2+(vertRes+1)*k+j);
Buffer->Indices.push_back(0+(vertRes+1)*k+j);
}
}
}
CSkyDomeSceneNode::~CSkyDomeSceneNode()
{
if (Buffer)
Buffer->drop();
}
//! renders the node.
void CSkyDomeSceneNode::render()
{
@ -124,15 +132,16 @@ void CSkyDomeSceneNode::render()
driver->setTransform(video::ETS_WORLD, mat);
driver->setMaterial(Buffer.Material);
driver->drawMeshBuffer(&Buffer);
driver->setMaterial(Buffer->Material);
driver->drawMeshBuffer(Buffer);
}
}
//! returns the axis aligned bounding box of this node
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.
video::SMaterial& CSkyDomeSceneNode::getMaterial(u32 i)
{
return Buffer.Material;
return Buffer->Material;
}

View File

@ -18,8 +18,9 @@ class CSkyDomeSceneNode : public ISceneNode
{
public:
CSkyDomeSceneNode(video::ITexture* texture, u32 horiRes, u32 vertRes,
f64 texturePercentage, f64 spherePercentage, ISceneNode* root,
ISceneManager* smgr, s32 id);
f64 texturePercentage, f64 spherePercentage,
ISceneNode* root, ISceneManager* smgr, s32 id);
virtual ~CSkyDomeSceneNode();
virtual void OnRegisterSceneNode();
virtual void render();
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; }
private:
SMeshBuffer Buffer;
SMeshBuffer* Buffer;
};

View File

@ -33,7 +33,7 @@ namespace scene
const core::vector3df& rotation,
const core::vector3df& 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),
OverrideDistanceThreshold(false), UseDefaultRotationPivot(true), ForceRecalculation(false),
OldCameraPosition(core::vector3df(-99999.9f, -99999.9f, -99999.9f)),
@ -45,6 +45,8 @@ namespace scene
setDebugName("CTerrainSceneNode");
#endif
RenderBuffer = new SMeshBufferLightMap();
if (FileSystem)
FileSystem->grab();
@ -61,6 +63,9 @@ namespace scene
if (FileSystem)
FileSystem->drop();
if (RenderBuffer)
RenderBuffer->drop();
}
@ -161,13 +166,13 @@ namespace scene
const u32 vertexCount = mb->getVertexCount();
// 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 )
{
RenderBuffer.Vertices[i] = mb->Vertices[i];
RenderBuffer.Vertices[i].Pos *= TerrainData.Scale;
RenderBuffer.Vertices[i].Pos += TerrainData.Position;
RenderBuffer->Vertices[i] = mb->Vertices[i];
RenderBuffer->Vertices[i].Pos *= TerrainData.Scale;
RenderBuffer->Vertices[i].Pos += TerrainData.Position;
}
// We no longer need the mb
@ -187,10 +192,10 @@ namespace scene
setRotation( TerrainData.Rotation );
// 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 );
RenderBuffer.setDirty();
RenderBuffer->setDirty();
const u32 endTime = os::Timer::getRealTime();
@ -297,13 +302,13 @@ namespace scene
const u32 vertexCount = mb->getVertexCount();
// 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++ )
{
RenderBuffer.Vertices[i] = mb->Vertices[i];
RenderBuffer.Vertices[i].Pos *= TerrainData.Scale;
RenderBuffer.Vertices[i].Pos += TerrainData.Position;
RenderBuffer->Vertices[i] = mb->Vertices[i];
RenderBuffer->Vertices[i].Pos *= TerrainData.Scale;
RenderBuffer->Vertices[i].Pos += TerrainData.Position;
}
// We no longer need the mb
@ -323,7 +328,7 @@ namespace scene
setRotation( TerrainData.Rotation );
// 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 );
u32 endTime = os::Timer::getTime();
@ -388,17 +393,17 @@ namespace scene
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;
rotMatrix.inverseRotateVect( RenderBuffer.Vertices[i].Pos );
RenderBuffer.Vertices[i].Pos += TerrainData.RotationPivot;
RenderBuffer->Vertices[i].Pos -= TerrainData.RotationPivot;
rotMatrix.inverseRotateVect( RenderBuffer->Vertices[i].Pos );
RenderBuffer->Vertices[i].Pos += TerrainData.RotationPivot;
}
calculateDistanceThresholds( true );
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
// 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 ) )
{
@ -508,12 +514,12 @@ namespace scene
index12 = getIndex( j, i, index, x, z + step );
index22 = getIndex( j, i, index, x + step, z + step );
RenderBuffer.Indices[IndicesToRender++] = index12;
RenderBuffer.Indices[IndicesToRender++] = index11;
RenderBuffer.Indices[IndicesToRender++] = index22;
RenderBuffer.Indices[IndicesToRender++] = index22;
RenderBuffer.Indices[IndicesToRender++] = index11;
RenderBuffer.Indices[IndicesToRender++] = index21;
RenderBuffer->Indices[IndicesToRender++] = index12;
RenderBuffer->Indices[IndicesToRender++] = index11;
RenderBuffer->Indices[IndicesToRender++] = index22;
RenderBuffer->Indices[IndicesToRender++] = index22;
RenderBuffer->Indices[IndicesToRender++] = index11;
RenderBuffer->Indices[IndicesToRender++] = index21;
// increment index position horizontally
x += step;
@ -528,7 +534,7 @@ namespace scene
}
}
RenderBuffer.setDirty(EBT_INDEX);
RenderBuffer->setDirty(EBT_INDEX);
if ( DynamicSelectorUpdate && TriangleSelector )
{
@ -554,12 +560,12 @@ namespace scene
driver->setMaterial(Mesh.getMeshBuffer(0)->getMaterial());
RenderBuffer.Indices.set_used(IndicesToRender);
RenderBuffer->Indices.set_used(IndicesToRender);
// 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:
if (DebugDataVisible)
@ -759,7 +765,8 @@ namespace scene
s32 numLODs;
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 );
return LODs.size();
@ -808,17 +815,17 @@ namespace scene
zval=z2val=0;
for (s32 z=0; z<TerrainData.Size; ++z)
{
RenderBuffer.Vertices[index].TCoords.X = xval;
RenderBuffer.Vertices[index].TCoords.Y = zval;
RenderBuffer->Vertices[index].TCoords.X = xval;
RenderBuffer->Vertices[index].TCoords.Y = zval;
if ( resolution2 == 0 )
{
RenderBuffer.Vertices[index].TCoords2 = RenderBuffer.Vertices[index].TCoords;
RenderBuffer->Vertices[index].TCoords2 = RenderBuffer->Vertices[index].TCoords;
}
else
{
RenderBuffer.Vertices[index].TCoords2.X = x2val;
RenderBuffer.Vertices[index].TCoords2.Y = z2val;
RenderBuffer->Vertices[index].TCoords2.X = x2val;
RenderBuffer->Vertices[index].TCoords2.Y = z2val;
}
++index;
zval += resBySize;
@ -828,7 +835,7 @@ namespace scene
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.
@ -1061,7 +1068,7 @@ namespace scene
for( s32 xx = x*(TerrainData.CalcPatchSize); xx <= ( x + 1 ) * TerrainData.CalcPatchSize; ++xx )
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
TerrainData.BoundingBox.addInternalBox( TerrainData.Patches[index].BoundingBox );
@ -1133,13 +1140,15 @@ namespace scene
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;
}
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];
}
@ -1283,7 +1292,7 @@ namespace scene
}
}
nb->RenderBuffer.Material = RenderBuffer.Material;
nb->RenderBuffer->Material = RenderBuffer->Material;
// finish

View File

@ -137,8 +137,7 @@ namespace scene
virtual IMesh* getMesh() { return &Mesh; }
//! 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.
//! \param mb: A reference to an SMeshBufferLightMap object
@ -308,7 +307,7 @@ namespace scene
STerrainData TerrainData;
SMesh Mesh;
SMeshBufferLightMap RenderBuffer;
SMeshBufferLightMap* RenderBuffer;
u32 VerticesToRender;
u32 IndicesToRender;

View File

@ -23,38 +23,40 @@ CTerrainTriangleSelector::CTerrainTriangleSelector ( ITerrainSceneNode* node, s3
setTriangleData(node, LOD);
}
//! destructor
CTerrainTriangleSelector::~CTerrainTriangleSelector()
{
TrianglePatches.TrianglePatchArray.clear();
}
//! Clears and sets triangle data
void CTerrainTriangleSelector::setTriangleData(ITerrainSceneNode* node, s32 LOD)
{
core::triangle3df tri;
core::array<u32> indices;
CTerrainSceneNode* terrainNode = (CTerrainSceneNode*)node;
// 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
const s32 count = (static_cast<CTerrainSceneNode*>(node))->TerrainData.PatchCount;
TrianglePatches.TotalTriangles = 0;
TrianglePatches.NumPatches = terrainNode->TerrainData.PatchCount * terrainNode->TerrainData.PatchCount;
TrianglePatches.NumPatches = count*count;
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());
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].Box = terrainNode->getBoundingBox( x, z );
u32 indexCount = terrainNode->getIndicesForPatch( indices, x, z, LOD );
TrianglePatches.TrianglePatchArray[tIndex].Box = node->getBoundingBox( x, z );
u32 indexCount = node->getIndicesForPatch( indices, x, z, LOD );
TrianglePatches.TrianglePatchArray[tIndex].Triangles.reallocate(indexCount/3);
for(u32 i = 0; i < indexCount; i += 3 )
@ -106,6 +108,7 @@ void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32
outTriangleCount = tIndex;
}
//! Gets all triangles which lie within a specific bounding box.
void CTerrainTriangleSelector::getTriangles ( core::triangle3df* triangles, s32 arraySize,
s32& outTriangleCount, const core::aabbox3d<f32>& box,

View File

@ -31,22 +31,33 @@ CVolumeLightSceneNode::CVolumeLightSceneNode(ISceneNode* parent, ISceneManager*
setDebugName("CVolumeLightSceneNode");
#endif
Buffer.setHardwareMappingHint(EHM_STATIC);
Buffer = new SMeshBuffer();
if (Buffer)
{
Buffer->setHardwareMappingHint(EHM_STATIC);
constructLight();
}
}
CVolumeLightSceneNode::~CVolumeLightSceneNode()
{
if (Buffer)
Buffer->drop();
}
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);
u16 nidx = (u16)tnidx;
if (!alreadyIn) {
nidx = Buffer.Vertices.size();
Buffer.Indices.push_back(nidx);
Buffer.Vertices.push_back(v);
nidx = Buffer->Vertices.size();
Buffer->Indices.push_back(nidx);
Buffer->Vertices.push_back(v);
} 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 az = LightDimensions.Z * 0.5f; // Z Axis
Buffer.Vertices.clear();
Buffer.Vertices.reallocate(6+12*(SubdivideU+SubdivideV));
Buffer.Indices.clear();
Buffer.Indices.reallocate(6+12*(SubdivideU+SubdivideV));
Buffer->Vertices.clear();
Buffer->Vertices.reallocate(6+12*(SubdivideU+SubdivideV));
Buffer->Indices.clear();
Buffer->Indices.reallocate(6+12*(SubdivideU+SubdivideV));
//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, 1, 1));
@ -161,33 +172,36 @@ void CVolumeLightSceneNode::constructLight()
bz += bzStep;
}
Buffer.recalculateBoundingBox();
Buffer->recalculateBoundingBox();
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.MaterialType = video::EMT_ONETEXTURE_BLEND;
Buffer->Material.MaterialTypeParam = pack_texureBlendFunc( video::EBF_SRC_COLOR, video::EBF_SRC_ALPHA, video::EMFN_MODULATE_1X );
Buffer.Material.Lighting = false;
Buffer.Material.ZWriteEnable = false;
Buffer->Material.Lighting = false;
Buffer->Material.ZWriteEnable = false;
Buffer.setDirty(EBT_VERTEX_AND_INDEX);
Buffer->setDirty(EBT_VERTEX_AND_INDEX);
}
//! renders the node.
void CVolumeLightSceneNode::render()
{
if (!Buffer)
return;
video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->setMaterial(Buffer.Material);
driver->drawMeshBuffer(&Buffer);
driver->setMaterial(Buffer->Material);
driver->drawMeshBuffer(Buffer);
}
//! returns the axis aligned bounding box of this node
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.
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);
nb->cloneMembers(this, newManager);
nb->Buffer.Material = Buffer.Material;
nb->Buffer->Material = Buffer->Material;
nb->drop();
return nb;

View File

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