basically this is self referencial, so , i guess should be more easy to add. (respect than the rigid body that need of a ton of obj)
the setup is basically self - made.
but you can shoose :
“elast” -> (elasticity …how many spring must have)
“inertia” -> (is the inverse of the friction, for many time the bone tent to bounce)
the setup current is to simulate the hair.
the only dependences that have is have to be another bone as parent.(really is not necessary but cut a lot of calculations)
the mechanism is very easy .
all is based in a vector global (dinWP) (we say that simulate a dynamic obj) that have also the velocity.
it limit indirectly also the rotation of bone .
since the vector cannot go over a range (maxDist) that is the half of the lengt of the bone.
and at the end , the bone , just align itself keep fix also the rotation one the Y axis since is used to_track_quat()
it should be pretty fast.
in a GUI , it can be a new constraints where you have to set only
elast and inertia (so , very easy)
what you think ?
it seem useful having a new constraints for bone as this ,or you thionk there already all necessary?
this is the code (must run from the armature)
[note that if you make a chain long not work too well, better 2 bone max ]
import bge from mathutils import Matrix,Vector def m(cont): own = cont.owner arm = own WT = arm.worldTransform if not "init" in arm: arm["init"] = 1 arm["bones"] =  for i in [ "Bone.001", "Bone.002", ] : b2 = arm.channels[i] b1 = arm.channels[str(b2.bone.parent)] fix = b1.pose_matrix.inverted() * b2.pose_tail dinWP = (WT * b2.pose_tail) vel = Vector() m4Loc = b1.pose_matrix.inverted() * b2.pose_matrix elast = 0.001 inertia = 0.99 maxDist = b2.bone.length/2 grav = Vector((0,0,-0.0027)) const = [b1,b2,fix,m4Loc,elast,inertia,grav,maxDist] vars = [dinWP,vel] arm["bones"].append([const, vars]) armWT = arm.worldTransform #armWT = arm.worldTransform for i in arm["bones"]: b1,b2,fix,m4Loc,elast,inertia,grav,maxDist = i dinWP,vel = i parMat = b1.pose_matrix fixAP = parMat * fix fixWP = armWT * fixAP vec = fixWP - dinWP if vec.magnitude > maxDist: dinWP += vec.normalized() * (vec.magnitude - maxDist) vec = fixWP - dinWP vel = (vel + (vec + grav)*elast)*inertia dinWP += vel dinAP = armWT.inverted() * dinWP dinBP = (parMat * m4Loc).inverted() * dinAP b2.rotation_quaternion = dinBP.to_track_quat("Y","Z") i = [dinWP,vel]
this the blend
armN3.blend (82.7 KB)