I'm finally getting around to adding collision free painting to my project in Newton 4.0. I'm having some trouble getting the proper contact info from Newton.
Here's a video on what I'm doing ....just dragging a 'phantom" node on top of a 2D static ground plane which is a static mesh body.
https://youtu.be/6sh9e9hkEjg
Here's the log of what's happening in the video. As you can see, for a while everything works correctly and I get 4 contacts where the 'phantom' touches the static ground. The all of a sudden, Newton reports 0 contacts. The log shows the world bounds of the 'phantom' and the static ground.
- Code: Select all
63.815504 DEBUG [17700 NewtonPhantom.h->Update:60] ---------------------------
63.815614 DEBUG [17700 NewtonPhantom.h->Update:72] phantom min{ -4.05148, -0.0636214, -2.07488}
63.815658 DEBUG [17700 NewtonPhantom.h->Update:73] phantom max{ -2.92376, 1.06362, -0.944919}
63.815709 DEBUG [17700 NewtonPhantom.h->Update:108] CONTACTING static_ground
63.815736 DEBUG [17700 NewtonPhantom.h->Update:111] min{ -5, 0, -5}
63.815759 DEBUG [17700 NewtonPhantom.h->Update:112] max{ 5, 0, 5}
63.815776 DEBUG [17700 NewtonPhantom.h->Update:126] CONTACT COUNT: 4
63.815828 DEBUG [15108 NewtonPhantom.h->Update:60] ---------------------------
63.815900 DEBUG [15108 NewtonPhantom.h->Update:72] phantom min{ -4.05148, -0.0636214, -2.07488}
63.815966 DEBUG [15108 NewtonPhantom.h->Update:73] phantom max{ -2.92376, 1.06362, -0.944919}
63.816039 DEBUG [15108 NewtonPhantom.h->Update:108] CONTACTING static_ground
63.816108 DEBUG [15108 NewtonPhantom.h->Update:111] min{ -5, 0, -5}
63.816178 DEBUG [15108 NewtonPhantom.h->Update:112] max{ 5, 0, 5}
63.816251 DEBUG [15108 NewtonPhantom.h->Update:126] CONTACT COUNT: 4
63.846677 DEBUG [18228 NewtonPhantom.h->Update:60] ---------------------------
63.846796 DEBUG [18228 NewtonPhantom.h->Update:72] phantom min{ -4.01191, -0.0632749, -1.75242}
63.846850 DEBUG [18228 NewtonPhantom.h->Update:73] phantom max{ -2.83238, 1.06327, -0.571427}
63.846940 DEBUG [18228 NewtonPhantom.h->Update:108] CONTACTING static_ground
63.846988 DEBUG [18228 NewtonPhantom.h->Update:111] min{ -5, 0, -5}
63.847064 DEBUG [18228 NewtonPhantom.h->Update:112] max{ 5, 0, 5}
63.847089 DEBUG [18228 NewtonPhantom.h->Update:126] CONTACT COUNT: 0
63.847127 DEBUG [15108 NewtonPhantom.h->Update:60] ---------------------------
63.847194 DEBUG [15108 NewtonPhantom.h->Update:72] phantom min{ -4.01191, -0.0632749, -1.75242}
63.847243 DEBUG [15108 NewtonPhantom.h->Update:73] phantom max{ -2.83238, 1.06327, -0.571427}
63.847293 DEBUG [15108 NewtonPhantom.h->Update:108] CONTACTING static_ground
63.847337 DEBUG [15108 NewtonPhantom.h->Update:111] min{ -5, 0, -5}
63.847381 DEBUG [15108 NewtonPhantom.h->Update:112] max{ 5, 0, 5}
63.847425 DEBUG [15108 NewtonPhantom.h->Update:126] CONTACT COUNT: 0
63.877395 DEBUG [15108 NewtonPhantom.h->Update:60] ---------------------------
63.877569 DEBUG [15108 NewtonPhantom.h->Update:72] phantom min{ -4.01191, -0.0632749, -1.75242}
63.877631 DEBUG [15108 NewtonPhantom.h->Update:73] phantom max{ -2.83238, 1.06327, -0.571427}
63.877684 DEBUG [15108 NewtonPhantom.h->Update:108] CONTACTING static_ground
63.877727 DEBUG [15108 NewtonPhantom.h->Update:111] min{ -5, 0, -5}
63.877761 DEBUG [15108 NewtonPhantom.h->Update:112] max{ 5, 0, 5}
63.877795 DEBUG [15108 NewtonPhantom.h->Update:126] CONTACT COUNT: 0
63.877827 DEBUG [9044 NewtonPhantom.h->Update:60] ---------------------------
And here's the NewtonPhantom class I'm using. Do you seen anything that I might be doing wrong?
- Code: Select all
class NewtonPhantom : public ndModel
{
// NewtonPhantom: A class representing a phantom collision shape in a physics simulation.
// Phantom shapes can interact with other physics bodies to gather collision data
// without affecting the physics simulation itself.
public:
// Constructor: Initializes a new phantom shape with a given shape and scene.
NewtonPhantom (ndScene* scene, ndShape* shape, RenderableNode phantomNode) :
ndModel(),
phantomNode(phantomNode),
phantomShape (shape),
worldMatrix (ndGetIdentityMatrix()),
notification (scene)
{
// The constructor initializes the phantom shape, world matrix, and notification system.
}
~NewtonPhantom() = default;
// GetContactCount: Returns the number of contact points detected.
ndInt32 getContactCount() const
{
return contactCount;
}
// GetContactPoint: Returns the current contact point in the simulation.
ndVector getContactPoint() const { return contactPoint; }
// Update: Overridden function that updates the phantom's state in each simulation step.
void Update (ndWorld* const world, ndFloat32) override
{
contactCount = -1;
ndMatrix phantomPose;
eigenToNewton (phantomNode->getSpaceTime().worldTransform, phantomPose);
worldMatrix = phantomPose;
// Calculates the current Axis-Aligned Bounding Box (AABB) in world space.
ndVector boxMin, boxMax;
phantomShape.CalculateAabb (worldMatrix, boxMin, boxMax);
LOG (DBUG) << "phantom min{ " << boxMin.GetX() << ", " << boxMin.GetY() << ", " << boxMin.GetZ() << "}";
LOG (DBUG) << "phantom max{ " << boxMax.GetX() << ", " << boxMax.GetY() << ", " << boxMax.GetZ() << "}";
// Notify callback for bodies within the AABB.
ndBodiesInAabbNotify notifyCallback;
world->BodiesInAabb (notifyCallback, boxMin, boxMax);
// Processes each body in the AABB.
for (ndInt32 i = 0; i < notifyCallback.m_bodyArray.GetCount(); ++i)
{
ndBody* const nbody = const_cast<ndBody*> (notifyCallback.m_bodyArray[i]);
ndBodyKinematic* const kBody = nbody->GetAsBodyKinematic();
const ndShapeInstance& otherShape = kBody->GetCollisionShape();
const ndMatrix& otherMatrix = notifyCallback.m_bodyArray[i]->GetMatrix();
// Ignores collisions with phantom's 'resting on' body
ndBodyNotify* const notify = nbody->GetNotifyCallback();
Renderable* const node = static_cast<Renderable*> (notify->GetUserData());
// if (node && restingOn && node == restingOn.get()) continue;
// Ignores collisions with itself
if (otherShape.GetShape() != phantomShape.GetShape())
{
if (node)
{
LOG (DBUG) << "CONTACTING " << node->getName();
node->getSpaceTime().updateWorldBounds (true);
AlignedBox3f box = node->getSpaceTime().worldBound;
LOG (DBUG) << "min{ " << box.min().x() << ", " << box.min().y() << ", " << box.min().z() << "}";
LOG (DBUG) << "max{ " << box.max().x() << ", " << box.max().y() << ", " << box.max().z() << "}";
}
ndFixSizeArray<ndContactPoint, 16> contactBuffer;
ndVector phantomVelocity = ndVector::m_zero;
ndVector otherVelocity = ndVector::m_zero;
ndContactSolver contSolver;
contSolver.CalculateContacts (&phantomShape, worldMatrix, phantomVelocity, &otherShape, otherMatrix, otherVelocity, contactBuffer, ¬ification);
contactCount = contactBuffer.GetCount();
LOG (DBUG) << "CONTACT COUNT: " << contactCount;
if (contactCount)
{
for (int j = 0; j < contactCount; ++j)
{
const ndContactPoint& cPnt = contactBuffer[j];
contactPoint = cPnt.m_point;
}
}
}
else
{
}
}
}
private:
RenderableNode phantomNode = nullptr;
ndShapeInstance phantomShape;
ndMatrix worldMatrix;
ndContactNotify notification;
ndInt32 contactCount = -1;
ndVector contactPoint = ndVector (std::numeric_limits<float>::max());
}; // end class NewtonPhantom