TGLTLSBFSSP: Cloths

Cloths

Having mastered the string. It is now very easy to make a cloth. Take a close look at a cloth, and you will find that it is simply a whole load of interwoven strings. You just need to add an extra dimension to your string routine. Imagine a cloth to be a sheet of points all connected together by springs. If two points get pulled further apart, then they experience a force pulling them together and vice versa.

This very simple model of a cloth seems to be resonably accurate. I have managed to get a very realistic cloth, draping over tables and wrinkling up at the edges (see picture below). You can lay a cloth over a torus, then drop a sphere onto it so that they both fall through the hole and the cloth ends up in a crumpled heap on the floor. I have tested this cloth routine against a real sheet and it compares very well. I have rendered some nice animation files of cloth which I will put here if I have space.

Actually, the picture above is rather misleading. It implies that you compare each point with its 4 nearest neighbours. Infact, if you do this, you will find that the cloth behaves much more like a fisherman's net. It is best if the points are connected to at least their 8 nearest neighbours. This will produce a very flexable cloth. If you go one step wider, and join to the 24 nearest neighbours, you will get a more realistic, stiffer cloth, though it's much slower to compute.

Here's some pseudo code do describe a massless cloth routine:

Every point on the cloth moves at a rate proportional to the sum of the forces acting on it from the neighbouring points.
Create a 2-dimensional array of co-ordinates to hold the x, y and z positions of the cloth in space. Initialise the values of cloth(p,q) to (p,q,0). You will need two of these arrays. One to hold the current state of the cloth, and the other to hold the new cloth that is being calculated. When you have finished calculating the cloth, copy all the values from your second array back to the first. For those who don't already know, a vector is an (x, y, z) of numbers. Numbers here are considered non-integers.

cloth1 (0 to 31, 0 to 31)
cloth2 (0 to 31, 0 to 31)

Variables:

VECTOR: MovementVector
VECTOR: SpringVector
VECTOR: ForceVector
VECTOR: Gravity  (initialised to (0, 0, g) where g is gravity, 0.02 is a good number)
NUMBER: Length
NUMBER: ForceScaler
NUMBER: NormalLength

For every point (p,q) on the cloth:

    MovementVector = Gravity

    For each of the 24 neighbouring points (NB obviously less at edges)
	SpringVector = (position in space of neighbour) - (position in space of point (p,q))
	Length       = length of SpringVector
	NormalLength = The length SpringVector would be if the cloth were unstretched
	ForceScaler  = (Length - NormalLength) / NormalLength
	SpringVector = SpringVector * (1/Length)
	ForceVector  = SpringVector * ForceScaler
	ForceVector  = ForceVector * SmallAmount
	add ForceVector to MovementVector
    end of loop

    Add MovementVector to cloth1(p,q) and store it in cloth2(p,q)
	
    make sure this point does not move inside an object
end of loop

Copy all the values in cloth2 to cloth1

keep doing all this forever

You will need some objects for the cloth to interact with. The simplest is a floor. Check each point on the cloth to see if it is below the floor, and if it is, then move it to the surface.
It is quite easy to make a sphere for the cloth to fall over. Check each point to see if it is inside the sphere. If it is, then move it to the nearest point on the surface of the sphere.

NUMBER: Distance
Distance = distance from the point(p,q) to the center of the sphere

if Distance < (radius of sphere) then:
    ForceVector = (position of point in space) - (center of sphere)
    ForceVector = Forcevector / Distance * radius
    point(p,q) = (center of sphere) + ForceVector
end if
It is also easy to make a torus and other objects. I'll leave that up to you though.


Adding wind

Adding wind to the cloth allows you to simulate the fluttering of flags and other cloth+wind kind of situations. This model is not totally accurate. The wind affects the cloth, but the cloth does not affect the wind, to do this would require a vast amount of fluid dynamic calculation. However, it produces resonable looking fluttering effects. For this you will need to be modeling cloth with mass.

First the cloth must be broken down into triangles. This is easy to do, since the cloth is already described as an array of points. The effect of the wind on the cloth is calculated on each of these triangles individually. At each point of the cloth, the sum of the effect of the wind on the surrounding triangles is calculated.
The force acting on a triangle due to air molecules bouncing off it will always be in the direction of the normal vector of that triangle. The normal vector for each triangle will obviously have to be calculated every frame because it will be constantly changing. The force will be proportional to the surface area of the triangle, the angle at which the wind hits the triangle, and the speed of the wind. It just so happens that when you use the Cross Product the calculate the normal vector of the triangle, the length of that vector is proportional to the area of the triangle, which makes things a little simpler.

Pseudocode to calculate effect of wind on cloth:

VECTOR: force
VECTOR: normal
VECTOR: wind
	
set force vector to (0,0,0) on all points on cloth
	
loop through all triangles	
    force = unitvector(normal) * dotproduct(normal, wind)
    add force to all points making up this triangle
end of loop

loop through all points on cloth
    add gravity to force
    add force to velocity
end of loop

	-- rest of cloth routine --


Just to spur you on to make your own cloth routine, and to show how useful it can be for importing into proper rendering engines, here's one I did earlier.

This cloth was draped over a cylinder and a torus to make the edges rounded, then imported into 3D Studio.

Definately very cool indeed.

Might make a good chat-up line..."hello, wanna come home and see my cloths...."


Realtime Cloth Demo

Magnus Adamsson sent me this realtime demo of a cloth falling over a sphere. If you have any questions about this demo, please direct them to the author.

Requires Windows and OpenGL.

cloth_demo
cloth_ma.zip - 17kb