Cloth Sim, please have a look :)

Blitz3D Forums/Blitz3D Programming/Cloth Sim, please have a look :)

Paolo(Posted 2004) [#1]
Let me know if you can understand any of this code.
The problem is I'm testing so there are many old lines (commented) still there just in case so don't pay attention to them.

The point is, I believe the code is pretty fast as it is right now and I could be able to finish having a function to generate cloth movement over any loaded mesh. But the problem is I can not figure out the proper code to find the 4 or 8 closest vertex to each vertex, so I decided to do a mesh in Blitz and manipulate each vertex separately.

Run this,
load a carpet texture of yours to have a better look:

by the way, there are some vars with spanish names :), for example

vecino = neighbor



Graphics3D 640,480,16,2


ClearTextureFilters

Function interpolate#(v#,a#,b#,c#,d#)
	Return c+(((v-a)*(d-c))/(b-a))
End Function

cam=CreateCamera()
	PositionEntity cam,0,2,-20
	CameraClsColor cam,100,100,100

fps=CreateTimer(30)

AmbientLight 50,50,50
l=CreateLight(2)
	PositionEntity l,0,5,0
	LightRange l,30

Const type_alf=1
Const type_c=2
	
;--------------------------------------------------------------
;------- PLANE -----------------------------------------------
grid=4


alf=CreateMesh()
	EntityFX alf,16
	EntityShininess alf,.75
	EntityColor alf,100,100,50

tex=LoadTexture("C:\WINDOWS\Escritorio\ClothSim\textures\Carpet.bmp",1)
	EntityTexture alf,tex
	
surf=CreateSurface(alf)

v_posx#=0
v_posz#=0
For g=0 To grid
	v_posx=0
	For g2=0 To grid
		AddVertex(surf,v_posx,0,v_posz,v_posx/8,v_posz/8,0)
;		c=CreateCube():PositionEntity c,v_posx,0,v_posz:ScaleEntity c,.2,.2,.2
		
		v_posx=v_posx+2
		v_index=v_index+1
	Next
	v_posz=v_posz+2
Next


For t=0 To 3
	AddTriangle(surf,t,t+6,t+1)
	AddTriangle(surf,t,t+6,t+5)
Next
For t=5 To 8
	AddTriangle(surf,t,t+6,t+1)
	AddTriangle(surf,t,t+6,t+5)
Next
For t=10 To 13
	AddTriangle(surf,t,t+6,t+1)
	AddTriangle(surf,t,t+6,t+5)
Next
For t=15 To 18
	AddTriangle(surf,t,t+6,t+1)
	AddTriangle(surf,t,t+6,t+5)
Next

For v=0 To CountVertices(surf)-1
	VertexNormal surf,v,0,1,0
Next

Dim vertexes#(CountVertices(surf),3)
lock_vertexs=True
Dim v_collis(CountVertices(surf))
	For v=0 To CountVertices(surf)-1
	v_collis(v)=CreateSphere(4)
		ScaleEntity v_collis(v),.15,.15,.15
		EntityColor v_collis(v),0,255,0
		EntityType v_collis(v),type_alf
		EntityRadius v_collis(v),.15
	Next

v_dumvecino=CreatePivot()
	ball1=CreateSphere(8,v_dumvecino)
	ScaleEntity ball1,.1,.1,.1
	EntityColor ball1,255,0,0
	EntityAlpha ball1,0
v_dumele=CreatePivot()
	ball2=CreateSphere(8,v_dumele)
	ScaleEntity ball2,.1,.1,.1
	EntityColor ball2,0,255,0
	EntityAlpha ball2,0
;-----------------------------------------------------------------------
;-----------------------------------------------------------------------

For c=1 To 1
	cube=CreateCube()
	PositionEntity cube,0,-10,0
	ScaleEntity cube,5,0.5,5
;	TurnEntity cube,0,Rand(-90,90),0
	EntityType cube,type_c
Next

Collisions type_alf,type_c,2,2

While Not KeyDown(1)
	WaitTimer(fps)

