hkpMoppBvTreeShape* FlatLand::createMoppShape() { hkpExtendedMeshShape* meshShape = createExtendedMeshShape(); hkpMoppBvTreeShape* mopp = createMoppShape(meshShape); meshShape->computeWeldingInfo(mopp, hkpWeldingUtility::WELDING_TYPE_ANTICLOCKWISE); return mopp; }
void WorldRayCastMultithreadedDemo::createBodies() { hkpRigidBodyCinfo rigidBodyInfo; rigidBodyInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(1, 1); hkPseudoRandomGenerator rand(100); // Note: with a SPU MOPP cache of 32768 bytes we can currently go to 811 objects and still get the broadphase onto SPU. for( int i = 0; i < 100; i++) { // All bodies created below are movable rigidBodyInfo.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA; // A collection of 100 rigid bodies is randomly created by generating an integer in the range(0,4) and choosing // one of the following shapes; MOPP, Convex Vertices, Box, Sphere or Triangle depending on the outcome: int shapeType = (int) (rand.getRandRange(0,1) * 5); switch(shapeType) { case 0: // Create MOPP body { hkpMoppBvTreeShape* shape = createMoppShape(); rigidBodyInfo.m_shape = shape; break; } // The construction of each of these is quite similar and for the purposes of this tutorial we will just outline // that of the Convex Vertices object, the code for which is presented below. // Create ConvexVertices body case 1: { // Data specific to this shape. int numVertices = 4; // 16 = 4 (size of "each float group", 3 for x,y,z, 1 for padding) * 4 (size of float) int stride = 16; float vertices[] = { // 4 vertices plus padding -2.0f, 1.0f, 1.0f, 0.0f, // v0 1.0f, 2.0f, 0.0f, 0.0f, // v1 0.0f, 0.0f, 3.0f, 0.0f, // v2 1.0f, -1.0f, 0.0f, 0.0f // v3 }; hkpConvexVerticesShape* shape; hkArray<hkVector4> planeEquations; hkGeometry geom; { hkStridedVertices stridedVerts; { stridedVerts.m_numVertices = numVertices; stridedVerts.m_striding = stride; stridedVerts.m_vertices = vertices; } hkGeometryUtility::createConvexGeometry( stridedVerts, geom, planeEquations ); { stridedVerts.m_numVertices = geom.m_vertices.getSize(); stridedVerts.m_striding = sizeof(hkVector4); stridedVerts.m_vertices = &(geom.m_vertices[0](0)); } shape = new hkpConvexVerticesShape(stridedVerts, planeEquations); } rigidBodyInfo.m_shape = shape; break; } // Create Box body case 2: { // Data specific to this shape. hkVector4 halfExtents = hkVector4(1.0f, 2.0f, 3.0f); hkpBoxShape* shape = new hkpBoxShape(halfExtents ); rigidBodyInfo.m_shape = shape; break; } // Create Sphere body case 3: { hkReal radius = rand.getRandRange(0.5f, 2.0f); hkpConvexShape* shape = new hkpSphereShape(radius); rigidBodyInfo.m_shape = shape; break; } // Create Triangle body case 4: { hkVector4 a(-1.5f, -1.5f, 0.0f); hkVector4 b(1.5f, -1.5f, 0.0f); hkVector4 c(0.0f, 1.5f, 0.0f); hkpTriangleShape* shape = new hkpTriangleShape(a, b, c); rigidBodyInfo.m_shape = shape; break; } } // end case // As usual we fill out the hkpRigidBodyCinfo 'blueprint' for the rigidbody, with the code above specifying // the necessary information for the 'm_shape' member. To create a hkpConvexVerticesShape we need a set of vertices and // we must generate a set of plane equations from these points. As you can see from the code this is all performed // prior to instantiating the shape. // Fake Inertia tensor for simplicity, assume it's a unit cube { hkVector4 halfExtents(0.5f, 0.5f, 0.5f); hkReal mass = 10.0f; hkpMassProperties massProperties; hkpInertiaTensorComputer::computeBoxVolumeMassProperties(halfExtents, mass, massProperties); rigidBodyInfo.m_inertiaTensor = massProperties.m_inertiaTensor; rigidBodyInfo.m_centerOfMass = massProperties.m_centerOfMass; rigidBodyInfo.m_mass = massProperties.m_mass; } // The object is then assigned a random position, orientation and angular velocity and added to the world: rigidBodyInfo.m_position.set( rand.getRandRange(-10.0f, 10.0f), rand.getRandRange(-10.0f, 10.0f), rand.getRandRange(0.0f, -40.0f)); rand.getRandomRotation( rigidBodyInfo.m_rotation ); rigidBodyInfo.m_collisionFilterInfo = hkpGroupFilterSetup::LAYER_DEBRIS; hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo); rigidBodyInfo.m_shape->removeReference(); // Give them an initial velocity hkVector4 angularVel(rand.getRandRange(-1.0f, 1.0f), rand.getRandRange(-1.0f, 1.0f), rand.getRandRange(-1.0f, 1.0f)); rigidBody->setAngularVelocity(angularVel); rigidBody->setAngularDamping(0.0f); m_world->addEntity(rigidBody); rigidBody->removeReference(); } }
MoppInstancingDemo::MoppInstancingDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env) { // Disable face culling setGraphicsState(HKG_ENABLED_CULLFACE, false); // // Setup the camera // { hkVector4 from(20.0f, 20.0f, -60.0f); hkVector4 to ( 0.0f, 0.0f, 0.0f); hkVector4 up ( 0.0f, 1.0f, 0.0f); setupDefaultCameras( env, from, to, up ); } // // Create the world // { hkpWorldCinfo info; info.m_gravity.set(0.0f, -9.5f, 0.0f); info.setBroadPhaseWorldSize(150.0f); info.setupSolverInfo( hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM ); m_world = new hkpWorld( info ); m_world->lock(); // Register ALL agents (though some may not be necessary) hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher()); setupGraphics(); } // // create the ground mopps // See the comments on createMoppShape() below. // m_originalMopp = createMoppShape(); m_smallMopp = createScaledMopp(m_originalMopp, .75f); m_bigMopp = createScaledMopp(m_originalMopp, 1.5f); hkpShape* shapes[3] = { m_originalMopp, m_smallMopp, m_bigMopp}; hkReal offsets[3] = {0.0f, -20.0f, 30.0f}; // // Create the fixed rigid bodies and add them to the world // for (int i=0; i<3; i++) { hkpRigidBodyCinfo groundInfo; groundInfo.m_motionType = hkpMotion::MOTION_FIXED; groundInfo.m_shape = shapes[i]; groundInfo.m_position.set(offsets[i],-2.6f,0.0f); m_fixedBodies[i] = new hkpRigidBody(groundInfo); m_world->addEntity( m_fixedBodies[i] ); // Drop some boxes on the mesh hkVector4 center(offsets[i] - 1.0f, 0, 2.5f); addBoxPile(10, center); } m_world->unlock(); }
hkpMoppBvTreeShape* TowerLand::createMoppShape() { hkpExtendedMeshShape* meshShape = createMeshShape(); return createMoppShape(meshShape); }
void BenchmarkSuiteDemo::CreatePhysicsTerrain( hkpWorld* world, const int side, float deltaHeight, float triangleEdgeLen ) { hkpSimpleMeshShape* meshShape = new hkpSimpleMeshShape( 0.05f /*radius*/); { meshShape->m_vertices.setSize( side * side ); for(int x = 0; x < side; x++) { for (int y = 0; y < side; y++ ) { float height = 0.0f; if ( (x&1) && (y&1) ) { height = -deltaHeight; } hkVector4 vertex ( triangleEdgeLen * (x * 1.0f - (side-1) * 0.5f), triangleEdgeLen * height, triangleEdgeLen * (y * 1.0f - (side-1) * 0.5f)); meshShape->m_vertices[x*side + y] = vertex ; } } } { meshShape->m_triangles.setSize( (side-1) * (side-1) * 2); int corner = 0; int curTri = 0; for(int i = 0; i < side - 1; i++) { for (int j = 0; j < side - 1; j++ ) { meshShape->m_triangles[curTri].m_a = corner+1; meshShape->m_triangles[curTri].m_b = corner+side; meshShape->m_triangles[curTri].m_c = corner; curTri++; meshShape->m_triangles[curTri].m_a = corner+side+1; meshShape->m_triangles[curTri].m_b = corner+side; meshShape->m_triangles[curTri].m_c = corner+1; curTri++; corner++; } corner++; } } hkpStorageExtendedMeshShape* extendedMesh = new hkpStorageExtendedMeshShape(); hkpExtendedMeshShape::TrianglesSubpart part; part.m_numTriangleShapes = meshShape->m_triangles.getSize(); part.m_numVertices = meshShape->m_vertices.getSize(); part.m_vertexBase = (float*)meshShape->m_vertices.begin(); part.m_stridingType = hkpExtendedMeshShape::INDICES_INT32; part.m_vertexStriding = sizeof(hkVector4); part.m_indexBase = meshShape->m_triangles.begin(); part.m_indexStriding = sizeof(hkpSimpleMeshShape::Triangle); extendedMesh->addTrianglesSubpart( part ); // No longer need the simple mesh meshShape->removeReference(); hkpRigidBodyCinfo ci; hkpShape* moppShape = createMoppShape( extendedMesh ); extendedMesh->removeReference(); ci.m_shape = moppShape; ci.m_restitution = 0.5f; ci.m_friction = 0.3f; ci.m_position.set( 0.0f, 0.0f, 0.0f ); ci.m_motionType = hkpMotion::MOTION_FIXED; world->addEntity( new hkpRigidBody( ci ) )->removeReference(); moppShape->removeReference(); }
ChunkMoppDemo::ChunkMoppDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env) { //setGraphicsState(HKG_ENABLED_WIREFRAME, true); // // Setup the camera // { hkVector4 from(55.0f, 50.0f, 55.0f); hkVector4 to ( 0.0f, 0.0f, 0.0f); hkVector4 up ( 0.0f, 1.0f, 0.0f); setupDefaultCameras(env, from, to, up, 0.1f, 20000.0f); } // // Create the world // { hkpWorldCinfo worldInfo; { worldInfo.m_gravity.set(0.0f, -9.81f, 0.0f); worldInfo.setBroadPhaseWorldSize(10000.0f); worldInfo.setupSolverInfo( hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM ); worldInfo.m_enableDeactivation = false; } m_world = new hkpWorld(worldInfo); m_world->lock(); // Register ALL agents (though some may not be necessary) hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher()); setupGraphics(); } hkpShapeCollection* meshShape = createMeshShape( VERTS_PER_SIDE, m_delayedCleanup ); m_shape = createMoppShape( meshShape, true ); m_shape->getAabb( hkTransform::getIdentity(), 0.1f, m_bounds ); // // create the ground mopp // { hkpRigidBodyCinfo terrainInfo; { hkVector4 size(100.0f, 1.0f, 100.0f); terrainInfo.m_shape = m_shape; terrainInfo.m_motionType = hkpMotion::MOTION_FIXED; terrainInfo.m_friction = 0.5f; hkpRigidBody* terrainBody = new hkpRigidBody(terrainInfo); m_world->addEntity(terrainBody); terrainBody->removeReference(); } terrainInfo.m_shape->removeReference(); } hkVector4 halfExtents; hkVector4 centre; { m_bounds.getHalfExtents( halfExtents ); m_bounds.getCenter( centre ); m_minIndex = (halfExtents(0) < halfExtents(1)) ? ((halfExtents(0) < halfExtents(2)) ? 0 : 2) : ((halfExtents(1) < halfExtents(2)) ? 1 : 2) ; } // Setup the camera { hkVector4 up; up.setZero4(); up(m_minIndex) = 1.0f; hkVector4 from; from.setAddMul4( m_bounds.m_max, up, 5.0f); setupDefaultCameras(env, from, centre, up, 0.1f, 10000.0f); } // // Create objects at random coordinates // { hkVector4 size(0.5f, 0.5f, 0.5f); hkpBoxShape* boxShape = new hkpBoxShape(size); hkpRigidBodyCinfo boxInfo; { boxInfo.m_mass = 1.0f; boxInfo.m_shape = boxShape; boxInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA; } hkPseudoRandomGenerator random(15); // // create the boxes // { hkVector4 range; range.setSub4( m_bounds.m_max, m_bounds.m_min ); range.mul4( 1.0f ); const int numObjects = 500; for (int i = 0; i < numObjects; i++) { hkVector4 pos; random.getRandomVector11(pos); pos.mul4(0.1f); pos.mul4(range); pos( m_minIndex ) += m_bounds.m_max( m_minIndex ) + i * (range(m_minIndex)) / numObjects + 4.0f; boxInfo.m_position = pos; hkpRigidBody* shape; shape = new hkpRigidBody(boxInfo); shape->setMaxLinearVelocity( 30 ); m_world->addEntity(shape); shape->removeReference(); } } boxShape->removeReference(); } m_world->unlock(); m_time = 0.0f; }