Verlet help

BlitzMax Forums/MiniB3D Module/Verlet help

SLotman(Posted 2011) [#1]
I need some help from you guys... I was trying to port some old blitz3D code to miniB3D, which was a small verlet engine.

After porting everything - I could notice some of the cubes are "twitching" while others seems to behave normally... I have no idea why - I suspect it's the AlignToVector function...

On Blitz3D, everything works normally.

Below the miniB3d code: (quite large!)



And below, the original code, on Blitz3D:


Can anyone help me out on this one??? I'm trying to find the problem the whole night... and it's morning already and I got no clue where it is =(


Yasha(Posted 2011) [#2]
Ha! That physics code looks familiar!

I wouldn't have said "twitching" so much as "rotating around the wrong axis". I would certainly suspect AlignToVector as well, especially given which cubes are affected (it seems to be most reproducible with cubes falling off the edge of the block; i.e. those that go through a 90 degree rotation, which I think the Euler-based miniB3D doesn't like).

Have you tried it with the mythical matrix-based miniB3D?

However, I'd also suggest either using a different VP lib as your base, if you haven't yet full internalised and understood it, or to make a few changes to this one. This particular implementation has all sorts of rubbish in it like constraints with variable lengths, which was intended to be the beginning of a "joint" system (and basically adds complexity for no great gain in anything) - there could be any number of errors in that (starting with the obvious error of trying to force the idea of "joints" into a VP system).

Last edited 2011


simonh(Posted 2011) [#3]
AlignToVector doesn't work 100% with standard minib3d I'm afraid.


AdamRedwoods(Posted 2011) [#4]
Works great! Wow!

I am using the minib3d 'small differences' version, which is nice and stable and uses Warner's internal matrix for TEntity. If you use this version, you may need to avoid the double TMatrix Type.

So I made the following changes and it is very nice:

Function AlignToVector2(ent:TEntity, vx:Float,vy:Float,vz:Float,axis%=1, rate#=1)
	If axis<1 Or axis>3 Then Return

	Local dd# = Magnitude(vx,vy,vz)
	If dd < 0.0001 Then Return
	
	vx = vx / dd
	vy = vy / dd
	vz = vz / dd	
	
	RotateEntity ent,0,0,0,1
			
	'get world axis	
	Local ax#, ay#, az#
	If (axis=1) Then ax=1; ay=0; az=0
	If (axis=2) Then ax=0; ay=1; az=0
	If (axis=3) Then ax=0; ay=0; az=1
	
 	'get transformation matrix from org. axis to new one
	Local m:TMatrix = New TMatrix	
	m = FromToRotation(ax,ay,az, vx,vy,vz)
	ent.mat.Multiply(m)

	
End Function


Basically it was that your result was going back through Euler transformations, where you could just apply the Rotation Matrix to the entity and get a better result.

I also didn't use the "axis" parameter to the AlignToVector2() function. Just left it to default=1 seemed to give smoother results.
AlignToVector2 body.mesh,(body.p[1].cx+body.p[3].cx)/Float(2.0)-mx, (body.p[1].cy+body.p[3].cy)/Float(2.0)-my, (body.p[1].cz+body.p[3].cz)/Float(2.0)-mz',2 ',1
AlignToVector2 body.mesh,(body.p[4].cx+body.p[5].cx)/Float(2.0)-mx, (body.p[4].cy+body.p[5].cy)/Float(2.0)-my, (body.p[4].cz+body.p[5].cz)/Float(2.0)-mz',3 ',1



Last edited 2011


AdamRedwoods(Posted 2011) [#5]
fun to pile them up in the loop:
PositionEntity dmesh, (Rnd()*20-10),15+30 + count*8, countZ + (Rnd()*20-10)


SLotman(Posted 2011) [#6]
Nope - that didn't work either.

Here the cubes from time to time just spin fast in the wrong direction, even with the "matrix" code, even ignoring the axis on the AlignToVector (which shouldn't be ignored btw)...

Edit: even trying the "smallfixes" version, the result is the same :(

Last edited 2011


AdamRedwoods(Posted 2011) [#7]
Ok, in my opinion, those cubes that spin to align to the world vector (1,0,0 axis=1) are doing what they're suppose to. I think the problem lies in the implementation, not euler rotations.

EDIT:
studying it more, it looks like the thought is to take the unit vector, by getting the point between the vertices of the cube, and aligning to that.

Last edited 2011


Yasha(Posted 2011) [#8]
it looks like the thought is to take the unit vector, by getting the point between the vertices of the cube, and aligning to that


That was the original idea, yes. Whether it was done correctly... I leave to you to tell me.

In hindsight that method is probably a really poor way to do things; I can't help but feel there must be some much more generic way to get the orientation of any arbitrary group of three points (thus not constraining it to cubes - this might also help a bit with jointed structures), as long as you know their starting position relative to each other.

Last edited 2011


SLotman(Posted 2011) [#9]
I gave up on that for now... I'm trying something with Newton, but without much success either :/

I've got collisions working, I can rotate and move stuff around using NewtonSetVelocity... but no matter how much I try, I can't get objects to fall :/


AdamRedwoods(Posted 2011) [#10]
Ok, I dove deeper.

All the equations look good. I simplified everything (code below) since we are getting an axis-angle rotation matrix, so we only need one "align to vector" routine, which gets our new "up" vector. No need for two that I can tell.

Here's my thought: we're also using miniB3D collisions, so I wonder if those collisions are causing problems to our rotations.

Is it possible to use verlet physics for everything or is the triangle-triangle intersection critical to the functionality? I'd have to investigate more.




Last edited 2011


Yasha(Posted 2011) [#11]
Is it possible to use verlet physics for everything or is the triangle-triangle intersection critical to the functionality?


...you just gave me a wonderful idea, thanks!


If you're unfamiliar with this method of simulating physics, a good read can be found here: http://www.gamasutra.com/resource_guide/20030121/jacobson_01.shtml

There are several points to consider about the system:

1) "Verlet integration" refers to the way the points' momentum is represented, in terms of its previous position and current position.

2) Combining a simplified Verlet integration with point-and-constraint meshes gives mass, collision response, rotation etc. more or less for free. A cleverly designed physics mesh theoretically wouldn't even need additional properties on the models. This particular implementation doesn't feature additional properties, which is good (for speed) and bad (for everything else). The need to faff about with AlignToVector is an unfortunate consequence of the fact that although the rotation is implicit, and thus "free", it's also only implicit and the points have no rotation of their own. A more sensible plan would, as you observed, use a rotation matrix instead which can be easily built around arbitrary pairs of points (even subsections of the complete mesh - much easier way to handle joints).

3) -
is the triangle-triangle intersection critical to the functionality?

The builtin collisions are only there to let it interact with non-physics scenery objects like the central block. Since the physics objects themselves only use sphere collisions between points (a cube is just eight largish spheres, which is why they'll never stack), they use a simple square root method between each other. If you wanted to use the system for anything practical though, you'd probably need some way to define collision polygons on the physics objects. At the time it was not clear how to do this.

4) In the presented implementation, each point loops over all other points to test for collisions. This is very bad! It pushes processing the scene into O(n^2) territory. Any usable physics system needs to use some kind of octree or hashspace instead to avoid this (otherwise, for anything more than a trivially small number of cubes, a "full" physics engine would give massively better performance - not much point in this "lightweight" method then).


...and now, back to coherence: