programming

rigidbody notes

these ones are really old. at least 2 years.

//vary up your timeStep to help things from vibrating. the idea is that things can sync to the frequency of the timeStep

//try slowing down the timeStep a ton and see if the vibrating magically goes away.

//you can only damp velocities just before you resolve collisions

//you want the farthest contact as far away from tolerance as possible

//idea, little axial ticks instead of raycasts

//remember that you have tween error accumulation

//maybe have the contacts record the velocities when they are created. once all contacts are created, zero of the velocity of the rigidibodies,
//the velocity will get reintroduced later, but in contact space

//randomize the order in which you check for collisions

//tweening zero and having shit still move is very bad

//remember that edConvexSolid vertices are not welded to the pool vertices

//maybe try rotating 100% first and then translating. i think this might let things move more.
//you could also try a couple of combinations of rotating and translating and choosing the one that gets you the farthest

//you could store the normal in local space, that way when you move the objects individually, future contacts will have a proper normal,
//this won't take much extra time because you could compute the normal for the all the objects before you resolve the collisions, remember that
//the object normal is based off of rbA

//build a prism from the triangle and raycast into that to generate the tolerance. the point of this is only so you can catch all collisions within
//the timestep. it may seem like just extruding out the front face is bullshit because why couldn't you just pretend the face is already extruded. it
//is not though because that extra space gives you slop for your math in the next time step. in fact, it might be better for the next timestep

//Basically, he cached collision points from last tick and if the same objects collided some of the points are re-used.
//Sounds like a nice way to stabilise the resting case.

//storing the contact position in world space is wrong too. crap. i really think you have to resolveCollisions before you move onto the next object.

//compute the maxTweenFractions for everything, but do not generate the contacts until all maxTweenFractions have been calculated. This will
//keep your contacts all in a single consistent space

//randomly increment the interval spacing

//it might be breaking between the triangle cracks?

//do edge-edge by finding the minimum distance for the start and end times. then take that ray and raycast into the normal geometry.

//you can probably do hierarchy dudes the same way as you do normal stuff. start at root, move the root how much it wants to go. then visit child, move
//it how much it wants, then keep going. to make other parts move when you kick a part, you add imaginary pin contacts anyway. this will propagate the
//impulses, but the joints can never move

//building a screwing cylinder for the entire object and then bound it with two planes so it is like an extruded pie. those 5 things (front,near,minangle,maxangle,radius)should cull a
//significant number of triangles from it very quickly. especially since the slice is typically going to be very small. you can do a similar thing for faces, but as a subset of
//the object pie. you can tighten the pie angle bounds and also the near and far bounds (near bounds can just be the start face plane). you can then add 2 (or more even) planes whose
//normal is perp to the screw direction

//try doing 2 or first contact times on the set of objects before you build the contact list
//--time=0
//--for multiple iterations
//----for each object A
//------for each object B that is not A
//--------find first contact
//--------if last generation then create a contact
//----time+=minTime
//--resolve collisions
//this should let things get out of the way so that you can eat more of the timestep, in theory you could keep going until there
//was no timestep left.

//scale impulses during the resolveCollisions and joint iterations

//try replacing all contacts with pins and see what happens. so basically get things stabilized, then later add in your impulses as forces

//try acceleration pins. you make virtual positions that represent the accelerations

//try only adding fudge during the first iteration, not every one. maybe do it a couple random times.

//try adding fudge to the pins

//swap gbContact rigidbodies. the normal should belong to B, not to A

//you could precompute tween matrices for 32 times or something, if you need more times than that, then compute it directly. how you index into it though?

//after you compute the maximumTween for everything, you can always back that time up. since you don't have 50 billion contacts you can keep backing that
//time up until all the contacts are at the half-way point in the tolerance. some contacts will probably disappear too.

//maybe it is just fine to do the vert-face tests with the plane extruded by tolerance. the edge-edge test is the trouble maker, so you could do that
//backing up thing with only that contact list. once the time is backed up from those, then go ahead and recompute the contacts with the new maximumTween

//just keep the contact positions in local space so you don't have to retransform them 500 times

//ramp up the fudge, or ramp it down to prevent extra vibrations

//try add the fudge in during the first iteration, but don't subtract it out until after the last iteration, maybe you should do a couple half of the
//iterations first before you do this

//contacts not getting created when they should is really bad. not for shit falling through each other either because that is not supposed to happen,
//no matter what, but for shit sticking, no contact equals no new motion

//gbRope as a single gbJoint that solves itself. not sure how you hook crap to it though.

//you could use verlet to help solve things. grab all the positions for the pin joints and move them where they want to go. run some verlet iterations
//on them. make the new velocity vectors for the pins the difference between the original position and the verlet position. you may want to run the whole
//process a bunch of times. this probably is a good way to get the rope to work with collisions.

