Commit bc94d5a4 authored by hybrid's avatar hybrid

Made geometry creation use IMesh instead of IAnimatedMesh. Moved Sphere...

Made geometry creation use IMesh instead of IAnimatedMesh. Moved Sphere meshbuffer into geometry creator and changed sphere scene node accordingly.

git-svn-id: svn://svn.code.sf.net/p/irrlicht/code/trunk@811 dfc29bdd-3216-0410-991c-e03cc46cb475
parent f41e314f
...@@ -98,8 +98,8 @@ namespace scene ...@@ -98,8 +98,8 @@ namespace scene
//! Returns the type of the animated mesh. //! Returns the type of the animated mesh.
/** In most cases it is not neccessary to use this method. /** In most cases it is not neccessary to use this method.
This is useful for making a save downcast, for example This is useful for making a safe downcast. For example,
if getMeshType() returns EAMT_MD2, its save to cast the if getMeshType() returns EAMT_MD2 it's safe to cast the
IAnimatedMesh to IAnimatedMeshMD2. IAnimatedMesh to IAnimatedMeshMD2.
\returns Type of the mesh. */ \returns Type of the mesh. */
virtual E_ANIMATED_MESH_TYPE getMeshType() const virtual E_ANIMATED_MESH_TYPE getMeshType() const
......
...@@ -745,7 +745,7 @@ namespace scene ...@@ -745,7 +745,7 @@ namespace scene
and looks like a plane with some hills on it. It is uses mostly for quick 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 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 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 retieved the mesh, because the mesh is added to the mesh pool, and can be retrieved
again using ISceneManager::getMesh() with the name as parameter. again using ISceneManager::getMesh() with the name as parameter.
\param name: The name of this mesh which must be specified in order \param name: The name of this mesh which must be specified in order
to be able to retrieve the mesh later with ISceneManager::getMesh(). to be able to retrieve the mesh later with ISceneManager::getMesh().
...@@ -779,7 +779,7 @@ namespace scene ...@@ -779,7 +779,7 @@ namespace scene
(8000x8000 pixels would be no problem) because the generator splits the (8000x8000 pixels would be no problem) because the generator splits the
files into smaller textures if necessary. files into smaller textures if necessary.
You must specify a name for the mesh, because the mesh is added to the mesh pool, You must specify a name for the mesh, because the mesh is added to the mesh pool,
and can be retieved again using ISceneManager::getMesh() with the name as parameter. and can be retrieved again using ISceneManager::getMesh() with the name as parameter.
\param meshname: The name of this mesh which must be specified in order \param meshname: The name of this mesh which must be specified in order
to be able to retrieve the mesh later with ISceneManager::getMesh(). to be able to retrieve the mesh later with ISceneManager::getMesh().
\param texture: Texture for the terrain. Please note that this is not a \param texture: Texture for the terrain. Please note that this is not a
...@@ -810,6 +810,11 @@ namespace scene ...@@ -810,6 +810,11 @@ namespace scene
f32 height=1.f, f32 cylinderHeight=0.6f, f32 height=1.f, f32 cylinderHeight=0.6f,
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
virtual IAnimatedMesh* addSphereMesh(const c8* name,
f32 radius=5.f, u32 polyCountX = 16,
u32 polyCountY = 16) = 0;
//! Returns the root scene node. //! Returns the root scene node.
/** This is the scene node which is parent /** This is the scene node which is parent
of all scene nodes. The root scene node is a special scene node which of all scene nodes. The root scene node is a special scene node which
......
...@@ -31,15 +31,15 @@ class plane3d ...@@ -31,15 +31,15 @@ class plane3d
// Constructors // Constructors
plane3d(): Normal(0,1,0) { recalculateD(vector3d<T>(0,0,0)); }; plane3d(): Normal(0,1,0) { recalculateD(vector3d<T>(0,0,0)); }
plane3d(const vector3d<T>& MPoint, const vector3d<T>& Normal) : Normal(Normal) { recalculateD(MPoint); }; plane3d(const vector3d<T>& MPoint, const vector3d<T>& Normal) : Normal(Normal) { recalculateD(MPoint); }
plane3d(T px, T py, T pz, T nx, T ny, T nz) : Normal(nx, ny, nz) { recalculateD(vector3d<T>(px, py, pz)); }; plane3d(T px, T py, T pz, T nx, T ny, T nz) : Normal(nx, ny, nz) { recalculateD(vector3d<T>(px, py, pz)); }
plane3d(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3) { setPlane(point1, point2, point3); }; plane3d(const vector3d<T>& point1, const vector3d<T>& point2, const vector3d<T>& point3) { setPlane(point1, point2, point3); }
// operators // operators
inline bool operator==(const plane3d<T>& other) const { return (D==other.D && Normal==other.Normal);}; inline bool operator==(const plane3d<T>& other) const { return (D==other.D && Normal==other.Normal);}
inline bool operator!=(const plane3d<T>& other) const { return !(D==other.D && Normal==other.Normal);}; inline bool operator!=(const plane3d<T>& other) const { return !(D==other.D && Normal==other.Normal);}
// functions // functions
......
This diff is collapsed.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
#ifndef __C_GEOMETRY_CREATOR_H_INCLUDED__ #ifndef __C_GEOMETRY_CREATOR_H_INCLUDED__
#define __C_GEOMETRY_CREATOR_H_INCLUDED__ #define __C_GEOMETRY_CREATOR_H_INCLUDED__
#include "IAnimatedMesh.h" #include "IMesh.h"
#include "IImage.h" #include "IImage.h"
...@@ -26,23 +26,24 @@ class CGeometryCreator ...@@ -26,23 +26,24 @@ class CGeometryCreator
{ {
public: public:
static IAnimatedMesh* createHillPlaneMesh( static IMesh* createHillPlaneMesh(
const core::dimension2d<f32>& tileSize, const core::dimension2d<s32>& tileCount, const core::dimension2d<f32>& tileSize, const core::dimension2d<s32>& 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);
static IAnimatedMesh* 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 IAnimatedMesh* createArrowMesh(const u32 tesselationCylinder, static IMesh* createArrowMesh(const u32 tesselationCylinder,
const u32 tesselationCone, const f32 height, const u32 tesselationCone, const f32 height,
const f32 cylinderHeight, const f32 width0, const f32 cylinderHeight, const f32 width0,
const f32 width1, const video::SColor vtxColor0, const f32 width1, const video::SColor vtxColor0,
const video::SColor vtxColor1); const video::SColor vtxColor1);
static IMesh* createSphereMesh(f32 radius, u32 polyCountX, u32 polyCountY);
}; };
......
...@@ -206,7 +206,7 @@ const core::aabbox3d<f32>& CMeshSceneNode::getBoundingBox() const ...@@ -206,7 +206,7 @@ const core::aabbox3d<f32>& CMeshSceneNode::getBoundingBox() const
//! returns the material based on the zero based index i. To get the amount //! returns the material based on the zero based index i. To get the amount
//! of materials used by this scene node, use getMaterialCount(). //! of materials used by this scene node, use getMaterialCount().
//! This function is needed for inserting the node into the scene hirachy on a //! This function is needed for inserting the node into the scene hierarchy on a
//! optimal position for minimizing renderstate changes, but can also be used //! optimal position for minimizing renderstate changes, but can also be used
//! to directly modify the material of a scene node. //! to directly modify the material of a scene node.
video::SMaterial& CMeshSceneNode::getMaterial(u32 i) video::SMaterial& CMeshSceneNode::getMaterial(u32 i)
......
...@@ -1199,7 +1199,7 @@ void CNullDriver::setFog(SColor color, bool linearFog, f32 start, f32 end, f32 d ...@@ -1199,7 +1199,7 @@ void CNullDriver::setFog(SColor color, bool linearFog, f32 start, f32 end, f32 d
//! Draws a mesh buffer //! Draws a mesh buffer
void CNullDriver::drawMeshBuffer( const scene::IMeshBuffer* mb) void CNullDriver::drawMeshBuffer(const scene::IMeshBuffer* mb)
{ {
if (!mb) if (!mb)
return; return;
......
...@@ -80,7 +80,7 @@ namespace scene ...@@ -80,7 +80,7 @@ namespace scene
//! constructor //! constructor
CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs, CSceneManager::CSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs,
gui::ICursorControl* cursorControl, IMeshCache* cache, gui::ICursorControl* cursorControl, IMeshCache* cache,
gui::IGUIEnvironment * gui) gui::IGUIEnvironment* gui)
: ISceneNode(0, 0), Driver(driver), FileSystem(fs), GUIEnvironment(gui), : ISceneNode(0, 0), Driver(driver), FileSystem(fs), GUIEnvironment(gui),
CursorControl(cursorControl), CollisionManager(0), MeshManipulator(0), CursorControl(cursorControl), CollisionManager(0), MeshManipulator(0),
ActiveCamera(0), ShadowColor(150,0,0,0), AmbientLight(0,0,0,0), ActiveCamera(0), ShadowColor(150,0,0,0), AmbientLight(0,0,0,0),
...@@ -244,10 +244,9 @@ gui::IGUIEnvironment* CSceneManager::getGUIEnvironment () ...@@ -244,10 +244,9 @@ gui::IGUIEnvironment* CSceneManager::getGUIEnvironment ()
//! Adds a text scene node, which is able to display //! Adds a text scene node, which is able to display
//! 2d text at a position in three dimensional space //! 2d text at a position in three dimensional space
ITextSceneNode* CSceneManager::addTextSceneNode(gui::IGUIFont* font, const wchar_t* text, ITextSceneNode* CSceneManager::addTextSceneNode(gui::IGUIFont* font,
video::SColor color, const wchar_t* text, video::SColor color, ISceneNode* parent,
ISceneNode* parent, const core::vector3df& position, const core::vector3df& position, s32 id)
s32 id)
{ {
if (!font) if (!font)
return 0; return 0;
...@@ -263,8 +262,8 @@ ITextSceneNode* CSceneManager::addTextSceneNode(gui::IGUIFont* font, const wchar ...@@ -263,8 +262,8 @@ ITextSceneNode* CSceneManager::addTextSceneNode(gui::IGUIFont* font, const wchar
} }
//! Adds a text scene node, which uses billboards //! Adds a text scene node, which uses billboards
ITextSceneNode* CSceneManager::addBillboardTextSceneNode(gui::IGUIFont* font, const wchar_t* text, ITextSceneNode* CSceneManager::addBillboardTextSceneNode(gui::IGUIFont* font,
ISceneNode* parent, const wchar_t* text, ISceneNode* parent,
const core::dimension2d<f32>& size, const core::dimension2d<f32>& size,
const core::vector3df& position, s32 id, const core::vector3df& position, s32 id,
video::SColor shade_top, video::SColor shade_down) video::SColor shade_top, video::SColor shade_down)
...@@ -415,8 +414,7 @@ ISceneNode* CSceneManager::addOctTreeSceneNode(IAnimatedMesh* mesh, ISceneNode* ...@@ -415,8 +414,7 @@ ISceneNode* CSceneManager::addOctTreeSceneNode(IAnimatedMesh* mesh, ISceneNode*
//! scenes with lots of geometry. The Octree is built on the fly from the mesh, much //! scenes with lots of geometry. The Octree is built on the fly from the mesh, much
//! faster then a bsp tree. //! faster then a bsp tree.
ISceneNode* CSceneManager::addOctTreeSceneNode(IMesh* mesh, ISceneNode* parent, ISceneNode* CSceneManager::addOctTreeSceneNode(IMesh* mesh, ISceneNode* parent,
s32 id, s32 minimalPolysPerNode, s32 id, s32 minimalPolysPerNode, bool alsoAddIfMeshPointerZero)
bool alsoAddIfMeshPointerZero)
{ {
if (!alsoAddIfMeshPointerZero && !mesh) if (!alsoAddIfMeshPointerZero && !mesh)
return 0; return 0;
...@@ -681,18 +679,30 @@ IDummyTransformationSceneNode* CSceneManager::addDummyTransformationSceneNode( ...@@ -681,18 +679,30 @@ IDummyTransformationSceneNode* CSceneManager::addDummyTransformationSceneNode(
//! the mesh, because the mesh is added to the mesh pool, and can be retrieved //! the mesh, because the mesh is added to the mesh pool, and can be retrieved
//! 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<s32>& tileCount, const core::dimension2d<f32>& tileSize,
video::SMaterial* material, f32 hillHeight, const core::dimension2d<f32>& countHills, const core::dimension2d<s32>& tileCount,
video::SMaterial* material, f32 hillHeight,
const core::dimension2d<f32>& countHills,
const core::dimension2d<f32>& textureRepeatCount) const core::dimension2d<f32>& textureRepeatCount)
{ {
if (!name || MeshCache->isMeshLoaded(name)) if (!name || MeshCache->isMeshLoaded(name))
return 0; return 0;
IAnimatedMesh* animatedMesh = CGeometryCreator::createHillPlaneMesh(tileSize, IMesh* mesh = CGeometryCreator::createHillPlaneMesh(tileSize,
tileCount, material, hillHeight, countHills, textureRepeatCount); tileCount, material, hillHeight, countHills,
textureRepeatCount);
if (!mesh)
return 0;
MeshCache->addMesh(name, animatedMesh); SAnimatedMesh* animatedMesh = new SAnimatedMesh();
if (!animatedMesh)
return 0;
animatedMesh->addMesh(mesh);
animatedMesh->recalculateBoundingBox();
mesh->drop();
MeshCache->addMesh(name, animatedMesh);
animatedMesh->drop(); animatedMesh->drop();
return animatedMesh; return animatedMesh;
...@@ -709,14 +719,21 @@ IAnimatedMesh* CSceneManager::addTerrainMesh(const c8* name, ...@@ -709,14 +719,21 @@ IAnimatedMesh* CSceneManager::addTerrainMesh(const c8* name,
if (!name || MeshCache->isMeshLoaded(name)) if (!name || MeshCache->isMeshLoaded(name))
return 0; return 0;
IAnimatedMesh* animatedMesh = CGeometryCreator::createTerrainMesh(texture, IMesh* mesh = CGeometryCreator::createTerrainMesh(texture, heightmap,
heightmap, stretchSize, maxHeight, getVideoDriver(), defaultVertexBlockSize); stretchSize, maxHeight, getVideoDriver(),
defaultVertexBlockSize);
if (!mesh)
return 0;
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
if (!animatedMesh) if (!animatedMesh)
return 0; return 0;
MeshCache->addMesh(name, animatedMesh); animatedMesh->addMesh(mesh);
animatedMesh->recalculateBoundingBox();
mesh->drop();
MeshCache->addMesh(name, animatedMesh);
animatedMesh->drop(); animatedMesh->drop();
return animatedMesh; return animatedMesh;
...@@ -728,18 +745,51 @@ IAnimatedMesh* CSceneManager::addArrowMesh(const c8* name, ...@@ -728,18 +745,51 @@ IAnimatedMesh* CSceneManager::addArrowMesh(const c8* name,
u32 tesselationCylinder, u32 tesselationCone, f32 height, u32 tesselationCylinder, u32 tesselationCone, f32 height,
f32 cylinderHeight, f32 width0,f32 width1) f32 cylinderHeight, f32 width0,f32 width1)
{ {
if (!name || MeshCache->isMeshLoaded(name)) if (!name || MeshCache->isMeshLoaded(name))
return 0; return 0;
IAnimatedMesh* animatedMesh = CGeometryCreator::createArrowMesh( IMesh* mesh = CGeometryCreator::createArrowMesh( tesselationCylinder,
tesselationCylinder, tesselationCone, height, cylinderHeight, width0,width1, vtxColor0, vtxColor1); tesselationCone, height, cylinderHeight, width0,width1,
vtxColor0, vtxColor1);
if (!mesh)
return 0;
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
if (!animatedMesh) if (!animatedMesh)
return 0; return 0;
animatedMesh->addMesh(mesh);
animatedMesh->recalculateBoundingBox();
mesh->drop();
MeshCache->addMesh(name, animatedMesh); MeshCache->addMesh(name, animatedMesh);
animatedMesh->drop();
return animatedMesh;
}
//! Adds a static sphere mesh to the mesh pool.
IAnimatedMesh* CSceneManager::addSphereMesh(const c8* name,
f32 radius, u32 polyCountX, u32 polyCountY)
{
if (!name || MeshCache->isMeshLoaded(name))
return 0;
IMesh* mesh = CGeometryCreator::createSphereMesh( radius, polyCountX, polyCountY);
if (!mesh)
return 0;
SAnimatedMesh* animatedMesh = new SAnimatedMesh();
if (!animatedMesh)
return 0;
animatedMesh->addMesh(mesh);
animatedMesh->recalculateBoundingBox();
mesh->drop();
MeshCache->addMesh(name, animatedMesh);
animatedMesh->drop(); animatedMesh->drop();
return animatedMesh; return animatedMesh;
...@@ -1161,8 +1211,8 @@ ISceneNodeAnimator* CSceneManager::createRotationAnimator(const core::vector3df& ...@@ -1161,8 +1211,8 @@ ISceneNodeAnimator* CSceneManager::createRotationAnimator(const core::vector3df&
//! creates a fly circle animator, which lets the attached scene node fly around a center. //! creates a fly circle animator, which lets the attached scene node fly around a center.
ISceneNodeAnimator* CSceneManager::createFlyCircleAnimator(const core::vector3df& normal, ISceneNodeAnimator* CSceneManager::createFlyCircleAnimator(
f32 radius, f32 speed, const core::vector3df& normal, f32 radius, f32 speed,
const core::vector3df& direction) const core::vector3df& direction)
{ {
ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyCircle(os::Timer::getTime(), normal, ISceneNodeAnimator* anim = new CSceneNodeAnimatorFlyCircle(os::Timer::getTime(), normal,
...@@ -1626,7 +1676,7 @@ bool CSceneManager::loadScene(io::IReadFile* file, ISceneUserDataSerializer* use ...@@ -1626,7 +1676,7 @@ bool CSceneManager::loadScene(io::IReadFile* file, ISceneUserDataSerializer* use
// for mesh loading, set collada loading attributes // for mesh loading, set collada loading attributes
bool bOldColladaSingleMesh = getParameters()->getAttributeAsBool(COLLADA_CREATE_SCENE_INSTANCES); bool oldColladaSingleMesh = getParameters()->getAttributeAsBool(COLLADA_CREATE_SCENE_INSTANCES);
getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, false); getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, false);
// read file // read file
...@@ -1638,7 +1688,7 @@ bool CSceneManager::loadScene(io::IReadFile* file, ISceneUserDataSerializer* use ...@@ -1638,7 +1688,7 @@ bool CSceneManager::loadScene(io::IReadFile* file, ISceneUserDataSerializer* use
// restore old collada parameters // restore old collada parameters
getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, bOldColladaSingleMesh); getParameters()->setAttribute(COLLADA_CREATE_SCENE_INSTANCES, oldColladaSingleMesh);
// finish up // finish up
...@@ -1675,7 +1725,6 @@ void CSceneManager::readSceneNode(io::IXMLReader* reader, ISceneNode* parent, IS ...@@ -1675,7 +1725,6 @@ void CSceneManager::readSceneNode(io::IXMLReader* reader, ISceneNode* parent, IS
} }
// read attributes // read attributes
while(reader->read()) while(reader->read())
{ {
bool endreached = false; bool endreached = false;
...@@ -2043,9 +2092,9 @@ video::SColorf CSceneManager::getAmbientLight() ...@@ -2043,9 +2092,9 @@ video::SColorf CSceneManager::getAmbientLight()
// creates a scenemanager // creates a scenemanager
ISceneManager* createSceneManager(video::IVideoDriver* driver, io::IFileSystem* fs, ISceneManager* createSceneManager(video::IVideoDriver* driver,
gui::ICursorControl* cursorcontrol, io::IFileSystem* fs, gui::ICursorControl* cursorcontrol,
gui::IGUIEnvironment *guiEnvironment ) gui::IGUIEnvironment *guiEnvironment)
{ {
return new CSceneManager(driver, fs, cursorcontrol, 0, guiEnvironment ); return new CSceneManager(driver, fs, cursorcontrol, 0, guiEnvironment );
} }
......
...@@ -179,7 +179,7 @@ namespace scene ...@@ -179,7 +179,7 @@ namespace scene
//! and looks like a plane with some hills on it. It is uses mostly for quick //! 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 //! 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 //! 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 retieved //! the mesh, because the mesh is added to the mesh pool, and can be retrieved
//! again using ISceneManager::getMesh with the name as parameter. //! again 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<s32>& tileCount,
...@@ -199,6 +199,10 @@ namespace scene ...@@ -199,6 +199,10 @@ namespace scene
f32 height, f32 cylinderHeight, f32 width0, f32 height, f32 cylinderHeight, f32 width0,
f32 width1); f32 width1);
//! Adds a static sphere mesh to the mesh pool.
IAnimatedMesh* CSceneManager::addSphereMesh(const c8* name,
f32 radius, u32 polyCountX, u32 polyCountY);
//! Adds a particle system scene node. //! Adds a particle system scene node.
virtual IParticleSystemSceneNode* addParticleSystemSceneNode( virtual IParticleSystemSceneNode* addParticleSystemSceneNode(
bool withDefaultEmitter=true, ISceneNode* parent=0, s32 id=-1, bool withDefaultEmitter=true, ISceneNode* parent=0, s32 id=-1,
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "CSphereSceneNode.h" #include "CSphereSceneNode.h"
#include "IVideoDriver.h" #include "IVideoDriver.h"
#include "ISceneManager.h" #include "ISceneManager.h"
#include "CGeometryCreator.h"
#include "S3DVertex.h" #include "S3DVertex.h"
#include "os.h" #include "os.h"
...@@ -16,14 +17,14 @@ namespace scene ...@@ -16,14 +17,14 @@ namespace scene
//! constructor //! constructor
CSphereSceneNode::CSphereSceneNode(f32 radius, u32 polyCountX, u32 polyCountY, ISceneNode* parent, ISceneManager* mgr, s32 id, CSphereSceneNode::CSphereSceneNode(f32 radius, u32 polyCountX, u32 polyCountY, ISceneNode* parent, ISceneManager* mgr, s32 id,
const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale) const core::vector3df& position, const core::vector3df& rotation, const core::vector3df& scale)
: ISceneNode(parent, mgr, id, position, rotation, scale), Radius(radius), : ISceneNode(parent, mgr, id, position, rotation, scale), Mesh(0),
PolyCountX(polyCountX), PolyCountY(polyCountY) Radius(radius), PolyCountX(polyCountX), PolyCountY(polyCountY)
{ {
#ifdef _DEBUG #ifdef _DEBUG
setDebugName("CSphereSceneNode"); setDebugName("CSphereSceneNode");
#endif #endif
setSizeAndPolys(); Mesh = CGeometryCreator::createSphereMesh(radius, polyCountX, polyCountY);
} }
...@@ -31,186 +32,27 @@ CSphereSceneNode::CSphereSceneNode(f32 radius, u32 polyCountX, u32 polyCountY, I ...@@ -31,186 +32,27 @@ CSphereSceneNode::CSphereSceneNode(f32 radius, u32 polyCountX, u32 polyCountY, I
//! destructor //! destructor
CSphereSceneNode::~CSphereSceneNode() CSphereSceneNode::~CSphereSceneNode()
{ {
if (Mesh)
Mesh->drop();
} }
void CSphereSceneNode::setSizeAndPolys()
{
// thanks to Alfaz93 who made his code available for Irrlicht on which
// this one is based!
// we are creating the sphere mesh here.
if (PolyCountX < 2)
PolyCountX = 2;
if (PolyCountY < 2)
PolyCountY = 2;
if (PolyCountX * PolyCountY > 32767) // prevent u16 overflow
if (PolyCountX > PolyCountY) // prevent u16 overflow
PolyCountX = 32767/PolyCountY-1;
else
PolyCountY = 32767/(PolyCountX+1);
u32 PolyCountXPitch = PolyCountX+1; // get to same vertex on next level
Buffer.Vertices.set_used((PolyCountXPitch * PolyCountY) + 2);
Buffer.Indices.set_used((PolyCountX * PolyCountY) * 6);
video::SColor clr(100, 255,255,255);
u32 i=0;
u32 level = 0;
for (u32 p1 = 0; p1 < PolyCountY-1; ++p1)
{
//main quads, top to bottom
for (u32 p2 = 0; p2 < PolyCountX - 1; ++p2)
{
const u32 curr = level + p2;
Buffer.Indices[i] = curr + PolyCountXPitch;
Buffer.Indices[++i] = curr;
Buffer.Indices[++i] = curr + 1;
Buffer.Indices[++i] = curr + PolyCountXPitch;
Buffer.Indices[++i] = curr+1;
Buffer.Indices[++i] = curr + 1 + PolyCountXPitch;
++i;
}
// the connectors from front to end
Buffer.Indices[i] = level + PolyCountX - 1 + PolyCountXPitch;
Buffer.Indices[++i] = level + PolyCountX - 1;
Buffer.Indices[++i] = level + PolyCountX;
++i;
Buffer.Indices[i] = level + PolyCountX - 1 + PolyCountXPitch;
Buffer.Indices[++i] = level + PolyCountX;
Buffer.Indices[++i] = level + PolyCountX + PolyCountXPitch;
++i;
level += PolyCountXPitch;
}
const u32 PolyCountSq = PolyCountXPitch * PolyCountY; // top point
const u32 PolyCountSq1 = PolyCountSq + 1; // bottom point
const u32 PolyCountSqM1 = (PolyCountY - 1) * PolyCountXPitch; // last row's first vertex
for (u32 p2 = 0; p2 < PolyCountX - 1; ++p2)
{
// create triangles which are at the top of the sphere
Buffer.Indices[i] = PolyCountSq;
Buffer.Indices[++i] = p2 + 1;
Buffer.Indices[++i] = p2;
++i;
// create triangles which are at the bottom of the sphere
Buffer.Indices[i] = PolyCountSqM1 + p2;
Buffer.Indices[++i] = PolyCountSqM1 + p2 + 1;
Buffer.Indices[++i] = PolyCountSq1;
++i;
}
// create final triangle which is at the top of the sphere
Buffer.Indices[i] = PolyCountSq;
Buffer.Indices[++i] = PolyCountX;
Buffer.Indices[++i] = PolyCountX-1;
++i;
// create final triangle which is at the bottom of the sphere
Buffer.Indices[i] = PolyCountSqM1 + PolyCountX - 1;
Buffer.Indices[++i] = PolyCountSqM1;
Buffer.Indices[++i] = PolyCountSq1;
// calculate the angle which separates all points in a circle
const f64 AngleX = 2 * core::PI / PolyCountX;
const f64 AngleY = core::PI / PolyCountY;
i = 0;
f64 axz;
// we don't start at 0.
f64 ay = 0;//AngleY / 2;
for (u32 y = 0; y < PolyCountY; ++y)
{
ay += AngleY;
const f64 sinay = sin(ay);
axz = 0;
// calculate the necessary vertices without the doubled one
for (u32 xz = 0;xz < PolyCountX; ++xz)
{
// calculate points position
const core::vector3df pos((f32)(Radius * cos(axz) * sinay),
(f32)(Radius * cos(ay)),
(f32)(Radius * sin(axz) * sinay));
// for spheres the normal is the position
core::vector3df normal(pos);
normal.normalize();
// calculate texture coordinates via sphere mapping
// tu is the same on each level, so only calculate once
f32 tu = 0.5f;
if (y==0)
{
if (normal.Y != -1.0f && normal.Y != 1.0f)
tu = (f32)(acos(core::clamp(normal.X/sinay, -1.0, 1.0)) * 0.5 *core::RECIPROCAL_PI64);
if (normal.Z < 0.0f)
tu=1-tu;
}
else
tu = Buffer.Vertices[i-PolyCountXPitch].TCoords.X;
Buffer.Vertices[i] = video::S3DVertex(pos.X, pos.Y, pos.Z,
normal.X, normal.Y, normal.Z,
clr, tu,
(f32)(ay*core::RECIPROCAL_PI64));
++i;
axz += AngleX;
}
// This is the doubled vertex on the initial position
Buffer.Vertices[i] = video::S3DVertex(Buffer.Vertices[i-PolyCountX]);
Buffer.Vertices[i].TCoords.X=1.0f;
++i;
}
// the vertex at the top of the sphere
Buffer.Vertices[i] = video::S3DVertex(0.0f,Radius,0.0f, 0.0f,1.0f,0.0f, clr, 0.5f, 0.0f);
// the vertex at the bottom of the sphere
++i;
Buffer.Vertices[i] = video::S3DVertex(0.0f,-Radius,0.0f, 0.0f,-1.0f,0.0f, clr, 0.5f, 1.0f);
// recalculate bounding box
Buffer.BoundingBox.reset(Buffer.Vertices[i].Pos);
Buffer.BoundingBox.addInternalPoint(Buffer.Vertices[i-1].Pos);
Buffer.BoundingBox.addInternalPoint(Radius,0.0f,0.0f);
Buffer.BoundingBox.addInternalPoint(-Radius,0.0f,0.0f);
Buffer.BoundingBox.addInternalPoint(0.0f,0.0f,Radius);
Buffer.BoundingBox.addInternalPoint(0.0f,0.0f,-Radius);
}
//! renders the node. //! renders the node.
void CSphereSceneNode::render() void CSphereSceneNode::render()
{ {
video::IVideoDriver* driver = SceneManager->getVideoDriver(); video::IVideoDriver* driver = SceneManager->getVideoDriver();
if (Buffer.Vertices.size() && Buffer.Indices.size()) if (Mesh && driver)
{ {
driver->setMaterial(Buffer.Material); driver->setMaterial(Mesh->getMeshBuffer(0)->getMaterial());
driver->setTransform(video::ETS_WORLD, AbsoluteTransformation); driver->setTransform(video::ETS_WORLD, AbsoluteTransformation);
driver->drawMeshBuffer(&Buffer); driver->drawMeshBuffer(Mesh->getMeshBuffer(0));
if ( DebugDataVisible & scene::EDS_BBOX ) if ( DebugDataVisible & scene::EDS_BBOX )
{ {
video::SMaterial m; video::SMaterial m;
m.Lighting = false; m.Lighting = false;
driver->setMaterial(m); driver->setMaterial(m);
driver->draw3DBox(Buffer.BoundingBox, video::SColor(255,255,255,255)); driver->draw3DBox(Mesh->getMeshBuffer(0)->getBoundingBox(), video::SColor(255,255,255,255));
} }
} }
} }
...@@ -220,7 +62,7 @@ void CSphereSceneNode::render() ...@@ -220,7 +62,7 @@ void CSphereSceneNode::render()
//! returns the axis aligned bounding box of this node //! returns the axis aligned bounding box of this node
const core::aabbox3d<f32>& CSphereSceneNode::getBoundingBox() const const core::aabbox3d<f32>& CSphereSceneNode::getBoundingBox() const
{ {
return Buffer.BoundingBox; return Mesh ? Mesh->getBoundingBox() : Box;
} }
...@@ -240,7 +82,10 @@ void CSphereSceneNode::OnRegisterSceneNode() ...@@ -240,7 +82,10 @@ void CSphereSceneNode::OnRegisterSceneNode()
//! to directly modify the material of a scene node. //! to directly modify the material of a scene node.
video::SMaterial& CSphereSceneNode::getMaterial(u32 i) video::SMaterial& CSphereSceneNode::getMaterial(u32 i)
{ {
return Buffer.Material; if (i>0 || !Mesh)
return ISceneNode::getMaterial(i);
else
return Mesh->getMeshBuffer(i)->getMaterial();
} }
...@@ -280,7 +125,11 @@ void CSphereSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttribute ...@@ -280,7 +125,11 @@ void CSphereSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttribute
Radius = irr::core::max_(Radius, 0.0001f); Radius = irr::core::max_(Radius, 0.0001f);
if ( !core::equals(Radius, oldRadius) || PolyCountX != oldPolyCountX || PolyCountY != oldPolyCountY) if ( !core::equals(Radius, oldRadius) || PolyCountX != oldPolyCountX || PolyCountY != oldPolyCountY)
setSizeAndPolys(); {
if (Mesh)
Mesh->drop();
Mesh = CGeometryCreator::createSphereMesh(Radius, PolyCountX, PolyCountY);
}
ISceneNode::deserializeAttributes(in, options); ISceneNode::deserializeAttributes(in, options);
} }
...@@ -288,14 +137,16 @@ void CSphereSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttribute ...@@ -288,14 +137,16 @@ void CSphereSceneNode::deserializeAttributes(io::IAttributes* in, io::SAttribute
//! Creates a clone of this scene node and its children. //! Creates a clone of this scene node and its children.
ISceneNode* CSphereSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager) ISceneNode* CSphereSceneNode::clone(ISceneNode* newParent, ISceneManager* newManager)
{ {
if (!newParent) newParent = Parent; if (!newParent)
if (!newManager) newManager = SceneManager; newParent = Parent;
if (!newManager)
newManager = SceneManager;
CSphereSceneNode* nb = new CSphereSceneNode(Radius, PolyCountX, PolyCountY, newParent, CSphereSceneNode* nb = new CSphereSceneNode(Radius, PolyCountX, PolyCountY, newParent,
newManager, ID, RelativeTranslation); newManager, ID, RelativeTranslation);
nb->cloneMembers(this, newManager); nb->cloneMembers(this, newManager);
nb->Buffer.Material = Buffer.Material; nb->getMaterial(0) = Mesh->getMeshBuffer(0)->getMaterial();
nb->drop(); nb->drop();
return nb; return nb;
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
#define __C_SHPERE_SCENE_NODE_H_INCLUDED__ #define __C_SHPERE_SCENE_NODE_H_INCLUDED__
#include "ISceneNode.h" #include "ISceneNode.h"
#include "SMeshBuffer.h" #include "IMesh.h"
namespace irr namespace irr
{ {
...@@ -57,9 +57,8 @@ namespace scene ...@@ -57,9 +57,8 @@ namespace scene
private: private:
void setSizeAndPolys(); IMesh* Mesh;
core::aabbox3d<f32> Box;
SMeshBuffer Buffer;
f32 Radius; f32 Radius;
u32 PolyCountX; u32 PolyCountX;
u32 PolyCountY; u32 PolyCountY;
......
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