Create Circle Mesh

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
floxXx
Posts: 9
Joined: Tue Mar 16, 2010 9:30 am

Create Circle Mesh

Post by floxXx »

I want to make a circle Mesh by setting 2 parameters ( radius and tileCount)

How to draw the Mesh?

There is already a function addSphereMesh(..) but this is a Sphere and not a circle.

Please leave some code here.


Functions:
alpha = 360 / tileCount;
CoordX = sin(alpha) * r;
CoordZ = cos(alhpa) * r;
CoordY = 0;

The Type should be IAnimatedMesh in the end.
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Re: Create Circle Mesh

Post by randomMesh »

Code: Select all

irr::scene::SMeshBuffer* createCircleFan(irr::u32 verts, irr::f32 radius, const irr::video::SColor& color)
{
	if (verts < 3)
		verts = 3;
	else if (65534 < verts)
		verts = 65534;

	irr::scene::SMeshBuffer* mb = new irr::scene::SMeshBuffer;
	if (!mb)
		return 0;

	irr::video::S3DVertex vertex;
	vertex.Normal.set(0, 1, 0);
	vertex.Color = color;

	// origin vertex
	vertex.Pos.set(0, 0, 0);
	vertex.TCoords.set(.5f, .5f);
	mb->Vertices.push_back(vertex);
	mb->Indices.push_back(0);

	for (irr::s32 n = verts; 0 <= n; --n)
	{
		const irr::f32 x = (irr::core::PI*2.f)*n/verts;

		const irr::f32 dx = sinf(x);
		const irr::f32 dz = cosf(x);

		// vertices are always in the xz plane
		vertex.Pos.set(dx*radius, 0, dz*radius);

		// scale tcoords from -1,1 to 0,1
		vertex.TCoords.set((dx + 1.f) * .5f, (dz + 1.f) * .5f);

		mb->Vertices.push_back(vertex);
		mb->Indices.push_back(n + 1);
	}

	return mb;
}
Draw the meshbuffer like this

Code: Select all

//don't forget to set material and transformation
      driver->drawIndexedTriangleFan( 
         (irr::video::S3DVertex*)circleBuffer->getVertices(), 
         circleBuffer->getVertexCount(), 
         &circleBuffer->getIndices()[0], 
         circleBuffer->getIndexCount() - 2);
Edit:
Removed wrong advice about MeshSceneNode :p
Last edited by randomMesh on Fri Mar 19, 2010 3:44 pm, edited 1 time in total.
"Whoops..."
Acki
Posts: 3496
Joined: Tue Jun 29, 2004 12:04 am
Location: Nobody's Place (Venlo NL)
Contact:

Post by Acki »

there is already something like this in the forum:
http://irrlicht.sourceforge.net/phpBB2/ ... 032#211032
while(!asleep) sheep++;
IrrExtensions:Image
http://abusoft.g0dsoft.com
try Stendhal a MORPG written in Java
floxXx
Posts: 9
Joined: Tue Mar 16, 2010 9:30 am

Post by floxXx »

Danke dir,

wenn sämtliche Einträge : "mb->Indices.push_back(..)"
gelöscht werden und nacher :

Code: Select all

for (irr::s32 n = vertices; 1<=n; --n)
   {
		mb->Indices.push_back(0);
		mb->Indices.push_back(n+1);
		mb->Indices.push_back(n);
   }
eingefügt funktioniert es.
Danke dir
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Post by randomMesh »

Code: Select all

int main()
{
	IrrlichtDevice* device = createDevice(video::EDT_OPENGL);
	irr::video::IVideoDriver* driver = device->getVideoDriver();
	irr::scene::ISceneManager* smgr = device->getSceneManager();

	smgr->addCameraSceneNodeFPS();

	irr::scene::IMeshBuffer* circleBuffer = createCircleFan(64, 50.0f, irr::video::SColor(255, 255, 255, 255));
	circleBuffer->recalculateBoundingBox();
	circleBuffer->setHardwareMappingHint(irr::scene::EHM_STATIC);

	irr::video::SMaterial mat;
	mat.Lighting = false;

	while (device->run())
	{
		driver->beginScene();
		smgr->drawAll();

		driver->setMaterial(mat);
		driver->setTransform(irr::video::ETS_WORLD, irr::core::IdentityMatrix);
		driver->drawIndexedTriangleFan(
			(irr::video::S3DVertex*)circleBuffer->getVertices(),
			circleBuffer->getVertexCount(),
			&circleBuffer->getIndices()[0],
			circleBuffer->getIndexCount() - 2);


		driver->endScene();
	}

	circleBuffer->drop();
	device->drop();

	return 0;
}
works without modification.
"Whoops..."
floxXx
Posts: 9
Joined: Tue Mar 16, 2010 9:30 am

Post by floxXx »

One more question / bug?

For test issues I use the Realisic Water Scene Node from this Forum on the circle Mesh.

But if I rotate the Camera, the water sometimes disappears. Move the camera and the water is visible again.

Is there a bug in my Circle Mesh or does the shader crashes with my mesh in a specific camera angle for some reasons beingt in the water shader from the Realisitic Water Scene Node? (hlsl)

Code RealisticWaterSceneNode

Code: Select all