//do a proper analysis of gbPin. after each iteration, the maximum error should get smaller

//the little random poppy crap when dorking with the ragdoll might cause collision trouble

//use the bounding box or sphere to compute the maximum velocity of an objects extents during a frame. if you are moving slow, subdividing down the
//timestep 50 billion times is a bad plan

//add tokamak style percentage time measurement

//some of the hitching may be caused by contacts not being created during the second backtracking

//break the entire intersect process in multiple iterations of smaller pieces of time. this makes it more likely for the entire set of objects to move

//try the classic timestepping stuff, but with the extra tolerance back out

//you could per vertice calculate how much time you need to back up by during the tolerance back out

//randomize the intersection order

//try messing with the intersection order, BA might be faster that AB. maybe even swap at runtime

//maybe remove contacts any time the number goes above say 3 per object, it won't intersect, but it will be cheaper

//put stuff to sleep in the resolve contacts section

//don't just subdivide time in half, use a table that can do crazy stuff like try the smallest time after trying the largest

//why do you check for intersections with the interval loop on the outside? try both and see which is fastest.

//in gbContact the error will always be the same during each iteration because it is based on position which won't change until
//the next timestep. maybe somehow adjust that error during each iteration.

//if you change the timestep and crazy shit is happening do a search for 85 because that is hardcoded in some places

//try sorting joints by mass, not sure which way. when i had the triWheeler really high mass compared to the tailgate, the tailgate when flying

//a pin only hierrarchy could be made by interpolating things seperate and then once the tween for that tree was done, move the pieces back in place, you
//stick keep a normal pin joint there, but the error would be zero

//make sure and apply the force from the shocks to the contact also

//the wierd popping of things could be caused by the quat singularity

//try messing with the E in pin. maybe make it negative to suck the pieces together

//keep a stuck count with each rigidBody. if you move 0 in time for N turns, then zero or limit velocity

//you could generate the contact list when you tween each object and then resolve it right then. after you have tweened all the
//objects you still generate a contact list for everyone. this might help get things unstuck a bit more

//scale the fudge based on object masses in a contact

//if your stickCount goes high enough that you need to reset the velocities, then set it to the velocity it had when it first got stuck

//if stuff gets stuck, you could add a spring or something to help it get unstuck or do extra collision resolves, maybe even have
//the iteration order for resolves and for tweening biased towards unsticking anybody that is stuck

//maybe it is a good idea to do your resolves as you are validating things?

//for resolveCollisions see what kind of answer relVelDot gets without fudge, then keep ramping up fudge util you get an answer that
//you like

//when you trying scaling values during resolve iterations remember that you can scale velocity and error independently

//the normalize call for relveldot maybe be dorking with things.

//maybe there is a way to convert pins to verlet. before you start iterating you build a previous position value based on the velocity. then for
//each iteration you extract out the velocities and send them on the way. after you are done, you convert it back to velocities. i am not sure if
//this is actually the same thing as it is now. it might not be, because you only end up converting the error over a single time.

//try using little springs instead of fudge

//you could make the tractor bucket work with a phantom object lifting stuff up a little

//it is important for wheels to make sure you always have a contact. having a tolerance twice as large for generating contacts
//would probably help. maybe even have contacts that only affects friction

//you can make up acceleration impulses by turning acceleration into velocity and doing impulse junk. you can only do it once resting contact has been
//reached. you might just have to init the normal velocities with -9.81

//you could put a sphere around the edges and do sphere-sphere and sphere-edge tests

//kill the spring near shock limits so it can't blow up

//try averaging velocities over the last few frames. if they are close to zero, zero them.

//throw the springs in with the joints and contacts, it might help the wheels from blowing up

//multiple blocks stacked don't jitter, but single blocks do. maybe simulate a fake block on top of things
//maybe apply gravity to all vertices as impulses during the contact calculation. kinda wierd, but
//maybe during the beginAdvance do it that way.

//try randomizing things more to improve the framerate

//if you sort your objects along axis's, then adjust your sort each time you tween an object, pair finding will be very fast

//after you iterate over the contacts, iterate over them again in a different way. if the blocks are all stacked nicely,
//then all the contacts should turn black

//try sorting contacts by height. first pass is top to bottom. second pass is bottom to top

//for pins don't fix the error every frame, that might help with shit breaking on the wheels because velocities are too large

//it looks like doom3 handles gravity seperate, kinda like. move everything horizontal first, then see how far you can move things down

//figure out what position and rotate for a tween of 1. now use that and the maximumTween ones to compute and error to add in
//during the contact junk. or, add it in after the frame.

//have long term deactivation stuff that acts over say 10 seconds. you can have short term acting over say 2 seconds. i guess you
//can implement this by keeping windowed averages around

//do the subtweens actually work correctly?

