verlet constraints

Blitz3D Forums/Blitz3D Programming/verlet constraints

RexRhino(Posted 2003) [#1]
OK, so since everyone else is working on ragdoll physics, rigid body, etc., I thought I would work on my own version in order to learn all about it.

I got most everything working, except for constraining distances. Here is my function:

Function verlet_close_distance(entity_1)
	Stop
	verlet_data.verlet = First verlet
	While verlet_data\entity <> entity_1
		verlet_data = After verlet_data
	Wend
	For x = 1 To verlet_max_connections
		If verlet_data\links[x] > 0
			link = verlet_data\links[x]
			distance# = EntityDistance#(entity_1,link)
			If distance# > verlet_data\distance#[x]
				yaw# = EntityYaw#(link)
				pitch# = EntityPitch#(link)
				roll# = EntityRoll#(link)
				range# = distance# - verlet_data\distance#[x]
				PointEntity link, entity_1,True
				MoveEntity link, range#, 0, 0
				RotateEntity link, pitch#, yaw#, roll#, True
			EndIf
		EndIf
	Next
End Function


Yes, yes, I know that the loop at the begining is inefficent, but this is just a test function which I will optimize later.

For some reason, objects aren't constrained. Instead, they just kind of orbit around each other in an irratic pattern. Since so many people have been writing this stuff lately, I am sure someone has encoutered this?


RexRhino(Posted 2003) [#2]
Ooops... never mind... I put the range# in the x axis instead of the z axis. It always seems to be the most simple mistakes that are the most hard to find. <sigh>


Bot Builder(Posted 2003) [#3]
why oh why is everyone using blitz movement and pointing commands to do constraints???? Halos' is so slow due to this. Agood way to do it is mathamatical , but it isn't hard at all.

First of all, you need the positional diffrence between the two verlets. call it the delta. Find the length of the delta ( sqr(dx^2+dy^2+dz^2) ), and call it deltalength. Another variable, difference, is the deltalength subtracted by the restlength, divided by the delta length. Finally, the delta's are multiplied by the various diffs, which results in the amount of movement required to put the constraint in restlength. Since you want to move each particle equally, this is halved, and now you have the amount that each particle should move. The direction of the first particle then needs to be reversed in order to move the particles towards each other(or away in the case that the constraint is compressed).

I'm sure a written discription sounds very complicated indeed, and I'm not very good at explaining. here's the psuedo code I based my discrtiption off of:

delta = x2-x1
deltalength = sqrt(delta*delta)
diff = (deltalength-restlength)/deltalength
x1=x1-delta*0.5*diff
x2=x2-delta*0.5*diff

Note that this is not blitz code. delta,x1,and x2 are vectors.

Here's my blitz interpretation:

dx#=EntityX#(c\Cp1\pivot)-EntityX#(c\Cp2\pivot)
dy#=EntityY#(c\Cp1\pivot)-EntityY#(c\Cp2\pivot)
dz#=EntityZ#(c\cp1\pivot)-EntityZ#(c\cp2\pivot)
cd#=Sqr(dx#*dx#+dy#*dy#+dz#*dz#)
diff#=(cd#-c\td#)/cd#
PositionEntity c\Cp1\pivot,EntityX#(c\Cp1\pivot)-(dx#*diff#*c\e#*.5),EntityY#(c\Cp1\pivot)-(dy#*diff#*c\e#*.5),EntityZ#(c\cp1\pivot)-(dz#*diff#*c\e#*.5)
PositionEntity c\Cp2\pivot,EntityX#(c\Cp2\pivot)+(dx#*diff#*c\e#*.5),EntityY#(c\Cp2\pivot)+(dy#*diff#*c\e#*.5),EntityZ#(c\cp2\pivot)+(dz#*diff#*c\e#*.5)


This could be optimised by first recording entityx/y/z in variables and calling them, but I was lazy, and this is from my first verlet engine.


RexRhino(Posted 2003) [#4]
What is "c\e#"?


Bot Builder(Posted 2003) [#5]
oops. sorry. c\e# is the "springiness" from 0-1. at 1 it is infinitly strong, and at 0 it is nothing. One thing that is advisable, and doesn't add to much speed lag is to include masses in your verlets. It's rather simple. Add together the masses of the two verlets effected by the constraint, and when calculating verlet #1's movement, replace the .5 with #2's mass/ total mass. Do the same for #2's movement. Replace the .5 with #1's mass/ total mass. If the two masses are equal, then this will be .5, the original value.

here's the code now.

dx#=EntityX#(c\Cp1\pivot)-EntityX#(c\Cp2\pivot)
dy#=EntityY#(c\Cp1\pivot)-EntityY#(c\Cp2\pivot)
dz#=EntityZ#(c\cp1\pivot)-EntityZ#(c\cp2\pivot)
cd#=Sqr(dx#*dx#+dy#*dy#+dz#*dz#)
diff#=(cd#-c\td#)/cd#
tmass#=c\Cp1\mass#+c\Cp2\mass#
tmp#=C\Cp2\mass#/tmass#
PositionEntity c\Cp1\pivot,EntityX#(c\Cp1\pivot)-(dx#*diff#*c\e#*tmp#),EntityY#(c\Cp1\pivot)-(dy#*diff#*c\e#*tmp#),EntityZ#(c\cp1\pivot)-(dz#*diff#*tmp#*.5)
tmp#=C\Cp1\mass#/tmass#
PositionEntity c\Cp2\pivot,EntityX#(c\Cp2\pivot)+(dx#*diff#*c\e#*tmp#),EntityY#(c\Cp2\pivot)+(dy#*diff#*c\e#*tmp#),EntityZ#(c\cp2\pivot)+(dz#*diff#*tmp#*.5)


Note that I haven't tested this one, but you should be able to get the jist of it.


RexRhino(Posted 2003) [#6]
The first equations are not working for me... What is restlength supposed to be... I think that is where I am going wrong.


Bot Builder(Posted 2003) [#7]
Restlength is the length at which the constraint is satisfied. ie, for a rigid body, the restlength is the length you want the constraint to keep two particles apart.