Example #1
0
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;
	}
Example #3
0
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);

}
Example #4
0
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);
		}
	}
}
Example #5
0
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;
}
Example #6
0
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());
}
Example #8
0
    // 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;
    }
Example #9
0
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);
}
Example #10
0
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);
}
Example #11
0
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);
	}
	*/
}
Example #12
0
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);
}
Example #13
0
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) );
		}
	}
	
}
Example #15
0
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;
}
Example #16
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;
}
Example #17
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);
}
Example #18
0
//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();
}
Example #19
0
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;

}
Example #20
0
//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();
}
Example #22
0
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);
}
Example #23
0
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..)
}
Example #24
0
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();
}
Example #26
0
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();
		}
	}
}
Example #28
0
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();
}