I have not going in depth yet, but it seem that is generation the contact correctly.
is hard to see because the console shape as complex,
can you do this,
replace the console with a simple box of dimensions 1 x 1 x 1 or something like that. then make that box a compound.
if you can no make a compound of a single shape, you can add another small one an place inside that large box. then test it to see if the bug happens.
This will allow me to make prediction of what should happens, and compare with what is actually happening, at the moment I see that the collision report 4 contacts, but I can't see if they are correct.
when I do that test this is a list of the contact as the object move around
frame: 2027, param: 0.335125, posit(7.155564 1.000977 3.544889)
frame: 2027, param: 0.335125, posit(7.335565 1.000977 3.856658)
frame: 2028, param: 0.338395, posit(6.615564 1.000977 3.856524)
frame: 2028, param: 0.338395, posit(6.795565 1.000977 4.168294)
...
frame: 2029, param: 0.338395, posit(7.335565 1.000977 3.856524)
frame: 2030, param: 0.374099, posit(6.974139 2.719478 4.417943)
frame: 2031, param: 0.362724, posit(6.974062 2.706977 4.441322)
frame: 2032, param: 0.346654, posit(6.967108 2.687375 4.464640)
frame: 2041, param: 0.970195, posit(6.973717 3.656548 4.602761)
frame: 2048, param: 0.827301, posit(7.048620 3.971725 4.820000)
frame: 2057, param: 0.999487, posit(6.612765 4.231726 4.820000)
frame: 2057, param: 0.999487, posit(6.785585 4.231726 5.120000)
frame: 2057, param: 0.999487, posit(7.159560 4.231726 5.120000)
frame: 2057, param: 0.999487, posit(7.332572 4.231726 4.820333)
frame: 2070, param: 0.978508, posit(6.612091 4.200046 5.072135)
frame: 2070, param: 0.978508, posit(6.639726 4.200046 5.120000)
frame: 2070, param: 0.978508, posit(6.757661 4.200046 4.820000)
frame: 2070, param: 0.978508, posit(7.186521 4.200046 4.820000)
you can see that when the player is at the floor, is reports contact of elevation 1.0
the as I jump it hit the lower part at 2.71, the another path that has a slanted face at 3.xx
and finally it rest of the back pane; which has a elevation of 4.168
This values seems right to me, by I do not know what to compared them too,
you can actually do that test by hacking the newton DLL and print those values and see why that weird behavior that happens after that, My guess that is has to do with the param hit point whi is 0.9 when it hit.
The function that you can edit to print this values is this.
- Code: Select all
dgInt32 dgBroadPhase::ConvexCast(const dgBroadPhaseNode** stackPool, dgFloat32* const distance, dgInt32 stack, const dgVector& velocA, const dgVector& velocB, dgFastRayTest& ray,
dgCollisionInstance* const shape, const dgMatrix& matrix, const dgVector& target, dgFloat32* const param, OnRayPrecastAction prefilter, void* const userData, dgConvexCastReturnInfo* const info, dgInt32 maxContacts, dgInt32 threadIndex) const
{
dgVector boxP0;
dgVector boxP1;
dgTriplex points[DG_CONVEX_CAST_POOLSIZE];
dgTriplex normals[DG_CONVEX_CAST_POOLSIZE];
dgFloat32 penetration[DG_CONVEX_CAST_POOLSIZE];
dgInt64 attributeA[DG_CONVEX_CAST_POOLSIZE];
dgInt64 attributeB[DG_CONVEX_CAST_POOLSIZE];
dgInt32 totalCount = 0;
dgAssert(matrix.TestOrthogonal());
shape->CalcAABB(matrix, boxP0, boxP1);
static int xxx;
xxx ++;
maxContacts = dgMin (maxContacts, DG_CONVEX_CAST_POOLSIZE);
dgAssert (!maxContacts || (maxContacts && info));
dgFloat32 maxParam = *param;
dgFloat32 timeToImpact = *param;
while (stack) {
stack--;
dgFloat32 dist = distance[stack];
if (dist > maxParam) {
break;
} else {
const dgBroadPhaseNode* const me = stackPool[stack];
dgBody* const body = me->GetBody();
if (body) {
if (!PREFILTER_RAYCAST(prefilter, body, body->m_collision, userData)) {
dgInt32 count = m_world->CollideContinue(shape, matrix, velocA, velocB, body->m_collision, body->m_matrix, velocB, velocB, timeToImpact, points, normals, penetration, attributeA, attributeB, maxContacts, threadIndex);
if (timeToImpact < maxParam) {
if ((timeToImpact - maxParam) < dgFloat32(-1.0e-3f)) {
totalCount = 0;
}
maxParam = timeToImpact;
if (count >= (maxContacts - totalCount)) {
count = maxContacts - totalCount;
}
for (dgInt32 i = 0; i < count; i++) {
info[totalCount].m_point[0] = points[i].m_x;
info[totalCount].m_point[1] = points[i].m_y;
info[totalCount].m_point[2] = points[i].m_z;
info[totalCount].m_point[3] = dgFloat32(0.0f);
info[totalCount].m_normal[0] = normals[i].m_x;
info[totalCount].m_normal[1] = normals[i].m_y;
info[totalCount].m_normal[2] = normals[i].m_z;
info[totalCount].m_normal[3] = dgFloat32(0.0f);
info[totalCount].m_penetration = penetration[i];
info[totalCount].m_contaID = attributeB[i];
// trace the contact point top see if they are valid
dgTrace (("frame: %d, param: %f, posit(%f %f %f)\n", xxx, maxParam, points[i].m_x, points[i].m_y, points[i].m_z));
info[totalCount].m_hitBody = body;
totalCount++;
}
}
if (maxParam < 1.0e-8f) {
break;
}
}
} else if (me->IsAggregate()) {
dgBroadPhaseAggregate* const aggregate = (dgBroadPhaseAggregate*)me;
const dgBroadPhaseNode* const node = aggregate->m_root;
if (node) {
dgVector minBox(node->m_minBox - boxP1);
dgVector maxBox(node->m_maxBox - boxP0);
dgFloat32 dist1 = ray.BoxIntersect(minBox, maxBox);
if (dist1 < maxParam) {
dgInt32 j = stack;
for (; j && (dist1 > distance[j - 1]); j--) {
stackPool[j] = stackPool[j - 1];
distance[j] = distance[j - 1];
}
stackPool[j] = node;
distance[j] = dist1;
stack++;
dgAssert(stack < DG_BROADPHASE_MAX_STACK_DEPTH);
}
}
} else {
dgBroadPhaseTreeNode* const node = (dgBroadPhaseTreeNode*)me;
const dgBroadPhaseNode* const left = node->m_left;
dgAssert(left);
dgVector minBox(left->m_minBox - boxP1);
dgVector maxBox(left->m_maxBox - boxP0);
dgFloat32 dist1 = ray.BoxIntersect(minBox, maxBox);
if (dist1 < maxParam) {
dgInt32 j = stack;
for (; j && (dist1 > distance[j - 1]); j--) {
stackPool[j] = stackPool[j - 1];
distance[j] = distance[j - 1];
}
stackPool[j] = left;
distance[j] = dist1;
stack++;
dgAssert(stack < DG_BROADPHASE_MAX_STACK_DEPTH);
}
const dgBroadPhaseNode* const right = node->m_right;
dgAssert(right);
minBox = right->m_minBox - boxP1;
maxBox = right->m_maxBox - boxP0;
dist1 = ray.BoxIntersect(minBox, maxBox);
if (dist1 < maxParam) {
dgInt32 j = stack;
for (; j && (dist1 > distance[j - 1]); j--) {
stackPool[j] = stackPool[j - 1];
distance[j] = distance[j - 1];
}
stackPool[j] = right;
distance[j] = dist1;
stack++;
dgAssert(stack < DG_BROADPHASE_MAX_STACK_DEPTH);
}
}
}
}
*param = maxParam;
return totalCount;
}
I suggest making that test compound shape so that it eassy to compare the results.