static int MakeRandomGuassianPointCloud (NewtonMesh* const mesh, dVector* const points, int count) { dVector size(0.0f); dMatrix matrix(dGetIdentityMatrix()); NewtonMeshCalculateOOBB(mesh, &matrix[0][0], &size.m_x, &size.m_y, &size.m_z); dVector minBox (matrix.m_posit - matrix[0].Scale (size.m_x) - matrix[1].Scale (size.m_y) - matrix[2].Scale (size.m_z)); dVector maxBox (matrix.m_posit + matrix[0].Scale (size.m_x) + matrix[1].Scale (size.m_y) + matrix[2].Scale (size.m_z)); size = (maxBox - minBox).Scale (0.5f); dVector origin = (maxBox + minBox).Scale (0.5f); dFloat biasExp = 10.0f; dFloat r = dSqrt (size.DotProduct3(size)); r = powf(r, 1.0f/biasExp); for (int i = 0; i < count; i++) { dVector& p = points[i]; bool test; do { p = dVector (2.0f * RandomVariable(r), 2.0f * RandomVariable(r), 2.0f * RandomVariable(r), 0.0f); dFloat len = dSqrt (p.DotProduct3(p)); dFloat scale = powf(len, biasExp) / len; p = p.Scale (scale) + origin; test = (p.m_x > minBox.m_x) && (p.m_x < maxBox.m_x) && (p.m_y > minBox.m_y) && (p.m_y < maxBox.m_y) && (p.m_z > minBox.m_z) && (p.m_z < maxBox.m_z); } while (!test); } return count; }
ShatterEffect(NewtonWorld* const world, NewtonMesh* const mesh, int interiorMaterial) :dList<ShatterAtom>(), m_world (world) { // first we populate the bounding Box area with few random point to get some interior subdivisions. // the subdivision are local to the point placement, by placing these points visual ally with a 3d tool // and have precise control of how the debris are created. // the number of pieces is equal to the number of point inside the Mesh plus the number of point on the mesh dVector size; dMatrix matrix(GetIdentityMatrix()); NewtonMeshCalculateOOBB(mesh, &matrix[0][0], &size.m_x, &size.m_y, &size.m_z); // pepper the inside of the BBox box of the mesh with random points int count = 0; dVector points[NUMBER_OF_ITERNAL_PARTS + 1]; while (count < NUMBER_OF_ITERNAL_PARTS) { dFloat x = RandomVariable(size.m_x); dFloat y = RandomVariable(size.m_y); dFloat z = RandomVariable(size.m_z); if ((x <= size.m_x) && (x >= -size.m_x) && (y <= size.m_y) && (y >= -size.m_y) && (z <= size.m_z) && (z >= -size.m_z)){ points[count] = dVector (x, y, z); count ++; } } // create a texture matrix, for applying the material's UV to all internal faces dMatrix textureMatrix (GetIdentityMatrix()); textureMatrix[0][0] = 1.0f / size.m_x; textureMatrix[1][1] = 1.0f / size.m_y; // now we call create we decompose the mesh into several convex pieces NewtonMesh* const debriMeshPieces = NewtonMeshVoronoiDecomposition (mesh, count, sizeof (dVector), &points[0].m_x, interiorMaterial, &textureMatrix[0][0]); // Get the volume of the original mesh NewtonCollision* const collision = NewtonCreateConvexHullFromMesh (m_world, mesh, 0.0f, 0); dFloat volume = NewtonConvexCollisionCalculateVolume (collision); NewtonReleaseCollision(m_world, collision); // now we iterate over each pieces and for each one we create a visual entity and a rigid body NewtonMesh* nextDebri; for (NewtonMesh* debri = NewtonMeshCreateFirstLayer (debriMeshPieces); debri; debri = nextDebri) { nextDebri = NewtonMeshCreateNextLayer (debriMeshPieces, debri); NewtonCollision* const collision = NewtonCreateConvexHullFromMesh (m_world, debri, 0.0f, 0); if (collision) { ShatterAtom& atom = Append()->GetInfo(); atom.m_mesh = new DemoMesh(debri); atom.m_collision = collision; NewtonConvexCollisionCalculateInertialMatrix (atom.m_collision, &atom.m_momentOfInirtia[0], &atom.m_centerOfMass[0]); dFloat debriVolume = NewtonConvexCollisionCalculateVolume (atom.m_collision); atom.m_massFraction = debriVolume / volume; } NewtonMeshDestroy(debri); } NewtonMeshDestroy(debriMeshPieces); }
void Init (dFloat location_x, dFloat location_z, PrimitiveType shapeType, int materialID, PrimitiveType castingShapeType) { m_pith = RandomVariable(3.1416f * 2.0f); m_yaw = RandomVariable(3.1416f * 2.0f); m_roll = RandomVariable(3.1416f * 2.0f); m_step = 15.0f * (dAbs (RandomVariable(0.25f)) + 0.0001f) * 3.1416f/180.0f; CreatCasterBody(location_x, location_z, shapeType, materialID); NewtonWorld* const world = ((CustomControllerManager<dClosestDistanceRecord>*)GetManager())->GetWorld(); DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(world); dMatrix matrix; NewtonBodyGetMatrix(m_body, &matrix[0][0]); matrix.m_posit.m_y += 10.0f; m_castingVisualEntity = new ClosestDistanceEntity (scene, matrix, materialID, castingShapeType); }
RandomVariable operator /(double c_arg, RandomVariable & rv_arg) { if (!c_arg) return RandomVariable(); RandomVariable result = rv_arg.algorithm->calculateRatio(c_arg, rv_arg); RandomVariable::graph.setParent1For(result, new DeltaDistribution(c_arg)); RandomVariable::graph.setParent2For(result, rv_arg); RandomVariable::graph.setOperationTypeFor(result, RATIO); return result; }
RandomVariable RandomVariable::operator *(double c_arg) { if (!c_arg) return RandomVariable(); RandomVariable result = algorithm->calculateProduct(*this, c_arg); graph.setParent1For(result, *this); graph.setParent2For(result, new DeltaDistribution(c_arg)); graph.setOperationTypeFor(result, PRODUCT); return result; }
static int MakeRandomPoisonPointCloud(NewtonMesh* const mesh, dVector* const points) { dVector size(0.0f); dMatrix matrix(dGetIdentityMatrix()); NewtonMeshCalculateOOBB(mesh, &matrix[0][0], &size.m_x, &size.m_y, &size.m_z); dVector minBox (matrix.m_posit - matrix[0].Scale (size.m_x) - matrix[1].Scale (size.m_y) - matrix[2].Scale (size.m_z)); dVector maxBox (matrix.m_posit + matrix[0].Scale (size.m_x) + matrix[1].Scale (size.m_y) + matrix[2].Scale (size.m_z)); size = maxBox - minBox; int xCount = int (size.m_x / POINT_DENSITY_PER_METERS) + 1; int yCount = int (size.m_y / POINT_DENSITY_PER_METERS) + 1; int zCount = int (size.m_z / POINT_DENSITY_PER_METERS) + 1; int count = 0; dFloat z0 = minBox.m_z; for (int iz = 0; (iz < zCount) && (count < MAX_POINT_CLOUD_SIZE); iz ++) { dFloat y0 = minBox.m_y; for (int iy = 0; (iy < yCount) && (count < MAX_POINT_CLOUD_SIZE); iy ++) { dFloat x0 = minBox.m_x; for (int ix = 0; (ix < xCount) && (count < MAX_POINT_CLOUD_SIZE); ix ++) { dFloat x = x0; dFloat y = y0; dFloat z = z0; x += RandomVariable(POISON_VARIANCE); y += RandomVariable(POISON_VARIANCE); z += RandomVariable(POISON_VARIANCE); points[count] = dVector (x, y, z); count ++; x0 += POINT_DENSITY_PER_METERS; } y0 += POINT_DENSITY_PER_METERS; } z0 += POINT_DENSITY_PER_METERS; } return count; }
void CreateCastingShapes(DemoEntityManager* const scene, dFloat size) { NewtonWorld* const world = scene->GetNewton(); int materialID = NewtonMaterialGetDefaultGroupID(world); dSetRandSeed (0); dVector shapeSize (size, size, size, 0.0f); PrimitiveType castSelection[] = {_SPHERE_PRIMITIVE, _CAPSULE_PRIMITIVE, _BOX_PRIMITIVE, _CYLINDER_PRIMITIVE, _REGULAR_CONVEX_HULL_PRIMITIVE, _CHAMFER_CYLINDER_PRIMITIVE}; m_count = sizeof (castSelection) / sizeof (castSelection[0]); m_castingGeometries = new DemoMesh*[m_count]; m_castingShapeArray = new NewtonCollision*[m_count]; dMatrix alignMatrix (dRollMatrix(3.141592f * 90.0f / 180.0f)); for (int i = 0; i < m_count; i ++) { dVector shapeSize (size + RandomVariable (size / 2.0f), size + RandomVariable (size / 2.0f), size + RandomVariable (size / 2.0f), 0.0f); #if 1 m_castingShapeArray[i] = CreateConvexCollision (world, &alignMatrix[0][0], shapeSize, castSelection[i], materialID); #else m_castingShapeArray[i] = NewtonCreateCompoundCollision (world, materialID); NewtonCompoundCollisionBeginAddRemove(m_castingShapeArray[i]); NewtonCollision* const collision = CreateConvexCollision (world, &alignMatrix[0][0], shapeSize, castSelection[i], materialID); NewtonCompoundCollisionAddSubCollision (m_castingShapeArray[i], collision); NewtonDestroyCollision(collision); NewtonCompoundCollisionEndAddRemove(m_castingShapeArray[i]); #endif m_castingGeometries[i] = new DemoMesh("geometry", m_castingShapeArray[i], "smilli.tga", "smilli.tga", "smilli.tga"); } // make and entity for showing the result of the convex cast dMatrix matrix (dGetIdentityMatrix()); matrix.m_posit.m_y = 2.0f; m_currentCastingShape = 0; m_castingEntity = new DemoEntity (matrix, NULL); m_castingEntity->SetMesh(m_castingGeometries[m_currentCastingShape], dGetIdentityMatrix()); }
Vector FrostedGlass::Sample(Vector* origin, Vector incident, Vector normal, float wavelength, std::mt19937* prng) { /* Generate a random microfacet normal based on the Beckmann distribution with the given roughness. */ float r1 = RandomVariable(prng); float r2 = RandomVariable(prng); float theta = atan(-pow(this->roughness, 2.0f) * log(1.0f - r1)); float phi = 2.0f * PI * r2; Vector m = spherical(phi, theta); /* Rotate the microfacet normal according to the actual surface normal. */ m = rotate(m, normal); /* Work out the correct n1 and n2 depending on the incident vector's direction relative to the normal. */ float cosI = incident * normal; float n1, n2; if (cosI > 0) { /* Incident and normal have the same direction, ray is inside the material. */ n1 = this->refractiveIndex->Lookup(wavelength); n2 = 1.0f; /* Flip the microfacet normal around. */ m = ZERO - m; } else { /* Incident and normal have opposite directions, so the ray is outside the material. */ n2 = this->refractiveIndex->Lookup(wavelength); n1 = 1.0f; /* Make the cosine positive. */ cosI = -cosI; } /* Calculate the refracted angle's cosine. */ float cosT = 1.0f - pow(n1 / n2, 2.0f) * (1.0f - pow(cosI, 2.0f)); /* Check for total internal reflection. */ if (cosT < 0.0f) { /* Total internal reflection occurred. */ (*origin) = (*origin) + m * EPSILON; return reflect(incident, m); } /* Otherwise, finish computing the angle. */ cosT = sqrt(cosT); /* Now, compute the Fresnel coefficients for reflection and refraction for a randomly polarized ray. */ float R = (pow((n1 * cosI - n2 * cosT) / (n1 * cosI + n2 * cosT), 2.0f) + pow((n2 * cosI - n1 * cosT) / (n1 * cosT + n2 * cosI), 2.0f)) * 0.5f; /* Perform a random trial to decide whether to reflect or refract the ray. */ if (RandomVariable(prng) < R) { /* Reflection. */ (*origin) = (*origin) + m * EPSILON; return reflect(incident, m); } else { /* Refraction. */ (*origin) = (*origin) - m * EPSILON; return incident * (n1 / n2) + m * ((n1 / n2) * cosI - cosT); } }
NewtonCollision* CreateConvexCollision (NewtonWorld* world, const dMatrix& srcMatrix, const dVector& originalSize, PrimitiveType type, int materialID__) { dVector size (originalSize); NewtonCollision* collision = NULL; switch (type) { case _NULL_PRIMITIVE: { collision = NewtonCreateNull (world); break; } case _SPHERE_PRIMITIVE: { // create the collision collision = NewtonCreateSphere (world, size.m_x * 0.5f, 0, NULL); break; } case _BOX_PRIMITIVE: { // create the collision collision = NewtonCreateBox (world, size.m_x, size.m_y, size.m_z, 0, NULL); break; } case _CONE_PRIMITIVE: { dFloat r = size.m_x * 0.5f; dFloat h = size.m_y; // create the collision collision = NewtonCreateCone (world, r, h, 0, NULL); break; } case _CYLINDER_PRIMITIVE: { // create the collision collision = NewtonCreateCylinder (world, size.m_x * 0.5f, size.m_y, 0, NULL); break; } case _CAPSULE_PRIMITIVE: { // create the collision collision = NewtonCreateCapsule (world, size.m_x * 0.5f, size.m_y, 0, NULL); break; } case _TAPERED_CAPSULE_PRIMITIVE: { // create the collision collision = NewtonCreateTaperedCapsule (world, size.m_x * 0.5f, size.m_z * 0.5f, size.m_y, 0, NULL); break; } case _CHAMFER_CYLINDER_PRIMITIVE: { // create the collision collision = NewtonCreateChamferCylinder (world, size.m_x * 0.5f, size.m_y, 0, NULL); break; } case _TAPERED_CYLINDER_PRIMITIVE: { // create the collision collision = NewtonCreateTaperedCylinder (world, size.m_x * 0.5f, size.m_z * 0.5f, size.m_y, 0, NULL); break; } case _RANDOM_CONVEX_HULL_PRIMITIVE: { // Create a clouds of random point around the origin #define SAMPLE_COUNT 200 dVector cloud [SAMPLE_COUNT]; // make sure that at least the top and bottom are present cloud [0] = dVector ( size.m_x * 0.5f, 0.0f, 0.0f, 0.0f); cloud [1] = dVector (-size.m_x * 0.5f, 0.0f, 0.0f, 0.0f); cloud [2] = dVector ( 0.0f, size.m_y * 0.5f, 0.0f, 0.0f); cloud [3] = dVector ( 0.0f, -size.m_y * 0.5f, 0.0f, 0.0f); cloud [4] = dVector (0.0f, 0.0f, size.m_z * 0.5f, 0.0f); cloud [5] = dVector (0.0f, 0.0f, -size.m_z * 0.5f, 0.0f); int count = 6; // populate the cloud with pseudo Gaussian random points for (int i = 6; i < SAMPLE_COUNT; i ++) { cloud [i].m_x = RandomVariable(size.m_x); cloud [i].m_y = RandomVariable(size.m_y); cloud [i].m_z = RandomVariable(size.m_z); count ++; } collision = NewtonCreateConvexHull (world, count, &cloud[0].m_x, sizeof (dVector), 0.01f, 0, NULL); break; } case _REGULAR_CONVEX_HULL_PRIMITIVE: { // Create a clouds of random point around the origin #define STEPS_HULL 6 //#define STEPS_HULL 3 dVector cloud [STEPS_HULL * 4 + 256]; int count = 0; dFloat radius = size.m_y; dFloat height = size.m_x * 0.999f; dFloat x = - height * 0.5f; dMatrix rotation (dPitchMatrix(2.0f * 3.141592f / STEPS_HULL)); for (int i = 0; i < 4; i ++) { dFloat pad = ((i == 1) || (i == 2)) * 0.25f * radius; dVector p (x, 0.0f, radius + pad); x += 0.3333f * height; dMatrix acc (dGetIdentityMatrix()); for (int j = 0; j < STEPS_HULL; j ++) { cloud[count] = acc.RotateVector(p); acc = acc * rotation; count ++; } } collision = NewtonCreateConvexHull (world, count, &cloud[0].m_x, sizeof (dVector), 0.02f, 0, NULL); break; } case _COMPOUND_CONVEX_CRUZ_PRIMITIVE: { //dMatrix matrix (GetIdentityMatrix()); dMatrix matrix (dPitchMatrix(15.0f * 3.1416f / 180.0f) * dYawMatrix(15.0f * 3.1416f / 180.0f) * dRollMatrix(15.0f * 3.1416f / 180.0f)); // NewtonCollision* const collisionA = NewtonCreateBox (world, size.m_x, size.m_x * 0.25f, size.m_x * 0.25f, 0, &matrix[0][0]); // NewtonCollision* const collisionB = NewtonCreateBox (world, size.m_x * 0.25f, size.m_x, size.m_x * 0.25f, 0, &matrix[0][0]); // NewtonCollision* const collisionC = NewtonCreateBox (world, size.m_x * 0.25f, size.m_x * 0.25f, size.m_x, 0, &matrix[0][0]); matrix.m_posit = dVector (size.m_x * 0.5f, 0.0f, 0.0f, 1.0f); NewtonCollision* const collisionA = NewtonCreateBox (world, size.m_x, size.m_x * 0.25f, size.m_x * 0.25f, 0, &matrix[0][0]); matrix.m_posit = dVector (0.0f, size.m_x * 0.5f, 0.0f, 1.0f); NewtonCollision* const collisionB = NewtonCreateBox (world, size.m_x * 0.25f, size.m_x, size.m_x * 0.25f, 0, &matrix[0][0]); matrix.m_posit = dVector (0.0f, 0.0f, size.m_x * 0.5f, 1.0f); NewtonCollision* const collisionC = NewtonCreateBox (world, size.m_x * 0.25f, size.m_x * 0.25f, size.m_x, 0, &matrix[0][0]); collision = NewtonCreateCompoundCollision (world, 0); NewtonCompoundCollisionBeginAddRemove(collision); NewtonCompoundCollisionAddSubCollision (collision, collisionA); NewtonCompoundCollisionAddSubCollision (collision, collisionB); NewtonCompoundCollisionAddSubCollision (collision, collisionC); NewtonCompoundCollisionEndAddRemove(collision); NewtonDestroyCollision(collisionA); NewtonDestroyCollision(collisionB); NewtonDestroyCollision(collisionC); break; } default: dAssert (0); } dMatrix matrix (srcMatrix); matrix.m_front = matrix.m_front.Scale (1.0f / dSqrt (matrix.m_front % matrix.m_front)); matrix.m_right = matrix.m_front * matrix.m_up; matrix.m_right = matrix.m_right.Scale (1.0f / dSqrt (matrix.m_right % matrix.m_right)); matrix.m_up = matrix.m_right * matrix.m_front; NewtonCollisionSetMatrix(collision, &matrix[0][0]); return collision; }
static void CreateSimpleVoronoiShatter (DemoEntityManager* const scene) { // create a collision primitive // dVector size (2.0f, 2.0f, 2.0f); // dVector size = dVector (10.0f, 0.5f, 10.0f, 0.0f); dVector size = dVector (5.0f, 5.0f, 5.0f, 0.0f); NewtonWorld* const world = scene->GetNewton(); // NewtonCollision* const collision = CreateConvexCollision (world, GetIdentityMatrix(), size, _BOX_PRIMITIVE, 0); NewtonCollision* const collision = CreateConvexCollision (world, GetIdentityMatrix(), size, _CAPSULE_PRIMITIVE, 0); // NewtonCollision* const collision = CreateConvexCollision (world, GetIdentityMatrix(), size, _SPHERE_PRIMITIVE, 0); // NewtonCollision* const collision = CreateConvexCollision (world, GetIdentityMatrix(), size, _REGULAR_CONVEX_HULL_PRIMITIVE, 0); // NewtonCollision* const collision = CreateConvexCollision (world, GetIdentityMatrix(), size, _RANDOM_CONVEX_HULL_PRIMITIVE, 0); // create a newton mesh from the collision primitive NewtonMesh* const mesh = NewtonMeshCreateFromCollision(collision); // apply a simple Box Mapping int tex0 = LoadTexture("reljef.tga"); NewtonMeshApplyBoxMapping(mesh, tex0, tex0, tex0); // pepper the bing box of the mesh with random points dVector points[NUMBER_OF_ITERNAL_PARTS + 100]; int count = 0; while (count < NUMBER_OF_ITERNAL_PARTS) { dFloat x = RandomVariable(size.m_x); dFloat y = RandomVariable(size.m_y); dFloat z = RandomVariable(size.m_z); if ((x <= size.m_x) && (x >= -size.m_x) && (y <= size.m_y) && (y >= -size.m_y) && (z <= size.m_z) && (z >= -size.m_z)){ points[count] = dVector (x, y, z); count ++; } } count = 4; // Create the array of convex pieces from the mesh int interior = LoadTexture("KAMEN-stup.tga"); // int interior = LoadTexture("camo.tga"); dMatrix textureMatrix (GetIdentityMatrix()); textureMatrix[0][0] = 1.0f / size.m_x; textureMatrix[1][1] = 1.0f / size.m_y; NewtonMesh* const convexParts = NewtonMeshVoronoiDecomposition (mesh, count, sizeof (dVector), &points[0].m_x, interior, &textureMatrix[0][0]); // NewtonMesh* const convexParts = NewtonMeshConvexDecomposition (mesh, 1000000); #if 1 dScene xxxx(world); dScene::dTreeNode* const modelNode = xxxx.CreateSceneNode(xxxx.GetRootNode()); dScene::dTreeNode* const meshNode = xxxx.CreateMeshNode(modelNode); dMeshNodeInfo* const modelMesh = (dMeshNodeInfo*)xxxx.GetInfoFromNode(meshNode); modelMesh->ReplaceMesh (convexParts); xxxx.Serialize("../../../media/xxx.ngd"); #endif DemoEntity* const entity = new DemoEntity(NULL); entity->SetMatrix(*scene, dQuaternion(), dVector (0, 10, 0, 0)); entity->InterpolateMatrix (*scene, 1.0f); scene->Append (entity); DemoMesh* const mesh1 = new DemoMesh(convexParts); entity->SetMesh(mesh1); mesh1->Release(); /* DemoEntity* const entity2 = new DemoEntity(NULL); entity2->SetMatrix(*scene, dQuaternion(), dVector (0, 10, 0, 0)); entity2->InterpolateMatrix (*scene, 1.0f); scene->Append (entity2); DemoMesh* const mesh2 = new DemoMesh(mesh); entity2->SetMesh(mesh2); mesh2->Release(); */ // make sure the assets are released before leaving the function if (convexParts) { NewtonMeshDestroy (convexParts); } NewtonMeshDestroy (mesh); NewtonReleaseCollision(world, collision); }
static void DestroyThisBodyCallback (const NewtonBody* body, const NewtonJoint* contactJoint) { NewtonWorld* world; NewtonMesh* topMesh; NewtonMesh* bottomMesh; NewtonMesh* effectMesh; RenderPrimitive* srcPrimitive; dMatrix matrix; dFloat maxForce; dVector point; dVector dir0; dVector dir1; // Get the world; world = NewtonBodyGetWorld (body); // find a the strongest force maxForce = 0.0f; for (void* contact = NewtonContactJointGetFirstContact (contactJoint); contact; contact = NewtonContactJointGetNextContact (contactJoint, contact)) { dVector force; NewtonMaterial* material; material = NewtonContactGetMaterial (contact); NewtonMaterialGetContactForce (material, &force.m_x); if (force.m_x > maxForce) { dVector normal; NewtonMaterialGetContactPositionAndNormal(material, &point[0], &normal[0]); NewtonMaterialGetContactTangentDirections (material, &dir0[0], &dir0[0]); } } // get the visual primitive srcPrimitive = (RenderPrimitive*) NewtonBodyGetUserData (body); // get the effect mesh that is use to create the debris pieces effectMesh = srcPrimitive->m_specialEffect; // calculate the cut plane plane NewtonBodyGetMatrix (body, &matrix[0][0]); dMatrix clipMatrix (dgGrammSchmidt(dir0) * dYawMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f)) * dRollMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f))); clipMatrix.m_posit = point; clipMatrix.m_posit.m_w = 1.0f; clipMatrix = clipMatrix * matrix.Inverse(); // break the mesh into two pieces NewtonMeshClip (effectMesh, meshClipper, &clipMatrix[0][0], &topMesh, &bottomMesh); if (topMesh && bottomMesh) { dFloat volume; NewtonMesh* meshPartA = NULL; NewtonMesh* meshPartB = NULL; volume = NewtonConvexCollisionCalculateVolume (NewtonBodyGetCollision(body)); // the clipper was able to make a cut now we can create new debris piece for replacement dMatrix clipMatrix1 (dgGrammSchmidt(dir1) * dYawMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f)) * dRollMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f))); NewtonMeshClip (bottomMesh, meshClipper, &clipMatrix1[0][0], &meshPartA, &meshPartB); if (meshPartA && meshPartB) { // creat another split (you can make as many depend of the FPS) CreateDebriPiece (body, meshPartA, volume); CreateDebriPiece (body, meshPartB, volume); NewtonMeshDestroy(meshPartA); NewtonMeshDestroy(meshPartB); } else { CreateDebriPiece (body, bottomMesh, volume); } NewtonMeshDestroy(bottomMesh); dMatrix clipMatrix2 (dgGrammSchmidt(dir1) * dYawMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f)) * dRollMatrix(30.0f * 3.1416f/180.0f * RandomVariable(1.0f))); NewtonMeshClip (topMesh, meshClipper, &clipMatrix2[0][0], &meshPartA, &meshPartB); if (meshPartA && meshPartB) { // creat another split (you can make as many depend of the FPS) CreateDebriPiece (body, meshPartA, volume); CreateDebriPiece (body, meshPartB, volume); NewtonMeshDestroy(meshPartA); NewtonMeshDestroy(meshPartB); } else { CreateDebriPiece (body, topMesh, volume); } NewtonMeshDestroy(topMesh); // remove the old visual from graphics world SceneManager* system = (SceneManager*) NewtonWorldGetUserData(world); delete srcPrimitive; system->Remove(srcPrimitive); // finally destroy this body; NewtonDestroyBody(world, body); } }
StupidComplexOfConvexShapes (DemoEntityManager* const scene, int count) :DemoEntity (dGetIdentityMatrix(), NULL) ,m_rayP0(0.0f, 0.0f, 0.0f, 0.0f) ,m_rayP1(0.0f, 0.0f, 0.0f, 0.0f) { scene->Append(this); count = 40; //count = 1; const dFloat size = 0.5f; DemoMesh* gemetries[32]; NewtonCollision* collisionArray[32]; NewtonWorld* const world = scene->GetNewton(); int materialID = NewtonMaterialGetDefaultGroupID(world); // create a pool of predefined convex mesh // PrimitiveType selection[] = {_SPHERE_PRIMITIVE, _BOX_PRIMITIVE, _CAPSULE_PRIMITIVE, _CYLINDER_PRIMITIVE, _CONE_PRIMITIVE, _TAPERED_CAPSULE_PRIMITIVE, _TAPERED_CYLINDER_PRIMITIVE, _CHAMFER_CYLINDER_PRIMITIVE, _RANDOM_CONVEX_HULL_PRIMITIVE, _REGULAR_CONVEX_HULL_PRIMITIVE}; PrimitiveType selection[] = {_SPHERE_PRIMITIVE}; for (int i = 0; i < int (sizeof (collisionArray) / sizeof (collisionArray[0])); i ++) { int index = dRand() % (sizeof (selection) / sizeof (selection[0])); dVector shapeSize (size + RandomVariable (size / 2.0f), size + RandomVariable (size / 2.0f), size + RandomVariable (size / 2.0f), 0.0f); shapeSize = dVector(size, size, size, 0.0f); collisionArray[i] = CreateConvexCollision (world, dGetIdentityMatrix(), shapeSize, selection[index], materialID); gemetries[i] = new DemoMesh("geometry", collisionArray[i], "wood_4.tga", "wood_4.tga", "wood_1.tga"); } // make a large complex of plane by adding lost of these shapes at a random location and oriention; NewtonCollision* const compound = NewtonCreateCompoundCollision (world, materialID); NewtonCompoundCollisionBeginAddRemove(compound); for (int i = 0 ; i < count; i ++) { for (int j = 0 ; j < count; j ++) { 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 = size * (j - count / 2) + RandomVariable (size * 0.5f); float y = RandomVariable (size * 2.0f); float z = size * (i - count / 2) + RandomVariable (size * 0.5f); dMatrix matrix (dPitchMatrix (pitch) * dYawMatrix (yaw) * dRollMatrix (roll)); matrix.m_posit = dVector (x, y, z, 1.0f); int index = dRand() % (sizeof (selection) / sizeof (selection[0])); DemoEntity* const entity = new DemoEntity(matrix, this); entity->SetMesh(gemetries[index], dGetIdentityMatrix()); NewtonCollisionSetMatrix (collisionArray[index], &matrix[0][0]); NewtonCompoundCollisionAddSubCollision (compound, collisionArray[index]); } } NewtonCompoundCollisionEndAddRemove(compound); CreateSimpleBody (world, NULL, 0.0f, dGetIdentityMatrix(), compound, 0); // destroy all collision shapes after they are used NewtonDestroyCollision(compound); for (int i = 0; i < int (sizeof (collisionArray) / sizeof (collisionArray[0])); i ++) { gemetries[i]->Release(); NewtonDestroyCollision(collisionArray[i]); } // now make and array of collision shapes for convex casting by mouse point click an drag CreateCastingShapes(scene, size * 2.0f); }
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); }