Amerio.Stephane Posted June 24, 2020 Share Posted June 24, 2020 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! Link to comment
christian.wolf2 Posted June 25, 2020 Share Posted June 25, 2020 (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 June 25, 2020 by christian.wolf2 Adding spoiler tab 2 Link to comment
Amerio.Stephane Posted June 25, 2020 Author Share Posted June 25, 2020 Hi Christian, Thanks a lot for sharing your code, this has helped me a lot! Link to comment
Recommended Posts