Commit 0ebbe960 authored by hybrid's avatar hybrid

Moved the arrow mesh parts into separate mesh constructor methods for cylinder...

Moved the arrow mesh parts into separate mesh constructor methods for cylinder and cone. Not yet exposed in the API.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@1410 dfc29bdd-3216-0410-991c-e03cc46cb475
parent d0888a25
...@@ -22,9 +22,6 @@ namespace scene ...@@ -22,9 +22,6 @@ namespace scene
{ {
public: public:
//! Destructor
virtual ~IMesh() { }
//! Returns the amount of mesh buffers. //! Returns the amount of mesh buffers.
/** \return Returns the amount of mesh buffers (IMeshBuffer) in this mesh. */ /** \return Returns the amount of mesh buffers (IMeshBuffer) in this mesh. */
virtual u32 getMeshBufferCount() const = 0; virtual u32 getMeshBufferCount() const = 0;
......
...@@ -893,6 +893,15 @@ namespace scene ...@@ -893,6 +893,15 @@ namespace scene
const core::dimension2d<s32>& defaultVertexBlockSize = core::dimension2d<s32>(64,64)) = 0; const core::dimension2d<s32>& defaultVertexBlockSize = core::dimension2d<s32>(64,64)) = 0;
//! add a static arrow mesh to the meshpool //! add a static arrow mesh to the meshpool
/** \param name Name of the mesh
\param vtxColor0 color of the cylinder
\param vtxColor1 color of the cone
\param tesselationCylinder Number of quads the cylinder side consists of
\param tesselationCone Number of triangles the cone's roof consits of
\param height Total height of the arrow
\param cylinderHeight Total height of the cylinder, should be lesser than total height
\param width0 Diameter of the cylinder
\param width1 Diameter of the cone's base, should be not smaller than the cylinder's diameter */
virtual IAnimatedMesh* addArrowMesh(const c8* name, virtual IAnimatedMesh* addArrowMesh(const c8* name,
video::SColor vtxColor0=0xFFFFFFFF, video::SColor vtxColor0=0xFFFFFFFF,
video::SColor vtxColor1=0xFFFFFFFF, video::SColor vtxColor1=0xFFFFFFFF,
...@@ -901,6 +910,10 @@ namespace scene ...@@ -901,6 +910,10 @@ namespace scene
f32 width0=0.05f, f32 width1=0.3f) = 0; f32 width0=0.05f, f32 width1=0.3f) = 0;
//! add a static sphere mesh to the meshpool //! add a static sphere mesh to the meshpool
/** \param name Name of the mesh
\param radius Radius of the sphere
\param polyCountX Number of quads used for the horizontal tiling
\param polyCountY Number of quads used for the vertical tiling */
virtual IAnimatedMesh* addSphereMesh(const c8* name, virtual IAnimatedMesh* addSphereMesh(const c8* name,
f32 radius=5.f, u32 polyCountX = 16, f32 radius=5.f, u32 polyCountX = 16,
u32 polyCountY = 16) = 0; u32 polyCountY = 16) = 0;
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include "SAnimatedMesh.h" #include "SAnimatedMesh.h"
#include "SMeshBuffer.h" #include "SMeshBuffer.h"
#include "SMesh.h" #include "SMesh.h"
#include "IMesh.h"
#include "IVideoDriver.h" #include "IVideoDriver.h"
#include "CImage.h" #include "CImage.h"
#include "os.h" #include "os.h"
...@@ -92,14 +93,14 @@ IMesh* CGeometryCreator::createHillPlaneMesh( ...@@ -92,14 +93,14 @@ IMesh* CGeometryCreator::createHillPlaneMesh(
// recalculate normals // recalculate normals
for (u32 i=0; i<buffer->Indices.size(); i+=3) for (u32 i=0; i<buffer->Indices.size(); i+=3)
{ {
core::plane3d<f32> p( const core::vector3df normal = core::plane3d<f32>(
buffer->Vertices[buffer->Indices[i+0]].Pos, buffer->Vertices[buffer->Indices[i+0]].Pos,
buffer->Vertices[buffer->Indices[i+1]].Pos, buffer->Vertices[buffer->Indices[i+1]].Pos,
buffer->Vertices[buffer->Indices[i+2]].Pos); buffer->Vertices[buffer->Indices[i+2]].Pos).Normal;
buffer->Vertices[buffer->Indices[i+0]].Normal = p.Normal; buffer->Vertices[buffer->Indices[i+0]].Normal = normal;
buffer->Vertices[buffer->Indices[i+1]].Normal = p.Normal; buffer->Vertices[buffer->Indices[i+1]].Normal = normal;
buffer->Vertices[buffer->Indices[i+2]].Normal = p.Normal; buffer->Vertices[buffer->Indices[i+2]].Normal = normal;
} }
if (material) if (material)
...@@ -115,11 +116,10 @@ IMesh* CGeometryCreator::createHillPlaneMesh( ...@@ -115,11 +116,10 @@ IMesh* CGeometryCreator::createHillPlaneMesh(
} }
IMesh* CGeometryCreator::createTerrainMesh(video::IImage* texture, IMesh* CGeometryCreator::createTerrainMesh(video::IImage* texture,
video::IImage* heightmap, const core::dimension2d<f32>& stretchSize, video::IImage* heightmap, const core::dimension2d<f32>& stretchSize,
f32 maxHeight, video::IVideoDriver* driver, f32 maxHeight, video::IVideoDriver* driver,
const core::dimension2d<s32> maxVtxBlockSize, const core::dimension2d<s32>& maxVtxBlockSize,
bool debugBorders) bool debugBorders)
{ {
if (!texture || !heightmap) if (!texture || !heightmap)
...@@ -199,15 +199,14 @@ IMesh* CGeometryCreator::createTerrainMesh(video::IImage* texture, ...@@ -199,15 +199,14 @@ IMesh* CGeometryCreator::createTerrainMesh(video::IImage* texture,
// recalculate normals // recalculate normals
for (u32 i=0; i<buffer->Indices.size(); i+=3) for (u32 i=0; i<buffer->Indices.size(); i+=3)
{ {
core::plane3d<f32> p( const core::vector3df normal = core::plane3d<f32>(
buffer->Vertices[buffer->Indices[i+0]].Pos, buffer->Vertices[buffer->Indices[i+0]].Pos,
buffer->Vertices[buffer->Indices[i+1]].Pos, buffer->Vertices[buffer->Indices[i+1]].Pos,
buffer->Vertices[buffer->Indices[i+2]].Pos); buffer->Vertices[buffer->Indices[i+2]].Pos).Normal;
p.Normal.normalize();
buffer->Vertices[buffer->Indices[i+0]].Normal = p.Normal; buffer->Vertices[buffer->Indices[i+0]].Normal = normal;
buffer->Vertices[buffer->Indices[i+1]].Normal = p.Normal; buffer->Vertices[buffer->Indices[i+1]].Normal = normal;
buffer->Vertices[buffer->Indices[i+2]].Normal = p.Normal; buffer->Vertices[buffer->Indices[i+2]].Normal = normal;
} }
if (buffer->Vertices.size()) if (buffer->Vertices.size())
...@@ -254,6 +253,7 @@ IMesh* CGeometryCreator::createTerrainMesh(video::IImage* texture, ...@@ -254,6 +253,7 @@ IMesh* CGeometryCreator::createTerrainMesh(video::IImage* texture,
return mesh; return mesh;
} }
/* /*
a cylinder, a cone and a cross a cylinder, a cone and a cross
point up on (0,1.f, 0.f ) point up on (0,1.f, 0.f )
...@@ -267,211 +267,22 @@ IMesh* CGeometryCreator::createArrowMesh(const u32 tesselationCylinder, ...@@ -267,211 +267,22 @@ IMesh* CGeometryCreator::createArrowMesh(const u32 tesselationCylinder,
const video::SColor vtxColor0, const video::SColor vtxColor0,
const video::SColor vtxColor1) const video::SColor vtxColor1)
{ {
SMeshBuffer* buffer; SMesh* mesh = (SMesh*)createCylinderMesh(width0, cylinderHeight, tesselationCylinder, vtxColor0, false);
video::S3DVertex v;
u32 i;
v.Color = vtxColor0;
// cylinder
buffer = new SMeshBuffer();
// floor, bottom
f32 angleStep = (core::PI * 2.f ) / tesselationCylinder;
for ( i = 0; i != tesselationCylinder; ++i )
{
f32 angle = angleStep * f32(i);
v.Color = vtxColor0;
v.Pos.X = width0 * cosf ( angle );
v.Pos.Y = 0.f;
v.Pos.Z = width0 * sinf ( angle );
v.Normal = v.Pos;
v.Normal.normalize ();
buffer->Vertices.push_back ( v );
v.Pos.X = width0 * 0.5f * cosf ( angle );
v.Pos.Y = cylinderHeight;
v.Pos.Z = width0 * 0.5f * sinf ( angle );
v.Normal = v.Pos;
v.Normal.normalize ();
buffer->Vertices.push_back ( v );
angle += ( angleStep / 2.f );
v.Color = vtxColor1;
v.Pos.X = ( width0 * 0.75f ) * cosf ( angle );
v.Pos.Y = 0.f;
v.Pos.Z = ( width0 * 0.75f ) * sinf ( angle );
v.Normal = v.Pos;
v.Normal.normalize ();
buffer->Vertices.push_back ( v );
v.Pos.X = ( width0 * 0.25f ) * cosf ( angle );
v.Pos.Y = cylinderHeight;
v.Pos.Z = ( width0 * 0.25f ) * sinf ( angle );
v.Normal = v.Pos;
v.Normal.normalize ();
buffer->Vertices.push_back ( v );
}
u32 nonWrappedSize = ( ( tesselationCylinder * 2 ) - 1 ) * 2;
for ( i = 0; i != nonWrappedSize; i += 2 )
{
buffer->Indices.push_back ( i + 2 );
buffer->Indices.push_back ( i + 0 );
buffer->Indices.push_back ( i + 1 );
buffer->Indices.push_back ( i + 2 );
buffer->Indices.push_back ( i + 1 );
buffer->Indices.push_back ( i + 3 );
}
buffer->Indices.push_back ( 0 ); IMesh* mesh2 = createConeMesh(width1, height-cylinderHeight, tesselationCone, vtxColor1, vtxColor0);
buffer->Indices.push_back ( i + 0 ); for (u32 i=0; i<mesh2->getMeshBufferCount(); ++i)
buffer->Indices.push_back ( i + 1 );
buffer->Indices.push_back ( 0 );
buffer->Indices.push_back ( i + 1 );
buffer->Indices.push_back ( 1 );
// close down
v.Pos.X = 0.f;
v.Pos.Y = 0.f;
v.Pos.Z = 0.f;
v.Normal.X = 0.f;
v.Normal.Y = -1.f;
v.Normal.Z = 0.f;
buffer->Vertices.push_back ( v );
u32 index = buffer->Vertices.size () - 1;
for ( i = 0; i != nonWrappedSize; i += 2 )
{ {
buffer->Indices.push_back ( index ); scene::IMeshBuffer* buffer = mesh2->getMeshBuffer(i);
buffer->Indices.push_back ( i + 0 ); for (u32 j=0; j<buffer->getVertexCount(); ++j)
buffer->Indices.push_back ( i + 2 ); buffer->getPosition(j).Y += cylinderHeight;
mesh->addMeshBuffer(buffer);
} }
mesh2->drop();
buffer->Indices.push_back ( index );
buffer->Indices.push_back ( i + 0 );
buffer->Indices.push_back ( 0 );
/*
// close top
v.Pos.X = 0.f;
v.Pos.Y = cylinderHeight;
v.Pos.Z = 0.f;
v.Normal.X = 0.f;
v.Normal.Y = 1.f;
v.Normal.Z = 0.f;
buffer->Vertices.push_back ( v );
index = buffer->Vertices.size () - 1;
for ( i = 0; i != nonWrappedSize; i += 2 )
{
buffer->Indices.push_back ( i + 1 );
buffer->Indices.push_back ( index );
buffer->Indices.push_back ( i + 3 );
}
buffer->Indices.push_back ( i + 1 );
buffer->Indices.push_back ( index );
buffer->Indices.push_back ( 1 );
*/
// add to mesh
SMesh* mesh = new SMesh();
buffer->recalculateBoundingBox();
mesh->addMeshBuffer(buffer);
buffer->drop();
// cone
buffer = new SMeshBuffer();
angleStep = (core::PI * 2.f ) / tesselationCone;
v.Color = vtxColor0;
for ( i = 0; i != tesselationCone; ++i )
{
f32 angle = angleStep * f32(i);
v.Color = vtxColor0;
v.Pos.X = width1 * cosf ( angle );
v.Pos.Y = cylinderHeight;
v.Pos.Z = width1 * sinf ( angle );
v.Normal = v.Pos;
v.Normal.normalize ();
buffer->Vertices.push_back ( v );
angle += angleStep / 2.f;
v.Color = vtxColor1;
v.Pos.X = (width1 * 0.75f ) * cosf ( angle );
v.Pos.Y = cylinderHeight;
v.Pos.Z = (width1 * 0.75f ) * sinf ( angle );
v.Normal = v.Pos;
v.Normal.normalize ();
buffer->Vertices.push_back ( v );
}
nonWrappedSize = buffer->Vertices.size () - 1;
// close top
v.Pos.X = 0.f;
v.Pos.Y = height;
v.Pos.Z = 0.f;
v.Normal.X = 0.f;
v.Normal.Y = 1.f;
v.Normal.Z = 0.f;
buffer->Vertices.push_back ( v );
index = buffer->Vertices.size () - 1;
for ( i = 0; i != nonWrappedSize; i += 1 )
{
buffer->Indices.push_back ( i + 0 );
buffer->Indices.push_back ( index );
buffer->Indices.push_back ( i + 1 );
}
buffer->Indices.push_back ( i + 0 );
buffer->Indices.push_back ( index );
buffer->Indices.push_back ( 0 );
// close down
v.Pos.X = 0.f;
v.Pos.Y = cylinderHeight;
v.Pos.Z = 0.f;
v.Normal.X = 0.f;
v.Normal.Y = -1.f;
v.Normal.Z = 0.f;
buffer->Vertices.push_back ( v );
index = buffer->Vertices.size () - 1;
for ( i = 0; i != nonWrappedSize; i += 1 )
{
buffer->Indices.push_back ( index );
buffer->Indices.push_back ( i + 0 );
buffer->Indices.push_back ( i + 1 );
}
buffer->Indices.push_back ( index );
buffer->Indices.push_back ( i + 0 );
buffer->Indices.push_back ( 0 );
// add to already existing mesh
buffer->recalculateBoundingBox();
mesh->addMeshBuffer(buffer);
buffer->drop();
mesh->recalculateBoundingBox();
return mesh; return mesh;
} }
/* A sphere with proper normals and texture coords */ /* A sphere with proper normals and texture coords */
IMesh* CGeometryCreator::createSphereMesh(f32 radius, u32 polyCountX, u32 polyCountY) IMesh* CGeometryCreator::createSphereMesh(f32 radius, u32 polyCountX, u32 polyCountY)
{ {
...@@ -643,5 +454,228 @@ IMesh* CGeometryCreator::createSphereMesh(f32 radius, u32 polyCountX, u32 polyCo ...@@ -643,5 +454,228 @@ IMesh* CGeometryCreator::createSphereMesh(f32 radius, u32 polyCountX, u32 polyCo
return mesh; return mesh;
} }
/* A cylinder with proper normals and texture coords */
IMesh* CGeometryCreator::createCylinderMesh(f32 radius, f32 length, u32 tesselation, const video::SColor& color, bool closeTop, f32 oblique)
{
SMeshBuffer* buffer = new SMeshBuffer();
const f32 recTesselation = core::reciprocal(tesselation);
const f32 recTesselationHalf = recTesselation * 0.5f;
const f32 angleStep = (core::PI * 2.f ) * recTesselation;
const f32 angleStepHalf = angleStep*0.5f;
u32 i;
video::S3DVertex v;
v.Color = color;
buffer->Vertices.reallocate(tesselation*4+(closeTop?2:1));
buffer->Indices.reallocate((tesselation*2)*(closeTop?12:9));
f32 tcx = 0.f;
for ( i = 0; i != tesselation; ++i )
{
const f32 angle = angleStep * i;
v.Pos.X = radius * cosf(angle);
v.Pos.Y = 0.f;
v.Pos.Z = radius * sinf(angle);
v.Normal = v.Pos;
v.Normal.normalize();
v.TCoords.X=tcx;
v.TCoords.Y=0.f;
buffer->Vertices.push_back(v);
v.Pos.X += oblique;
v.Pos.Y = length;
v.Normal = v.Pos;
v.Normal.normalize();
v.TCoords.Y=1.f;
buffer->Vertices.push_back(v);
v.Pos.X = radius * cosf(angle + angleStepHalf);
v.Pos.Y = 0.f;
v.Pos.Z = radius * sinf(angle + angleStepHalf);
v.Normal = v.Pos;
v.Normal.normalize();
v.TCoords.X=tcx+recTesselationHalf;
v.TCoords.Y=0.f;
buffer->Vertices.push_back(v);
v.Pos.X += oblique;
v.Pos.Y = length;
v.Normal = v.Pos;
v.Normal.normalize();
v.TCoords.Y=1.f;
buffer->Vertices.push_back(v);
tcx += recTesselation;
}
const u32 nonWrappedSize = ( tesselation* 4 ) - 2;
for ( i = 0; i != nonWrappedSize; i += 2 )
{
buffer->Indices.push_back ( i + 2 );
buffer->Indices.push_back ( i + 0 );
buffer->Indices.push_back ( i + 1 );
buffer->Indices.push_back ( i + 2 );
buffer->Indices.push_back ( i + 1 );
buffer->Indices.push_back ( i + 3 );
}
buffer->Indices.push_back ( 0 );
buffer->Indices.push_back ( i + 0 );
buffer->Indices.push_back ( i + 1 );
buffer->Indices.push_back ( 0 );
buffer->Indices.push_back ( i + 1 );
buffer->Indices.push_back ( 1 );
// close down
v.Pos.X = 0.f;
v.Pos.Y = 0.f;
v.Pos.Z = 0.f;
v.Normal.X = 0.f;
v.Normal.Y = -1.f;
v.Normal.Z = 0.f;
v.TCoords.X = 1.f;
v.TCoords.Y = 1.f;
buffer->Vertices.push_back ( v );
u32 index = buffer->Vertices.size () - 1;
for ( i = 0; i != nonWrappedSize; i += 2 )
{
buffer->Indices.push_back ( index );
buffer->Indices.push_back ( i + 0 );
buffer->Indices.push_back ( i + 2 );
}
buffer->Indices.push_back ( index );
buffer->Indices.push_back ( i + 0 );
buffer->Indices.push_back ( 0 );
if (closeTop)
{
// close top
v.Pos.X = oblique;
v.Pos.Y = length;
v.Pos.Z = 0.f;
v.Normal.X = 0.f;
v.Normal.Y = 1.f;
v.Normal.Z = 0.f;
v.TCoords.X = 0.f;
v.TCoords.Y = 0.f;
buffer->Vertices.push_back ( v );
index = buffer->Vertices.size () - 1;
for ( i = 0; i != nonWrappedSize; i += 2 )
{
buffer->Indices.push_back ( i + 1 );
buffer->Indices.push_back ( index );
buffer->Indices.push_back ( i + 3 );
}
buffer->Indices.push_back ( i + 1 );
buffer->Indices.push_back ( index );
buffer->Indices.push_back ( 1 );
}
buffer->recalculateBoundingBox();
SMesh* mesh = new SMesh();
mesh->addMeshBuffer(buffer);
mesh->recalculateBoundingBox();
buffer->drop();
return mesh;
}
/* A cone with proper normals and texture coords */
IMesh* CGeometryCreator::createConeMesh(f32 radius, f32 length, u32 tesselation, const video::SColor& colorTop, const video::SColor& colorBottom, f32 oblique)
{
SMeshBuffer* buffer = new SMeshBuffer();
const f32 angleStep = (core::PI * 2.f ) / tesselation;
const f32 angleStepHalf = angleStep*0.5f;
video::S3DVertex v;
u32 i;
v.Color = colorTop;
for ( i = 0; i != tesselation; ++i )
{
f32 angle = angleStep * f32(i);
v.Pos.X = radius * cosf(angle);
v.Pos.Y = 0.f;
v.Pos.Z = radius * sinf(angle);
v.Normal = v.Pos;
v.Normal.normalize();
buffer->Vertices.push_back(v);
angle += angleStepHalf;
v.Pos.X = radius * cosf(angle);
v.Pos.Y = 0.f;
v.Pos.Z = radius * sinf(angle);
v.Normal = v.Pos;
v.Normal.normalize();
buffer->Vertices.push_back(v);
}
const u32 nonWrappedSize = buffer->Vertices.size() - 1;
// close top
v.Pos.X = oblique;
v.Pos.Y = length;
v.Pos.Z = 0.f;
v.Normal.X = 0.f;
v.Normal.Y = 1.f;
v.Normal.Z = 0.f;
buffer->Vertices.push_back(v);
u32 index = buffer->Vertices.size() - 1;
for ( i = 0; i != nonWrappedSize; i += 1 )
{
buffer->Indices.push_back ( i + 0 );
buffer->Indices.push_back ( index );
buffer->Indices.push_back ( i + 1 );
}
buffer->Indices.push_back(i + 0);
buffer->Indices.push_back(index);
buffer->Indices.push_back(0);
// close down
v.Color = colorBottom;
v.Pos.X = 0.f;
v.Pos.Y = 0.f;
v.Pos.Z = 0.f;
v.Normal.X = 0.f;
v.Normal.Y = -1.f;
v.Normal.Z = 0.f;
buffer->Vertices.push_back(v);
index = buffer->Vertices.size() - 1;
for ( i = 0; i != nonWrappedSize; i += 1 )
{
buffer->Indices.push_back(index);
buffer->Indices.push_back(i + 0);
buffer->Indices.push_back(i + 1);
}
buffer->Indices.push_back(index);
buffer->Indices.push_back(i + 0);
buffer->Indices.push_back(0);
buffer->recalculateBoundingBox();
SMesh* mesh = new SMesh();
mesh->addMeshBuffer(buffer);
buffer->drop();
mesh->recalculateBoundingBox();
return mesh;
}
} // end namespace scene } // end namespace scene
} // end namespace irr } // end namespace irr
...@@ -34,7 +34,7 @@ public: ...@@ -34,7 +34,7 @@ public:
static IMesh* createTerrainMesh(video::IImage* texture, static IMesh* createTerrainMesh(video::IImage* texture,
video::IImage* heightmap, const core::dimension2d<f32>& stretchSize, video::IImage* heightmap, const core::dimension2d<f32>& stretchSize,
f32 maxHeight, video::IVideoDriver* driver, f32 maxHeight, video::IVideoDriver* driver,
const core::dimension2d<s32> defaultVertexBlockSize, const core::dimension2d<s32>& defaultVertexBlockSize,
bool debugBorders=false); bool debugBorders=false);
static IMesh* createArrowMesh(const u32 tesselationCylinder, static IMesh* createArrowMesh(const u32 tesselationCylinder,
...@@ -44,6 +44,10 @@ public: ...@@ -44,6 +44,10 @@ public:
const video::SColor vtxColor1); const video::SColor vtxColor1);
static IMesh* createSphereMesh(f32 radius, u32 polyCountX, u32 polyCountY); static IMesh* createSphereMesh(f32 radius, u32 polyCountX, u32 polyCountY);
static IMesh* createCylinderMesh(f32 radius, f32 length, u32 tesselation, const video::SColor& color=video::SColor(0xffffffff), bool closeTop=true, f32 oblique=0.f);
static 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);
}; };
......
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