RealisticWaterSceneNode::RealisticWaterSceneNode(scene::ISceneManager* sceneManager,video::ITexture* bumpTexture,
												f32 radius, f32 vertices, bool WavesToCenter,
												ITimer* timer, core::dimension2di renderTargetSize,
												scene::ISceneNode* parent, s32 id):
	scene::ISceneNode( parent?parent:sceneManager->getRootSceneNode(), sceneManager, id),
	Timer(timer), Size(radius,radius), SceneManager(sceneManager), RefractionMap(0), ReflectionMap(0),
	WindForce(20.0f),WindDirection(0,1),WaveHeight(0.3f), WaterColor(0.1f, 0.1f, 0.6f, 1.0f), ColorBlendFactor(0.2f), Camera(0)
{
	VideoDriver = SceneManager->getVideoDriver();

	scene::ICameraSceneNode* CurrentCamera=SceneManager->getActiveCamera(); //get current camera
	Camera=SceneManager->addCameraSceneNode(); //create new camera

    Camera->setFarValue(CurrentCamera->getFarValue());
	Camera->setFOV(CurrentCamera->getFOV());
	SceneManager->setActiveCamera(CurrentCamera); //set back the previous camera	

	
   if (vertices < 3) 
      vertices = 3; 
   else if (65534 < vertices) 
      vertices = 65534; 

   irr::scene::SMeshBuffer* mb = new irr::scene::SMeshBuffer; 
 
   irr::video::S3DVertex vertex; 
   vertex.Normal.set(0, 1, 0); 
   vertex.Color.setAlpha(WaterColor.a); 
   vertex.Color.setBlue(WaterColor.b); 
   vertex.Color.setGreen(WaterColor.g); 
   vertex.Color.setRed(WaterColor.r); 

   // origin vertex 
   vertex.Pos.set(0, 0, 0); 
   vertex.TCoords.set(.5f, .5f); 
   mb->Vertices.push_back(vertex); 

   for (irr::s32 n = vertices; 0 <= n; --n) 
   { 
      const irr::f32 x = (irr::core::PI*2.f)*n/vertices; 

      const irr::f32 dx = sinf(x); 
      const irr::f32 dz = cosf(x); 

      // vertices are always in the xz plane 
      vertex.Pos.set(dx*radius, 0, dz*radius); 

      // scale tcoords from -1,1 to 0,1 
      vertex.TCoords.set((dx + 1.f) * .5f, (dz + 1.f) * .5f); 

      mb->Vertices.push_back(vertex); 
   } 
   for (irr::s32 n = vertices; 1<=n; --n)
   {
		mb->Indices.push_back(0);
		mb->Indices.push_back(n+1);
		mb->Indices.push_back(n);
   }


   scene::SMesh *WaterMesh = new scene::SMesh; 
   WaterMesh->addMeshBuffer(mb); 
   mb->drop(); 
   WaterMesh->recalculateBoundingBox(); 

	WaterSceneNode=SceneManager->addMeshSceneNode(WaterMesh,this);
	
	video::IGPUProgrammingServices* GPUProgrammingServices = VideoDriver->getGPUProgrammingServices();

	std::string WaterPixelShader;
	std::string WaterVertexShader;

	if (VideoDriver->getDriverType()==video::EDT_DIRECT3D9)
	{
		WaterPixelShader="shaders/Water_ps.hlsl";
		WaterVertexShader="shaders/Water_vs.hlsl";
	}
	else if (VideoDriver->getDriverType()==video::EDT_OPENGL)
	{
		WaterPixelShader="shaders/Water_ps.glsl";
		WaterVertexShader="shaders/Water_vs.glsl";
	}

	ShaderMaterial=GPUProgrammingServices->addHighLevelShaderMaterialFromFiles(
		WaterVertexShader.c_str(),"main",video::EVST_VS_1_1,
		WaterPixelShader.c_str(),"main",video::EPST_PS_2_0,
		this,video::EMT_LIGHTMAP);

	WaterSceneNode->setMaterialType((video::E_MATERIAL_TYPE)ShaderMaterial);

	WaterSceneNode->setMaterialTexture(0,bumpTexture);

	irr::core::dimension2d<u32> renderSize;
	renderSize.set(renderTargetSize.Width,renderTargetSize.Height);
	RefractionMap=VideoDriver->addRenderTargetTexture(renderSize);
	ReflectionMap=VideoDriver->addRenderTargetTexture(renderSize);
	WaterSceneNode->setMaterialTexture(1,RefractionMap);
	WaterSceneNode->setMaterialTexture(2,ReflectionMap);
}
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

The code from randomMesh requires that the mesh is rendered as tri-fan. This won't work with the dfault mesh scene node. If the latter is intended (which is probably also required for the water scene node), you need to use the full index set. However, you will also need a proper bbox then, which needs to be created in the meshbuffer, and the updated in the SMesh and the mesh scene node via updateBoundingBox.
floxXx
Posts: 9
Joined: Tue Mar 16, 2010 9:30 am

Post by floxXx »

and what does that mean?
hybrid
Admin
Posts: 14143
Joined: Wed Apr 19, 2006 9:20 pm
Location: Oldenburg(Oldb), Germany
Contact:

Post by hybrid »

That the error with the water node might be fixed when using your way of adding the indices, and adding several updateBoundingBox calls where necessary. You might also have to add the vertices to the mehsbuffer's bbox in order to get a proper init.
floxXx
Posts: 9
Joined: Tue Mar 16, 2010 9:30 am

Post by floxXx »

hybrid thank you so much

add:
mb->recalculateBoundingBox();
netpipe
Posts: 670
Joined: Fri Jun 06, 2008 12:50 pm
Location: Edmonton, Alberta, Canada
Contact:

Post by netpipe »

randomMesh i try your circle code with 1.7 and nothing shows up.
randomMesh
Posts: 1186
Joined: Fri Dec 29, 2006 12:04 am

Post by randomMesh »

This is a flat disk (like planet earth). Remember to disable backface culling if you want to see it from behind. Or just move the camera.

Code: Select all

camera->setPosition(irr::core::vector3df(0.0, 50.0,-10));
works well.
"Whoops..."
Post Reply