A place to discuss everything related to Newton Dynamics.
Moderators: Sascha Willems, walaber
by pHySiQuE » Mon Oct 24, 2011 1:18 am
NewtonCollisionCollideContinue seems to miss collisions between a sphere and the edge of a treecollision. It only works when the sphere collides with a face of the treecollision.

- yesno.jpg (17.57 KiB) Viewed 4919 times
-
pHySiQuE
-
- Posts: 608
- Joined: Fri Sep 02, 2011 9:54 pm
by Julio Jerez » Mon Oct 24, 2011 5:35 am
do you have a test to reproduce it?
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by pHySiQuE » Mon Oct 24, 2011 4:07 pm
Click the left mouse button to cast a sphere at the scene. If you hit anything, the upper-left corner will print "Hit", otherwise it will print "Miss". Any time you hit something, a sphere will be moved to the contact position.

- Image4.jpg (41.93 KiB) Viewed 4895 times

- Image6.jpg (45.94 KiB) Viewed 4895 times
Here is the code I use:
- Code: Select all
NewtonCollision* sphere = _raycastSphere[radius];
if (!sphere)
{
sphere = NewtonCreateSphere(_collisionWorld,radius,radius,radius,0,NULL);
_raycastSphere[radius] = sphere;
}
const int maxSize = 256;
float mat0[16];
mat0[0]=1; mat0[1]=0; mat0[2]=0; mat0[3]=0;
mat0[4]=0; mat0[5]=1; mat0[6]=0; mat0[7]=0;
mat0[8]=0; mat0[9]=0; mat0[10]=1; mat0[11]=0;
mat0[12]=p0.x; mat0[13]=p0.y; mat0[14]=p0.z; mat0[15]=1;
float mat1[16];
float velocity0[3] = {p1.x-p0.x,p1.y-p0.y,p1.z-p0.z};
float velocity1[3] = {0,0,0};
float omega0[3] = {0,0,0};
float omega1[3] = {0,0,0};
mat1[0]=1; mat1[1]=0; mat1[2]=0; mat1[3]=0;
mat1[4]=0; mat1[5]=1; mat1[6]=0; mat1[7]=0;
mat1[8]=0; mat1[9]=0; mat1[10]=1; mat1[11]=0;
mat1[12]=0; mat1[13]=0; mat1[14]=0; mat1[15]=1;
float contacts[maxSize*3];
float timeOfImpact[maxSize];
float normals[maxSize*3];
float penetration[maxSize];
int count = NewtonCollisionCollideContinue(_collisionWorld,maxSize,1.0,sphere,mat0,velocity0,omega0,collision,mat1,velocity1,omega1,timeOfImpact,contacts,normals,penetration,0);
if (count>0)
{
Print(count);
if (closest)
{
for (i=0; i<count; i++)
{
mat.MakeDir(Vec3(velocity0[0],velocity0[1],velocity0[2]).Normalize(),AXIS_Z);
if (i==0)
{
d = timeOfImpact[i];
p.x = p0.x*(1.0-d) + p1.x*d; p.y = p0.y*(1.0-d) + p1.y*d; p.z = p0.z*(1.0-d) + p1.z*d;
p.x = p.x + normal[i*3+0]*penetration[i]; p.y = p.y + normal[i*3+1]*penetration[i]; p.z = p.z + normal[i*3+2]*penetration[i];
p = TFormPoint(p,identity,mat);
min = p.z;
pick.position.x = p0.x*(1.0-d) + p1.x*d + normal[i*3+0]*penetration[i];
pick.position.y = p0.y*(1.0-d) + p1.y*d + normal[i*3+1]*penetration[i];
pick.position.z = p0.z*(1.0-d) + p1.z*d + normal[i*3+2]*penetration[i];
return true;
}
else
{
d = timeOfImpact[i];
p.x = p0.x*(1.0-d) + p1.x*d; p.y = p0.y*(1.0-d) + p1.y*d; p.z = p0.z*(1.0-d) + p1.z*d;
p.x = p.x + normal[i*3+0]*penetration[i]; p.y = p.y + normal[i*3+1]*penetration[i]; p.z = p.z + normal[i*3+2]*penetration[i];
p = TFormPoint(p,identity,mat);
if (p.z<min)
{
min = p.z;
pick.normal.x = normals[i*3+0]; pick.normal.y = normals[i*3+1]; pick.normal.z = normals[i*3+2];
pick.position.x = p0.x*(1.0-d) + p1.x*d + normal[i*3+0]*penetration[i];
pick.position.y = p0.y*(1.0-d) + p1.y*d + normal[i*3+1]*penetration[i];
pick.position.z = p0.z*(1.0-d) + p1.z*d + normal[i*3+2]*penetration[i];
}
}
}
}
return true;
}
Last edited by
pHySiQuE on Mon Dec 05, 2011 4:55 am, edited 1 time in total.
-
pHySiQuE
-
- Posts: 608
- Joined: Fri Sep 02, 2011 9:54 pm
by Julio Jerez » Tue Oct 25, 2011 7:46 pm
Ha but I can not debug a exe, you have to make either usin teh newton.dll or send the source of teh demo.
I see that miss when I click near the corner bur how do you know this is related to continue collision? for what I can see this is a ray miss or something like that.
also are those boxed collision tree or a tree collision? I know for a fact that continue collision works well on both but I can not say from an EXE.
O I see, you are using convex cast to find the hit point, is that what you are doing?
can you post the source so that I can check it out?
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by pHySiQuE » Tue Oct 25, 2011 8:38 pm
Our game's source code is really big and I can't post it.
The scene model is a collision tree.
I am using continuous collision with a sphere to make a ray cast with a radius.
The part of the code that handles this is posted above.
If you cannot figure out the problem from this information, I can probably try to make a simpler demo, but it will take a while to do...
-
pHySiQuE
-
- Posts: 608
- Joined: Fri Sep 02, 2011 9:54 pm
by Julio Jerez » Wed Oct 26, 2011 12:01 am
Yes I see the function but that is not enough because it forces me to write lot of code to reproduce a simple framewok to do the same that the demo is doing.
can you make a simply test using the same mesh and the piece of code you are using to can the shape.
or maybe even better you can simply link to the Newton.DLL rather than link to a static newton.lib library.
I can always debug the DLL from visual studio, not need for the source.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by pHySiQuE » Fri Oct 28, 2011 6:50 pm
Here is a project that demonstrates the problem. It creates a treecollision consisting of two quad faces in an "L" shape.
Use one of the following macros to test behavior:
#define TEST_HORIZONTAL (right to left)
#define TEST_VERTICAL (up to down)
#define TEST_CORNER (both)
Vertical and horizontal both incur one collision. The corner test does not hit anything at all.
You must have the Newton SDK from Google code in a folder called "newton-dynamics" for this to compile.
- Attachments
-
newtontest.rar
- (3.93 KiB) Downloaded 190 times
-
pHySiQuE
-
- Posts: 608
- Joined: Fri Sep 02, 2011 9:54 pm
by Julio Jerez » Sat Oct 29, 2011 9:40 am
Ok I have linked to ithe SDK that I currently have, (thsi is teh one in SVN whick I beleiev is very close to what is in Goggle version 33)
I added the last line to destroy the world and release collision,
yes I see I see that TEST_HORIZONTAL and TEST_VERTICAL print a hit
but TEST_CORNER fail.
I will debug it,
very clear test demo, thank you.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by Julio Jerez » Sat Oct 29, 2011 1:02 pm
you are right i looks like there is a bug in function
MovingPointToPolygonContact (const dgVector& p, const dgVector& veloc, dgFloat32 radius, dgContactPoint& contact)
this is a special case of extruded collision.
Is is based on the fact that a extruded sphere, is an aligned capsule, so CC collision for a Sphere can the especial case of discrete capsules which axis is aligned to the velocity vector.
which this i means is that a discrete capsule hitting on the same circumstance will also fail. but the bug does not extend to other shapes since they all use the general minkossky rutine, so that is good.
I am fixing it now, stand by.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by pHySiQuE » Sat Oct 29, 2011 2:36 pm
Thanks.
-
pHySiQuE
-
- Posts: 608
- Joined: Fri Sep 02, 2011 9:54 pm
by Julio Jerez » Sat Oct 29, 2011 3:38 pm
Ok I fix it, it was a silly bug, after I calculated the intersection point, the contact point can have tow solutions, because a sphere is a quadratic surface.
so it basically comes to calculate the intersection points between a line origination at the center of a sphere and the surface of the sphere, for those tow equations we can get the contact point as follow
equation of the line is
p = C - Vel * t
C on the sphere center
and the equation of the sphere is
dot (p - C) = r * r
in the substitution I made this mistake
dot ((C - Vel * t), (C - Vel * t)) = r * r
instead of
dot ((C - Vel * t - C) , (C - Vel * t - C) ) = r * r
the first equation may leads incorrect roots, and in this case it generated two negative roots which means there is not intersection, and this is normal because teh equation is simple wrong and C is very big compare to Vel
the second substitution is the correct one is correct and produces to root with symmetry
t = r / sqrt ( dot (vel, vel)
doing that fixed the problem.
The normal is (0.07, 0.07, 0) but you will only get that normal if you optimize the collision shape by calling: NewtonTreeCollisionEndBuild(collision,1);
if you do not do that then the collision shape does not have the edge connectivity information and it can not determine that the two Faces share an edge that makes a convex vonoroi region.
the resulting edge normal is the weighted average of the two faces sharing the edge.
This is a unique feature of the Newton engine that makes collision trees act as if they were convex shapes producing perfect smooth contacts on convex edges of collision trees.
but it can only do that for collision trees with connectivity edge information, which can only happen for optimized collision shapes.
when the collision tree is not optimized, then the engine reports the normal with the largest projection to the edge normal as the edge normal.
in this case (0, 1, 0) or (1, 0, 0)
try with optimization and without so that you can see the difference.
you can sync to SVN to get the fix.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by pHySiQuE » Sat Oct 29, 2011 5:58 pm
The results of the function now seem to be completely random...not sure what is happening, I will have to test some more...
-
pHySiQuE
-
- Posts: 608
- Joined: Fri Sep 02, 2011 9:54 pm
by Julio Jerez » Sat Oct 29, 2011 6:10 pm
what do you mean random? what values are you getting?
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
by pHySiQuE » Sat Oct 29, 2011 6:46 pm
The returned collision count seems wrong, and when a collision does occur, the time of impact is a very small number, like 0.00101. Sometimes collisions occur when I am not even looking at the mesh, and sometimes they totally miss.
The example project I posted works correctly, but my real application does not. When I switch back to the older Newton code, it works as it was before, so I am pretty sure I'm not doing anything wrong.
-
pHySiQuE
-
- Posts: 608
- Joined: Fri Sep 02, 2011 9:54 pm
by Julio Jerez » Sat Oct 29, 2011 6:58 pm
are you using the optimiza collision tree?
if so, tunr optimization of and see if it is correect.
That will separate the part that determine an edge normal is inside a convex voroni region.
edit:
I am sorry, I mislead you. I was wrong the edge information does no depend on the optimization it is alway present.
Let use do this, in file c:\\newton-dynamics-200\coreLibrary_200\source\physics\dgCollisionMesh.cpp
find this function
- Code: Select all
dgInt32 dgCollisionMesh::dgCollisionConvexPolygon::ClipContacts (dgInt32 count, dgContactPoint* const contactOut, const dgMatrix& globalMatrix) const
{
dgVector normal (globalMatrix.RotateVector(m_normal));
if (m_normalIndex) {
add thsi hack
- Code: Select all
dgInt32 dgCollisionMesh::dgCollisionConvexPolygon::ClipContacts (dgInt32 count, dgContactPoint* const contactOut, const dgMatrix& globalMatrix) const
{
dgVector normal (globalMatrix.RotateVector(m_normal));
if (0) {
the will prenvent the test to see if an edge normal in within a voronoi conve edge. I suspect the bug is there.
-
Julio Jerez
- Moderator

-
- Posts: 12426
- Joined: Sun Sep 14, 2003 2:18 pm
- Location: Los Angeles
-
Return to General Discussion
Who is online
Users browsing this forum: No registered users and 2 guests