Fixed HillPlane Mesh to work with arbitrary sizes.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@812 dfc29bdd-3216-0410-991c-e03cc46cb475
master
hybrid 2007-07-30 17:14:55 +00:00
parent bc94d5a4a2
commit 31eff65735
9 changed files with 72 additions and 70 deletions

View File

@ -1,5 +1,7 @@
Changes in version 1.4 (... 2007) Changes in version 1.4 (... 2007)
- Fixed the hillplane mesh to work with non-quadratic dimensions as well. Changed the interface also, so use a u32 dimension to specify the tilecount now.
- Hires timers are disabled on windows systems with more than one CPU, due to bugs - Hires timers are disabled on windows systems with more than one CPU, due to bugs
in the BIOS of many multi-core motherboards. To enable hires timers in your project, in the BIOS of many multi-core motherboards. To enable hires timers in your project,
use SetProcessAffinityMask to set to use only one CPU before creating the device. use SetProcessAffinityMask to set to use only one CPU before creating the device.

View File

@ -99,7 +99,7 @@ int main()
mesh = smgr->addHillPlaneMesh("myHill", mesh = smgr->addHillPlaneMesh("myHill",
core::dimension2d<f32>(20,20), core::dimension2d<f32>(20,20),
core::dimension2d<s32>(40,40), 0, 0, core::dimension2d<u32>(40,40), 0, 0,
core::dimension2d<f32>(0,0), core::dimension2d<f32>(0,0),
core::dimension2d<f32>(10,10)); core::dimension2d<f32>(10,10));

View File

@ -768,7 +768,7 @@ namespace scene
exists. If successful, a pointer to the mesh is returned. exists. If successful, a pointer to the mesh is returned.
This pointer should not be dropped. See IUnknown::drop() for more information. */ This pointer should not be dropped. See IUnknown::drop() for more information. */
virtual IAnimatedMesh* addHillPlaneMesh(const c8* name, virtual IAnimatedMesh* addHillPlaneMesh(const c8* name,
const core::dimension2d<f32>& tileSize, const core::dimension2d<s32>& tileCount, const core::dimension2d<f32>& tileSize, const core::dimension2d<u32>& tileCount,
video::SMaterial* material = 0, f32 hillHeight = 0.0f, video::SMaterial* material = 0, f32 hillHeight = 0.0f,
const core::dimension2d<f32>& countHills = core::dimension2d<f32>(0.0f, 0.0f), const core::dimension2d<f32>& countHills = core::dimension2d<f32>(0.0f, 0.0f),
const core::dimension2d<f32>& textureRepeatCount = core::dimension2d<f32>(1.0f, 1.0f)) = 0; const core::dimension2d<f32>& textureRepeatCount = core::dimension2d<f32>(1.0f, 1.0f)) = 0;

View File

@ -13,10 +13,24 @@ namespace irr
namespace scene namespace scene
{ {
/*
011 111
/6,8------/5 y
/ | / | ^ z
/ | / | | /
010 3,9-------2 | |/
| 7- - -10,4 101 *---->x
| / | /
|/ | /
0------11,1/
000 100
*/
//! constructor //! constructor
CCubeSceneNode::CCubeSceneNode(f32 size, ISceneNode* parent, ISceneManager* mgr, s32 id, CCubeSceneNode::CCubeSceneNode(f32 size, ISceneNode* parent, ISceneManager* mgr,
const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) s32 id, const core::vector3df& position,
: ISceneNode(parent, mgr, id, position, rotation, scale), Size(size) const core::vector3df& rotation, const core::vector3df& scale)
: ISceneNode(parent, mgr, id, position, rotation, scale), Size(size)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CCubeSceneNode"); setDebugName("CCubeSceneNode");
@ -26,20 +40,18 @@ CCubeSceneNode::CCubeSceneNode(f32 size, ISceneNode* parent, ISceneManager* mgr,
7,3,0, 7,6,3, 9,5,2, 9,8,5, 0,11,10, 0,10,7}; 7,3,0, 7,6,3, 9,5,2, 9,8,5, 0,11,10, 0,10,7};
Buffer.Indices.set_used(36); Buffer.Indices.set_used(36);
for (s32 i=0; i<36; ++i) for (u32 i=0; i<36; ++i)
Buffer.Indices[i] = u[i]; Buffer.Indices[i] = u[i];
setSize(); setSize();
} }
//! destructor //! destructor
CCubeSceneNode::~CCubeSceneNode() CCubeSceneNode::~CCubeSceneNode()
{ {
} }
void CCubeSceneNode::setSize() void CCubeSceneNode::setSize()
{ {
// we are creating the cube mesh here. // we are creating the cube mesh here.
@ -65,7 +77,7 @@ void CCubeSceneNode::setSize()
Buffer.BoundingBox.reset(0,0,0); Buffer.BoundingBox.reset(0,0,0);
for (int i=0; i<12; ++i) for (u32 i=0; i<12; ++i)
{ {
Buffer.Vertices[i].Pos -= core::vector3df(0.5f, 0.5f, 0.5f); Buffer.Vertices[i].Pos -= core::vector3df(0.5f, 0.5f, 0.5f);
Buffer.Vertices[i].Pos *= Size; Buffer.Vertices[i].Pos *= Size;
@ -74,34 +86,16 @@ void CCubeSceneNode::setSize()
} }
//! renders the node. //! renders the node.
void CCubeSceneNode::render() void CCubeSceneNode::render()
{ {
/*
011 111
/6--------/5 y
/ | / | ^ z
/ | / | | /
010 3---------2 | |/
| 7- - -| -4 101 *---->x
| / | /
|/ | /
0---------1/
000 100
*/
video::IVideoDriver* driver = SceneManager->getVideoDriver(); video::IVideoDriver* driver = SceneManager->getVideoDriver();
driver->setMaterial(Buffer.Material); driver->setMaterial(Buffer.Material);
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawMeshBuffer(&Buffer); driver->drawMeshBuffer(&Buffer);
} }
//! returns the axis aligned bounding box of this node //! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CCubeSceneNode::getBoundingBox() const const core::aabbox3d<f32>& CCubeSceneNode::getBoundingBox() const
{ {
@ -174,7 +168,6 @@ ISceneNode* CCubeSceneNode::clone(ISceneNode* newParent, ISceneManager* newManag
} }
} // end namespace scene } // end namespace scene
} // end namespace irr } // end namespace irr

View File

@ -56,7 +56,6 @@ namespace scene
virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0); virtual ISceneNode* clone(ISceneNode* newParent=0, ISceneManager* newManager=0);
private: private:
void setSize(); void setSize();
SMeshBuffer Buffer; SMeshBuffer Buffer;

View File

@ -18,70 +18,77 @@ namespace scene
// creates a hill plane // creates a hill plane
IMesh* CGeometryCreator::createHillPlaneMesh( IMesh* CGeometryCreator::createHillPlaneMesh(
const core::dimension2d<f32>& tileSize, const core::dimension2d<f32>& tileSize,
const core::dimension2d<s32>& tc, video::SMaterial* material, const core::dimension2d<u32>& tc, video::SMaterial* material,
f32 hillHeight, const core::dimension2d<f32>& ch, f32 hillHeight, const core::dimension2d<f32>& ch,
const core::dimension2d<f32>& textureRepeatCount) const core::dimension2d<f32>& textureRepeatCount)
{ {
core::dimension2d<s32> tileCount = tc; core::dimension2d<u32> tileCount = tc;
core::dimension2d<f32> countHills = ch; core::dimension2d<f32> countHills = ch;
if (countHills.Width < 0.01f)
countHills.Width = 1.f;
if (countHills.Height < 0.01f)
countHills.Height = 1.f;
// center
const core::position2d<f32> center((tileSize.Width * tileCount.Width) / 2.0f, (tileSize.Height * tileCount.Height) / 2.0f);
// texture coord step
const core::dimension2d<f32> tx(
textureRepeatCount.Width / tileCount.Width,
textureRepeatCount.Height / tileCount.Height);
// add one more point in each direction for proper tile count
++tileCount.Height;
++tileCount.Width;
SMeshBuffer* buffer = new SMeshBuffer(); SMeshBuffer* buffer = new SMeshBuffer();
video::S3DVertex vtx; video::S3DVertex vtx;
vtx.Color.set(255,255,255,255); vtx.Color.set(255,255,255,255);
if (countHills.Width < 0.01f) // create vertices from left-front to right-back
countHills.Width = 1; u32 x;
if (countHills.Height < 0.01f)
countHills.Height = 1;
const f32 halfX = (tileSize.Width * tileCount.Width) / 2.0f;
const f32 halfY = (tileSize.Height * tileCount.Height) / 2.0f;
const core::dimension2d<f32> tx(
1.0f / (tileCount.Width / textureRepeatCount.Width),
1.0f / (tileCount.Height / textureRepeatCount.Height));
++tileCount.Height;
++tileCount.Width;
// create vertices
s32 x;
f32 sx=0.f, tsx=0.f;
for (x=0; x<tileCount.Width; ++x) for (x=0; x<tileCount.Width; ++x)
{ {
for (s32 y=0; y<tileCount.Height; ++y) f32 sy=0.f, tsy=0.f;
for (u32 y=0; y<tileCount.Height; ++y)
{ {
vtx.Pos.set(tileSize.Width * x - halfX, 0, tileSize.Height * y - halfY); vtx.Pos.set(sx - center.X, 0, sy - center.Y);
vtx.TCoords.set(x * tx.Width, 1.0f - y * tx.Height); vtx.TCoords.set(tsx, 1.0f - tsy);
if (hillHeight) if (hillHeight != 0.0f)
vtx.Pos.Y = (f32)(sin(vtx.Pos.X * countHills.Width * irr::core::PI / halfX) * vtx.Pos.Y = (f32)(sin(vtx.Pos.X * countHills.Width * irr::core::PI / center.X) *
cos(vtx.Pos.Z * countHills.Height * irr::core::PI / halfY)) cos(vtx.Pos.Z * countHills.Height * irr::core::PI / center.Y))
*hillHeight; *hillHeight;
buffer->Vertices.push_back(vtx); buffer->Vertices.push_back(vtx);
sy += tileSize.Height;
tsy += tx.Height;
} }
sx += tileSize.Width;
tsx += tx.Width;
} }
// create indices // create indices
for (x=0; x<tileCount.Width-1; ++x) for (x=0; x<tileCount.Width-1; ++x)
{ {
for (s32 y=0; y<tileCount.Height-1; ++y) for (u32 y=0; y<tileCount.Height-1; ++y)
{ {
s32 current = y*tileCount.Width + x; const s32 current = x*tileCount.Height + y;
buffer->Indices.push_back(current); buffer->Indices.push_back(current);
buffer->Indices.push_back(current + 1); buffer->Indices.push_back(current + 1);
buffer->Indices.push_back(current + tileCount.Width); buffer->Indices.push_back(current + tileCount.Height);
buffer->Indices.push_back(current + 1); buffer->Indices.push_back(current + 1);
buffer->Indices.push_back(current + 1 + tileCount.Width); buffer->Indices.push_back(current + 1 + tileCount.Height);
buffer->Indices.push_back(current + tileCount.Width); buffer->Indices.push_back(current + tileCount.Height);
} }
} }
// recalculate normals // recalculate normals
for (u32 i=0; i<buffer->Indices.size(); i+=3) for (u32 i=0; i<buffer->Indices.size(); i+=3)
{ {

View File

@ -27,7 +27,7 @@ class CGeometryCreator
public: public:
static IMesh* createHillPlaneMesh( static IMesh* createHillPlaneMesh(
const core::dimension2d<f32>& tileSize, const core::dimension2d<s32>& tileCount, const core::dimension2d<f32>& tileSize, const core::dimension2d<u32>& tileCount,
video::SMaterial* material, f32 hillHeight, const core::dimension2d<f32>& countHills, video::SMaterial* material, f32 hillHeight, const core::dimension2d<f32>& countHills,
const core::dimension2d<f32>& textureRepeatCount); const core::dimension2d<f32>& textureRepeatCount);

View File

@ -680,7 +680,7 @@ IDummyTransformationSceneNode* CSceneManager::addDummyTransformationSceneNode(
//! again using ISceneManager::getMesh with the name as parameter. //! again using ISceneManager::getMesh with the name as parameter.
IAnimatedMesh* CSceneManager::addHillPlaneMesh(const c8* name, IAnimatedMesh* CSceneManager::addHillPlaneMesh(const c8* name,
const core::dimension2d<f32>& tileSize, const core::dimension2d<f32>& tileSize,
const core::dimension2d<s32>& tileCount, const core::dimension2d<u32>& tileCount,
video::SMaterial* material, f32 hillHeight, video::SMaterial* material, f32 hillHeight,
const core::dimension2d<f32>& countHills, const core::dimension2d<f32>& countHills,
const core::dimension2d<f32>& textureRepeatCount) const core::dimension2d<f32>& textureRepeatCount)

View File

@ -175,16 +175,17 @@ namespace scene
); );
//! Adds a Hill Plane mesh to the mesh pool. The mesh is generated on the fly //! Adds a Hill Plane mesh to the mesh pool. The mesh is
//! and looks like a plane with some hills on it. It is uses mostly for quick //! generated on the fly and looks like a plane with some hills
//! tests of the engine only. You can specify how many hills there should be //! on it. You can specify how many hills should be on the plane
//! on the plane and how high they should be. Also you must specify a name for //! and how high they should be. Also you must specify a name
//! the mesh, because the mesh is added to the mesh pool, and can be retrieved //! for the mesh because the mesh is added to the mesh pool and
//! again using ISceneManager::getMesh with the name as parameter. //! can be retrieved back using ISceneManager::getMesh with the
//! name as parameter.
virtual IAnimatedMesh* addHillPlaneMesh(const c8* name, virtual IAnimatedMesh* addHillPlaneMesh(const c8* name,
const core::dimension2d<f32>& tileSize, const core::dimension2d<s32>& tileCount, const core::dimension2d<f32>& tileSize, const core::dimension2d<u32>& tileCount,
video::SMaterial* material = 0, f32 hillHeight = 0.0f, video::SMaterial* material = 0, f32 hillHeight = 0.0f,
const core::dimension2d<f32>& countHills = core::dimension2d<f32>(0.0f, 0.0f), const core::dimension2d<f32>& countHills = core::dimension2d<f32>(1.0f, 1.0f),
const core::dimension2d<f32>& textureRepeatCount = core::dimension2d<f32>(1.0f, 1.0f)); const core::dimension2d<f32>& textureRepeatCount = core::dimension2d<f32>(1.0f, 1.0f));
//! Adds a terrain mesh to the mesh pool. //! Adds a terrain mesh to the mesh pool.