Use geometry creator method in Volume light node.
Changed scene node type of volume light to its own type. git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2343 dfc29bdd-3216-0410-991c-e03cc46cb475master
parent
f91ece5e39
commit
58fcce1640
|
@ -75,6 +75,9 @@ namespace scene
|
|||
//! Quake3 Model Scene Node ( has tag to link to )
|
||||
ESNT_MD3_SCENE_NODE = MAKE_IRR_ID('m','d','3','_'),
|
||||
|
||||
//! Volume Light Scene Node
|
||||
ESNT_VOLUME_LIGHT = MAKE_IRR_ID('v','o','l','l'),
|
||||
|
||||
//! Maya Camera Scene Node
|
||||
/** Legacy, for loading version <= 1.4.x .irr files */
|
||||
ESNT_CAMERA_MAYA = MAKE_IRR_ID('c','a','m','M'),
|
||||
|
|
|
@ -27,21 +27,20 @@ namespace scene
|
|||
: ISceneNode(parent, mgr, id, position, rotation, scale) {};
|
||||
|
||||
//! Returns type of the scene node
|
||||
virtual ESCENE_NODE_TYPE getType() const { return ESNT_CUBE; }
|
||||
virtual ESCENE_NODE_TYPE getType() const { return ESNT_VOLUME_LIGHT; }
|
||||
|
||||
virtual void setSubDivideU (const u32 inU) =0;
|
||||
virtual void setSubDivideV (const u32 inV) =0;
|
||||
virtual void setSubDivideU(const u32 inU) =0;
|
||||
virtual void setSubDivideV(const u32 inV) =0;
|
||||
|
||||
virtual u32 getSubDivideU () const =0;
|
||||
virtual u32 getSubDivideV () const =0;
|
||||
virtual u32 getSubDivideU() const =0;
|
||||
virtual u32 getSubDivideV() const =0;
|
||||
|
||||
virtual void setFootColour(const video::SColor inColour) =0;
|
||||
virtual void setTailColour(const video::SColor inColour) =0;
|
||||
|
||||
virtual video::SColor getFootColour () const =0;
|
||||
virtual video::SColor getTailColour () const =0;
|
||||
virtual video::SColor getFootColour() const =0;
|
||||
virtual video::SColor getTailColour() const =0;
|
||||
|
||||
virtual IMeshBuffer * getMeshBuffer(void) const =0;
|
||||
};
|
||||
|
||||
} // end namespace scene
|
||||
|
|
|
@ -21,185 +21,52 @@ CVolumeLightSceneNode::CVolumeLightSceneNode(ISceneNode* parent, ISceneManager*
|
|||
const core::vector3df& position,
|
||||
const core::vector3df& rotation, const core::vector3df& scale)
|
||||
: IVolumeLightSceneNode(parent, mgr, id, position, rotation, scale),
|
||||
LPDistance(8.0f), SubdivideU(subdivU), SubdivideV(subdivV),
|
||||
FootColour(foot), TailColour(tail),
|
||||
Mesh(0), LPDistance(8.0f),
|
||||
SubdivideU(subdivU), SubdivideV(subdivV),
|
||||
FootColor(foot), TailColor(tail),
|
||||
LightDimensions(core::vector3df(1.0f, 1.2f, 1.0f))
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
setDebugName("CVolumeLightSceneNode");
|
||||
#endif
|
||||
|
||||
Buffer = new SMeshBuffer();
|
||||
if (Buffer)
|
||||
{
|
||||
Buffer->setHardwareMappingHint(EHM_STATIC);
|
||||
constructLight();
|
||||
}
|
||||
constructLight();
|
||||
}
|
||||
|
||||
|
||||
CVolumeLightSceneNode::~CVolumeLightSceneNode()
|
||||
{
|
||||
if (Buffer)
|
||||
Buffer->drop();
|
||||
}
|
||||
|
||||
|
||||
void CVolumeLightSceneNode::addToBuffer(const video::S3DVertex& v)
|
||||
{
|
||||
const s32 tnidx = Buffer->Vertices.linear_reverse_search(v);
|
||||
const bool alreadyIn = (tnidx != -1);
|
||||
u16 nidx = (u16)tnidx;
|
||||
if (!alreadyIn) {
|
||||
nidx = (u16)Buffer->Vertices.size();
|
||||
Buffer->Indices.push_back(nidx);
|
||||
Buffer->Vertices.push_back(v);
|
||||
} else
|
||||
Buffer->Indices.push_back(nidx);
|
||||
if (Mesh)
|
||||
Mesh->drop();
|
||||
}
|
||||
|
||||
|
||||
void CVolumeLightSceneNode::constructLight()
|
||||
{
|
||||
const core::vector3df lightPoint(0, -(LPDistance*LightDimensions.Y), 0);
|
||||
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));
|
||||
//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));
|
||||
addToBuffer(video::S3DVertex(ax , 0,-az, 0,0,0, FootColour, 1, 0));
|
||||
|
||||
addToBuffer(video::S3DVertex(ax , 0,-az, 0,0,0, FootColour, 1, 0));
|
||||
addToBuffer(video::S3DVertex(-ax, 0,-az, 0,0,0, FootColour, 0, 0));
|
||||
addToBuffer(video::S3DVertex(-ax, 0, az, 0,0,0, FootColour, 0, 1));
|
||||
|
||||
f32 tu = 0.f;
|
||||
const f32 tuStep = 1.f/SubdivideU;
|
||||
f32 bx = -ax;
|
||||
const f32 bxStep = LightDimensions.X * tuStep;
|
||||
// Slices in X/U space
|
||||
for (u32 i = 0; i <= SubdivideU; ++i)
|
||||
{
|
||||
// These are the two endpoints for a slice at the foot
|
||||
core::vector3df end1(bx, 0.0f, -az);
|
||||
core::vector3df end2(bx, 0.0f, az);
|
||||
|
||||
end1 -= lightPoint; // get a vector from point to lightsource
|
||||
end1.normalize(); // normalize vector
|
||||
end1 *= LightDimensions.Y; // multiply it out by shootlength
|
||||
|
||||
end1.X += bx; // Add the original point location to the vector
|
||||
end1.Z -= az;
|
||||
|
||||
// Do it again for the other point.
|
||||
end2 -= lightPoint;
|
||||
end2.normalize();
|
||||
end2 *= LightDimensions.Y;
|
||||
|
||||
end2.X += bx;
|
||||
end2.Z += az;
|
||||
|
||||
addToBuffer(video::S3DVertex(bx , 0, az, 0,0,0, FootColour, tu, 1));
|
||||
addToBuffer(video::S3DVertex(bx , 0, -az, 0,0,0, FootColour, tu, 0));
|
||||
addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, TailColour, tu, 1));
|
||||
|
||||
addToBuffer(video::S3DVertex(bx , 0, -az, 0,0,0, FootColour, tu, 0));
|
||||
addToBuffer(video::S3DVertex(end1.X , end1.Y, end1.Z, 0,0,0, TailColour, tu, 0));
|
||||
addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, TailColour, tu, 1));
|
||||
|
||||
//back side
|
||||
addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, TailColour, tu, 1));
|
||||
addToBuffer(video::S3DVertex(-bx , 0, -az, 0,0,0, FootColour, tu, 1));
|
||||
addToBuffer(video::S3DVertex(-bx , 0, az, 0,0,0, FootColour, tu, 0));
|
||||
|
||||
addToBuffer(video::S3DVertex(-bx , 0, az, 0,0,0, FootColour, tu, 0));
|
||||
addToBuffer(video::S3DVertex(-end1.X , end1.Y, -end1.Z, 0,0,0, TailColour, tu, 0));
|
||||
addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, TailColour, tu, 1));
|
||||
tu += tuStep;
|
||||
bx += bxStep;
|
||||
}
|
||||
|
||||
f32 tv = 0.f;
|
||||
const f32 tvStep = 1.f/SubdivideV;
|
||||
f32 bz = -az;
|
||||
const f32 bzStep = LightDimensions.Z * tvStep;
|
||||
// Slices in Z/V space
|
||||
for(u32 i = 0; i <= SubdivideV; ++i)
|
||||
{
|
||||
// These are the two endpoints for a slice at the foot
|
||||
core::vector3df end1(-ax, 0.0f, bz);
|
||||
core::vector3df end2(ax, 0.0f, bz);
|
||||
|
||||
end1 -= lightPoint; // get a vector from point to lightsource
|
||||
end1.normalize(); // normalize vector
|
||||
end1 *= LightDimensions.Y; // multiply it out by shootlength
|
||||
|
||||
end1.X -= ax; // Add the original point location to the vector
|
||||
end1.Z += bz;
|
||||
|
||||
// Do it again for the other point.
|
||||
end2 -= lightPoint;
|
||||
end2.normalize();
|
||||
end2 *= LightDimensions.Y;
|
||||
|
||||
end2.X += ax;
|
||||
end2.Z += bz;
|
||||
|
||||
addToBuffer(video::S3DVertex(-ax , 0, bz, 0,0,0, FootColour, 0, tv));
|
||||
addToBuffer(video::S3DVertex(ax , 0, bz, 0,0,0, FootColour, 1, tv));
|
||||
addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, TailColour, 1, tv));
|
||||
|
||||
addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, TailColour, 1, tv));
|
||||
addToBuffer(video::S3DVertex(end1.X , end1.Y, end1.Z, 0,0,0, TailColour, 0, tv));
|
||||
addToBuffer(video::S3DVertex(-ax , 0, bz, 0,0,0, FootColour, 0, tv));
|
||||
|
||||
//back side
|
||||
addToBuffer(video::S3DVertex(ax , 0, -bz, 0,0,0, FootColour, 0, tv));
|
||||
addToBuffer(video::S3DVertex(-ax , 0, -bz, 0,0,0, FootColour, 1, tv));
|
||||
addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, TailColour, 1, tv));
|
||||
|
||||
addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, TailColour, 1, tv));
|
||||
addToBuffer(video::S3DVertex(-end1.X , end1.Y, -end1.Z, 0,0,0, TailColour, 0, tv));
|
||||
addToBuffer(video::S3DVertex(ax , 0, -bz, 0,0,0, FootColour, 0, tv));
|
||||
tv += tvStep;
|
||||
bz += bzStep;
|
||||
}
|
||||
|
||||
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.Lighting = false;
|
||||
Buffer->Material.ZWriteEnable = false;
|
||||
|
||||
Buffer->setDirty(EBT_VERTEX_AND_INDEX);
|
||||
if (Mesh)
|
||||
Mesh->drop();
|
||||
Mesh = SceneManager->getGeometryCreator()->createVolumeLightMesh(SubdivideU, SubdivideV, FootColor, TailColor);
|
||||
}
|
||||
|
||||
|
||||
//! renders the node.
|
||||
void CVolumeLightSceneNode::render()
|
||||
{
|
||||
if (!Buffer)
|
||||
if (!Mesh)
|
||||
return;
|
||||
|
||||
video::IVideoDriver* driver = SceneManager->getVideoDriver();
|
||||
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
|
||||
|
||||
driver->setMaterial(Buffer->Material);
|
||||
driver->drawMeshBuffer(Buffer);
|
||||
driver->setMaterial(Mesh->getMeshBuffer(0)->getMaterial());
|
||||
driver->drawMeshBuffer(Mesh->getMeshBuffer(0));
|
||||
}
|
||||
|
||||
|
||||
//! returns the axis aligned bounding box of this node
|
||||
const core::aabbox3d<f32>& CVolumeLightSceneNode::getBoundingBox() const
|
||||
{
|
||||
return Buffer->BoundingBox;
|
||||
return Mesh->getBoundingBox();
|
||||
}
|
||||
|
||||
|
||||
|
@ -220,7 +87,7 @@ void CVolumeLightSceneNode::OnRegisterSceneNode()
|
|||
//! to directly modify the material of a scene node.
|
||||
video::SMaterial& CVolumeLightSceneNode::getMaterial(u32 i)
|
||||
{
|
||||
return Buffer->Material;
|
||||
return Mesh->getMeshBuffer(i)->getMaterial();
|
||||
}
|
||||
|
||||
|
||||
|
@ -233,29 +100,41 @@ u32 CVolumeLightSceneNode::getMaterialCount() const
|
|||
|
||||
void CVolumeLightSceneNode::setSubDivideU (const u32 inU)
|
||||
{
|
||||
SubdivideU = inU;
|
||||
constructLight();
|
||||
if (inU != SubdivideU)
|
||||
{
|
||||
SubdivideU = inU;
|
||||
constructLight();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVolumeLightSceneNode::setSubDivideV (const u32 inV)
|
||||
{
|
||||
SubdivideV = inV;
|
||||
constructLight();
|
||||
if (inV != SubdivideV)
|
||||
{
|
||||
SubdivideV = inV;
|
||||
constructLight();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVolumeLightSceneNode::setFootColour(const video::SColor inColouf)
|
||||
void CVolumeLightSceneNode::setFootColour(const video::SColor inColor)
|
||||
{
|
||||
FootColour = inColouf;
|
||||
constructLight();
|
||||
if (inColor != FootColor)
|
||||
{
|
||||
FootColor = inColor;
|
||||
constructLight();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CVolumeLightSceneNode::setTailColour(const video::SColor inColouf)
|
||||
void CVolumeLightSceneNode::setTailColour(const video::SColor inColor)
|
||||
{
|
||||
TailColour = inColouf;
|
||||
constructLight();
|
||||
if (inColor != TailColor)
|
||||
{
|
||||
TailColor = inColor;
|
||||
constructLight();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -268,8 +147,8 @@ void CVolumeLightSceneNode::serializeAttributes(io::IAttributes* out, io::SAttri
|
|||
out->addInt("subDivideU", SubdivideU);
|
||||
out->addInt("subDivideV", SubdivideV);
|
||||
|
||||
out->addColor("footColour", FootColour);
|
||||
out->addColor("tailColour", TailColour);
|
||||
out->addColor("footColour", FootColor);
|
||||
out->addColor("tailColour", TailColor);
|
||||
|
||||
out->addVector3d("lightDimension", LightDimensions);
|
||||
}
|
||||
|
@ -287,8 +166,8 @@ void CVolumeLightSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttr
|
|||
SubdivideV = in->getAttributeAsInt("subDivideV");
|
||||
SubdivideV = core::max_(SubdivideV, 1u);
|
||||
|
||||
FootColour = in->getAttributeAsColor("footColour");
|
||||
TailColour = in->getAttributeAsColor("tailColour");
|
||||
FootColor = in->getAttributeAsColor("footColour");
|
||||
TailColor = in->getAttributeAsColor("tailColour");
|
||||
|
||||
LightDimensions = in->getAttributeAsVector3d("lightDimension");
|
||||
|
||||
|
@ -307,10 +186,10 @@ ISceneNode* CVolumeLightSceneNode::clone(ISceneNode* newParent, ISceneManager* n
|
|||
newManager = SceneManager;
|
||||
|
||||
CVolumeLightSceneNode* nb = new CVolumeLightSceneNode(newParent,
|
||||
newManager, ID, SubdivideU, SubdivideV, FootColour, TailColour, RelativeTranslation);
|
||||
newManager, ID, SubdivideU, SubdivideV, FootColor, TailColor, RelativeTranslation);
|
||||
|
||||
nb->cloneMembers(this, newManager);
|
||||
nb->Buffer->Material = Buffer->Material;
|
||||
nb->getMaterial(0) = Mesh->getMeshBuffer(0)->getMaterial();
|
||||
|
||||
nb->drop();
|
||||
return nb;
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#define __VOLUME_LIGHT_SCENE_NODE_H_INCLUDED__
|
||||
|
||||
#include "IVolumeLightSceneNode.h"
|
||||
#include "SMeshBuffer.h"
|
||||
#include "IMesh.h"
|
||||
|
||||
namespace irr
|
||||
{
|
||||
|
@ -37,11 +37,7 @@ namespace scene
|
|||
//! returns the axis aligned bounding box of this node
|
||||
virtual const core::aabbox3d<f32>& getBoundingBox() const;
|
||||
|
||||
//! returns the material based on the zero based index i. To get the amount
|
||||
//! of materials used by this scene node, use getMaterialCount().
|
||||
//! This function is needed for inserting the node into the scene hirachy on a
|
||||
//! optimal position for minimizing renderstate changes, but can also be used
|
||||
//! to directly modify the material of a scene node.
|
||||
//! returns the material based on the zero based index i.
|
||||
virtual video::SMaterial& getMaterial(u32 i);
|
||||
|
||||
//! returns amount of materials used by this scene node.
|
||||
|
@ -59,25 +55,22 @@ namespace scene
|
|||
//! Creates a clone of this scene node and its children.
|
||||
virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0);
|
||||
|
||||
virtual void setSubDivideU (const u32 inU);
|
||||
virtual void setSubDivideV (const u32 inV);
|
||||
virtual void setSubDivideU(const u32 inU);
|
||||
virtual void setSubDivideV(const u32 inV);
|
||||
|
||||
virtual u32 getSubDivideU () const { return SubdivideU; }
|
||||
virtual u32 getSubDivideV () const { return SubdivideV; }
|
||||
virtual u32 getSubDivideU() const { return SubdivideU; }
|
||||
virtual u32 getSubDivideV() const { return SubdivideV; }
|
||||
|
||||
virtual void setFootColour(const video::SColor inColouf);
|
||||
virtual void setTailColour(const video::SColor inColouf);
|
||||
virtual void setFootColour(const video::SColor inColor);
|
||||
virtual void setTailColour(const video::SColor inColor);
|
||||
|
||||
virtual video::SColor getFootColour () const { return FootColour; }
|
||||
virtual video::SColor getTailColour () const { return TailColour; }
|
||||
|
||||
virtual IMeshBuffer * getMeshBuffer(void) const { return Buffer; }
|
||||
virtual video::SColor getFootColour() const { return FootColor; }
|
||||
virtual video::SColor getTailColour() const { return TailColor; }
|
||||
|
||||
private:
|
||||
void addToBuffer(const video::S3DVertex& v);
|
||||
void constructLight();
|
||||
|
||||
SMeshBuffer* Buffer;
|
||||
IMesh* Mesh;
|
||||
|
||||
f32 LPDistance; // Distance to hypothetical lightsource point -- affects fov angle
|
||||
|
||||
|
@ -86,8 +79,8 @@ namespace scene
|
|||
// NOTE : Total number of polygons = 2 + ((SubdivideU + 1) + (SubdivideV + 1)) * 2
|
||||
// Each slice being a quad plus the rectangular plane at the bottom.
|
||||
|
||||
video::SColor FootColour; // Color at the source
|
||||
video::SColor TailColour; // Color at the end.
|
||||
video::SColor FootColor; // Color at the source
|
||||
video::SColor TailColor; // Color at the end.
|
||||
|
||||
core::vector3df LightDimensions; // LightDimensions.Y Distance of shooting -- Length of beams
|
||||
// LightDimensions.X and LightDimensions.Z determine the size/dimension of the plane
|
||||
|
|
Loading…
Reference in New Issue