//if a tween of 1 fails, then try a small tween, if that fails, then bisect

//keep a maximum impulse applied for each contact iteration, if it goes below some threshold. you are done.

//apply contact rotational impulses delayed by a frame, this might help keep shit from vibrating

//don't always apply both translational and rotational impulses, just ignore one sometimes

//add fudge in as velocity only

//big tolerances are good for contacts, but bad for seperation. so have a big tolerance so you can catch so velocity changes
//but scale it based on the tolerance so it is weaker until you get to a certain min tolerance

//you could average last contact and current contact to get a average contact. use all 3, randomly choose 2, but always the og one

//choose the contact generation tolerance per object, if it is moving, up it

//return positive values from the relVelDot calc. then use this value to seed the fudge value

//have a lastRelVelDot stored with the contact and use that as the fudge value

//remove duplicate contacts, it actually happens pretty often. 2 blocks stacked can be 40

//try just choosing a single contact per pair

//only resolve the contacts with big tolerances once or twice

//try only generating contacts during the applyMaximumTween

//try actually resolving the contacts and joints during the applyMaximumTween while you are at it

//only do the last contacts once or twice

//sort by relVelDot

//try relaxation for resting contact

//your goal is to eat all of the velocities for the tick

//try eating energy

//put _separation in contacts and actually allow a negative value. scary. if it is negative fix it. the problem is
//knowing what the seperation actually is. the only time you know is the first time a vertex intersects.

//add an angularVelocity limit

//if you have some slow frames, maybe speed up the tick to play catch up

//model joint limits with a set of planes and a stopper point

//move stuff until it intersects. do tolerances just as before, but on opposite sides. don't give a crap about what intersected
//what. only if you don't generate any contacts do you have a problem?

//it would be really, really nice not to have to bisect, but try bisecting the intersection. the goal is penetrate, but not too much.

//maximum clamp the velocity to always be less than the tolerance

//bisect, but once you find an answer with contacts, keep letting it move forward until your contacts count drops

//fudging velA is different that fudging velB is different than fudging relVelDot

//try damping fudge based on velocity

//it might be better to use the individual triangle edges because then you can kick out earlier, it also makes the edge-edge contact problem easier

//you probably will need a mu for 2 directions so wheels work

//make it so you can add walls around the area and add a puck that you can smack stuff with, right now it works like crap

//check how fast things in a group are rotating, if they are rotating too fast, then increase the rate for that group

//during iterations, try not applying the impulse right away for small impulses, save them up until they get to a decent value, maybe even save them
//up across ticks

//friction could happen based on seperation

//make a conveyor belt example

http:www.telekinesys.com/demos/demo-properties2.html

//make 2 disks into a wheel and have keys to make it spin

//add in gravity velocities for last contact, resolve, subtract it out

//the energy coming in must be less than the energy going out

//moving everything at once may remove that obvious order popping when your raise a stack

//instead of putting something to sleep instantly, put it to sleep over several frames by damping it

//you could have a higher maxEnergy for sleeping if you let the count run longer. you could have a short term and long term sleep too

//you could do an energy diff from the prior frame if you include the height above the ground.

//maybe mass should not be a part of the sleep energy equation

//group together contacts that belong to the same object and share a plane. if the relVels are similar between them, build a
//convex hull around them and take the average of that. then apply only a single impulse at that position.

//visit each object and apply all of the impulses that would happen to that object, but do not propagate them. now there is an
//impulse that you can apply to the center of mass. now for each iteration, first apply impulses to the center of masses. when you
//do that, the other impulses will get subtracted out

//a variant of that might be to compute the COM impulse and subtract that out from all of the other impulses.

//give the contacts id. that way you could set an id for each wheel in a raycast car and use that info to simulate fake wheels

//you can do bounding box stuff with tolerances too, you just have increase the bounding box by the tolerance size

//try the getting rid of gravity, solving, and putting it back trick again (it might screw with friction so watch out)

//maybe always use the larger tolerance bounding box for intersections?

//maybe do damping like in springs for the pin contact

//try breaking up collisionResolve into 2 pieces one for collision and one to help it remove the errors. this might make collisions
//look better. it also might take less iterations to solve each piece.

//break up the pins also into two parts, impulse and error

//try only correcting the error during one iteration

//the only time it jitters is when there is a single box. if you stack a box on top of it, it works fine. maybe you can always
//stack a virtual box on things

//watch if you get a bisect during the next frame for a given touchingGroup, if so, you can try increasing the iterations

//look at the ragdoll, the top joints stretch more than the bottom ones, so you should be iterating those more. you could do
//choose the iteration number based upon error.

//try iterating joints and contacts seperate again

//base the number of iterations on joint error

//build a crank and piston

//break joints into 2 processes, fixing velocity and fixing error