;s=GetSurface(test,1)
;	If KeyHit(28)
;	VertexCoords s,v,VertexX(s,v),VertexY(s,v)-2,VertexZ(s,v)
;	v=v+1
;	EndIf
	
;	TurnEntity alf,0,0,1
	
	PointEntity cam,v_dumele;alf
;	MoveEntity cam,.1,0,0


	If KeyDown(30)	
	vertexes(20,1)=vertexes(20,1)+.1
	vertexes(24,1)=vertexes(24,1)+.1
	vertexes(21,1)=vertexes(21,1)+.1
	vertexes(23,1)=vertexes(23,1)+.1
	EndIf
	If KeyDown(31)	
	vertexes(20,1)=vertexes(20,1)-.1
	vertexes(24,1)=vertexes(24,1)-.1
	vertexes(21,1)=vertexes(21,1)-.1
	vertexes(23,1)=vertexes(23,1)-.1
	EndIf

	If KeyDown(200)	
	vertexes(20,2)=vertexes(20,2)+.2
	vertexes(24,2)=vertexes(24,2)+.2
	vertexes(21,2)=vertexes(21,2)+.2
	vertexes(23,2)=vertexes(23,2)+.2
	EndIf
	If KeyDown(208)	
	vertexes(20,2)=vertexes(20,2)-.2
	vertexes(24,2)=vertexes(24,2)-.2
	vertexes(21,2)=vertexes(21,2)-.2
	vertexes(23,2)=vertexes(23,2)-.2
	EndIf
	If KeyDown(205)	
	vertexes(20,0)=vertexes(20,0)+.2
	vertexes(24,0)=vertexes(24,0)+.2
	vertexes(21,0)=vertexes(21,0)+.2
	vertexes(23,0)=vertexes(23,0)+.2
	EndIf
	If KeyDown(203)	
	vertexes(20,0)=vertexes(20,0)-.2
	vertexes(24,0)=vertexes(24,0)-.2
	vertexes(21,0)=vertexes(21,0)-.2
	vertexes(23,0)=vertexes(23,0)-.2
	EndIf

	If KeyHit(57) lock_vertexs=Not lock_vertexs
	
	If KeyDown(28)
	VertexCoords surf,24,EntityX(cube)+4,5,EntityZ(cube)
	VertexCoords surf,23,EntityX(cube)+2,5,EntityZ(cube)
	VertexCoords surf,21,EntityX(cube)-2,5,EntityZ(cube)
	VertexCoords surf,20,EntityX(cube)-4,5,EntityZ(cube)
	EndIf


	x#=0
	y#=0
	z#=0
	
	;**********************************
	;--- change this parameters for testing ----

	attract_force#=.65 	;better not above 1
	separation_dist#=4	;better not under 2
	
	smooth=12
	gravity#=.05;.075
	
	;------------------------------------------------
	;**********************************


	For v=0 To CountVertices(surf)-1
		Select v

			Case 20
				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-5),VertexY(surf,v-5),VertexZ(surf,v-5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-5,separation_dist,attract_force)

;				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
;				PositionEntity v_dumvecino,VertexX(surf,v+1),VertexY(surf,v+1),VertexZ(surf,v+1)
;				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+1,separation_dist,attract_force)

			Case 24
				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-5),VertexY(surf,v-5),VertexZ(surf,v-5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-5,separation_dist,attract_force)

