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.
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.
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...."
|