View Full Version : Newton again...

21-07-2007, 01:47 PM

I'm having some more trouble with newton,

I'm trying to get collision detection with particles, at the moment i want the particle to "die" when it collides with something other than another particle.

In my test app, i have a face along the XZ plane with the particle system above it, dropping like rain (see screenshot).
I have a newton debug rendering (the white boxes in the particles and on the face).

When the app is created, i create the scene (in which creates an empty newton world object) and a material object, i then create the face using NewtonCreateTreeCollision and set the world size around the face with a height of -200 - 200, i apply the scene's material id to the object.

When i create the particle, i use the newton box, and create a new material that is used on all the particles with in the particle group. I am not using any newton physics with the particles, instead i update the particles matrix and send it to newton.

I have collision callbacks set to the materials, however none of them are called when a particle collides with the face.

Initialize newton for the face:

nColl: PNewtonCollision;
i: Integer;
v: Array [0..3] Of TVector3f;
tmpM: Geometry.TMatrix4f;
Min,Max: TVector3f;
nColl := NewtonCreateTreeCollision(_XScene.World, Nil);
v[0] := Vertices[3].Point;
v[1] := Vertices[2].Point;
v[2] := Vertices[1].Point;
v[3] := Vertices[0].Point;
NewtonTreeCollisionAddFace(nColl, 4, @v[0], SizeOf(TVector3f), 1);
NewtonTreeCollisionEndBuild(nColl, 0);

If nColl = Nil Then Exit;
_Body := NewtonCreateBody(_XScene.World, nColl);

tmpM := MatrixTransform(Position, Rotation, Vector3fMake(1, 1, 1));
NewtonBodySetMatrix(_Body, @tmpM[0, 0]);
NewtonBodySetMaterialGroupID(_Body, _XScene.MaterialID);
NewtonBodySetUserData(_Body, Self);

NewtonCollisionCalculateAABB(nColl, @tmpM[0, 0], @Min[0], @Max[0]);

If Min[0] > _XScene.WorldSize[0][0] Then _XScene.WorldSize[0][0] := Min[0];
If Min[1] > _XScene.WorldSize[0][1] Then _XScene.WorldSize[0][1] := Min[1];
If Min[2] > _XScene.WorldSize[0][2] Then _XScene.WorldSize[0][2] := Min[2];
If Max[0] > _XScene.WorldSize[1][0] Then _XScene.WorldSize[1][0] := Max[0];
If Max[0] > _XScene.WorldSize[1][1] Then _XScene.WorldSize[1][1] := Max[1];
If Max[0] > _XScene.WorldSize[1][2] Then _XScene.WorldSize[1][2] := Max[2];

NewtonReleaseCollision(_XScene.World, nColl);

Scene newton:

fWorld := NewtonCreate(Nil, Nil);
// other code..
DefaultID := NewtonMaterialGetDefaultGroupID(fWorld);
fMaterialID := NewtonMaterialCreateGroupID(fWorld);
NewtonMaterialSetDefaultFriction(fWorld, DefaultID, fMaterialID, 0.01, 0.01);
NewtonMaterialSetDefaultElasticity(fWorld, DefaultID, fMaterialID, 0.01);

Particle Group:

fMaterialID := NewtonMaterialCreateGroupID(_XScene.World);
NewtonMaterialSetCollisionCallback(_XScene.World, _XScene.MaterialID, fMaterialID, @_XScene.MaterialID, @CollisionBegin, @CollisionWorld, Nil);
NewtonMaterialSetCollisionCallback(_XScene.World, fMaterialID, fMaterialID, @fMaterialID, @CollisionBegin, @CollisionParticle, Nil);

On particle move:

If (fParticles[Value].Body = Nil) And (fCollision) Then fParticles[Value].initNewton;
If fParticles&#91;Value&#93;.Body <> Nil Then
tmpM &#58;= MatrixTransform&#40;fParticlePosition, Vector3fMake&#40;0, 0, 0&#41;, Vector3fMake&#40;1, 1, 1&#41;&#41;;
NewtonBodySetMatrix&#40;fParticles&#91;Value&#93;.Body, @tmpM&#91;0, 0&#93;&#41;;

Particle initialize newton:

nColl&#58; PNewtonCollision;
Position&#58; TVector3f;
maxSize&#58; Single;
tmpM&#58; TMatrix4f;
If fBody <Nil> maxSize Then maxSize &#58;= TXParticleGroup&#40;fOwner&#41;.EndSize;

Position &#58;= Vector3fMake&#40;TXParticleGroup&#40;fOwner&#41;.X, TXParticleGroup&#40;fOwner&#41;.Y, TXParticleGroup&#40;fOwner&#41;.Z&#41;;

nColl &#58;= NewtonCreateBox&#40;_XScene.World, maxSize, maxSize, maxSize, Nil&#41;;
fBody &#58;= NewtonCreateBody&#40;_XScene.World, nColl&#41;;
NewtonReleaseCollision&#40;_XScene.World, nColl&#41;;

tmpM &#58;= MatrixTransform&#40;Position, Vector3fMake&#40;0, 0, 0&#41;, Vector3fMake&#40;1, 1, 1&#41;&#41;;
NewtonBodySetMatrix&#40;fBody, @tmpM&#91;0, 0&#93;&#41;;

NewtonBodySetMaterialGroupID&#40;fBody, TXParticleGroup&#40;fOwner&#41;.MaterialID&#41;;
NewtonBodySetUserData&#40;fBody, Self&#41;;

Im uterly stuck on this, and from all the examples i have looked at i can't see anything wrong..

Many thanks

21-07-2007, 02:42 PM
what exactly is the problem?

21-07-2007, 04:03 PM
The problem is that there is no collision detection, either that or my callbacks are not called when there is a collision between the particles and the face or something is wrong with the code somewhere.

21-07-2007, 04:46 PM
Ofcourse they don't collide.. you manually move them..

NewtonBodySetMatrix(fParticles[Value].Body, @tmpM[0, 0]);

In newton, you create objects and move them by applying forces in forcetorque callback..

Aniway, if you are trying to create a particle system in newton, use raycasting... it works pretty well... usually..

21-07-2007, 05:00 PM
Ah thanks, i kinda had a feeling that it was that... was hoping that i could do it that way... nevermind.

Thanks :)

In your opinon what would be best, raycasting or using the newtons forces?

21-07-2007, 06:05 PM
Ah thanks, i kinda had a feeling that it was that... was hoping that i could do it that way... nevermind.

Thanks :)

In your opinon what would be best, raycasting or using the newtons forces?

raycasting works well for fast gun particles, but not for anything, for example things that have low velocity, low velocity raycast-powered particles have tendency to fall thru things.

22-07-2007, 07:28 PM
Great many thanks

I have managed to implement raycasting, it seems to work (although a little buggy), i also attempted to add a newton version (with all the physics done via newton) for another particle system, however it seemed to crash if i had more than 40 particles :(