I finally found time, to port OgreNewt for newtondynamics4 with the help of AI and my knowledge
So I'm back and excited to see which new Newton Dynamics features I can integrate into my engine.
I'm now struggling issue by issue and make progress.
So i now stuck on TreeCollision. I tried lots of stuff, but TreeCollision is not really working for any mesh: Either other shapes are not colliding with it, or i get a crash in newtondynamics:
Stacktrace:
- Code: Select all
ndNewton_d.dll!ndVector::ndVector(const ndVector & copy) Zeile 1167 C++ ndNewton_d.dll!ndShapeConvexPolygon::CalculatePlaneIntersection(const ndVector & normalIn={...}, const ndVector & origin={...}, ndVector * const contactsOut=0x0000009f5a5f2750) Zeile 95 C++ ndNewton_d.dll!ndShapeInstance::CalculatePlaneIntersection(const ndVector & normal={...}, const ndVector & point={...}, ndVector * const contactsOut=0x0000009f5a5f2750) Zeile 557 C++ ndNewton_d.dll!ndContactSolver::CalculateContacts(const ndVector & point0={...}, const ndVector & point1={...}, const ndVector & normal={...}) Zeile 4428 C++ ndNewton_d.dll!ndContactSolver::ConvexToConvexContactsDiscrete() Zeile 2547 C++ ndNewton_d.dll!ndShapeConvexPolygon::CalculateContactToConvexHullDescrete(const ndShapeInstance * const parentMesh=0x0000009f5a5f15a0, ndContactSolver & contactSolver={...}) Zeile 839 C++ ndNewton_d.dll!ndContactSolver::CalculatePolySoupToHullContactsDescrete(ndPolygonMeshDesc & data={...}) Zeile 4221 C++ ndNewton_d.dll!ndContactSolver::ConvexToStaticMeshContactsDiscrete() Zeile 4272 C++ ndNewton_d.dll!ndContactSolver::ConvexContactsDiscrete() Zeile 2469 C++ ndNewton_d.dll!ndContactSolver::CalculateContactsDiscrete() Zeile 2429 C++ ndNewton_d.dll!ndScene::CalculateJointContacts(int threadIndex=0, ndContact * const contact=0x00000236c2f5e0c0) Zeile 487 C++ ndNewton_d.dll!ndScene::CalculateContacts(int threadIndex=0, ndContact * const contact=0x00000236c2f5e0c0) Zeile 938 C++ ndNewton_d.dll!ndScene::CalculateContacts::__l5::<Lambdafunktion>(int groupId=1, int threadIndex=0) Zeile 1684 C++ ndNewton_d.dll!ndFunction<void <Lambdafunktion>(int, int)>::operator()(int threadIndex=1, int threadCount=0) Zeile 138 C++ ndNewton_d.dll!ndThreadPool::ParallelExecute<ndFunction<void <Lambdafunktion>(int, int)>>(const ndFunction<void <Lambdafunktion>(int, int)> & function={...}, int workGroupCount=4, int groupsPerThreads=8) Zeile 306 C++ ndNewton_d.dll!ndScene::CalculateContacts() Zeile 1689 C++ ndNewton_d.dll!ndWorld::SubStepUpdate(float timestep=0.00416666688) Zeile 430 C++ ndNewton_d.dll!ndWorld::MainUpdate() Zeile 370 C++ ndNewton_d.dll!ndWorld::ThreadFunction() Zeile 390 C++ ndNewton_d.dll!ndWorldScene::ThreadFunction() Zeile 54 C++ ndNewton_d.dll!ndThread::ThreadFunctionCallback() Zeile 156 C++ [Externer Code] I get for the copy ndVector really * values in newtondynamics4: inline ndVector(const ndVector& copy) :m_type(copy.m_type) { } 0x0000009f5a5ef860 {m_f=0x0000009f5a5ef860 {1.56921612e+16, 2.228e-43#DEN, -3.00642766e+26, 4.591e-41#DEN} ...}
This is the TreeCollision Code for an Ogre::v1::Entity:
- Code: Select all
namespace
{
inline bool isFiniteVec(const Ogre::Vector3& v)
{
return std::isfinite(v.x) && std::isfinite(v.y) && std::isfinite(v.z);
}
inline bool buildFaceTriplet(const Ogre::Vector3& a,
const Ogre::Vector3& b,
const Ogre::Vector3& c,
ndVector outFace[3],
FaceWinding fw)
{
if (!isFiniteVec(a) || !isFiniteVec(b) || !isFiniteVec(c))
return false;
const Ogre::Vector3 e0 = b - a;
const Ogre::Vector3 e1 = c - a;
const Ogre::Real area2 = e0.crossProduct(e1).squaredLength();
if (area2 <= Ogre::Real(1e-12))
return false; // reject degenerate
outFace[0] = ndVector(a.x, a.y, a.z, 1.0f);
outFace[1] = ndVector(b.x, b.y, b.z, 1.0f);
outFace[2] = ndVector(c.x, c.y, c.z, 1.0f);
if (fw == FW_REVERSE)
std::swap(outFace[1], outFace[2]);
return true;
}
}
TreeCollision::TreeCollision(const World* world,
Ogre::v1::Entity* obj,
bool optimize,
unsigned int id,
FaceWinding fw)
: Collision(world)
, m_faceCount(0)
, m_categoryId(id)
{
Ogre::Vector3 scale(1, 1, 1);
if (auto* node = obj ? obj->getParentNode() : nullptr)
scale = node->_getDerivedScaleUpdated();
std::vector<Ogre::Vector3> vertices;
std::vector<int> indices;
if (obj)
{
Ogre::v1::MeshPtr mesh = obj->getMesh();
if (!mesh.isNull())
{
const unsigned short subCount = mesh->getNumSubMeshes();
bool sharedAdded = false;
for (unsigned short si = 0; si < subCount; ++si)
{
Ogre::v1::SubMesh* sub = mesh->getSubMesh(si);
if (!sub) continue;
if (sub->operationType != Ogre::OperationType::OT_TRIANGLE_LIST)
continue;
Ogre::v1::VertexData* vdata = nullptr;
if (sub->useSharedVertices)
{
if (!sharedAdded)
{
vdata = mesh->sharedVertexData[0];
sharedAdded = true;
}
}
else
{
vdata = sub->vertexData[0];
}
if (!vdata) continue;
const Ogre::v1::VertexElement* posElem =
vdata->vertexDeclaration->findElementBySemantic(Ogre::VES_POSITION);
if (!posElem) continue;
const size_t vertexOffset = vertices.size();
const size_t vStart = vdata->vertexStart;
const size_t vCount = vdata->vertexCount;
Ogre::v1::HardwareVertexBufferSharedPtr vbuf =
vdata->vertexBufferBinding->getBuffer(posElem->getSource());
unsigned char* base = static_cast<unsigned char*>(
vbuf->lock(Ogre::v1::HardwareBuffer::HBL_READ_ONLY));
const size_t stride = vbuf->getVertexSize();
for (size_t j = 0; j < vCount; ++j)
{
unsigned char* ptr = base + (vStart + j) * stride;
float* p = nullptr;
posElem->baseVertexPointerToElement(ptr, &p);
Ogre::Vector3 v(p[0], p[1], p[2]);
if (!isFiniteVec(v))
continue;
vertices.push_back(v * scale);
}
vbuf->unlock();
Ogre::v1::IndexData* iData = sub->indexData[0];
if (!iData) continue;
Ogre::v1::HardwareIndexBufferSharedPtr ib = iData->indexBuffer;
const size_t iCount = iData->indexCount;
const size_t iStart = iData->indexStart;
if (iCount < 3) continue;
if (ib->getType() == Ogre::v1::HardwareIndexBuffer::IT_32BIT)
{
const unsigned int* baseIdx =
static_cast<const unsigned int*>(ib->lock(Ogre::v1::HardwareBuffer::HBL_READ_ONLY));
const unsigned int* iptr = baseIdx + iStart;
for (size_t k = 0; k < iCount; ++k)
indices.push_back(int(iptr[k]) + int(vertexOffset));
ib->unlock();
}
else
{
const unsigned short* baseIdx =
static_cast<const unsigned short*>(ib->lock(Ogre::v1::HardwareBuffer::HBL_READ_ONLY));
const unsigned short* iptr = baseIdx + iStart;
for (size_t k = 0; k < iCount; ++k)
indices.push_back(int(iptr[k]) + int(vertexOffset));
ib->unlock();
}
}
}
}
if (m_col)
m_col->Release();
ndPolygonSoupBuilder meshBuilder;
meshBuilder.Begin();
const size_t triCount = indices.size() / 3;
for (size_t t = 0; t < triCount; ++t)
{
const int i0 = indices[t * 3 + 0];
const int i1 = indices[t * 3 + 1];
const int i2 = indices[t * 3 + 2];
if (i0 < 0 || i1 < 0 || i2 < 0 ||
i0 >= (int)vertices.size() ||
i1 >= (int)vertices.size() ||
i2 >= (int)vertices.size())
continue;
ndVector face[3];
if (!buildFaceTriplet(vertices[i0], vertices[i1], vertices[i2], face, fw))
continue;
for (int j = 0; j < 3; ++j)
face[j].m_w = 1.0f;
meshBuilder.AddFace(&face[0].m_x, sizeof(ndVector), 3, static_cast<ndInt32>(id));
++m_faceCount;
}
meshBuilder.End(optimize);
m_shapeInstance = new ndShapeInstance(new ndShapeStatic_bvh(meshBuilder));
m_col = m_shapeInstance->GetShape();
}
Maybe you see, what I'm doing wrong?
Best Regards
Lax