;				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
;				PositionEntity v_dumvecino,VertexX(surf,v-1),VertexY(surf,v-1),VertexZ(surf,v-1)
;				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-1,separation_dist,attract_force)
		
			Case 0
				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v+1),VertexY(surf,v+1),VertexZ(surf,v+1)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+1,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v+5),VertexY(surf,v+5),VertexZ(surf,v+5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+5,separation_dist,attract_force)

			Case 1,2,3
				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-1),VertexY(surf,v-1),VertexZ(surf,v-1)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-1,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v+5),VertexY(surf,v+5),VertexZ(surf,v+5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+5,separation_dist,attract_force)
			
				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v+1),VertexY(surf,v+1),VertexZ(surf,v+1)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+1,separation_dist,attract_force)

			Case 4
				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-1),VertexY(surf,v-1),VertexZ(surf,v-1)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-1,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v+5),VertexY(surf,v+5),VertexZ(surf,v+5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+5,separation_dist,attract_force)

			Case 5,10
				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-5),VertexY(surf,v-5),VertexZ(surf,v-5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-5,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v+1),VertexY(surf,v+1),VertexZ(surf,v+1)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+1,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v+5),VertexY(surf,v+5),VertexZ(surf,v+5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+5,separation_dist,attract_force)
			
			Case 15
				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-5),VertexY(surf,v-5),VertexZ(surf,v-5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-5,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v+1),VertexY(surf,v+1),VertexZ(surf,v+1)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+1,separation_dist,attract_force)

					If Not lock_vertexs
					PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
					PositionEntity v_dumvecino,VertexX(surf,v+5),VertexY(surf,v+5),VertexZ(surf,v+5)
					SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+5,separation_dist,attract_force)
					EndIf

			Case 9,14
				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-5),VertexY(surf,v-5),VertexZ(surf,v-5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-5,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-1),VertexY(surf,v-1),VertexZ(surf,v-1)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-1,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v+5),VertexY(surf,v+5),VertexZ(surf,v+5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+5,separation_dist,attract_force)
			
			Case 19
				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-5),VertexY(surf,v-5),VertexZ(surf,v-5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-5,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-1),VertexY(surf,v-1),VertexZ(surf,v-1)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-1,separation_dist,attract_force)

					If Not lock_vertexs
					PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
					PositionEntity v_dumvecino,VertexX(surf,v+5),VertexY(surf,v+5),VertexZ(surf,v+5)
					SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+5,separation_dist,attract_force)
					EndIf

			Case 22
;				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
;				PositionEntity v_dumvecino,VertexX(surf,v-1),VertexY(surf,v-1),VertexZ(surf,v-1)
;				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-1,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-5),VertexY(surf,v-5),VertexZ(surf,v-5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-5,separation_dist,attract_force)

;				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
;				PositionEntity v_dumvecino,VertexX(surf,v+1),VertexY(surf,v+1),VertexZ(surf,v+1)
;				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+1,separation_dist,attract_force)

			Case 21
				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-5),VertexY(surf,v-5),VertexZ(surf,v-5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-5,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v+1),VertexY(surf,v+1),VertexZ(surf,v+1)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+1,separation_dist,attract_force)

			Case 23
				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-1),VertexY(surf,v-1),VertexZ(surf,v-1)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-1,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-5),VertexY(surf,v-5),VertexZ(surf,v-5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-5,separation_dist,attract_force)

			Case 6,7,8,11,12,13,16,17,18
				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-1),VertexY(surf,v-1),VertexZ(surf,v-1)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-1,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v-5),VertexY(surf,v-5),VertexZ(surf,v-5)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v-5,separation_dist,attract_force)

				PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
				PositionEntity v_dumvecino,VertexX(surf,v+1),VertexY(surf,v+1),VertexZ(surf,v+1)
				SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+1,separation_dist,attract_force)

				If v<>16 And v<>18
					PositionEntity v_dumele,VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
					PositionEntity v_dumvecino,VertexX(surf,v+5),VertexY(surf,v+5),VertexZ(surf,v+5)
					SET_VERTEX_VELOCITY(v_dumvecino,v_dumele,v+5,separation_dist,attract_force)
				EndIf

		End Select	
	Next
	
	For v=0 To CountVertices(surf)-1
		vertexes(v,0)=vertexes(v,0)+(-vertexes(v,0)/smooth)
		vertexes(v,1)=vertexes(v,1)+(-vertexes(v,1)/smooth)
		;Apply Gravity
		If lock_vertexs=True
			If v<>20 And v<>21 And v<>23 And v<>24
			vertexes(v,1)=vertexes(v,1)-gravity
			EndIf
		Else
		vertexes(v,1)=vertexes(v,1)-gravity
		EndIf		
		vertexes(v,2)=vertexes(v,2)+(-vertexes(v,2)/smooth)

		VertexCoords surf,v,VertexX(surf,v)+vertexes(v,0),VertexY(surf,v)+vertexes(v,1),VertexZ(surf,v)+vertexes(v,2)

;		If VertexX(surf,v)>-5 And VertexX(surf,v)<5
;			If VertexZ(surf,v)>-5 And VertexZ(surf,v)<5
				If VertexY(surf,v)<-9
				VertexCoords surf,v,VertexX(surf,v),-9,VertexZ(surf,v)
;				vertexes(v,0)=0
;				vertexes(v,1)=0
;				vertexes(v,2)=0
				EndIf
;			EndIf
;		EndIf
		
;		If CountCollisions(v_collis(v))>0
;		VertexCoords surf,v,EntityX(v_collis(v)),EntityY(v_collis(v)),EntityZ(v_collis(v))
;		Else
;		PositionEntity v_collis(v),VertexX(surf,v),VertexY(surf,v),VertexZ(surf,v)
;		EndIf
	Next

;	For v=0 To CountVertices(surf)-1
;		MoveEntity v_collis(v),(VertexX(surf,v)-EntityX(v_collis(v)))/20,(VertexY(surf,v)-EntityY(v_collis(v)))/20,(VertexZ(surf,v)-EntityZ(v_collis(v)))/20
;		If CountCollisions(v_collis(v)) End
;	Next
	
	UpdateWorld
	RenderWorld
	
;	Text 40,40,TrisRendered()
;	Text 40,60,vertexes(21,0)+" , "+vertexes(21,1)+" , "+vertexes(21,2)
	
	Text 20,40,"-Use Arrows to Move"	
	Text 20,60,"-Use A and S to MoveUP and MoveDOWN"	
	Text 20,80,"-Use SPACE to toggle gravity"	
	Text 20,100,"-Use ENTER to restore to initial position"
	Text 20,120,"-Use W to toggle Wireframe View"
	
	If KeyHit(17) wire=Not wire WireFrame wire
	Flip
Wend

Function SET_VERTEX_VELOCITY(vecino,ele,vertex,separation#,attract#=.2,newforceX#=0,newforceY#=0,newforceZ#=0)
	dist#=EntityDistance(vecino,ele)
	force#=interpolate(dist,0,separation,attract,-attract)
	
	vectorX#=EntityX(vecino)-EntityX(ele)
	vectorY#=EntityY(vecino)-EntityY(ele)
	vectorZ#=EntityZ(vecino)-EntityZ(ele)
	
	vectorX_U#=vectorX/dist
	vectorY_U#=vectorY/dist
	vectorZ_U#=vectorZ/dist
	
	newforceX=newforceX+(force*vectorX_U)
	newforceY=newforceY+(force*vectorY_U)
	newforceZ=newforceZ+(force*vectorZ_U)

	vertexes(vertex,0)=vertexes(vertex,0)+newforceX
	vertexes(vertex,1)=vertexes(vertex,1)+newforceY
	vertexes(vertex,2)=vertexes(vertex,2)+newforceZ
End Function

MoveMouse 400,300
End





Bot Builder(Posted 2004) [#2]
not bad. quite good actually.

I would recommend having diagonal "springs" to make the cloth resist folding up though.

Andreas_blixt wrote somthing similar - http://www.blitzcoder.com/cgi-bin/showcase/showcase_showentry.pl?id=andreas_blixt11272003032437&comments=no - Including some other verlet examples, but it appears to be down :/


Picklesworth(Posted 2004) [#3]
hm, quite a coincedence. I was just looking at that showcase entry an hour ago :D
Very nice cloth system Paolo. I think I'll use this as a guidline for the clothsim setup in my tokamak scene builder (which will have many special things).


Richard Betson(Posted 2004) [#4]
Very nice. I like ;)

L8r,


puki(Posted 2004) [#5]
I like it too "Paolo". Nice.


Paolo(Posted 2004) [#6]
thanks guys!

dillpickle,
it could be really great if you can implement this with tokamak :)


Also, have you try modifying where says this in the code
;--- change this parameters for testing ----

for example, put "separation_dist=20" and look what happend :)


RifRaf(Posted 2004) [#7]
wow too bad it cant be done effeciently on a large scale. (many many cloths) could be used in games on characters and such.