verlet constraints
Blitz3D Forums/Blitz3D Programming/verlet constraints
| ||
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? |
| ||
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> |
| ||
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. |
| ||
What is "c\e#"? |
| ||
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. |
| ||
The first equations are not working for me... What is restlength supposed to be... I think that is where I am going wrong. |
| ||
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. |