Height Field Collision Issue

Report any bugs here and we'll post fixes

Moderators: Sascha Willems, Thomas

Re: Height Field Collision Issue

Postby Julio Jerez » Thu Jan 13, 2022 10:05 am

ok added the repro to the sand box,
the first bug I see is the matrix is no correct. this like

ndMatrix mBodyMatrix = dGetIdentityMatrix();
mBodyMatrix.m_posit = ndVector(-2.0f, 5.0f, -5.0f, 0.0f);

posit should be
mBodyMatrix.m_posit = ndVector(-2.0f, 5.0f, -5.0f, 1.0f);

and you were a repeat offender, you made the same mistake in function
void CreateBoxCompoundShape(ndShapeInstance& parentInstance)

Newton no longer does that kind of baby siting for the app. In 3.xx that was doing in Newton.cpp layer but not anymore.

after fixing that, I see one box falling and colling with the floor.
I enabled display collision, and I see the compound made of two boxes at almost the same location.
please sync and check if this bug is still there.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Height Field Collision Issue

Postby Julio Jerez » Thu Jan 13, 2022 10:16 am

oh I see is not two boxes, it is a box make out of five thin walls,
I am not sure what the sphere represent but for what I can see,
after fixing the matrix this is working unless I should expect a different behavior.

one more thing, not that is important I see you make the compound

begin
add shape
end

begin
add shape
end
...

it is more efficient to do it

begin
add shape
add shape
...
end

I chnge the demo because other people may see and think this is the way it should be
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Height Field Collision Issue

Postby Esharc » Thu Jan 13, 2022 10:31 am

Thank you. What a silly mistake, after setting the matrix correctly it works on my side as well.
Esharc
 
Posts: 120
Joined: Tue Jan 10, 2017 5:23 am
Location: South Africa

Re: Height Field Collision Issue

Postby Esharc » Fri Jan 14, 2022 4:40 am

Hi Julio,

It looks as if some collisions of the cone shape are missing. I have created a video of the situation that I am experiencing.

https://www.youtube.com/watch?v=CqR1r7RRzH8

In the video, when the cone shape is grey then it does not detect any collisions, and when it is red then it does detect collisions.

I am using the CalculateContacts functions that you recently added to the contact solver. The purple box that you see around the cone shape is showing the AABB extents of the shape.
Esharc
 
Posts: 120
Joined: Tue Jan 10, 2017 5:23 am
Location: South Africa

Re: Height Field Collision Issue

Postby Esharc » Fri Jan 14, 2022 8:00 am

I noticed that when I call SetMatrix on a body, the collision shape instance does not update as well.
In my test case I have a body connected to another body with a hinge that pushes up against a third body. If I then move the third body using SetMatrix, the body moves, but the second body that is moving on the hinge still collides with the old position of the body. Is there a way to set the collision shape matrix as well when setting the body's matrix?

*EDIT*
I added a function in ndBodyKinematic that does the same as the UpdateCollisionMatrix() function and that solved the issue. Will it be possible to make that function public?
Esharc
 
Posts: 120
Joined: Tue Jan 10, 2017 5:23 am
Location: South Africa

Re: Height Field Collision Issue

Postby Julio Jerez » Fri Jan 14, 2022 9:03 am

Do you mean make Update collision matrix public?
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Height Field Collision Issue

Postby Esharc » Fri Jan 14, 2022 9:12 am

Julio Jerez wrote:Do you mean make Update collision matrix public?

Yes, or add another function that can do something similar? Or if the body matrix is set, maybe update the collision shape matrix as well?
Esharc
 
Posts: 120
Joined: Tue Jan 10, 2017 5:23 am
Location: South Africa

Re: Height Field Collision Issue

Postby Julio Jerez » Fri Jan 14, 2022 10:21 am

I think I have to be a new function, is what UpdateCollisionMatrix does.

Code: Select all
void ndBodyKinematic::UpdateCollisionMatrix()
{
   m_transformIsDirty = 1;
   m_shapeInstance.SetGlobalMatrix(m_shapeInstance.GetLocalMatrix() * m_matrix);
   m_shapeInstance.CalculateAabb(m_shapeInstance.GetGlobalMatrix(), m_minAabb, m_maxAabb);
}


as you can see it does update the collision shape global matrix and aabb, however that is no enught to guarantee collision.

in the game that function is called during the collision update from here.

