Commit f91ece5e authored by hybrid's avatar hybrid

volume light mesh creation methods, provided by iondune

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@2342 dfc29bdd-3216-0410-991c-e03cc46cb475
parent d7cde7f6
......@@ -20,14 +20,14 @@ namespace video
namespace scene
{
//! Helper class for creating geometry on the fly.
//! Helper class for creating geometry on the fly.
/** You can get an instance of this class through ISceneManager::getGeometryCreator() */
class IGeometryCreator : public IReferenceCounted
{
public:
//! Create a psuedo-random mesh representing a hilly terrain.
/**
/**
\param tileSize The size of each time.
\param tileCount The number of tiles in each dimension.
\param material The material to apply to the mesh.
......@@ -36,37 +36,44 @@ public:
\param textureRepeatCount The number of times to repeat the material texture along each dimension.
*/
virtual IMesh* createHillPlaneMesh(
const core::dimension2d<f32>& tileSize, const core::dimension2d<u32>& tileCount,
video::SMaterial* material, f32 hillHeight, const core::dimension2d<f32>& countHills,
const core::dimension2d<f32>& textureRepeatCount) const = 0;
const core::dimension2d<f32>& tileSize,
const core::dimension2d<u32>& tileCount,
video::SMaterial* material, f32 hillHeight,
const core::dimension2d<f32>& countHills,
const core::dimension2d<f32>& textureRepeatCount) const =0;
//! Create a terrain mesh from an image representing a heightfield.
/**
/**
\param texture The texture to apply to the terrain.
\param heightmap An image that will be interpreted as a heightmap. The brightness
(average colour) of each pixel is interpreted as a height, with a 255 brightness
pixel producing the maximum height.
\param stretchSize The size that each pixel will produce, i.e. a 512x512 heightmap
and a stretchSize of (10.f, 20.f) will produce a mesh of size 5120.f x 10240.f
\param heightmap An image that will be interpreted as a heightmap. The
brightness (average colour) of each pixel is interpreted as a height,
with a 255 brightness pixel producing the maximum height.
\param stretchSize The size that each pixel will produce, i.e. a
512x512 heightmap
and a stretchSize of (10.f, 20.f) will produce a mesh of size
5120.f x 10240.f
\param maxHeight The maximum height of the terrain.
\param driver The current video driver.
\param defaultVertexBlockSize (to be documented)
\param debugBorders (to be documented)
*/
virtual IMesh* createTerrainMesh(video::IImage* texture,
video::IImage* heightmap, const core::dimension2d<f32>& stretchSize,
f32 maxHeight, video::IVideoDriver* driver,
const core::dimension2d<u32>& defaultVertexBlockSize,
bool debugBorders=false) const = 0;
video::IImage* heightmap,
const core::dimension2d<f32>& stretchSize,
f32 maxHeight, video::IVideoDriver* driver,
const core::dimension2d<u32>& defaultVertexBlockSize,
bool debugBorders=false) const =0;
//! Create an arrow mesh, composed of a cylinder and a cone.
/**
\param tesselationCylinder Number of quads composing the cylinder.
\param tesselationCone Number of triangles composing the cone's roof.
\param height Total height of the arrow
\param cylinderHeight Total height of the cylinder, should be lesser than total height
\param cylinderHeight Total height of the cylinder, should be lesser
than total height
\param widthCylinder Diameter of the cylinder
\param widthCone Diameter of the cone's base, should be not smaller than the cylinder's diameter
\param widthCone Diameter of the cone's base, should be not smaller
than the cylinder's diameter
\param colorCylinder color of the cylinder
\param colorCone color of the cone
*/
......@@ -74,7 +81,7 @@ public:
const u32 tesselationCone = 8, const f32 height = 1.f,
const f32 cylinderHeight = 0.6f, const f32 widthCylinder = 0.05f,
const f32 widthCone = 0.3f, const video::SColor colorCylinder = 0xFFFFFFFF,
const video::SColor colorCone = 0xFFFFFFFF) const = 0;
const video::SColor colorCone = 0xFFFFFFFF) const =0;
//! Create a sphere mesh.
......@@ -83,8 +90,8 @@ public:
\param polyCountX Number of quads used for the horizontal tiling
\param polyCountY Number of quads used for the vertical tiling
*/
virtual IMesh* createSphereMesh(f32 radius = 5.f, u32 polyCountX = 16,
u32 polyCountY = 16) const = 0;
virtual IMesh* createSphereMesh(f32 radius = 5.f,
u32 polyCountX = 16, u32 polyCountY = 16) const =0;
//! Create a cylinder mesh.
/**
......@@ -95,9 +102,10 @@ public:
\param closeTop If true, close the ends of the cylinder, otherwise leave them open.
\param oblique (to be documented)
*/
virtual IMesh* createCylinderMesh(f32 radius, f32 length, u32 tesselation,
const video::SColor& color=video::SColor(0xffffffff),
bool closeTop=true, f32 oblique=0.f) const = 0;
virtual IMesh* createCylinderMesh(f32 radius, f32 length,
u32 tesselation,
const video::SColor& color=video::SColor(0xffffffff),
bool closeTop=true, f32 oblique=0.f) const =0;
//! Create a cone mesh.
/**
......@@ -108,10 +116,21 @@ public:
\param colorBottom The color of the bottom of the cone.
\param oblique (to be documented)
*/
virtual IMesh* createConeMesh(f32 radius, f32 length, u32 tesselation,
const video::SColor& colorTop=video::SColor(0xffffffff),
const video::SColor& colorBottom=video::SColor(0xffffffff),
f32 oblique=0.f) const = 0;
virtual IMesh* createConeMesh(f32 radius, f32 length, u32 tesselation,
const video::SColor& colorTop=video::SColor(0xffffffff),
const video::SColor& colorBottom=video::SColor(0xffffffff),
f32 oblique=0.f) const =0;
//! Create a volume light mesh.
/**
\param SubdivideU Horizontal patch count.
\param SubdivideV Vertical patch count.
\param FootColor Color at the bottom of the light.
\param TailColor Color at the mid of the light.
*/
virtual IMesh* createVolumeLightMesh(const u32 SubdivideU, const u32 SubdivideV,
const video::SColor FootColor,
const video::SColor TailColor) const =0;
};
......
This diff is collapsed.
......@@ -680,6 +680,160 @@ IMesh* CGeometryCreator::createConeMesh(f32 radius, f32 length, u32 tesselation,
}
void CGeometryCreator::addToBuffer(const video::S3DVertex& v, SMeshBuffer* Buffer) const
{
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);
}
IMesh* CGeometryCreator::createVolumeLightMesh(
const u32 SubdivideU, const u32 SubdivideV,
const video::SColor FootColor, const video::SColor TailColor) const
{
const f32 LPDistance = 8.0f;
const core::vector3df LightDimensions = core::vector3df(1.0f, 1.2f, 1.0f) ;
SMeshBuffer* Buffer = new SMeshBuffer();
Buffer->setHardwareMappingHint(EHM_STATIC);
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, FootColor, 0, 1),Buffer);
addToBuffer(video::S3DVertex( ax, 0, az, 0,0,0, FootColor, 1, 1),Buffer);
addToBuffer(video::S3DVertex( ax, 0,-az, 0,0,0, FootColor, 1, 0),Buffer);
addToBuffer(video::S3DVertex( ax, 0,-az, 0,0,0, FootColor, 1, 0),Buffer);
addToBuffer(video::S3DVertex(-ax, 0,-az, 0,0,0, FootColor, 0, 0),Buffer);
addToBuffer(video::S3DVertex(-ax, 0, az, 0,0,0, FootColor, 0, 1),Buffer);
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, FootColor, tu, 1),Buffer);
addToBuffer(video::S3DVertex(bx , 0, -az, 0,0,0, FootColor, tu, 0),Buffer);
addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, TailColor, tu, 1),Buffer);
addToBuffer(video::S3DVertex(bx , 0, -az, 0,0,0, FootColor, tu, 0),Buffer);
addToBuffer(video::S3DVertex(end1.X , end1.Y, end1.Z, 0,0,0, TailColor, tu, 0),Buffer);
addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, TailColor, tu, 1),Buffer);
//back side
addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, TailColor, tu, 1),Buffer);
addToBuffer(video::S3DVertex(-bx , 0, -az, 0,0,0, FootColor, tu, 1),Buffer);
addToBuffer(video::S3DVertex(-bx , 0, az, 0,0,0, FootColor, tu, 0),Buffer);
addToBuffer(video::S3DVertex(-bx , 0, az, 0,0,0, FootColor, tu, 0),Buffer);
addToBuffer(video::S3DVertex(-end1.X , end1.Y, -end1.Z, 0,0,0, TailColor, tu, 0),Buffer);
addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, TailColor, tu, 1),Buffer);
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, FootColor, 0, tv),Buffer);
addToBuffer(video::S3DVertex(ax , 0, bz, 0,0,0, FootColor, 1, tv),Buffer);
addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, TailColor, 1, tv),Buffer);
addToBuffer(video::S3DVertex(end2.X , end2.Y, end2.Z, 0,0,0, TailColor, 1, tv),Buffer);
addToBuffer(video::S3DVertex(end1.X , end1.Y, end1.Z, 0,0,0, TailColor, 0, tv),Buffer);
addToBuffer(video::S3DVertex(-ax , 0, bz, 0,0,0, FootColor, 0, tv),Buffer);
//back side
addToBuffer(video::S3DVertex(ax , 0, -bz, 0,0,0, FootColor, 0, tv),Buffer);
addToBuffer(video::S3DVertex(-ax , 0, -bz, 0,0,0, FootColor, 1, tv),Buffer);
addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, TailColor, 1, tv),Buffer);
addToBuffer(video::S3DVertex(-end2.X , end2.Y, -end2.Z, 0,0,0, TailColor, 1, tv),Buffer);
addToBuffer(video::S3DVertex(-end1.X , end1.Y, -end1.Z, 0,0,0, TailColor, 0, tv),Buffer);
addToBuffer(video::S3DVertex(ax , 0, -bz, 0,0,0, FootColor, 0, tv),Buffer);
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);
Buffer->recalculateBoundingBox();
SMesh* mesh = new SMesh();
mesh->addMeshBuffer(Buffer);
Buffer->drop();
mesh->recalculateBoundingBox();
return mesh;
}
} // end namespace scene
} // end namespace irr
......@@ -6,6 +6,7 @@
#define __C_GEOMETRY_CREATOR_H_INCLUDED__
#include "IGeometryCreator.h"
#include "SMeshBuffer.h"
namespace irr
{
......@@ -16,6 +17,7 @@ namespace scene
//! class for creating geometry on the fly
class CGeometryCreator : public IGeometryCreator
{
void addToBuffer(const video::S3DVertex& v, SMeshBuffer* Buffer) const;
public:
IMesh* createHillPlaneMesh(
......@@ -44,6 +46,10 @@ public:
IMesh* createConeMesh(f32 radius, f32 length, u32 tesselation,
const video::SColor& colorTop=video::SColor(0xffffffff),
const video::SColor& colorBottom=video::SColor(0xffffffff), f32 oblique=0.f) const;
IMesh* createVolumeLightMesh(const u32 SubdivideU, const u32 SubdivideV,
const video::SColor FootColor,
const video::SColor TailColor) const;
};
......
......@@ -504,12 +504,14 @@ IMeshSceneNode* CSceneManager::addQuake3SceneNode(IMeshBuffer* meshBuffer,
#endif
}
//! adds Volume Lighting Scene Node.
//! the returned pointer must not be dropped.
IVolumeLightSceneNode* CSceneManager::addVolumeLightSceneNode(ISceneNode* parent, s32 id,
const u32 subdivU, const u32 subdivV,
const video::SColor foot, const video::SColor tail,
const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale)
IVolumeLightSceneNode* CSceneManager::addVolumeLightSceneNode(
ISceneNode* parent, s32 id,
const u32 subdivU, const u32 subdivV,
const video::SColor foot, const video::SColor tail,
const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale)
{
if (!parent)
parent = this;
......@@ -520,6 +522,7 @@ IVolumeLightSceneNode* CSceneManager::addVolumeLightSceneNode(ISceneNode* parent
return node;
}
//! adds a test scene node for test purposes to the scene. It is a simple cube of (1,1,1) size.
//! the returned pointer must not be dropped.
IMeshSceneNode* CSceneManager::addCubeSceneNode(f32 size, ISceneNode* parent,
......@@ -1037,6 +1040,36 @@ IAnimatedMesh* CSceneManager::addSphereMesh(const core::string<c16>& name,
//! Adds a static volume light mesh to the mesh pool.
IAnimatedMesh* CSceneManager::addVolumeLightMesh(const core::string<c16>& name,
const u32 SubdivideU, const u32 SubdivideV,
const video::SColor FootColor, const video::SColor TailColor)
{
if (MeshCache->isMeshLoaded(name))
return MeshCache->getMeshByFilename(name);
IMesh* mesh = GeometryCreator->createVolumeLightMesh(SubdivideU, SubdivideV, FootColor, TailColor);
if (!mesh)
return 0;
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
if (!animatedMesh)
{
mesh->drop();
return 0;
}
animatedMesh->addMesh(mesh);
mesh->drop();
animatedMesh->recalculateBoundingBox();
MeshCache->addMesh(name, animatedMesh);
animatedMesh->drop();
return animatedMesh;
}
//! Returns the root scene node. This is the scene node wich is parent
//! of all scene nodes. The root scene node is a special scene node which
//! only exists to manage all scene nodes. It is not rendered and cannot
......
......@@ -226,6 +226,12 @@ namespace scene
IAnimatedMesh* addSphereMesh(const core::string<c16>& name,
f32 radius=5.f, u32 polyCountX=16, u32 polyCountY=16);
//! Adds a static volume light mesh to the mesh pool.
IAnimatedMesh* addVolumeLightMesh(const core::string<c16>& name,
const u32 SubdivideU = 32, const u32 SubdivideV = 32,
const video::SColor FootColor = video::SColor(51, 0, 230, 180),
const video::SColor TailColor = video::SColor(0, 0, 0, 0));
//! Adds a particle system scene node.
virtual IParticleSystemSceneNode* addParticleSystemSceneNode(
bool withDefaultEmitter=true, ISceneNode* parent=0, s32 id=-1,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment