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)
- 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
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.

View File

@ -99,7 +99,7 @@ int main()
mesh = smgr->addHillPlaneMesh("myHill",
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>(10,10));

View File

@ -768,7 +768,7 @@ namespace scene
exists. If successful, a pointer to the mesh is returned.
This pointer should not be dropped. See IUnknown::drop() for more information. */
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,
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;

View File

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

View File

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

View File

@ -18,70 +18,77 @@ namespace scene
// creates a hill plane
IMesh* CGeometryCreator::createHillPlaneMesh(
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,
const core::dimension2d<f32>& textureRepeatCount)
{
core::dimension2d<s32> tileCount = tc;
core::dimension2d<u32> tileCount = tc;
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();
video::S3DVertex vtx;
vtx.Color.set(255,255,255,255);
if (countHills.Width < 0.01f)
countHills.Width = 1;
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;
// create vertices from left-front to right-back
u32 x;
f32 sx=0.f, tsx=0.f;
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.TCoords.set(x * tx.Width, 1.0f - y * tx.Height);
vtx.Pos.set(sx - center.X, 0, sy - center.Y);
vtx.TCoords.set(tsx, 1.0f - tsy);
if (hillHeight)
vtx.Pos.Y = (f32)(sin(vtx.Pos.X * countHills.Width * irr::core::PI / halfX) *
cos(vtx.Pos.Z * countHills.Height * irr::core::PI / halfY))
if (hillHeight != 0.0f)
vtx.Pos.Y = (f32)(sin(vtx.Pos.X * countHills.Width * irr::core::PI / center.X) *
cos(vtx.Pos.Z * countHills.Height * irr::core::PI / center.Y))
*hillHeight;
buffer->Vertices.push_back(vtx);
sy += tileSize.Height;
tsy += tx.Height;
}
sx += tileSize.Width;
tsx += tx.Width;
}
// create indices
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 + 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 + tileCount.Width);
buffer->Indices.push_back(current + tileCount.Width);
buffer->Indices.push_back(current + 1 + tileCount.Height);
buffer->Indices.push_back(current + tileCount.Height);
}
}
// recalculate normals
for (u32 i=0; i<buffer->Indices.size(); i+=3)
{

View File

@ -27,7 +27,7 @@ class CGeometryCreator
public:
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,
const core::dimension2d<f32>& textureRepeatCount);

View File

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