Since OpenGL Core does not have a nice line-draw function with possibilities for texturing, line-width or curves, here is a small example to draw softbody ropes from the Bullet-Physic Engine. I’m using my YAOGL library to access the OpenGL State-Machine.

A rope (or string) thereby consists of several segments. A rope with one segment is a straight line.

#### The Rope Segment

There are several possibilities to create a rope segment. A simple form could be a 2D Billboard. A 2D Billboard consists of a plane which is alway oriented to the viewers direction. But even for small visual elements these depthless objects look ugly.

Therefore I’m using a 3D model, which is a regular cylinder with unit length.

int starStringImpId = [world createImpersonator:@"Rope"]; YAImpersonator* starStringImp = [world getImpersonator:starStringImpId];

The cylinder was created with Blender and exported to a file with the name **Rope.y3d**.

#### The Length of the Rope

To calculate the length of the rope you need its start and end position:

YAVector3f* positionFrom = star.translation; YAVector3f* positionTo = [[YAVector3f alloc] initCopy: positionFrom]; positionTo.y = 10;

The rope starts at the current position of the *star* and ends at the *ceiling* which has a hight of 10 units.

In this case the length of the rope is easily calculate by `positionTo.y - positionFrom.y`

. For a general approach you would use vector-subtraction or simply:

float stringLength = [positionFrom distanceTo: positionTo];

The *length* of the rope has now to be mapped to the *size* of the segment. Since the 3D Model “Rope” has unit length this is:

starStringImp.size.y = stringLength / 2.f;

#### Positioning the Rope

The center of the rope segment has to be centered between `positionFrom`

(the star) and `positionTo`

(the ceiling):

YAVector3f* position = positionTo; [position subVector:positionFrom]; [position mulScalar:.5f]; [position addVector:positionFrom]; [[starStringImp translation] setVector:position];

The *positionTo* vector is mapped according to the world-origin (0,0,0), halved and repositioned above the star-object.

#### Calculating the Segment Direction

The direction of the segment was already calculated during the positioning. It is the normalized vector from the origin.

YAVector3f* direction = [[YAVector3f alloc] initCopy:position]; [direction subVector:positionFrom]; [direction normalize];

To calculate the object rotation you could do something like this to get the angles around the world X-Axis and Z-Axis:

float rotZ = ToDegree(acosf([direction dotVector: vZAxis])); float rotX = ToDegree(acosf([direction dotVector: vXAxis]));

Only two *angles* are necessary to calculate the rotation of an object. But mapping to or from *euler* vectors is alway a bad idea. If the possibility exists, it is advisable to use quaternions.

starStringImp.useQuaternionRotation = YES; YAQuaternion* quat = [[YAQuaternion alloc]initEulerDeg:0 pitch:rotZ roll: rotX]; [starStringImp setRotationQuaternion:quat];

Or even faster with:

YAQuaternion* quat = [[YAQuaternion alloc]initVector: direction];

#### The Recursion

As mentioned above, a rope typically consists of several segments. Instead of the complete distance you calculate each segment separately. In YAOGL you can do this with:

YABulletEngineTranslator* physics = [[YABulletEngineTranslator alloc] initIn:world]; NSArray* ropes = [physics ropeDescriptions];

Each rope element in the ropes array holds all segments of one rope. Here is an example of the presented algorithm: