photo

ObjectMeshDynamic creation API

Recommended Posts

Hello,

Following on my trials with creating cables, I'm trying to create the rope manually through the ObjectMeshDynamic API, and oh boy do I struggle :(

  • there are very few samples code, and they are quite confusing, as they only demonstrate very basic geometries, without reusing indexes for example. Crashes have been aaaaaall my day :(
  • how do I specify the normal of a vertex? This is essential so the geometry can be inflated through the shader.
  • I did manage to create a segmented cylinder, but only with quads. I couldn't find a way to do it with triangle strips that reuse indexes from one segment to the other. As I'm sure your primitive Cylinder does such a thing, how could I peek at this code?

For reference, here is the code I wrote, most probably very suboptimal, so how should I rewrite it?

Spoiler

	const float alpha = 3.1519265f*2.f / slices;
	const float radius = 0.05;
	ObjectMeshDynamicPtr o = ObjectMeshDynamic::create(ObjectMeshDynamic::IMMUTABLE_ALL);
	for (int ig = 0; ig <= segments; ++ig) {
		o->addTriangleQuads(slices);
		for (int is = 0; is < slices - 1; ++is) {
			float c0 = cosf(alpha*is)*radius;
			float s0 = sinf(alpha*is)*radius;
			float c1 = cosf(alpha*(is + 1))*radius;
			float s1 = sinf(alpha*(is + 1))*radius;
			o->addVertex(vec3(c0, dg*(ig + 1), s0));
			o->addVertex(vec3(c1, dg*(ig + 1), s1));
			o->addVertex(vec3(c1, dg*ig, s1));
			o->addVertex(vec3(c0, dg*ig, s0));
		}
		float c0 = cosf(alpha*(slices - 1))*radius;
		float s0 = sinf(alpha*(slices - 1))*radius;
		float c1 = cosf(0)*radius;
		float s1 = sinf(0)*radius;
		o->addVertex(vec3(c0, dg*(ig + 1), s0));
		o->addVertex(vec3(c1, dg*(ig + 1), s1));
		o->addVertex(vec3(c1, dg*ig, s1));
		o->addVertex(vec3(c0, dg*ig, s0));
	}

	o->updateBounds();
	o->updateTangents();
	o->updateIndices();
	o->flushVertex();
	o->flushIndices();

 

Thanks!

Share this post


Link to post
Posted (edited)

Hi Stephane,

 

creating dynamic meshes with vertices and indices are also not that hard. Please have a look at the example code:

Spoiler



ObjectMeshDynamicPtr createCylinder(int slices, int segments, float radius, float segmentHeight)
{
	//1. Step: Create your dynamic mesh and allocate your number of vertices and indices
	ObjectMeshDynamicPtr cylinderMesh = ObjectMeshDynamic::create();

	cylinderMesh->allocateVertex(slices * segments + slices);
	cylinderMesh->allocateIndices((slices* segments + slices) * 3);


	float angle = (360.f / static_cast<float>(slices)) * UNIGINE_DEG2RAD;
	
	//2. Step: Create your bottom vertices (at height = 0.f)
	float slicesAngle = 0.f;
	
	for (int i = 0; i < slices; ++i)
	{
		vec3 vertexPosition;
		vertexPosition.x = radius * sinf(slicesAngle);
		vertexPosition.y = radius * cosf(slicesAngle);
		vertexPosition.z = 0.f;

		cylinderMesh->addVertex(vertexPosition);

		slicesAngle += angle;
		
	}

	//3. Step: create your cylinder segments

	slicesAngle = 0.f;
	float height = segmentHeight;

	for (int i = 1; i <= segments; ++i)
	{
		vec3 vertexPosition;
		vertexPosition.x = radius * sinf(slicesAngle);
		vertexPosition.y = radius * cosf(slicesAngle);
		vertexPosition.z = height;

		cylinderMesh->addVertex(vertexPosition);
		slicesAngle += angle;
		
		for (int j = 1; j < slices; ++j)
		{
			vertexPosition.x = radius * sinf(slicesAngle);
			vertexPosition.y = radius * cosf(slicesAngle);
			vertexPosition.z = height;

			cylinderMesh->addVertex(vertexPosition);

			cylinderMesh->addIndex((i - 1) * slices + j - 1);
			cylinderMesh->addIndex(i * slices + j - 1);
			cylinderMesh->addIndex((i - 1) * slices + j);

			cylinderMesh->addIndex(i * slices + j - 1);
			cylinderMesh->addIndex(i * slices + j);
			cylinderMesh->addIndex((i - 1) * slices + j);


			slicesAngle += angle;
			
		}

		cylinderMesh->addIndex((i - 1) * slices + slices - 1);
		cylinderMesh->addIndex(i * slices + slices - 1);
		cylinderMesh->addIndex((i - 1) * slices);

		cylinderMesh->addIndex(i * slices + slices - 1);
		cylinderMesh->addIndex((i - 1) * slices + slices);
		cylinderMesh->addIndex((i - 1) * slices);
		

		slicesAngle = 0.f;
		height += segmentHeight;
	}

	//Step 4: update tangents and bounds.
	cylinderMesh->updateTangents();
	cylinderMesh->updateBounds();

	return cylinderMesh;
	
}


 

Allocating memory for vertices and indices at the beginning can be done via two functions and makes performance a little bit better. After that you only need to add your vertices and triangle indices to the dynamic mesh. And that's it! For normals and triangle direction always make sure to add triangle indices in clockwise direction.

The above shown code sample only adds the cylinder sides but not the bottom/top surface but you can easily start from there. Hope that helps!

 

Best

Christian

 

 

Edited by christian.wolf2
Adding spoiler tab
  • Like 2

Share this post


Link to post

Hi Christian,

Thanks a lot for sharing your code, this has helped me a lot!

Share this post


Link to post