iPhysicsCollision* iPhysics::createUserMeshCollision(const iaVector3f& minBox, const iaVector3f& maxBox, iPhysicsUserMeshCollisionHandler* handler, uint64 worldID) { iPhysicsCollision* result = nullptr; const NewtonWorld* world = static_cast<const NewtonWorld*>(getWorld(worldID)->getNewtonWorld()); if (world != nullptr) { NewtonCollision* collision = NewtonCreateUserMeshCollision(static_cast<const NewtonWorld*>(world), minBox.getData(), maxBox.getData(), handler, CollideCallback, reinterpret_cast<NewtonUserMeshCollisionRayHitCallback>(RayHitCallback), DestroyCallback, GetCollisionInfo, reinterpret_cast<NewtonUserMeshCollisionAABBTest>(AABBOverlapTest), GetFacesInAABB, nullptr, 0); result = new iPhysicsCollision(collision, worldID); NewtonCollisionSetUserID(static_cast<const NewtonCollision*>(collision), result->getID()); _collisionsListMutex.lock(); _collisions[result->getID()] = result; _collisionsListMutex.unlock(); } return result; }
/** * @brief * Constructor */ BodyTerrain::BodyTerrain(PLPhysics::World &cWorld, uint32 nWidth, uint32 nHeight, const float fTerrain[], const Vector3 &vBoxMin, const Vector3 &vBoxMax, const Vector3 &vScale) : PLPhysics::BodyTerrain(cWorld, static_cast<World&>(cWorld).CreateBodyImpl()), m_nWidth(nWidth), m_nHeight(nHeight), m_pfTerrain(fTerrain), m_vBoxMin(vBoxMin), m_vBoxMax(vBoxMax), m_vScale(vScale) { // Deactivate the physics simulation if required const bool bSimulationActive = cWorld.IsSimulationActive(); if (bSimulationActive) cWorld.SetSimulationActive(false); // Get the Newton physics world NewtonWorld *pNewtonWorld = static_cast<World&>(cWorld).GetNewtonWorld(); // Create collision primitive NewtonCollision *pCollision = NewtonCreateUserMeshCollision(pNewtonWorld, m_vBoxMin, m_vBoxMax, this, MeshCollisionCollideCallback, UserMeshCollisionRayHitCallback, nullptr, nullptr, nullptr, 0); // Create the rigid body // [TODO] Remove this as soon as there's an up-to-date Linux version of Newton Game Dynamics available! #if (NEWTON_MAJOR_VERSION == 2) && (NEWTON_MINOR_VERSION >= 28) Newton::NewtonBody *pNewtonBody = NewtonCreateBody(pNewtonWorld, pCollision, Matrix4x4::Identity); #else Newton::NewtonBody *pNewtonBody = NewtonCreateBody(pNewtonWorld, pCollision); #endif NewtonReleaseCollision(pNewtonWorld, pCollision); // Initialize the Newton physics body static_cast<BodyImpl&>(GetBodyImpl()).InitializeNewtonBody(*this, *pNewtonBody, 0.0f); // Reactivate the physics simulation if required if (bSimulationActive) cWorld.SetSimulationActive(bSimulationActive); }
dInfinitePlane (NewtonWorld* const world, const dVector& plane) :m_minBox (-0.1f, -2000.0f, -2000.0f, 0.0f) ,m_maxBox ( 0.1f, 2000.0f, 2000.0f, 0.0f) { // get the transformation matrix that takes the plane to the world local space m_rotation = dGrammSchmidt(plane); // build a unit grid in local space (this will be the shadow at projection of the collision aabb) m_unitSphape[0] = dVector (0.0f, 1.0f, 1.0f); m_unitSphape[1] = dVector (0.0f, -1.0f, 1.0f); m_unitSphape[2] = dVector (0.0f, -1.0f, -1.0f); m_unitSphape[3] = dVector (0.0f, 1.0f, -1.0f); // save the plane in local space m_plane = m_rotation.UntransformPlane (plane); #ifdef PASS_A_QUAD // passing a single quad for (int i = 0; i < MAX_THREAD_FACES; i ++) { m_faceIndices[i][0] = 4; // face attribute m_indexArray[i][4] = 0; // face normal m_indexArray[i][4 + 1] = 4; // face area (the plane is clipped around the box, the face size is always optimal) m_indexArray[i][4 + 2 + 4] = 0; for (int j = 0; j < 4; j ++) { // face vertex index m_indexArray[i][j] = j; // face adjacent index (infinite plane does not have shared edge with other faces) m_indexArray[i][j + 4 + 2] = 4; } } #else // passing two triangle for (int i = 0; i < MAX_THREAD_FACES; i ++) { // first triangle { // index count m_faceIndices[i][0] = 3; // face indices m_indexArray[i][0] = 0; m_indexArray[i][1] = 1; m_indexArray[i][2] = 2; // face attribute m_indexArray[i][3] = 0; // face normal m_indexArray[i][4] = 4; // face adjacent index (infinite plane does not have shared edge with other faces) m_indexArray[i][5] = 4; m_indexArray[i][6] = 4; m_indexArray[i][7] = 4; // face area (the plane is clipped around the box, the face size is always optimal) m_indexArray[i][8] = 0; } // second triangle { // index count m_faceIndices[i][1] = 3; // face indices m_indexArray[i][0 + 9] = 0; m_indexArray[i][1 + 9] = 2; m_indexArray[i][2 + 9] = 3; // face attribute m_indexArray[i][3 + 9] = 0; // face normal m_indexArray[i][4 + 9] = 4; // face adjacent index (infinite plane does not have shared edge with other faces) m_indexArray[i][5 + 9] = 4; m_indexArray[i][6 + 9] = 4; m_indexArray[i][7 + 9] = 4; // face area (the plane is clipped around the box, the face size is always optimal) m_indexArray[i][8 + 9] = 0; } } #endif // create a Newton user collision m_collision = NewtonCreateUserMeshCollision (world, &m_minBox[0], &m_maxBox[0], this, PlaneCollisionCollideCallback, PlaneMeshCollisionRayHitCallback, PlaneCollisionDestroyCallback, PlaneCollisionGetCollisionInfo, PlaneCollisionAABBOverlapTest, PlaneCollisionGetFacesInAABB, UserCollisionSerializationCallback, 0); // set a debug display call back NewtonStaticCollisionSetDebugCallback (m_collision, ShowMeshCollidingFaces); // set the collisoin offset Matrix; NewtonCollisionSetMatrix(m_collision, &m_rotation[0][0]); }