Code: Select all
void ndScene::UpdateAabb(ndInt32, ndBodyKinematic* const body)
{
   ndSceneBodyNode* const bodyNode = body->GetSceneBodyNode();
   body->UpdateCollisionMatrix();
      
   dAssert(!bodyNode->GetLeft());
   dAssert(!bodyNode->GetRight());
   dAssert(!body->GetCollisionShape().GetShape()->GetAsShapeNull());

   const ndInt32 test = dBoxInclusionTest(body->m_minAabb, body->m_maxAabb, bodyNode->m_minBox, bodyNode->m_maxBox);
   if (!test)
   {
      bodyNode->SetAabb(body->m_minAabb, body->m_maxAabb);
      if (!m_rootNode->GetAsSceneBodyNode())
....


this is so that during update collision the broad phase is only update once per call, if we do it in reverse order, meaning set the broad phase each time set matrix is call, them it will requires lot of synchronization, and also it could be expensive.

and since update collision shape does not update the bradphase, we need a new SetMatrix function

one that call SetMatrix, the calls void ndScene::UpdateAabb(ndInt32, ndBodyKinematic* const body)
so that is take case of the scene update.

I added like this

D_COLLISION_API void SetMatrixUpdateScene(const ndMatrix& matrix);

please try it out.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Height Field Collision Issue

Postby Julio Jerez » Fri Jan 14, 2022 12:36 pm

On this,
Esharc wrote:Hi Julio,

It looks as if some collisions of the cone shape are missing. I have created a video of the situation that I am experiencing.

https://www.youtube.com/watch?v=CqR1r7RRzH8

please tell me of the problem is solved by the new function that update the collision aabb in the broad phase.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Height Field Collision Issue

Postby Esharc » Mon Jan 17, 2022 2:13 am

Hi Julio,

The function that you added worked for the collision shape not updating when moving the body. But it did not solve the issue of the cone collision shape missing some collisions, that issue is still there.
Esharc
 
Posts: 120
Joined: Tue Jan 10, 2017 5:23 am
Location: South Africa

Re: Height Field Collision Issue

Postby Julio Jerez » Mon Jan 17, 2022 2:17 am

I added your compound demo to the sandBox, is named ndBasicCompoundCollision.cpp

can you recreate the test there?
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Height Field Collision Issue

Postby Esharc » Mon Jan 17, 2022 10:29 am

Ok, I have added a test for the missing cone collisions.

Code: Select all
/* Copyright (c) <2003-2021> <Newton Game Dynamics>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely
*/

#include "ndSandboxStdafx.h"
#include "ndSkyBox.h"
#include "ndTargaToOpenGl.h"
#include "ndDemoMesh.h"
#include "ndDemoCamera.h"
#include "ndPhysicsUtils.h"
#include "ndPhysicsWorld.h"
#include "ndMakeStaticMap.h"
#include "ndDemoEntityManager.h"
#include "ndDemoInstanceEntity.h"

#include <iostream>

static ndBodyDynamic* AddRigidBody(ndDemoEntityManager* const scene,
   const ndMatrix& matrix, const ndShapeInstance& shape,
   ndDemoInstanceEntity* const rootEntity, ndFloat32 mass)
{
   ndBodyDynamic* const body = new ndBodyDynamic();
   ndDemoEntity* const entity = new ndDemoEntity(matrix, rootEntity);

   body->SetNotifyCallback(new ndDemoEntityNotify(scene, entity));
   body->SetMatrix(matrix);
   body->SetCollisionShape(shape);
   body->SetMassMatrix(mass, shape);

   ndWorld* const world = scene->GetWorld();
   world->AddBody(body);
   return body;
}

class CBasicGhostObject : public ndModel
{
public:
   CBasicGhostObject(ndDemoEntityManager* const scene)
      :ndModel()
      ,m_GhostShape(new ndShapeCone(2.0, 10.0))
      , m_WorldMatrix(dGetIdentityMatrix())
   {
      ndDemoMeshIntance* const geometry = new ndDemoMeshIntance("coneShape", scene->GetShaderCache(), &m_GhostShape, "earthmap.tga", "earthmap.tga", "earthmap.tga");
      ndDemoInstanceEntity* const entity = new ndDemoInstanceEntity(geometry);
      scene->AddEntity(entity);
      ndMatrix mMatrix = dGetIdentityMatrix();
      m_WorldMatrix.m_posit = ndVector(0.0, 2.1, 0.0, 1.0);
      AddRigidBody(scene, m_WorldMatrix, m_GhostShape, entity, 0.0);
   }
   virtual void Update(ndWorld* const world, ndFloat32 timestep)
   {
      ndBodiesInAabbNotify notifyCallback;
      world->BodiesInAabb(notifyCallback);

      for (ndInt32 iIndex = 0; iIndex < notifyCallback.m_bodyArray.GetCount(); ++iIndex)
      {
         auto otherShape = notifyCallback.m_bodyArray[iIndex]->GetAsBodyKinematic()->GetCollisionShape();
         auto otherMatrix = notifyCallback.m_bodyArray[iIndex]->GetMatrix();

         if (otherShape.GetShape() != m_GhostShape.GetShape())
         {
            ndFixSizeArray<ndContactPoint, 16> contactBuffer;
            ndContactSolver contSolver;
            contSolver.CalculateContacts(&m_GhostShape, m_WorldMatrix, ndVector::m_zero, &otherShape, otherMatrix, ndVector::m_zero, contactBuffer);
            ndInt32 iNumContacts = contactBuffer.GetCount();

            if (iNumContacts > 0)
            {
               std::cout << "Ghost object colliding with other object." << std::endl;
            }
         }
      }
   }

   ndShapeInstance m_GhostShape;
   ndMatrix m_WorldMatrix;
};

void CreateGhostObject(ndDemoEntityManager* const scene)
{
   auto pGhostObject = new CBasicGhostObject(scene);
   scene->GetWorld()->AddModel(pGhostObject);
}

void CreateBoxShape(ndDemoEntityManager* const scene)
{
   ndShapeInstance shapeInstance(new ndShapeBox(1.0, 1.0, 1.0));
   ndDemoMeshIntance* const geometry = new ndDemoMeshIntance("boxShape", scene->GetShaderCache(), &shapeInstance, "earthmap.tga", "earthmap.tga", "earthmap.tga");
   ndDemoInstanceEntity* const entity = new ndDemoInstanceEntity(geometry);
   scene->AddEntity(entity);
   ndMatrix mMatrix = dGetIdentityMatrix();
   mMatrix.m_posit = ndVector(-4.0, 1.0, -2.0, 1.0);
   AddRigidBody(scene, mMatrix, shapeInstance, entity, 0.0);
}

void ndBasicCompoundShapeDemo(ndDemoEntityManager* const scene)
{
   CreateGhostObject(scene);
   CreateBoxShape(scene);

   ndVector origin(ndVector::m_zero);
   ndQuaternion rot(dYawMatrix(45.0f * ndDegreeToRad));
   origin.m_x -= 3.0f;
   origin.m_y += 5.0f;

   origin.m_x -= 15.0f;
   origin.m_z += 15.0f;

   scene->SetCameraMatrix(rot, origin);
}


I just added a cout call when a collision is detected. When you run the demo, there is no collision, but if you stop the demo, set the position of the box to
Code: Select all
mMatrix.m_posit = ndVector(-4.0, 1.0, 2.0, 1.0);
in the CreateBoxShape function then there are collisions.

I hope that is clear, I could not get it so that the keyboard inputs could move the box around, so I just opted to move it manually before starting the demo. The demo does not take long to load luckily :D
Esharc
 
Posts: 120
Joined: Tue Jan 10, 2017 5:23 am
Location: South Africa

Re: Height Field Collision Issue

Postby Julio Jerez » Mon Jan 17, 2022 4:08 pm

I pasted it is the sand box and I see the bug yes.
the shapes are colliding, but it seems there is a rounding error in the function

ndInt32 ndContactSolver::ConvexPolygonToLineIntersection

the collision is between a line and a triangle, but the line falls exactly on the triable edge, and that routine interpret that as no colling.
that seems like a big bug, because is not on the cone shape, it is in the generic contact calculation.

the line makes sense, since a round shape like a cone, a cylinder, a capsule, will find a line as the colling feature. the triangle also make sense, since the box is flat. what is strange is the like been on the exact edge, I would expect the line to clearly interest the poly.

I will debug it tonight.
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Height Field Collision Issue

Postby Julio Jerez » Mon Jan 17, 2022 4:49 pm

oh never mine, it is the cone,
ndInt32 ndShapeCone::CalculatePlaneIntersection(const ndVector& normal, const ndVector& origin, ndVector* const contactsOut) const
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

Re: Height Field Collision Issue

Postby Julio Jerez » Mon Jan 17, 2022 9:45 pm

ok try again.

as far as I can tell this bug happen because of round error.
what happen is that the combined shape for the cone and the box touch the origin of the Mink space at a perfect smooth round, so as the closest points to the origin are refined, the polygon that the shape coset distance the origin get very small. and since the normal is the area of that triangle,

the cross product start to produce degenerated normals that a little tilt as compared to the ideal surface normal of the round shape.

the solution to this is to quantize the round shape. so that the support vertex does not return a point of the continue surface of the round area but instead, the closet point of the three consecutive segment of the quantized surface.

that was how I solve in 3.14 but is 4.0 since we are using implicit surfaces for spheres, capsule, and camfered cylinders. for example a sphere is just a fat point, a capsule is a line, camfered cylder are disks, but I forgot that cylinders and cones cannot be defined implicitly like that so teh use the actual surface.

since we know the shape are colliding because we do get the closest points. them in that case we can just return the closet point as the contacts.

later I will quantize the cylinder and the cone so that but does no happens, but please see
if this fixed the immediate problem.
I solved by
Julio Jerez
Moderator
Moderator
 
Posts: 12249
Joined: Sun Sep 14, 2003 2:18 pm
Location: Los Angeles

PreviousNext

Return to Bugs and Fixes

Who is online

Users browsing this forum: No registered users and 2 guests

cron