iPhysicsCollision* iPhysics::createMesh(shared_ptr<iMesh> mesh, int64 faceAttribute, const iaMatrixf& offset, uint64 worldID) { iPhysicsCollision* result = nullptr; const NewtonWorld* world = static_cast<const NewtonWorld*>(getWorld(worldID)->getNewtonWorld()); if (world != nullptr) { NewtonCollision* collision = NewtonCreateTreeCollision(static_cast<const NewtonWorld*>(world), 0); NewtonTreeCollisionBeginBuild(collision); float32 temp[12]; temp[3] = 1.0f; temp[7] = 1.0f; temp[11] = 1.0f; uint32* indexes = mesh->getIndexData(); float32* vertexes = mesh->getVertexData(); uint32 vertexFloatCount = mesh->getVertexSize() / 4; uint32 vertexPos = 0; uint32 indexCount = mesh->getIndexesCount(); for (int i = 0; i < indexCount; i += 3) { vertexPos = (indexes[i + 0] * vertexFloatCount); temp[0] = vertexes[vertexPos++]; temp[1] = vertexes[vertexPos++]; temp[2] = vertexes[vertexPos++]; vertexPos = (indexes[i + 1] * vertexFloatCount); temp[4] = vertexes[vertexPos++]; temp[5] = vertexes[vertexPos++]; temp[6] = vertexes[vertexPos++]; vertexPos = (indexes[i + 2] * vertexFloatCount); temp[8] = vertexes[vertexPos++]; temp[9] = vertexes[vertexPos++]; temp[10] = vertexes[vertexPos++]; NewtonTreeCollisionAddFace(collision, 3, temp, sizeof(float32) * 4, faceAttribute); } NewtonTreeCollisionEndBuild(collision, 0); result = new iPhysicsCollision(collision, worldID); NewtonCollisionSetUserID(static_cast<const NewtonCollision*>(collision), result->getID()); _collisionsListMutex.lock(); _collisions[result->getID()] = result; _collisionsListMutex.unlock(); } return result; }
iPhysicsCollision* iPhysics::createCylinder(float32 radius, float32 height, const iaMatrixf& offset, uint64 worldID) { iPhysicsCollision* result = nullptr; const NewtonWorld* world = static_cast<const NewtonWorld*>(getWorld(worldID)->getNewtonWorld()); if (world != nullptr) { NewtonCollision* collision = NewtonCreateCylinder(static_cast<const NewtonWorld*>(world), radius, height, 0, 0, offset.getData()); result = new iPhysicsCollision(collision, worldID); NewtonCollisionSetUserID(static_cast<const NewtonCollision*>(collision), result->getID()); _collisionsListMutex.lock(); _collisions[result->getID()] = result; _collisionsListMutex.unlock(); } return result; }
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; }
static void MakeFunnyCompound (DemoEntityManager* const scene, const dVector& origin) { NewtonWorld* const world = scene->GetNewton(); // create an empty compound collision NewtonCollision* const compound = NewtonCreateCompoundCollision (world, 0); #if 1 NewtonCompoundCollisionBeginAddRemove(compound); // add a bunch of convex collision at random position and orientation over the surface of a big sphere float radio = 5.0f; for (int i = 0 ; i < 300; i ++) { NewtonCollision* collision = NULL; float pitch = RandomVariable (1.0f) * 2.0f * 3.1416f; float yaw = RandomVariable (1.0f) * 2.0f * 3.1416f; float roll = RandomVariable (1.0f) * 2.0f * 3.1416f; float x = RandomVariable (0.5f); float y = RandomVariable (0.5f); float z = RandomVariable (0.5f); if ((x == 0.0f) && (y == 0.0f) && (z == 0.0f)){ x = 0.1f; } dVector p (x, y, z, 1.0f) ; p = p.Scale (radio / dSqrt (p % p)); dMatrix matrix (dPitchMatrix (pitch) * dYawMatrix (yaw) * dRollMatrix (roll)); matrix.m_posit = p; int r = dRand(); switch ((r >>2) & 3) { case 0: { collision = NewtonCreateSphere(world, 0.5, 0, &matrix[0][0]) ; break; } case 1: { collision = NewtonCreateCapsule(world, 0.3f, 0.2f, 0.5f, 0, &matrix[0][0]) ; break; } case 2: { collision = NewtonCreateCylinder(world, 0.25, 0.5, 0.25, 0, &matrix[0][0]) ; break; } case 3: { collision = NewtonCreateCone(world, 0.25, 0.25, 0, &matrix[0][0]) ; break; } } dAssert (collision); // we can set a collision id, and use data per sub collision NewtonCollisionSetUserID(collision, i); NewtonCollisionSetUserData(collision, (void*) i); // add this new collision NewtonCompoundCollisionAddSubCollision (compound, collision); NewtonDestroyCollision(collision); } // finish adding shapes NewtonCompoundCollisionEndAddRemove(compound); { // remove the first 10 shapes // test remove shape form a compound NewtonCompoundCollisionBeginAddRemove(compound); void* node = NewtonCompoundCollisionGetFirstNode(compound); for (int i = 0; i < 10; i ++) { //NewtonCollision* const collision = NewtonCompoundCollisionGetCollisionFromNode(compound, node); void* const nextNode = NewtonCompoundCollisionGetNextNode(compound, node); NewtonCompoundCollisionRemoveSubCollision(compound, node); node = nextNode; } // finish remove void* handle1 = NewtonCompoundCollisionGetNodeByIndex (compound, 30); void* handle2 = NewtonCompoundCollisionGetNodeByIndex (compound, 100); NewtonCollision* const shape1 = NewtonCompoundCollisionGetCollisionFromNode (compound, handle1); NewtonCollision* const shape2 = NewtonCompoundCollisionGetCollisionFromNode (compound, handle2); NewtonCollision* const copyShape1 = NewtonCollisionCreateInstance (shape1); NewtonCollision* const copyShape2 = NewtonCollisionCreateInstance (shape2); // you can also remove shape by their index NewtonCompoundCollisionRemoveSubCollisionByIndex (compound, 30); NewtonCompoundCollisionRemoveSubCollisionByIndex (compound, 100); handle1 = NewtonCompoundCollisionAddSubCollision (compound, copyShape1); handle2 = NewtonCompoundCollisionAddSubCollision (compound, copyShape2); NewtonDestroyCollision(copyShape1); NewtonDestroyCollision(copyShape2); NewtonCompoundCollisionEndAddRemove(compound); } { // show how to modify the children of a compound collision NewtonCompoundCollisionBeginAddRemove(compound); for (void* node = NewtonCompoundCollisionGetFirstNode(compound); node; node = NewtonCompoundCollisionGetNextNode(compound, node)) { NewtonCollision* const collision = NewtonCompoundCollisionGetCollisionFromNode(compound, node); // you can scale, change the matrix, change the inertia, do anything you want with the change NewtonCollisionSetUserData(collision, NULL); } NewtonCompoundCollisionEndAddRemove(compound); } // NewtonCollisionSetScale(compound, 0.5f, 0.25f, 0.125f); #else //test Yeside compound shape shape // - Rotation="1.5708 -0 0" Translation="0 0 0.024399" Size="0.021 0.096" Pos="0 0 0.115947" // - Rotation="1.5708 -0 0" Translation="0 0 0.056366" Size="0.195 0.024" Pos="0 0 0.147914" // - Rotation="1.5708 -0 0" Translation="0 0 -0.056366" Size="0.0065 0.07 Pos="0 0 0.035182" NewtonCompoundCollisionBeginAddRemove(compound); NewtonCollision* collision; dMatrix offsetMatrix (dPitchMatrix(1.5708f)); offsetMatrix.m_posit.m_z = 0.115947f; collision = NewtonCreateCylinder (world, 0.021f, 0.096f, 0, &offsetMatrix[0][0]) ; NewtonCompoundCollisionAddSubCollision (compound, collision); NewtonDestroyCollision(collision); offsetMatrix.m_posit.m_z = 0.035182f; collision = NewtonCreateCylinder (world, 0.0065f, 0.07f, 0, &offsetMatrix[0][0]) ; NewtonCompoundCollisionAddSubCollision (compound, collision); NewtonDestroyCollision(collision); offsetMatrix.m_posit.m_z = 0.147914f; collision = NewtonCreateCylinder (world, 0.195f, 0.024f, 0, &offsetMatrix[0][0]) ; NewtonCompoundCollisionAddSubCollision (compound, collision); NewtonDestroyCollision(collision); NewtonCompoundCollisionEndAddRemove(compound); #endif // for now we will simple make simple Box, make a visual Mesh DemoMesh* const visualMesh = new DemoMesh ("big ball", compound, "metal_30.tga", "metal_30.tga", "metal_30.tga"); int instaceCount = 2; dMatrix matrix (dGetIdentityMatrix()); matrix.m_posit = origin; for (int ix = 0; ix < instaceCount; ix ++) { for (int iz = 0; iz < instaceCount; iz ++) { dFloat y = origin.m_y; dFloat x = origin.m_x + (ix - instaceCount/2) * 15.0f; dFloat z = origin.m_z + (iz - instaceCount/2) * 15.0f; matrix.m_posit = FindFloor (world, dVector (x, y + 10.0f, z, 0.0f), 20.0f); ; matrix.m_posit.m_y += 15.0f; CreateSimpleSolid (scene, visualMesh, 10.0f, matrix, compound, 0); } } visualMesh->Release(); NewtonDestroyCollision(compound); }