static void CreateVisualEntity (DemoEntityManager* const scene, NewtonBody* const body) { dMatrix matrix; NewtonBodyGetMatrix(body, &matrix[0][0]); DemoEntity* const visualEntity = new DemoEntity(matrix, NULL); scene->Append(visualEntity); // set the entiry as the user data; NewtonBodySetUserData (body, visualEntity); // create the mesh geometry and attach it to the entity DemoMesh* const visualMesh = new DemoMesh ("fraturedMainMesh"); visualEntity->SetMesh (visualMesh, dGetIdentityMatrix()); visualMesh->Release(); // create the mesh and set the vertex array, but not the sub meshes NewtonCollision* const fracturedCompoundCollision = NewtonBodyGetCollision(body); dAssert (NewtonCollisionGetType(fracturedCompoundCollision) == SERIALIZE_ID_FRACTURED_COMPOUND); // add the vertex data NewtonFracturedCompoundMeshPart* const mainMesh = NewtonFracturedCompoundGetMainMesh (fracturedCompoundCollision); AddMeshVertexwData (visualMesh, mainMesh, fracturedCompoundCollision); // now add the sub mesh by calling the call back OnReconstructMainMeshCallBack (body, mainMesh, fracturedCompoundCollision); }
void RayCastCompoundsAllSubShapes(const dVector& origin, const dVector& end) { m_param = 1.0f; m_body = NULL; NewtonWorld* const world = GetWorld(); NewtonWorldRayCast(world, &origin[0], &end[0], PickCompound, this, NULL, 0); if (m_body) { // we found a compound, find all sub shape on teh path of the ray dMatrix matrix; NewtonBodyGetMatrix(m_body, &matrix[0][0]); dVector localP0(matrix.UntransformVector(origin)); dVector localP1(matrix.UntransformVector(end)); NewtonCollision* const compoundCollision = NewtonBodyGetCollision(m_body); dAssert(NewtonCollisionGetType(compoundCollision) == SERIALIZE_ID_COMPOUND); for (void* node = NewtonCompoundCollisionGetFirstNode(compoundCollision); node; node = NewtonCompoundCollisionGetNextNode(compoundCollision, node)) { dVector normal; dLong attribute; NewtonCollision* const subShape = NewtonCompoundCollisionGetCollisionFromNode(compoundCollision, node); dFloat xxx = NewtonCollisionRayCast(subShape, &localP0[0], &localP1[0], &normal[0], &attribute); if (xxx < 1.0f) { dTrace (("sub shape hit\n")) } } } }
static void OnReconstructMainMeshCallBack (NewtonBody* const body, NewtonFracturedCompoundMeshPart* const mainMesh, const NewtonCollision* const fracturedCompoundCollision) { DemoEntity* const entity = (DemoEntity*)NewtonBodyGetUserData(body); DemoMesh* const visualMesh = (DemoMesh*)entity->GetMesh(); dAssert (visualMesh->IsType(DemoMesh::GetRttiType())); dAssert (NewtonCollisionGetType(fracturedCompoundCollision) == SERIALIZE_ID_FRACTURED_COMPOUND); DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(NewtonBodyGetWorld(body)); dAssert (scene); visualMesh->RemoveAll(); for (void* segment = NewtonFracturedCompoundMeshPartGetFirstSegment(mainMesh); segment; segment = NewtonFracturedCompoundMeshPartGetNextSegment (segment)) { DemoSubMesh* const subMesh = visualMesh->AddSubMesh(); int material = NewtonFracturedCompoundMeshPartGetMaterial (segment); int indexCount = NewtonFracturedCompoundMeshPartGetIndexCount (segment); subMesh->m_textureHandle = AddTextureRef ((GLuint)material); subMesh->m_shader = scene->GetShaderCache().m_diffuseEffect; subMesh->AllocIndexData (indexCount); subMesh->m_indexCount = NewtonFracturedCompoundMeshPartGetIndexStream (fracturedCompoundCollision, mainMesh, segment, (int*)subMesh->m_indexes); } visualMesh->OptimizeForRender(); }
static dFloat PickCompound(const NewtonBody* const body, const NewtonCollision* const shapeHit, const dFloat* const hitContact, const dFloat* const hitNormal, dLong collisionID, void* const userData, dFloat intersectParam) { NewtonCollision* const collision = NewtonBodyGetCollision(body); if (NewtonCollisionGetType(collision) == SERIALIZE_ID_COMPOUND) { dShowAllSubShapes* const me = (dShowAllSubShapes*)userData; if (intersectParam < me->m_param) { me->m_param = intersectParam; me->m_body = body; return intersectParam; } } return 1.2f; }
void DebugRenderWorldCollision (const NewtonWorld* const world, DEBUG_DRAW_MODE mode) { glDisable(GL_TEXTURE_2D); if (mode == m_lines) { glDisable (GL_LIGHTING); glBegin(GL_LINES); } else { glBegin(GL_TRIANGLES); } for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { NewtonCollision* const collision = NewtonBodyGetCollision(body); int collisionType = NewtonCollisionGetType (collision); switch (collisionType) { //SERIALIZE_ID_SPHERE: //SERIALIZE_ID_CAPSULE: //SERIALIZE_ID_CHAMFERCYLINDER: //SERIALIZE_ID_TAPEREDCAPSULE: //SERIALIZE_ID_CYLINDER: //SERIALIZE_ID_TAPEREDCYLINDER: //SERIALIZE_ID_BOX: //SERIALIZE_ID_CONE: //SERIALIZE_ID_CONVEXHULL: //SERIALIZE_ID_NULL: //SERIALIZE_ID_COMPOUND: //SERIALIZE_ID_CLOTH_PATCH: //SERIALIZE_ID_DEFORMABLE_SOLID: // case SERIALIZE_ID_TREE: // case SERIALIZE_ID_SCENE: // case SERIALIZE_ID_USERMESH: case SERIALIZE_ID_HEIGHTFIELD: // case SERIALIZE_ID_COMPOUND_BREAKABLE: break; default: DebugShowBodyCollision (body, mode); } } glEnd(); glDisable (GL_LIGHTING); glBegin(GL_LINES); glColor3f(1.0f, 1.0f, 0.0f); for (int i = 0; i < g_debugDisplayCount; i += 2) { glVertex3f (g_debugDisplayCallback[i].m_x, g_debugDisplayCallback[i].m_y, g_debugDisplayCallback[i].m_z); glVertex3f (g_debugDisplayCallback[i+1].m_x, g_debugDisplayCallback[i+1].m_y, g_debugDisplayCallback[i+1].m_z); } glEnd(); }
void Render(DemoEntityManager* const scene) { NewtonCollision* const deformableCollision = NewtonBodyGetCollision(m_body); dAssert((NewtonCollisionGetType(deformableCollision) == SERIALIZE_ID_CLOTH_PATCH) || (NewtonCollisionGetType(deformableCollision) == SERIALIZE_ID_DEFORMABLE_SOLID)); const dFloat* const particles = NewtonDeformableMeshGetParticleArray(deformableCollision); int stride = NewtonDeformableMeshGetParticleStrideInBytes(deformableCollision) / sizeof (dFloat); // calculate vertex skinning for (int i = 0; i < m_vertexCount; i++) { int index = m_indexMap[i] * stride; m_vertex[i * 3 + 0] = particles[index + 0]; m_vertex[i * 3 + 1] = particles[index + 1]; m_vertex[i * 3 + 2] = particles[index + 2]; } DemoMesh::Render(scene); }
void DemoEntityManager::BodyDeserialization (NewtonBody* const body, void* const bodyUserData, NewtonDeserializeCallback deserializecallback, void* const serializeHandle) { int size; char bodyIndentification[256]; deserializecallback (serializeHandle, &size, sizeof (size)); deserializecallback (serializeHandle, bodyIndentification, size); // get the world and the scene form the world user data NewtonWorld* const world = NewtonBodyGetWorld(body); DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(world); // here we attach a visual object to the entity, dMatrix matrix; NewtonBodyGetMatrix(body, &matrix[0][0]); DemoEntity* const entity = new DemoEntity(matrix, NULL); scene->Append (entity); NewtonBodySetUserData (body, entity); NewtonBodySetTransformCallback(body, DemoEntity::TransformCallback); NewtonBodySetForceAndTorqueCallback(body, PhysicsApplyGravityForce); NewtonCollision* const collision = NewtonBodyGetCollision(body); #ifdef USE_STATIC_MESHES_DEBUG_COLLISION if (NewtonCollisionGetType(collision) == SERIALIZE_ID_TREE) { NewtonStaticCollisionSetDebugCallback (collision, ShowMeshCollidingFaces); } #endif //for visual mesh we will collision mesh and convert it to a visual mesh using NewtonMesh dTree <DemoMeshInterface*, const void*>* const cache = (dTree <DemoMeshInterface*, const void*>*)bodyUserData; dTree <DemoMeshInterface*, const void*>::dTreeNode* node = cache->Find(NewtonCollisionDataPointer (collision)); if (!node) { DemoMeshInterface* mesh = new DemoMesh(bodyIndentification, collision, NULL, NULL, NULL); node = cache->Insert(mesh, NewtonCollisionDataPointer (collision)); } else { node->GetInfo()->AddRef(); } DemoMeshInterface* const mesh = node->GetInfo(); entity->SetMesh(mesh, dGetIdentityMatrix()); mesh->Release(); }
static void OnEmitFracturedCompound (NewtonBody* const fracturedCompound) { NewtonWorld* const world = NewtonBodyGetWorld(fracturedCompound); DemoEntityManager* const scene = (DemoEntityManager*)NewtonWorldGetUserData(world); // set the force an torque call back NewtonBodySetForceAndTorqueCallback (fracturedCompound, PhysicsApplyGravityForce); // set the transform callback NewtonBodySetTransformCallback (fracturedCompound, DemoEntity::TransformCallback); // create the visual entity and mesh, and set the use data dMatrix matrix; NewtonBodyGetMatrix (fracturedCompound, &matrix[0][0]); DemoEntity* const visualChunkEntity = new DemoEntity(matrix, NULL); scene->Append(visualChunkEntity); NewtonBodySetUserData (fracturedCompound, visualChunkEntity); // create the mesh geometry and attach it to the entity DemoMesh* const visualChunkMesh = new DemoMesh ("fracturedChuckMesh"); visualChunkEntity->SetMesh (visualChunkMesh, dGetIdentityMatrix()); visualChunkMesh->Release(); // get the fractured compound mesh from the body NewtonCollision* const fracturedCompoundCollision = NewtonBodyGetCollision(fracturedCompound); dAssert (NewtonCollisionGetType(fracturedCompoundCollision) == SERIALIZE_ID_FRACTURED_COMPOUND); // add the vertex data NewtonFracturedCompoundMeshPart* const mainMesh = NewtonFracturedCompoundGetMainMesh (fracturedCompoundCollision); AddMeshVertexwData (visualChunkMesh, mainMesh, fracturedCompoundCollision); // add the mesh indices OnReconstructMainMeshCallBack (fracturedCompound, mainMesh, fracturedCompoundCollision); }
void Render(DemoEntityManager* const scene) { NewtonCollision* const deformableCollision = NewtonBodyGetCollision(m_body); dAssert((NewtonCollisionGetType(deformableCollision) == SERIALIZE_ID_CLOTH_PATCH) || (NewtonCollisionGetType(deformableCollision) == SERIALIZE_ID_DEFORMABLE_SOLID)); const dFloat* const particles = NewtonDeformableMeshGetParticleArray(deformableCollision); int stride = NewtonDeformableMeshGetParticleStrideInBytes(deformableCollision) / sizeof (dFloat); // calculate vertex skinning for (int i = 0; i < m_vertexCount; i++) { int index = m_indexMap[i] * stride; m_vertex[i * 3 + 0] = particles[index + 0]; m_vertex[i * 3 + 1] = particles[index + 1]; m_vertex[i * 3 + 2] = particles[index + 2]; // clear the normal for next loop m_normal[i * 3 + 0] = 0.0f; m_normal[i * 3 + 1] = 0.0f; m_normal[i * 3 + 2] = 0.0f; } // calculate vertex normals int normalStride = 3; for (DemoMesh::dListNode* segmentNode = GetFirst(); segmentNode; segmentNode = segmentNode->GetNext()) { const DemoSubMesh& subSegment = segmentNode->GetInfo(); for (int i = 0; i < subSegment.m_indexCount; i += 3) { int i0 = subSegment.m_indexes[i + 0] * normalStride; int i1 = subSegment.m_indexes[i + 1] * normalStride; int i2 = subSegment.m_indexes[i + 2] * normalStride; dVector p0(m_vertex[i0], m_vertex[i0 + 1], m_vertex[i0 + 2], 0.0f); dVector p1(m_vertex[i1], m_vertex[i1 + 1], m_vertex[i1 + 2], 0.0f); dVector p2(m_vertex[i2], m_vertex[i2 + 1], m_vertex[i2 + 2], 0.0f); dVector p10(p1 - p0); dVector p20(p2 - p0); dVector normal(p10.CrossProduct(p20)); normal = normal.Scale(1.0f / dSqrt(normal.DotProduct3(normal))); m_normal[i0 + 0] += normal.m_x; m_normal[i0 + 1] += normal.m_y; m_normal[i0 + 2] += normal.m_z; m_normal[i1 + 0] += normal.m_x; m_normal[i1 + 1] += normal.m_y; m_normal[i1 + 2] += normal.m_z; m_normal[i2 + 0] += normal.m_x; m_normal[i2 + 1] += normal.m_y; m_normal[i2 + 2] += normal.m_z; } } // normalize all the normals for (int i = 0; i < m_vertexCount; i++) { dVector n(m_normal[i * 3 + 0], m_normal[i * 3 + 1], m_normal[i * 3 + 2], 0.0f); n = n.Scale(1.0f / dSqrt(n.DotProduct3(n))); m_normal[i * 3 + 0] = n.m_x; m_normal[i * 3 + 1] = n.m_y; m_normal[i * 3 + 2] = n.m_z; } glDisable(GL_CULL_FACE); DemoMesh::Render(scene); glEnable(GL_CULL_FACE); }
void CustomVehicleController::Init (NewtonCollision* const chassisShape, const dMatrix& vehicleFrame, dFloat mass, const dVector& gravityVector) { m_finalized = false; m_externalContactStatesCount = 0; m_sleepCounter = VEHICLE_SLEEP_COUNTER; m_freeContactList = m_externalContactStatesPoll.GetFirst(); CustomVehicleControllerManager* const manager = (CustomVehicleControllerManager*) GetManager(); NewtonWorld* const world = manager->GetWorld(); // create a compound collision NewtonCollision* const vehShape = NewtonCreateCompoundCollision(world, 0); NewtonCompoundCollisionBeginAddRemove(vehShape); // if the shape is a compound collision ass all the pieces one at a time int shapeType = NewtonCollisionGetType (chassisShape); if (shapeType == SERIALIZE_ID_COMPOUND) { for (void* node = NewtonCompoundCollisionGetFirstNode(chassisShape); node; node = NewtonCompoundCollisionGetNextNode (chassisShape, node)) { NewtonCollision* const subCollision = NewtonCompoundCollisionGetCollisionFromNode(chassisShape, node); NewtonCompoundCollisionAddSubCollision (vehShape, subCollision); } } else { dAssert ((shapeType == SERIALIZE_ID_CONVEXHULL) || (shapeType == SERIALIZE_ID_BOX)); NewtonCompoundCollisionAddSubCollision (vehShape, chassisShape); } NewtonCompoundCollisionEndAddRemove (vehShape); // create the rigid body for this vehicle dMatrix locationMatrix (dGetIdentityMatrix()); m_body = NewtonCreateDynamicBody(world, vehShape, &locationMatrix[0][0]); // set vehicle mass, inertia and center of mass NewtonBodySetMassProperties (m_body, mass, vehShape); // set linear and angular drag to zero dVector drag(0.0f, 0.0f, 0.0f, 0.0f); NewtonBodySetLinearDamping(m_body, 0); NewtonBodySetAngularDamping(m_body, &drag[0]); // destroy the collision help shape NewtonDestroyCollision (vehShape); // initialize vehicle internal components NewtonBodyGetCentreOfMass (m_body, &m_chassisState.m_com[0]); m_chassisState.m_comOffset = dVector (0.0f, 0.0f, 0.0f, 0.0f); m_chassisState.m_gravity = gravityVector; m_chassisState.m_gravityMag = dSqrt (gravityVector % gravityVector); m_chassisState.Init(this, vehicleFrame); // m_stateList.Append(&m_staticWorld); m_stateList.Append(&m_chassisState); // create the normalized size tire shape m_tireCastShape = NewtonCreateChamferCylinder(world, 0.5f, 1.0f, 0, NULL); // initialize all components to empty m_engine = NULL; m_brakes = NULL; m_steering = NULL; m_handBrakes = NULL; SetDryRollingFrictionTorque (100.0f/4.0f); SetAerodynamicsDownforceCoefficient (0.5f * dSqrt (gravityVector % gravityVector), 60.0f * 0.447f); }
void PrecessingTops (DemoEntityManager* const scene) { scene->CreateSkyBox(); // customize the scene after loading // set a user friction variable in the body for variable friction demos // later this will be done using LUA script dMatrix offsetMatrix (dGetIdentityMatrix()); CreateLevelMesh (scene, "flatPlane.ngd", 1); dVector location (0.0f, 0.0f, 0.0f, 0.0f); dVector size (3.0f, 2.0f, 0.0f, 0.0f); // create an array of cones const int count = 10; // all shapes use the x axis as the axis of symmetry, to make an upright cone we apply a 90 degree rotation local matrix dMatrix shapeOffsetMatrix (dRollMatrix(-3.141592f/2.0f)); AddPrimitiveArray(scene, 50.0f, location, size, count, count, 5.0f, _CONE_PRIMITIVE, 0, shapeOffsetMatrix); // till the cont 30 degrees, and apply a local high angular velocity dMatrix matrix (dRollMatrix (-25.0f * 3.141592f / 180.0f)); dVector omega (0.0f, 50.0f, 0.0f); omega = matrix.RotateVector (omega); dVector damp (0.0f, 0.0f, 0.0f, 0.0f); int topscount = 0; NewtonBody* array[count * count]; NewtonWorld* const world = scene->GetNewton(); for (NewtonBody* body = NewtonWorldGetFirstBody(world); body; body = NewtonWorldGetNextBody(world, body)) { NewtonCollision* const collision = NewtonBodyGetCollision(body); dVector com; if (NewtonCollisionGetType (collision) == SERIALIZE_ID_CONE) { array[topscount] = body; topscount ++; } } for (int i = 0; i < topscount ; i ++) { dMatrix bodyMatrix; NewtonBody* const body = array[i]; NewtonBodyGetMatrix(body, &bodyMatrix[0][0]); matrix.m_posit = bodyMatrix.m_posit; matrix.m_posit.m_y += 1.0f; NewtonBodySetMatrix(body, &matrix[0][0]); dFloat Ixx; dFloat Iyy; dFloat Izz; dFloat mass; NewtonBodyGetMassMatrix(body, &mass, &Ixx, &Iyy, &Izz); NewtonBodySetMassMatrix(body, mass, Ixx, Iyy * 8.0f, Izz); NewtonBodySetOmega (body, &omega[0]); NewtonBodySetAutoSleep (body, 0); NewtonBodySetLinearDamping(body, 0.0f); NewtonBodySetAngularDamping (body, &damp[0]); } // place camera into position dMatrix camMatrix (dGetIdentityMatrix()); dQuaternion rot (camMatrix); dVector origin (-40.0f, 5.0f, 0.0f, 0.0f); scene->SetCameraMatrix(rot, origin); }