void VehicleManagerDemo::buildLandscape() { if (1) { // // Create the ground we'll drive on. // { hkpRigidBodyCinfo groundInfo; // // Set the if condition to 0 if you want to test the heightfield // if ( 1 ) { FlatLand* fl = new FlatLand(); m_track = fl; groundInfo.m_shape = fl->createMoppShapeForSpu(); groundInfo.m_position.set(5.0f, -2.0f, 5.0f); groundInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo( GROUND_LAYER, 0 ); } { groundInfo.m_motionType = hkpMotion::MOTION_FIXED; groundInfo.m_friction = 0.5f; hkpRigidBody* groundbody = new hkpRigidBody(groundInfo); m_world->addEntity(groundbody); groundbody->removeReference(); } groundInfo.m_shape->removeReference(); } } if (1) { hkVector4 halfExtents(10.0f, 0.1f, 10.0f); hkVector4 startPos(-240.0f, -7.8f, 0.0f); hkVector4 diffPos (30.0f, 0.0f, 0.0f); createDodgeBoxes(5, halfExtents, startPos, diffPos); } if (1) { hkVector4 halfExtents(10.0f, 0.05f, 10.0f); hkVector4 startPos(-240.0f, -7.85f, 30.0f); hkVector4 diffPos (30.0f, 0.0f, 0.0f); createDodgeBoxes(5, halfExtents, startPos, diffPos); } if (1) { int gridSize = 1 + int(hkMath::sqrt( hkReal(m_env->m_cpuMhz/100) )); createRagdollGrid( m_world, gridSize, gridSize, 4.0f, 4.0f, m_ragdolls ); } }
//creates and registers a new square rigidbody - assumes position is set btRigidBody* PhysicsEngine::createBoxRigidBody(Entity* entity, const vector3df& scale, float mass){ //create rigidbody's transform using entity's position btTransform transform; transform.setIdentity(); vector3df pos = entity->getNode()->getPosition(); transform.setOrigin(btVector3(pos.X, pos.Y, pos.Z)); //create the motionState of the object btDefaultMotionState* motionState = new btDefaultMotionState(transform); //create the bounding volume btVector3 halfExtents(scale.X*0.5f, scale.Y*0.5f, scale.Z*0.5f); btCollisionShape* shape = new btBoxShape(halfExtents); //create intertia info for the shape btVector3 localinertia; shape->calculateLocalInertia(mass, localinertia); //now create the rigidBody btRigidBody* rigidBody = new btRigidBody(mass, motionState, shape, localinertia); //add a pointer to rigidBody pointing to associated Entity rigidBody->setUserPointer(entity); //add the rigidBody to the world _world->addRigidBody(rigidBody); //and add to the list of rigidBodies _rigidBodies.push_back(rigidBody); //finally return created body return rigidBody; }
void btCapsuleShape::calculateLocalInertia(btScalar mass,btVector3& inertia) const { //as an approximation, take the inertia of the box that bounds the spheres btTransform ident; ident.setIdentity(); btScalar radius = getRadius(); btVector3 halfExtents(radius,radius,radius); halfExtents[getUpAxis()]+=getHalfHeight(); btScalar margin = CONVEX_DISTANCE_MARGIN; btScalar lx=btScalar(2.)*(halfExtents[0]+margin); btScalar ly=btScalar(2.)*(halfExtents[1]+margin); btScalar lz=btScalar(2.)*(halfExtents[2]+margin); const btScalar x2 = lx*lx; const btScalar y2 = ly*ly; const btScalar z2 = lz*lz; const btScalar scaledmass = mass * btScalar(.08333333); inertia[0] = scaledmass * (y2+z2); inertia[1] = scaledmass * (x2+z2); inertia[2] = scaledmass * (x2+y2); }
void BasicDemo::createGround(int cubeShapeId) { { btVector4 color(0.3,0.3,1,1); btVector4 halfExtents(50,50,50,1); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-50,0)); m_glApp->m_instancingRenderer->registerGraphicsInstance(cubeShapeId,groundTransform.getOrigin(),groundTransform.getRotation(),color,halfExtents); btBoxShape* groundShape = new btBoxShape(btVector3(btScalar(halfExtents[0]),btScalar(halfExtents[1]),btScalar(halfExtents[2]))); //We can also use DemoApplication::localCreateRigidBody, but for clarity it is provided here: { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body); } } }
hkpRigidBody* GameUtils::createBox(const hkVector4& size, const hkReal mass, const hkVector4& position, hkReal radius) { hkVector4 halfExtents(size(0) * 0.5f, size(1) * 0.5f, size(2) * 0.5f); hkpBoxShape* cube = new hkpBoxShape(halfExtents, radius); //create a rigid body construction template hkpRigidBodyCinfo boxInfo; if (mass != 0.f) { boxInfo.m_mass = mass; hkMassProperties massProperties; hkpInertiaTensorComputer::computeBoxVolumeMassProperties(halfExtents, mass, massProperties); boxInfo.m_inertiaTensor = massProperties.m_inertiaTensor; boxInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA; } else { boxInfo.m_motionType = hkpMotion::MOTION_FIXED; } boxInfo.m_rotation.setIdentity(); boxInfo.m_shape = cube; boxInfo.m_position = position; //create a rigid body (using the template above) hkpRigidBody* boxRigidBody = new hkpRigidBody(boxInfo); cube->removeReference(); return boxRigidBody; }
void ShapeInfoTests::testBoxShape() { ShapeInfo info; glm::vec3 halfExtents(1.23f, 4.56f, 7.89f); info.setBox(halfExtents); DoubleHashKey key = info.getHash(); btCollisionShape* shape = ShapeInfoUtil::createShapeFromInfo(info); if (!shape) { std::cout << __FILE__ << ":" << __LINE__ << " ERROR: NULL Box shape" << std::endl; } ShapeInfo otherInfo = info; DoubleHashKey otherKey = otherInfo.getHash(); if (key.getHash() != otherKey.getHash()) { std::cout << __FILE__ << ":" << __LINE__ << " ERROR: expected Box shape hash = " << key.getHash() << " but found hash = " << otherKey.getHash() << std::endl; } if (key.getHash2() != otherKey.getHash2()) { std::cout << __FILE__ << ":" << __LINE__ << " ERROR: expected Box shape hash2 = " << key.getHash2() << " but found hash2 = " << otherKey.getHash2() << std::endl; } delete shape; }
void Object_Player::createBoxObject(hkpWorld* world) { // Create a temp body info hkpCharacterRigidBodyCinfo bodyInfo; // Box Parameters hkVector4 halfExtents(scale.x, scale.y, scale.z); // Create Box Based on Parameters hkpBoxShape* boxShape = new hkpBoxShape(halfExtents); // Set The Object's Properties bodyInfo.m_shape = boxShape; bodyInfo.m_position.set(position.x, position.y, position.z, 0.0f); // Calculate Mass Properties hkMassProperties massProperties; hkpInertiaTensorComputer::computeShapeVolumeMassProperties(boxShape, mass, massProperties); // Set Mass Properties bodyInfo.m_mass = 100.0f; // Create Rigid Body objectBody = new hkpCharacterRigidBody(bodyInfo); // No longer need the reference on the shape, as the rigidbody owns it now boxShape->removeReference(); // Add Rigid Body to the World world->addEntity(objectBody->getRigidBody()); }
// TODO: this could probably be made tighter Mat4 CreateDirLightVPMatrix(const FrustumCorners& frustumCorners, const Vec3& lightDir) { Mat4 lightViewMatrix = glm::lookAt(Vec3(0.0f), -lightDir, Vec3(0.0f, -1.0f, 0.0f)); Vec4 transf = lightViewMatrix * frustumCorners[0]; float maxZ = transf.z, minZ = transf.z; float maxX = transf.x, minX = transf.x; float maxY = transf.y, minY = transf.y; for (uint32_t i = 1; i < 8; ++i) { transf = lightViewMatrix * frustumCorners[i]; if (transf.z > maxZ) maxZ = transf.z; if (transf.z < minZ) minZ = transf.z; if (transf.x > maxX) maxX = transf.x; if (transf.x < minX) minX = transf.x; if (transf.y > maxY) maxY = transf.y; if (transf.y < minY) minY = transf.y; } lightViewMatrix[3][0] = -(minX + maxX) * 0.5f; lightViewMatrix[3][1] = -(minY + maxY) * 0.5f; lightViewMatrix[3][2] = -(minZ + maxZ) * 0.5f; Vec3 halfExtents((maxX - minX) * 0.5, (maxY - minY) * 0.5, (maxZ - minZ) * 0.5); return OrthographicMatrix(-halfExtents.x, halfExtents.x, halfExtents.y, -halfExtents.y, halfExtents.z, -halfExtents.z) * lightViewMatrix; }
btRigidBody* BulletPhysics::CreateBox(float width, float height, float depth, const glm::mat4* world, float mass, float restitution, float friction, float linear_damp, float angular_damp, bool kinematic, unsigned short group, unsigned short mask) { btVector3 halfExtents(width/2, height/2, depth/2); btCollisionShape* shape = new btBoxShape(halfExtents); if (kinematic) mass = 0; return CreateShape(shape, world, mass, restitution, friction, linear_damp, angular_damp, kinematic, group, mask); }
btRigidBody* BulletPhysics::CreateCylinder(float radius, float length, const glm::mat4* world, float mass, float restitution, float friction, float linear_damp, float angular_damp, bool kinematic, unsigned short group, unsigned short mask) { btVector3 halfExtents(radius, radius, length/2); btCollisionShape* shape = new btCylinderShape(halfExtents); if (kinematic) mass = 0; return CreateShape(shape, world, mass, restitution, friction, linear_damp, angular_damp, kinematic, group, mask); }
MapCell::MapCell(Ogre::Vector3 a_Position) : m_pMyCellTurf(NULL) //, m_CombinedGravity(Ogre::Vector3::ZERO) /*, m_pAdjNorth(0) , m_pAdjSouth(0) , m_pAdjEast(0) , m_pAdjWest(0) , m_pAdjUp(0) , m_pAdjDown(0)*/ , m_Position(a_Position) { // Create build raycast targets for(int curDir = 1; curDir <= 32; curDir *= 2) { // Which side of the cell is it? Ogre::Vector3 dirVector = GetUnitVectorFromDir(curDir); // Setup the transforms Ogre::Vector3 offsetPos = dirVector * 0.505; Ogre::Vector3 lookatPos = 2 * dirVector; btVector3 halfExtents(0.5f, 0.5f, 0.5f); halfExtents.setX(offsetPos.x * 0.005f); halfExtents.setY(offsetPos.y * 0.005f); halfExtents.setZ(offsetPos.z * 0.005f); } /* m_pAtomEntitySceneNode->setPosition(offsetPos); m_pAtomEntitySceneNode->lookAt(lookatPos, Ogre::Node::TS_LOCAL); m_pAtomEntitySceneNode->yaw(Ogre::Degree(90)); //create physics body and initialise to starting position m_pCollisionShape = new btBoxShape(halfExtents); btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), OGRE2BT(m_pAtomEntitySceneNode->_getDerivedPosition()))); btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0, groundMotionState, m_pCollisionShape, btVector3(0,0,0)); m_pRigidBody = new btRigidBody(groundRigidBodyCI); m_pRigidBody->setUserPointer(this); //add new rigid body to world btDiscreteDynamicsWorld& dynamicsWorld = GetDynamicsWorld(); if(m_IsBuildPoint) { SetEntityVisible(false); m_pAtomEntity->setMaterialName("cell_highlight_material"); dynamicsWorld.addRigidBody(m_pRigidBody, COLLISION_BUILDPOINT, RAYCAST_BUILD); //todo: is this working? //m_pRigidBody->setCollisionFlags(m_pRigidBody->CF_NO_CONTACT_RESPONSE); } else { dynamicsWorld.addRigidBody(m_pRigidBody, COLLISION_STRUCTURE, RAYCAST_BUILD|COLLISION_OBJ|COLLISION_MOB); } */ }
void Bullet2GpuDemo::setupScene(const ConstructionInfo& ci) { // m_data->m_np = np; // m_data->m_bp = bp; // m_data->m_rigidBodyPipeline m_gpuDynamicsWorld = new b3GpuDynamicsWorld(m_data->m_bp,m_data->m_np,m_data->m_rigidBodyPipeline); b3Vector3 halfExtents(100,1,100); b3BoxShape* boxShape = new b3BoxShape(halfExtents); b3Vector3 localInertia; b3Scalar mass=1.f; boxShape->calculateLocalInertia(mass,localInertia); b3RigidBody* body = new b3RigidBody(mass,0,boxShape,localInertia); m_gpuDynamicsWorld->addRigidBody(body); }
void ShapeManagerTests::addBoxShape() { ShapeInfo info; glm::vec3 halfExtents(1.23f, 4.56f, 7.89f); info.setBox(halfExtents); ShapeManager shapeManager; btCollisionShape* shape = shapeManager.getShape(info); ShapeInfo otherInfo; ShapeInfoUtil::collectInfoFromShape(shape, otherInfo); btCollisionShape* otherShape = shapeManager.getShape(otherInfo); if (shape != otherShape) { std::cout << __FILE__ << ":" << __LINE__ << " ERROR: Box ShapeInfo --> shape --> ShapeInfo --> shape did not work" << std::endl; } }
void SlidingWorldDemo::drawUnsimulatedBodies() { for (int i = 0; i < m_boxes.getSize(); i++) { hkpRigidBody* rb = m_boxes[i]; // Check if in simulation if( rb->getWorld() == HK_NULL ) { // Get center, and draw a gray box here hkVector4 pos = rb->getPosition(); const hkReal halfSize = 0.5f; hkVector4 halfExtents(halfSize, halfSize, halfSize); hkVector4 min, max; min.setSub4(pos, halfExtents); max.setAdd4(pos, halfExtents); drawAabb(min, max, hkColor::rgbFromChars(170, 170, 170, 150) ); } } }
static int gCreateSphereShape(lua_State *L) { int argc = lua_gettop(L); if (argc==2) { btVector3 halfExtents(1,1,1); if (!lua_isuserdata(L,1)) { std::cerr << "error: first argument to createSphereShape should be world"; return 0; } //expect userdata = sLuaDemo->m_dynamicsWorld btScalar radius = lua_tonumber(L,2); btCollisionShape* colShape = new btSphereShape(radius); lua_pushlightuserdata (L, colShape); return 1; } else { std::cerr << "Error: invalid number of arguments to createSphereShape, expected 2 (world,radius) but got " << argc; } return 0; }
static int gCreateCubeShape(lua_State *L) { int argc = lua_gettop(L); if (argc==4) { btVector3 halfExtents(1,1,1); if (!lua_isuserdata(L,1)) { std::cerr << "error: first argument to createCubeShape should be world"; return 0; } //expect userdata = sLuaDemo->m_dynamicsWorld halfExtents = btVector3(lua_tonumber(L,2),lua_tonumber(L,3),lua_tonumber(L,4)); btCollisionShape* colShape = new btBoxShape(halfExtents); lua_pushlightuserdata (L, colShape); return 1; } else { std::cerr << "Error: invalid number of arguments to createCubeShape, expected 4 (world,halfExtentsX,halfExtentsY,halfExtentsX) but got " << argc; } return 0; }
//Create a dynamic falling body void Visualize::addDynamicBody() { hkpRigidBodyCinfo bodyInfo; hkVector4 halfExtents(0.5f, 0.5f, 0.5f); bodyInfo.m_shape = new hkpBoxShape(halfExtents); hkMassProperties massProperties; hkpInertiaTensorComputer::computeShapeVolumeMassProperties(bodyInfo.m_shape, 1, massProperties); bodyInfo.setMassProperties(massProperties); bodyInfo.m_position.set(0, 10, 0); bodyInfo.m_angularVelocity.set(-2, -2, -2); bodyInfo.m_linearVelocity.set(5, -5, 5); //add a 3d dynamic falling body dynamicBody_irr = scene_manager->addCubeSceneNode(1.0f, 0, -1, core::vector3df(0, 10, 0), core::vector3df(0, 0, 0), core::vector3df(1, 1, 1)); scene_manager->getMeshManipulator()->setVertexColors(dynamicBody_irr->getMesh(), video::SColor(0, 0, 255, 0)); //dynamicBody_irr->setMaterialFlag(video::EMF_LIGHTING, false); dynamicBody_irr->addShadowVolumeSceneNode(); dynamicBody_irr->setMaterialFlag(video::EMF_ANTI_ALIASING, true); dynamicBody_irr->setMaterialType(video::EMT_SOLID); dynamicBody_irr->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true); dynamicBody_hk = new hkpRigidBody(bodyInfo); bodyInfo.m_shape->removeReference(); m_world->addEntity(dynamicBody_hk); }
//Create a fixed ground body void Visualize::createGround() { hkpRigidBodyCinfo bodyInfo; hkVector4 halfExtents(20, 0.5f, 20); bodyInfo.m_shape = new hkpBoxShape(halfExtents); bodyInfo.m_position.set(0, -0.5f, 0); bodyInfo.m_motionType = hkpMotion::MOTION_FIXED; //we don't need to save this node, because it is fixed (no physics applyied on it) scene::IMeshSceneNode* ground_node = scene_manager->addCubeSceneNode(1.0f, 0, -1, core::vector3df(0, -0.5f, 0), core::vector3df(0, 0, 0), core::vector3df(40, 1, 40)); if (ground_node) { ground_node->addShadowVolumeSceneNode(); //we have no texture, than we need the light to see our ground //ground_node->setMaterialFlag(video::EMF_LIGHTING, false); ground_node->setMaterialFlag(video::EMF_ANTI_ALIASING, true); ground_node->setMaterialType(video::EMT_SOLID); ground_node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true); scene_manager->getMeshManipulator()->setVertexColors(ground_node->getMesh(), video::SColor(0, 255, 0, 0)); } hkpRigidBody* body = new hkpRigidBody(bodyInfo); bodyInfo.m_shape->removeReference(); m_world->addEntity(body); body->removeReference(); }
btHeightfieldTerrainShape::btHeightfieldTerrainShape(int heightStickWidth, int heightStickLength,void* heightfieldData,btScalar maxHeight,int upAxis,bool useFloatData,bool flipQuadEdges) : btConcaveShape (), m_heightStickWidth(heightStickWidth), m_heightStickLength(heightStickLength), m_maxHeight(maxHeight), m_width((btScalar)heightStickWidth-1), m_length((btScalar)heightStickLength-1), m_heightfieldDataUnknown(heightfieldData), m_useFloatData(useFloatData), m_flipQuadEdges(flipQuadEdges), m_useDiamondSubdivision(false), m_upAxis(upAxis), m_localScaling(btScalar(1.),btScalar(1.),btScalar(1.)) { m_shapeType = TERRAIN_SHAPE_PROXYTYPE; btScalar quantizationMargin = 1.f; //enlarge the AABB to avoid division by zero when initializing the quantization values btVector3 clampValue(quantizationMargin,quantizationMargin,quantizationMargin); btVector3 halfExtents(0,0,0); switch (m_upAxis) { case 0: { halfExtents.setValue( btScalar(m_maxHeight), btScalar(m_width), //?? don't know if this should change btScalar(m_length)); break; } case 1: { halfExtents.setValue( btScalar(m_width), btScalar(m_maxHeight), btScalar(m_length)); break; }; case 2: { halfExtents.setValue( btScalar(m_width), btScalar(m_length), btScalar(m_maxHeight) ); break; } default: { //need to get valid m_upAxis btAssert(0); } } halfExtents*= btScalar(0.5); m_localAabbMin = -halfExtents - clampValue; m_localAabbMax = halfExtents + clampValue; btVector3 aabbSize = m_localAabbMax - m_localAabbMin; }
//make a box geometry of dimension 2x4x6 void Serialize::setGeometry() { hkVector4 halfExtents(1.0f, 2.0f, 3.0f); hkVector4* v = geometry->m_vertices.expandBy(8); v[0].set(-halfExtents(0), halfExtents(1), halfExtents(2)); v[1].set(halfExtents(0), halfExtents(1), halfExtents(2)); v[2].set(halfExtents(0), -halfExtents(1), halfExtents(2)); v[3].set(-halfExtents(0), -halfExtents(1), halfExtents(2)); v[4].set(-halfExtents(0), halfExtents(1), -halfExtents(2)); v[5].set(halfExtents(0), halfExtents(1), -halfExtents(2)); v[6].set(halfExtents(0), -halfExtents(1), -halfExtents(2)); v[7].set(-halfExtents(0), -halfExtents(1), -halfExtents(2)); geometry->m_triangles.expandBy(1)->set(3, 2, 1); geometry->m_triangles.expandBy(1)->set(3, 1, 0); geometry->m_triangles.expandBy(1)->set(6, 7, 4); geometry->m_triangles.expandBy(1)->set(6, 4, 5); geometry->m_triangles.expandBy(1)->set(4, 7, 3); geometry->m_triangles.expandBy(1)->set(4, 3, 0); geometry->m_triangles.expandBy(1)->set(2, 6, 5); geometry->m_triangles.expandBy(1)->set(2, 5, 1); geometry->m_triangles.expandBy(1)->set(7, 6, 2); geometry->m_triangles.expandBy(1)->set(7, 2, 3); geometry->m_triangles.expandBy(1)->set(1, 5, 4); geometry->m_triangles.expandBy(1)->set(1, 4, 0); }
TriSampledHeightFieldDemo::TriSampledHeightFieldDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env, DEMO_FLAGS_NO_SERIALIZE) { // Disable face culling setGraphicsState(HKG_ENABLED_CULLFACE, false); // Setup a camera in the right place to see our demo. { hkVector4 from( -3.7f, 5, 17.6f ); hkVector4 to (-1.5f, 1, 1.1f ); hkVector4 up ( 0.0f, 1.0f, 0.0f); setupDefaultCameras(env, from, to, up); } { hkpWorldCinfo info; info.setBroadPhaseWorldSize( 100.0f ); info.m_collisionTolerance = 0.03f; m_world = new hkpWorld(info); m_world->lock(); setupGraphics(); } hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() ); // // Create two movable rigid bodies to fall on the two heightfields. // { hkVector4 halfExtents(1.f, .25f, 1.f ); hkpShape* shape = new hkpBoxShape( halfExtents , 0 ); for (int i = 0; i < 2; i++ ) { hkpRigidBodyCinfo ci; ci.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA; ci.m_shape = shape; ci.m_mass = 4.f; hkpMassProperties m; hkpInertiaTensorComputer::computeShapeVolumeMassProperties(shape,4, m); ci.m_inertiaTensor = m.m_inertiaTensor; ci.m_position.set( hkReal(i * 7) - 5 , 4, 3 ); hkpRigidBody* body = new hkpRigidBody( ci ); m_world->addEntity(body); body->removeReference(); } shape->removeReference(); } { // Create our heightfield hkpSampledHeightFieldBaseCinfo ci; ci.m_xRes = 7; ci.m_zRes = 7; SimpleSampledHeightFieldShape* heightFieldShape = new SimpleSampledHeightFieldShape( ci ); { // // Create the first fixed rigid body, using the standard heightfield as the shape // hkpRigidBodyCinfo rci; rci.m_motionType = hkpMotion::MOTION_FIXED; rci.m_position.set(-8, 0, 0); rci.m_shape = heightFieldShape; rci.m_friction = 0.2f; hkpRigidBody* bodyA = new hkpRigidBody( rci ); m_world->addEntity(bodyA); bodyA->removeReference(); // // Create the second fixed rigid body, using the triSampledHeightfield // // Wrap the heightfield in a hkpTriSampledHeightFieldCollection: hkpTriSampledHeightFieldCollection* collection = new hkpTriSampledHeightFieldCollection( heightFieldShape ); // Now wrap the hkpTriSampledHeightFieldCollection in a hkpTriSampledHeightFieldBvTreeShape hkpTriSampledHeightFieldBvTreeShape* bvTree = new hkpTriSampledHeightFieldBvTreeShape( collection ); // Finally, assign the new hkpTriSampledHeightFieldBvTreeShape to be the rigid body's shape rci.m_shape = bvTree; rci.m_position.set(-1,0,0); hkpRigidBody* bodyB = new hkpRigidBody( rci ); m_world->addEntity(bodyB); bodyB->removeReference(); heightFieldShape->removeReference(); collection->removeReference(); bvTree->removeReference(); } hkString left("Standard heightfield."); m_env->m_textDisplay->outputText3D(left, -7, -.2f, 7, 0xffffffff, 2000); hkString right("Triangle heightfield."); m_env->m_textDisplay->outputText3D(right, -1, -.2f, 7, 0xffffffff, 2000); } m_world->unlock(); }
void UnderlayPlating::InstantiateStructure(bool a_IsBuildPoint) { //an overlay plate is essentially an "outer cover" for the tile in one of the six cardinal directions //system is currently setup to handle any combination of the six, but it probably shouldn't be m_IsBuildPoint = a_IsBuildPoint; Ogre::SceneManager& sceneManager = GetSceneManager(); //std::cout << "instantiating UnderlayPlating with direction " << m_Direction << std::endl; m_AtomFlags = RCD_CAN_DESTROY; //create entity m_pAtomEntity = sceneManager.createEntity("UnderlayPlating_" + num2string(m_AtomID), "cell_underlay.mesh"); m_pAtomEntitySceneNode->attachObject(m_pAtomEntity); StopFlashingColour(); //set up the directional offsets Ogre::Vector3 offsetPos(0, 0, 0); Ogre::Vector3 lookatPos(0, 0, 0); btVector3 halfExtents(0.5f, 0.5f, 0.5f); //std::cout << " new overlay plating" << std::endl; if(m_Direction & NORTH) { offsetPos.z += 0.395f; lookatPos.z += 1; halfExtents.setZ(0.005f); //std::cout << "NORTH " << (isPhysical ? "plating" : "trigger") << std::endl; } if(m_Direction & SOUTH) { offsetPos.z -= 0.395f; lookatPos.z -= 1; halfExtents.setZ(0.005f); //std::cout << "SOUTH " << (isPhysical ? "plating" : "trigger") << std::endl; } if(m_Direction & EAST) { offsetPos.x += 0.395f; lookatPos.x += 1; halfExtents.setX(0.005f); //std::cout << "EAST " << (isPhysical ? "plating" : "trigger") << std::endl; } if(m_Direction & WEST) { offsetPos.x -= 0.395f; lookatPos.x -= 1; halfExtents.setX(0.005f); //std::cout << "WEST " << (isPhysical ? "plating" : "trigger") << std::endl; } if(m_Direction & UP) { offsetPos.y += 0.395f; lookatPos.y += 1; halfExtents.setY(0.005f); //std::cout << "UP " << (isPhysical ? "plating" : "trigger") << std::endl; } if(m_Direction & DOWN) { offsetPos.y -= 0.395f; lookatPos.y -= 1; halfExtents.setY(0.005f); //std::cout << "DOWN " << (isPhysical ? "plating" : "trigger") << std::endl; } m_pAtomEntitySceneNode->setPosition(offsetPos); m_pAtomEntitySceneNode->lookAt(lookatPos, Ogre::Node::TS_LOCAL); m_pAtomEntitySceneNode->yaw(Ogre::Degree(90)); //create physics body and initialise to starting position m_pCollisionShape = new btBoxShape(halfExtents); btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), OGRE2BT(m_pAtomEntitySceneNode->_getDerivedPosition()))); btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0, groundMotionState, m_pCollisionShape, btVector3(0,0,0)); m_pRigidBody = new btRigidBody(groundRigidBodyCI); m_pRigidBody->setUserPointer(this); //add new rigid body to world btDiscreteDynamicsWorld& dynamicsWorld = GetDynamicsWorld(); if(m_IsBuildPoint) { SetEntityVisible(false); m_pAtomEntity->setMaterialName("cell_highlight_material"); dynamicsWorld.addRigidBody(m_pRigidBody, COLLISION_BUILDPOINT, RAYCAST_BUILD); //todo: is this working? //m_pRigidBody->setCollisionFlags(m_pRigidBody->CF_NO_CONTACT_RESPONSE); } else { dynamicsWorld.addRigidBody(m_pRigidBody, COLLISION_STRUCTURE, RAYCAST_BUILD|COLLISION_OBJ|COLLISION_MOB); } InitCollisionShapeDebugDraw(Ogre::ColourValue::Red); }
void BrickWallBuilder::buildBrickWall(const BrickwallBuilderDescriptor& bwDescriptor, hkArray<hkpRigidBody*>& bricksOut, hkArray<hkpConstraintInstance*>& constraintsOut ) { hkVector4 halfExtents( bwDescriptor.m_brickShape->getHalfExtents() ); // move start point depending on wall size hkVector4 posX( hkVector4::getZero() ); posX(0) = -bwDescriptor.m_width * halfExtents(0); posX(0) += halfExtents(0); posX(1) = -halfExtents(1); // reserve space for all bricks and constraints bricksOut.reserve(bwDescriptor.m_height * bwDescriptor.m_width * 2); constraintsOut.reserve( (2 * bwDescriptor.m_height - 1) * (2 * bwDescriptor.m_width - 1) + bwDescriptor.m_width - 1); hkReal thresholdDelta = (bwDescriptor.m_strength > bwDescriptor.m_lowerThreshold)? (bwDescriptor.m_strength - bwDescriptor.m_lowerThreshold) /(bwDescriptor.m_height*2-1) : 0.0f; // set brick properties, used for all the bricks hkpRigidBodyCinfo boxInfo; computeBrickInfo(bwDescriptor.m_brickShape, bwDescriptor.m_brickMass, boxInfo); // QUI int colOffset=bwDescriptor.m_height; for(int x=0;x<bwDescriptor.m_width;x++) // along the ground, left to right { hkVector4 pos(posX); // breaking threshold for this row hkReal rowThreshold = bwDescriptor.m_strength; for(int y=0; y<bwDescriptor.m_height; y++) // bottom to top { pos(1) += (halfExtents(1) + bwDescriptor.m_brickShape->getRadius()) * 2.0f; // build rigid body for brick int brickIndOne; { brickIndOne=bricksOut.getSize(); boxInfo.m_position.setRotatedDir( bwDescriptor.m_transform.getRotation() /*bwDescriptor.m_orientation*/,pos); boxInfo.m_position.add4( bwDescriptor.m_transform.getTranslation() /*bwDescriptor.m_position*/); boxInfo.m_rotation.set( bwDescriptor.m_transform.getRotation() ); //bwDescriptor.m_orientation; bricksOut.pushBack(new hkpRigidBody(boxInfo)); } // At each step 2 constraints are built: hkBool constraintsAdded[] = {false, false}; // 1 - A constraint to the ground OR a constraint to the brick below the one just built if( y == 0 ) { // attach the first row to the ground (if requested) if(bwDescriptor.m_attachToGround) constraintsOut.pushBack(buildBreakableConstraintInstance(bricksOut[brickIndOne], bwDescriptor.m_theGround, rowThreshold*1000)); } else { // create a breakable constraint from the brick and the one below constraintsOut.pushBack(buildBreakableConstraintInstance(bricksOut[brickIndOne], bricksOut[brickIndOne - 1], rowThreshold)); constraintsAdded[0]=true; } // 2 - a constraint to the brick to the left if( x > 0 ) // check if there is a previous column { // create a constraint from the new brick and the corresponding brick from the previous column // the first row is made of unbreakable constraints if(y==0 && bwDescriptor.m_attachToGround) constraintsOut.pushBack(buildConstraintInstance(bricksOut[brickIndOne], bricksOut[brickIndOne - colOffset])); else constraintsOut.pushBack(buildBreakableConstraintInstance(bricksOut[brickIndOne], bricksOut[brickIndOne - colOffset], rowThreshold)); constraintsAdded[1]=true; } if(bwDescriptor.m_setCollisionFilter) { // Set filter info bool b = constraintsAdded[0]; bool l = constraintsAdded[1]; hkUint32 filterInfo = BrickFilter::calcFilterInfo(y, x, bwDescriptor.m_wallID, l, b); bricksOut[brickIndOne]->setCollisionFilterInfo(filterInfo); } rowThreshold -= thresholdDelta; } // end of for(..y..) // advance to next col posX(0) += bwDescriptor.m_gapWidth + halfExtents(0)*2.0f; } // end of for(..x..) }
BigRigDemo::BigRigDemo(hkDemoEnvironment* env) : CarDemo(env, false) { // Create the vehicles // // Create tractor shape. // hkpListShape* tractorShape = HK_NULL; { hkReal xSize = 1.9f; hkReal xSizeFrontTop = 0.7f; hkReal xSizeFrontMid = 1.6f; hkReal ySize = 0.9f; hkReal ySizeMid = ySize - 0.7f; hkReal zSize = 1.0f; //hkReal xBumper = 1.9f; //hkReal yBumper = 0.35f; //hkReal zBumper = 1.0f; hkVector4 halfExtents(1.0f, 0.35f, 1.0f); // 16 = 4 (size of "each float group", 3 for x,y,z, 1 for padding) * 4 (size of float). int stride = sizeof(float) * 4; { int numVertices = 10; float vertices[] = { xSizeFrontTop, ySize, zSize, 0.0f, // v0 xSizeFrontTop, ySize, -zSize, 0.0f, // v1 xSize, -ySize, zSize, 0.0f, // v2 xSize, -ySize, -zSize, 0.0f, // v3 -xSize, ySize, zSize, 0.0f, // v4 -xSize, ySize, -zSize, 0.0f, // v5 -xSize, -ySize, zSize, 0.0f, // v6 -xSize, -ySize, -zSize, 0.0f, // v7 xSizeFrontMid, ySizeMid, zSize, 0.0f, // v8 xSizeFrontMid, ySizeMid, -zSize, 0.0f, // v9 }; hkpBoxShape* boxShape = new hkpBoxShape(halfExtents, 0.05f ); hkTransform transform; transform.setIdentity(); transform.setTranslation(hkVector4(-2.5f, -0.55f, 0.0f)); hkpConvexTransformShape* transformShape = new hkpConvexTransformShape(boxShape, transform); boxShape->removeReference(); hkpConvexVerticesShape* convexShape; { hkStridedVertices stridedVerts; { stridedVerts.m_numVertices = numVertices; stridedVerts.m_striding = stride; stridedVerts.m_vertices = vertices; } convexShape = new hkpConvexVerticesShape(stridedVerts); } hkArray<hkpShape*> shapeArray; shapeArray.pushBack(transformShape); shapeArray.pushBack(convexShape); tractorShape = new hkpListShape(shapeArray.begin(), shapeArray.getSize()); transformShape->removeReference(); convexShape->removeReference(); } } // // Create trailer shape. // hkpListShape* trailerShape = HK_NULL; { hkVector4 halfExtents1(5.0f, 1.5f, 1.0f); // Box hkVector4 halfExtents2(1.0f, 1.0f, 1.0f); // Tongue hkTransform transform; transform.setIdentity(); { hkpBoxShape* boxShape1 = new hkpBoxShape(halfExtents1, 0.05f ); hkpBoxShape* boxShape2 = new hkpBoxShape(halfExtents2, 0.05f ); transform.setTranslation(hkVector4(6.0f, 0.5f, 0.0f)); hkpConvexTransformShape* transformShape = new hkpConvexTransformShape(boxShape2, transform); boxShape2->removeReference(); hkArray<hkpShape*> shapeArray; shapeArray.pushBack(boxShape1); shapeArray.pushBack(transformShape); trailerShape = new hkpListShape(shapeArray.begin(), shapeArray.getSize()); boxShape1->removeReference(); transformShape->removeReference(); } } // Create the tractor vehicles { m_world->lock(); { HK_ASSERT(0x526edf5d, m_world->getCollisionFilter() && m_world->getCollisionFilter()->m_type == hkpCollisionFilter::HK_FILTER_GROUP); hkpGroupFilter* groupFilter = static_cast<hkpGroupFilter*>(const_cast<hkpCollisionFilter*>(m_world->getCollisionFilter())); m_vehicles.clear(); for (int vehicleId = 0; vehicleId < m_numVehicles; vehicleId++) { int vehicleGroup = groupFilter->getNewSystemGroup(); // // Create the tractor. // { // // Create the tractor body. // hkpRigidBody* tractorRigidBody; { hkpRigidBodyCinfo tractorInfo; tractorInfo.m_shape = tractorShape; tractorInfo.m_friction = 0.8f; tractorInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA; tractorInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(0, vehicleGroup ); // Position chassis on the ground. tractorInfo.m_position.set(0.0f, -3.0f, (vehicleId + 1) * 9.0f); //tractorInfo.m_angularDamping = 0.5f; // No need to set the inertia tensor, as this will be set automatically by the vehicle setup tractorInfo.m_mass = 15000.0f; tractorInfo.m_inertiaTensor.setDiagonal( 1.f, 1.f, 1.f ); tractorInfo.m_centerOfMass.set( -1.0f, -0.8f, 0.0f); tractorRigidBody = new hkpRigidBody(tractorInfo); } m_vehicles.expandOne(); TractorSetup tsetup; createTractorVehicle( tsetup, tractorRigidBody, m_vehicles.getSize()-1); tractorRigidBody->removeReference(); } // // Create the trailer body. // { hkpRigidBody* trailerRigidBody; { hkpRigidBodyCinfo trailerInfo; trailerInfo.m_shape = trailerShape; trailerInfo.m_friction = 0.8f; trailerInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA; trailerInfo.m_position.set(-9.0f, -3.0f, (1 + vehicleId) * 9.0f); trailerInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(0, vehicleGroup ); // No need to set the inertia tensor, as this will be set automatically by the vehicle setup trailerInfo.m_mass = 10000.0f; trailerInfo.m_inertiaTensor.setDiagonal( 1.f, 1.f, 1.f ); // Trailers are generally bottom-heavy to improve stability. // Move the centre of mass lower but keep it within the chassis limits. trailerInfo.m_centerOfMass.set(-1.0f, -1.0f, 0.0f); trailerRigidBody = new hkpRigidBody(trailerInfo); } m_vehicles.expandOne(); TrailerSetup tsetup; createTrailerVehicle( tsetup, trailerRigidBody, m_vehicles.getSize()-1); HK_SET_OBJECT_COLOR((hkUlong)trailerRigidBody->getCollidable(), 0x80ff8080); trailerRigidBody->removeReference(); } } tractorShape->removeReference(); trailerShape->removeReference(); } // // Create the wheels // createDisplayWheels(0.5f, 0.2f); // Attach Tractors and Trailers for (int vehicleId = 0; vehicleId < m_vehicles.getSize(); vehicleId+=2) { hkpRigidBody* tractor = m_vehicles[vehicleId].m_vehicle->getChassis(); hkpRigidBody* trailer = m_vehicles[vehicleId + 1 ].m_vehicle->getChassis(); // // Use a hinge constraint to connect the tractor to the trailer // if (0) { // // Set the pivot // hkVector4 axis(0.0f, 1.0f, 0.0f); hkVector4 point1(-3.5f, 0.4f, 0.0f); hkVector4 point2(6.0f, -0.4f, 0.0f); // Create constraint hkpHingeConstraintData* hc = new hkpHingeConstraintData(); hc->setInBodySpace(point1, point2, axis, axis); m_world->createAndAddConstraintInstance( tractor, trailer, hc )->removeReference(); hc->removeReference(); } // // Use a ball-and-socket constraint to connect the tractor to the trailer // else if (0) { hkVector4 point1(-3.5f, 0.4f, 0.0f); hkVector4 point2(6.0f, -0.4f, 0.0f); // Create the constraint hkpBallAndSocketConstraintData* bs = new hkpBallAndSocketConstraintData(); bs->setInBodySpace(point1, point2); m_world->createAndAddConstraintInstance( tractor, trailer, bs )->removeReference(); bs->removeReference(); } // // Use a ragdoll constraint to connect the tractor to the trailer // else if(1) { hkReal planeMin = HK_REAL_PI * -0.45f; hkReal planeMax = HK_REAL_PI * 0.45f; hkReal twistMin = HK_REAL_PI * -0.005f; hkReal twistMax = HK_REAL_PI * 0.005f; hkReal coneMin = HK_REAL_PI * -0.55f; hkReal coneMax = HK_REAL_PI * 0.55f; hkpRagdollConstraintData* rdc = new hkpRagdollConstraintData(); rdc->setPlaneMinAngularLimit(planeMin); rdc->setPlaneMaxAngularLimit(planeMax); rdc->setTwistMinAngularLimit(twistMin); rdc->setTwistMaxAngularLimit(twistMax); hkVector4 twistAxisA(1.0f, 0.0f, 0.0f); hkVector4 planeAxisA(0.0f, 0.0f, 1.0f); hkVector4 twistAxisB(1.0f, 0.0f, 0.0f); hkVector4 planeAxisB(0.0f, 0.0f, 1.0f); hkVector4 point1(-2.3f, -0.7f, 0.0f); hkVector4 point2( 7.2f, -1.3f, 0.0f); rdc->setInBodySpace(point1, point2, planeAxisA, planeAxisB, twistAxisA, twistAxisB); rdc->setAsymmetricConeAngle(coneMin, coneMax); m_world->createAndAddConstraintInstance(tractor, trailer, rdc)->removeReference(); rdc->removeReference(); } } m_world->unlock(); } // // Create the camera. // { hkp1dAngularFollowCamCinfo cinfo; cinfo.m_yawSignCorrection = 1.0f; cinfo.m_upDirWS.set(0.0f, 1.0f, 0.0f); cinfo.m_rigidBodyForwardDir.set(1.0f, 0.0f, 0.0f); cinfo.m_set[0].m_velocity = 10.0f; cinfo.m_set[1].m_velocity = 50.0f; cinfo.m_set[0].m_speedInfluenceOnCameraDirection = 1.0f; cinfo.m_set[1].m_speedInfluenceOnCameraDirection = 1.0f; cinfo.m_set[0].m_angularRelaxation = 3.5f; cinfo.m_set[1].m_angularRelaxation = 4.5f; // The two camera positions ("slow" and "fast" rest positions) are both the same here, // -6 units behind the chassis, and 2 units above it. Again, this is dependent on // m_chassisCoordinateSystem. cinfo.m_set[0].m_positionUS.set( -27.0f, 8.0f, 0.0f); cinfo.m_set[1].m_positionUS.set( -27.0f, 8.0f, 0.0f); cinfo.m_set[0].m_lookAtUS.set ( 2.0f, 0.0f, 0.0f ); cinfo.m_set[1].m_lookAtUS.set ( 2.0f, 0.0f, 0.0f ); cinfo.m_set[0].m_fov = 70.0f; cinfo.m_set[1].m_fov = 70.0f; m_camera.reinitialize( cinfo ); } }
AsymetricCharacterRbDemo::AsymetricCharacterRbDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env) { // Create the world { hkpWorldCinfo info; info.setBroadPhaseWorldSize( 350.0f ); info.m_gravity.set(0, -9.8f, 0); info.m_collisionTolerance = 0.01f; info.m_contactPointGeneration = hkpWorldCinfo::CONTACT_POINT_ACCEPT_ALWAYS; m_world = new hkpWorld( info ); m_world->lock(); hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher()); setupGraphics(); } // Create a terrain (more bumpy as in the classical character proxy demo) TerrainHeightFieldShape* heightFieldShape; { hkpSampledHeightFieldBaseCinfo ci; ci.m_xRes = 64; ci.m_zRes = 64; ci.m_scale.set(1.6f, 0.2f, 1.6f); // Fill in a data array m_data = hkAllocate<hkReal>((ci.m_xRes * ci.m_zRes), HK_MEMORY_CLASS_DEMO); for (int x = 0; x < ci.m_xRes; x++) { for (int z = 0; z < ci.m_zRes; z++) { hkReal dx,dz,height = 0; int octave = 1; // Add together a few sine and cose waves for (int i=0; i< 3; i++) { dx = hkReal(x * octave) / ci.m_xRes; dz = hkReal(z * octave) / ci.m_zRes; height += 4 * i * hkMath::cos(dx * HK_REAL_PI) * hkMath::sin(dz * HK_REAL_PI); height -= 2.5f; octave *= 2; } m_data[x*ci.m_zRes + z] = height; } } heightFieldShape = new TerrainHeightFieldShape( ci , m_data ); // Create terrain as a fixed rigid body { hkpRigidBodyCinfo rci; rci.m_motionType = hkpMotion::MOTION_FIXED; rci.m_position.setMul4( -0.5f, heightFieldShape->m_extents ); // center the heighfield rci.m_shape = heightFieldShape; rci.m_friction = 0.5f; hkpRigidBody* terrain = new hkpRigidBody( rci ); m_world->addEntity(terrain); terrain->removeReference(); } heightFieldShape->removeReference(); } // Create some random static pilars (green) and smaller dynamic boxes (blue) { hkPseudoRandomGenerator randgen(12345); for (int i=0; i < 80; i++) { if (i%2) { // Dynamic boxes of random size hkVector4 size; randgen.getRandomVector11(size); size.setAbs4( size ); size.mul4(0.5f); hkVector4 minSize; minSize.setAll3(0.25f); size.add4(minSize); // Random position hkVector4 position; randgen.getRandomVector11( position ); position(0) *= 25; position(2) *= 25; position(1) = 4; { // To illustrate using the shape, create a rigid body by first defining a template. hkpRigidBodyCinfo rci; rci.m_shape = new hkpBoxShape( size ); rci.m_position = position; rci.m_friction = 0.5f; rci.m_restitution = 0.0f; // Density of concrete const hkReal density = 2000.0f; rci.m_mass = size(0)*size(1)*size(2)*density; hkVector4 halfExtents(size(0) * 0.5f, size(1) * 0.5f, size(2) * 0.5f); hkpMassProperties massProperties; hkpInertiaTensorComputer::computeBoxVolumeMassProperties(halfExtents, rci.m_mass, massProperties); rci.m_inertiaTensor = massProperties.m_inertiaTensor; rci.m_motionType = hkpMotion::MOTION_BOX_INERTIA; // Create a rigid body (using the template above). hkpRigidBody* box = new hkpRigidBody(rci); // Remove reference since the body now "owns" the Shape. rci.m_shape->removeReference(); box->addProperty(HK_PROPERTY_DEBUG_DISPLAY_COLOR, int(hkColor::DARKBLUE)); // Finally add body so we can see it, and remove reference since the world now "owns" it. m_world->addEntity(box)->removeReference(); } } else { // Fixed pilars of random size hkVector4 size; randgen.getRandomVector11(size); size.setAbs4( size ); hkVector4 minSize; minSize.setAll3(0.5f); size.add4(minSize); size(1) = 2.5f; // Random position hkVector4 position; randgen.getRandomVector11( position ); position(0) *= 25; position(2) *= 25; position(1) = 0; { // To illustrate using the shape, create a rigid body by first defining a template. hkpRigidBodyCinfo rci; rci.m_shape = new hkpBoxShape( size ); rci.m_position = position; rci.m_friction = 0.1f; rci.m_motionType = hkpMotion::MOTION_FIXED; // Create a rigid body (using the template above). hkpRigidBody* pilar = new hkpRigidBody(rci); // Remove reference since the body now "owns" the shape. rci.m_shape->removeReference(); pilar->addProperty(HK_PROPERTY_DEBUG_DISPLAY_COLOR, int(hkColor::DARKGREEN)); // Finally add body so we can see it, and remove reference since the world now "owns" it. m_world->addEntity(pilar); pilar->removeReference(); } } } } // Create a character rigid body { // Construct a shape hkVector4 vertexA(0.4f,0,0); hkVector4 vertexB(-0.4f,0,0); // Create a capsule to represent the character standing hkpShape* capsule = new hkpCapsuleShape(vertexA, vertexB, 0.6f); // Construct a character rigid body hkpCharacterRigidBodyCinfo info; info.m_mass = 100.0f; info.m_shape = capsule; info.m_maxForce = 1000.0f; info.m_up = UP; info.m_position.set(32.0f, 3.0f, 10.0f); info.m_maxSlope = HK_REAL_PI/2.0f; // Only vertical plane is too steep m_characterRigidBody = new hkpCharacterRigidBody( info ); m_world->addEntity( m_characterRigidBody->getRigidBody() ); capsule->removeReference(); } // Create the character state machine and context { hkpCharacterState* state; hkpCharacterStateManager* manager = new hkpCharacterStateManager(); state = new hkpCharacterStateOnGround(); manager->registerState( state, HK_CHARACTER_ON_GROUND); state->removeReference(); state = new hkpCharacterStateInAir(); manager->registerState( state, HK_CHARACTER_IN_AIR); state->removeReference(); state = new hkpCharacterStateJumping(); manager->registerState( state, HK_CHARACTER_JUMPING); state->removeReference(); state = new hkpCharacterStateClimbing(); manager->registerState( state, HK_CHARACTER_CLIMBING); state->removeReference(); m_characterContext = new hkpCharacterContext(manager, HK_CHARACTER_IN_AIR); manager->removeReference(); // Set new filter parameters for final output velocity filtering // Smoother interactions with small dynamic boxes m_characterContext->setCharacterType(hkpCharacterContext::HK_CHARACTER_RIGIDBODY); m_characterContext->setFilterParameters(0.9f,12.0f,200.0f); } // Initialize hkpSurfaceInfo of ground from previous frame // Specific case (character is in the air, UP is Y) m_previousGround = new hkpSurfaceInfo(UP,hkVector4::getZero(),hkpSurfaceInfo::UNSUPPORTED); m_framesInAir = 0; // Current camera angle about up m_currentAngle = 0.0f; // Init actual time m_time = 0.0f; // Init rigid body normal m_rigidBodyNormal = UP; m_world->unlock(); }
void MultiDofDemo::initPhysics() { m_guiHelper->setUpAxis(1); if(g_firstInit) { m_guiHelper->getRenderInterface()->getActiveCamera()->setCameraDistance(btScalar(10.*scaling)); m_guiHelper->getRenderInterface()->getActiveCamera()->setCameraPitch(50); g_firstInit = false; } ///collision configuration contains default setup for memory, collision setup m_collisionConfiguration = new btDefaultCollisionConfiguration(); ///use the default collision dispatcher. For parallel processing you can use a diffent dispatcher (see Extras/BulletMultiThreaded) m_dispatcher = new btCollisionDispatcher(m_collisionConfiguration); m_broadphase = new btDbvtBroadphase(); //Use the btMultiBodyConstraintSolver for Featherstone btMultiBody support btMultiBodyConstraintSolver* sol = new btMultiBodyConstraintSolver; m_solver = sol; //use btMultiBodyDynamicsWorld for Featherstone btMultiBody support btMultiBodyDynamicsWorld* world = new btMultiBodyDynamicsWorld(m_dispatcher,m_broadphase,sol,m_collisionConfiguration); m_dynamicsWorld = world; // m_dynamicsWorld->setDebugDrawer(&gDebugDraw); m_guiHelper->createPhysicsDebugDrawer(m_dynamicsWorld); m_dynamicsWorld->setGravity(btVector3(0,-10,0)); ///create a few basic rigid bodies btVector3 groundHalfExtents(50,50,50); btCollisionShape* groundShape = new btBoxShape(groundHalfExtents); //groundShape->initializePolyhedralFeatures(); // btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),50); m_collisionShapes.push_back(groundShape); btTransform groundTransform; groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,-50,00)); ///////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////// bool damping = true; bool gyro = true; int numLinks = 5; bool spherical = true; //set it ot false -to use 1DoF hinges instead of 3DoF sphericals bool multibodyOnly = false; bool canSleep = true; bool selfCollide = true; bool multibodyConstraint = false; btVector3 linkHalfExtents(0.05, 0.37, 0.1); btVector3 baseHalfExtents(0.05, 0.37, 0.1); btMultiBody* mbC = createFeatherstoneMultiBody_testMultiDof(world, numLinks, btVector3(-0.4f, 3.f, 0.f), linkHalfExtents, baseHalfExtents, spherical, g_floatingBase); //mbC->forceMultiDof(); //if !spherical, you can comment this line to check the 1DoF algorithm g_floatingBase = ! g_floatingBase; mbC->setCanSleep(canSleep); mbC->setHasSelfCollision(selfCollide); mbC->setUseGyroTerm(gyro); // if(!damping) { mbC->setLinearDamping(0.f); mbC->setAngularDamping(0.f); }else { mbC->setLinearDamping(0.1f); mbC->setAngularDamping(0.9f); } // m_dynamicsWorld->setGravity(btVector3(0, -9.81 ,0)); //m_dynamicsWorld->getSolverInfo().m_numIterations = 100; ////////////////////////////////////////////// if(numLinks > 0) { btScalar q0 = 45.f * SIMD_PI/ 180.f; if(!spherical) { mbC->setJointPosMultiDof(0, &q0); } else { btQuaternion quat0(btVector3(1, 1, 0).normalized(), q0); quat0.normalize(); mbC->setJointPosMultiDof(0, quat0); } } /// addColliders_testMultiDof(mbC, world, baseHalfExtents, linkHalfExtents); ///////////////////////////////////////////////////////////////// btScalar groundHeight = -51.55; if (!multibodyOnly) { btScalar mass(0.); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) groundShape->calculateLocalInertia(mass,localInertia); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects groundTransform.setIdentity(); groundTransform.setOrigin(btVector3(0,groundHeight,0)); btDefaultMotionState* myMotionState = new btDefaultMotionState(groundTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,groundShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); //add the body to the dynamics world m_dynamicsWorld->addRigidBody(body,1,1+2);//,1,1+2); } ///////////////////////////////////////////////////////////////// if(!multibodyOnly) { btVector3 halfExtents(.5,.5,.5); btBoxShape* colShape = new btBoxShape(halfExtents); //btCollisionShape* colShape = new btSphereShape(btScalar(1.)); m_collisionShapes.push_back(colShape); /// Create Dynamic Objects btTransform startTransform; startTransform.setIdentity(); btScalar mass(1.f); //rigidbody is dynamic if and only if mass is non zero, otherwise static bool isDynamic = (mass != 0.f); btVector3 localInertia(0,0,0); if (isDynamic) colShape->calculateLocalInertia(mass,localInertia); startTransform.setOrigin(btVector3( btScalar(0.0), 0.0, btScalar(0.0))); //using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects btDefaultMotionState* myMotionState = new btDefaultMotionState(startTransform); btRigidBody::btRigidBodyConstructionInfo rbInfo(mass,myMotionState,colShape,localInertia); btRigidBody* body = new btRigidBody(rbInfo); m_dynamicsWorld->addRigidBody(body);//,1,1+2); if (multibodyConstraint) { btVector3 pointInA = -linkHalfExtents; // btVector3 pointInB = halfExtents; btMatrix3x3 frameInA; btMatrix3x3 frameInB; frameInA.setIdentity(); frameInB.setIdentity(); btVector3 jointAxis(1.0,0.0,0.0); //btMultiBodySliderConstraint* p2p = new btMultiBodySliderConstraint(mbC,numLinks-1,body,pointInA,pointInB,frameInA,frameInB,jointAxis); btMultiBodyFixedConstraint* p2p = new btMultiBodyFixedConstraint(mbC,numLinks-1,mbC,numLinks-4,pointInA,pointInA,frameInA,frameInB); p2p->setMaxAppliedImpulse(2.0); m_dynamicsWorld->addMultiBodyConstraint(p2p); } } m_guiHelper->autogenerateGraphicsObjects(m_dynamicsWorld); ///////////////////////////////////////////////////////////////// }
void OptimizedWorldRaycastDemo::createBodies() { hkpRigidBodyCinfo rigidBodyInfo; rigidBodyInfo.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(1, 1); hkPseudoRandomGenerator rand(100); hkArray<hkpEntity*> bodyArray; bodyArray.reserve(m_numRigidBodies); hkpShape* shape; { hkVector4 halfExtents(0.5f, 0.5f, 0.5f); shape = new hkpBoxShape( halfExtents, 0.0f ); } for( int i = 0; i < m_numRigidBodies; i++) { // All bodies created below are movable rigidBodyInfo.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA; // A collection of many rigid bodies is randomly created using a hkpBoxShape rigidBodyInfo.m_shape = shape; // 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 { hkReal mass = 10.0f; hkReal d = mass * 0.5f; rigidBodyInfo.m_inertiaTensor.setDiagonal( d,d,d ); rigidBodyInfo.m_mass = mass; } // The object is then assigned a random position, orientation and angular velocity and added to the world: rigidBodyInfo.m_position.set( rand.getRandRange(-1.f*m_worldSizeX, 1.f*m_worldSizeX), rand.getRandRange(-1.f*m_worldSizeY, 1.f*m_worldSizeY), rand.getRandRange(-1.f*m_worldSizeZ, 1.f*m_worldSizeZ)); rand.getRandomRotation( rigidBodyInfo.m_rotation ); rigidBodyInfo.m_collisionFilterInfo = hkpGroupFilterSetup::LAYER_DEBRIS; hkpRigidBody* rigidBody = new hkpRigidBody(rigidBodyInfo); // Give them an intial 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); bodyArray.pushBack( rigidBody ); // There is no gravity vector for this world and so the bodies will appear to float in space. } shape->removeReference(); // Batch add all bodies to the system and defragment the broadphase m_world->addEntityBatch( bodyArray.begin(), bodyArray.getSize() ); m_world->getBroadPhase()->defragment(); // // Remove all references to bodies. They are now referenced by m_world // { for ( int i = 0; i < bodyArray.getSize(); i++ ) { bodyArray[i]->removeReference(); } } }
void btConvexShape::getAabbNonVirtual (const btTransform& t, btVector3& aabbMin, btVector3& aabbMax) const { switch (m_shapeType) { case SPHERE_SHAPE_PROXYTYPE: { btSphereShape* sphereShape = (btSphereShape*)this; btScalar radius = sphereShape->getImplicitShapeDimensions().getX();// * convexShape->getLocalScaling().getX(); btScalar margin = radius + sphereShape->getMarginNonVirtual(); const btVector3& center = t.getOrigin(); btVector3 extent(margin,margin,margin); aabbMin = center - extent; aabbMax = center + extent; } break; case CYLINDER_SHAPE_PROXYTYPE: /* fall through */ case BOX_SHAPE_PROXYTYPE: { btBoxShape* convexShape = (btBoxShape*)this; btScalar margin=convexShape->getMarginNonVirtual(); btVector3 halfExtents = convexShape->getImplicitShapeDimensions(); halfExtents += btVector3(margin,margin,margin); btMatrix3x3 abs_b = t.getBasis().absolute(); btVector3 center = t.getOrigin(); btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); aabbMin = center - extent; aabbMax = center + extent; break; } case TRIANGLE_SHAPE_PROXYTYPE: { btTriangleShape* triangleShape = (btTriangleShape*)this; btScalar margin = triangleShape->getMarginNonVirtual(); for (int i=0;i<3;i++) { btVector3 vec(btScalar(0.),btScalar(0.),btScalar(0.)); vec[i] = btScalar(1.); btVector3 sv = localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis()); btVector3 tmp = t(sv); aabbMax[i] = tmp[i]+margin; vec[i] = btScalar(-1.); tmp = t(localGetSupportVertexWithoutMarginNonVirtual(vec*t.getBasis())); aabbMin[i] = tmp[i]-margin; } } break; case CAPSULE_SHAPE_PROXYTYPE: { btCapsuleShape* capsuleShape = (btCapsuleShape*)this; btVector3 halfExtents(capsuleShape->getRadius(),capsuleShape->getRadius(),capsuleShape->getRadius()); int m_upAxis = capsuleShape->getUpAxis(); halfExtents[m_upAxis] = capsuleShape->getRadius() + capsuleShape->getHalfHeight(); halfExtents += btVector3(capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual(),capsuleShape->getMarginNonVirtual()); btMatrix3x3 abs_b = t.getBasis().absolute(); btVector3 center = t.getOrigin(); btVector3 extent = halfExtents.dot3(abs_b[0], abs_b[1], abs_b[2]); aabbMin = center - extent; aabbMax = center + extent; } break; case CONVEX_POINT_CLOUD_SHAPE_PROXYTYPE: case CONVEX_HULL_SHAPE_PROXYTYPE: { btPolyhedralConvexAabbCachingShape* convexHullShape = (btPolyhedralConvexAabbCachingShape*)this; btScalar margin = convexHullShape->getMarginNonVirtual(); convexHullShape->getNonvirtualAabb (t, aabbMin, aabbMax, margin); } break; default: #ifndef __SPU__ this->getAabb (t, aabbMin, aabbMax); #else btAssert (0); #endif break; } // should never reach here btAssert (0); }
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(); } }
UserRayHitCollectorDemo::UserRayHitCollectorDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env), m_time(0.0f) { // // Setup the camera. // { hkVector4 from(-8.0f, 25.0f, 20.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.setBroadPhaseWorldSize( 100.0f ); m_world = new hkpWorld(info); m_world->lock(); setupGraphics(); } // // Create a row of colored rigid bodies // { hkVector4 halfExtents(.5f, .5f, .5f ); hkpShape* shape = new hkpBoxShape( halfExtents , 0 ); int colors[4] = { hkColor::RED, hkColor::GREEN, hkColor::BLUE, hkColor::YELLOW }; for (int i = 0; i < 4; i++ ) { hkpRigidBodyCinfo ci; ci.m_motionType = hkpMotion::MOTION_FIXED; ci.m_shape = shape; ci.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(i+1); ci.m_position.set( i * 3.0f, 0.f, 0.0f); hkpRigidBody* body = new hkpRigidBody( ci ); body->addProperty( COLOR_PROPERTY_ID, colors[i] ); m_world->addEntity(body); body->removeReference(); // show the objects in nice transparent colors colors[i] &= ~hkColor::rgbFromChars( 0, 0, 0 ); colors[i] |= hkColor::rgbFromChars( 0, 0, 0, 120 ); HK_SET_OBJECT_COLOR((hkUlong)body->getCollidable(), colors[i]); } shape->removeReference(); } m_world->unlock(); }