//clamp errorMag because the velocities are not facing in the right direction. ie, you can have a larger error if your
//velocities are pointing in the right direction

//sort by height and then by velocities. probably highest velocities should move first

//dominos are a good test for subgroup sleeping, however you can still have the worst case of someone trying to pick up all the
//dominos for the end. still, that last domino really only effects a couple dominos down even though it technically is touching
//all of them. you might be able to do the first iteration as a complete iteration and see what things are affected. anything
//not effected by some tolerance is removed from the list. actually, this might work as a general way of doing things

//give each rigidbody a list of contacts, sort by rigidbody velocities. solve all the contacts for a rigidbody, then move onto the
//next rigidbody. this does end up solving contacts more than once in each pass, but hopefully it ends up being less passes to
//solve the problem. also, it should be more stable because you are solving it at once

//get rid of contacts that don't have velocities towards each other, sure they could interact after, but who cares, the next tick will get them

//have a keep you can push to put it in matrix style slow motion mode

//if intersection succeeds, but tolerance fails, things go bad quickly. that poofing thing happens.

//instead of fixing the separation distance at each contact, from all of those for a pair, fix it by applying an impulse
//between the center of masses of the pair

//generate the intersection/tolerance pairs from the gbBoxTree using raw triangles at the leaves. from that generate an optimized
//set of precomputed crap and see what the speed difference really would be if you had that info laying around. you could always
//compute both each tick and get a real estimate of its value (ignoring the precomp time)

//from gdalgorithms
//I wrote Tokamak. The collision detection module in Tokamak returns only one, deepest penetration point. I got around doing multiple-contact point CD routine by caching the last three collision results between the two bodies. I also check if the cached-contact points are still valid, before supplying them to the constrain solver.
//To test if the cached contact points are still valid, I stored the contact points in object's local space (one from each object), then compare their distance apart in world space with a theshold. If the distance apart is greater than the theshold then it indicates that the objects have moved too much since the time the cached contact point was record, and therefore the contact point is no longer valid, and it wont get pass to the constrain solver.

//not bisecting and only generating contacts at tolerance works at 100fps instead of 40fps when doing the intersect test, so if
//you can get away with doing only a single step, that is probably a good idea

//you can ignore bisecting between two objects if you know both objects are barely moving relative to each other. gravity might
//screw this up though

//what if you don't care about the contact normal? instead choose from a set of them. the one you want is the one that makes the
//objects fly apart the best, you could choose the cardinal directions and the diagnols in each local coordinate system and try
//them all.

lots of cool demos to build here: http:www.maxon.net/pages/products/c4d/modules/dynamics/hl_dynamics_01_e.html

//when you move the block on the bottom of a stack up, the movement can not take place until after the objects above it get out of the way, the
//objects can't get out of the way until the timestep after the movement occurs so there will always will be a hitch. you could keep the contacts around
//from the last frame, apply all the onceVelocities (and damping?), then resolve the contacts again

//the contacts from the previous frame hint at minimum distance for the next frame. not sure how useful they will be since they are really close. you
//could increase the bounding box, but with a boxTree that might be expensive

/*
* Split any correction required to fulfil a constraint evenly across
as many of the participating elements of that constraint as possible.

* It seems that the majority rules an iteratively-solved constraint
system -- if there are very many constraints fighting a very few,
the few will tend to really suffer while the majority get good
solutions even when there exist some 'perfect' solutions that
could please all. I'm sure that there are many tricks that
can be borrowed from N-dimensional hill-climbing (which I
think that iterative constraint solving strongly resembles) to
improve the chances of finding global maxima though.
*/

//You could iterate through the joints in the opposite order every other iteration.

//linear tweens are good because it is easy to bound them over time. though doing it the normal way may not be so hard

//bisect to find intersections. take the hit position and find the tolerance to its edges, if it within tolerance, mix in the
//edge normal

//same as above, but push the triangle the negative normal direction a little and do a real point to triangle min tolarance

//within a 1/50 second step, keep a list of distances for all pairs. any pair that is too far to interact in a 1/50 second is
//not added. you can then move the pairs and recalc just the distances sort by distance and you will know when you need to stop

//the buggy demo on the ode community page is very good

//sparta style cdlines, but automatically built by random sampling and raycasting. optimized, then put into a spatial
//structure. the world does not need them, only things that move do?

//After you have a single contact with your method, and the boxes are just
//touching but not intersecting, you can limit the further search of contacts
//to the separating plane formed by the contact point and normal.

//don't do vertex-face, just do edge-face and choose the point on that edge certain distance from the face

//safe boxes. when an object is moving against a big static mesh, you can build box that is larger than the object
//and gather all the triangles from the big static mesh. often, if the mesh is not touching the ground, zero triangles
//will be in the box. the question is, would this be faster than traversing the big tree everytime. another option
//might be to build a mini-tree just for the box.