示例#1
0
void MoppInstancingDemo::addBoxPile(int numBoxes, hkVector4Parameter offset)
{
	hkVector4 boxRadii( 0.5f, 0.5f, 0.5f);
	hkpBoxShape* cubeShape = new hkpBoxShape(boxRadii, 0 );

	hkpRigidBodyCinfo boxInfo;

	boxInfo.m_mass = 1.0f;
	boxInfo.m_shape = cubeShape;
	hkpInertiaTensorComputer::setShapeVolumeMassProperties(boxInfo.m_shape, boxInfo.m_mass, boxInfo);
	boxInfo.m_rotation.setIdentity();
	boxInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA;

	for (int i = 0; i < numBoxes; i++ )
	{
		//
		// create a rigid body (using the template above) and add to the m_world
		//
		boxInfo.m_position.set(0, i * 1.4f, -.15f*i);
		boxInfo.m_position.add4(offset);
		boxInfo.m_restitution = .2f;

		hkpRigidBody* boxRigidBody = new hkpRigidBody(boxInfo);
		m_world->addEntity( boxRigidBody );
		boxRigidBody->removeReference();
	}
	cubeShape->removeReference();
}
static void CreateFlatCubeGrid( hkpWorld* world, int size, float height = 0 )
{
	hkReal boxDim = 1.0f;
	float delta = boxDim * 3.0f;

	hkReal boxRadius = 0.01f;
	hkVector4 boxRadii(boxDim, boxDim, boxDim);
	hkpShape* boxShape = new hkpBoxShape( boxRadii, boxRadius );

	// flat cube grid, made up of (1.5*size)*(1.5*size) cubes
	for (int x = -size/2; x < size; x++)
	{
		for (int y = -size/2; y < size; y++)
		{
			hkpRigidBodyCinfo boxInfo;

			boxInfo.m_mass = 100.0f;
			hkReal d = boxInfo.m_mass * boxDim * boxDim / 6.0f;
			boxInfo.m_inertiaTensor.setDiagonal(d,d,d);

			boxInfo.m_shape = boxShape;
			boxInfo.m_motionType = hkpMotion::MOTION_DYNAMIC;
			boxInfo.m_position.set( x * delta, boxDim + height, y * delta);
			boxInfo.m_restitution = 0.0f;
			boxInfo.m_solverDeactivation = hkpRigidBodyCinfo::SOLVER_DEACTIVATION_MAX;

			hkpRigidBody* boxRigidBody = new hkpRigidBody(boxInfo);
			world->addEntity( boxRigidBody );
			boxRigidBody->removeReference();	// Remove reference, since we no long
		}
	}
	boxShape->removeReference();
}
static void CreateFall( hkpWorld* world, int height )
{
	hkReal boxDim = 1.0f;
	hkReal boxRadius = 0.01f;
	hkVector4 boxRadii(boxDim *.5f, boxDim *.5f - boxRadius, boxDim *.5f);
	hkpShape* boxShape = new hkpBoxShape( boxRadii, boxRadius );

	// 64 columns of cubes, of height 'height'
	for (int x = -4; x < 4; x++)
	{
		for (int y = -4; y < 4; y++)
		{
			for (int z = 0; z < height; z++)
			{
				hkpRigidBodyCinfo boxInfo;

				boxInfo.m_mass = 100.0f;
				hkReal d = boxInfo.m_mass * boxDim * boxDim / 6.0f;
				boxInfo.m_inertiaTensor.setDiagonal(d,d,d);

				boxInfo.m_shape = boxShape;
				boxInfo.m_motionType = hkpMotion::MOTION_DYNAMIC;
				boxInfo.m_position.set( x* 3.0f, z * 1.0f, y * 3.0f);
				boxInfo.m_restitution = 0.0f;
				boxInfo.m_angularDamping = 1.0f;
				boxInfo.m_linearDamping = .0f;
				boxInfo.m_friction = 1.0f;
				boxInfo.m_solverDeactivation = hkpRigidBodyCinfo::SOLVER_DEACTIVATION_MAX;

				hkpRigidBody* boxRigidBody = new hkpRigidBody(boxInfo);
				world->addEntity( boxRigidBody );
				boxRigidBody->removeReference();	// Remove reference, since we no long
			}
		}
	}

	boxShape->removeReference();
}
MassChangerDemo::MassChangerDemo(hkDemoEnvironment* env)
    :	hkDefaultPhysicsDemo(env)
{
    // Disable warnings:
    hkError::getInstance().setEnabled(0xf0de4356, false); // 'Your m_contactRestingVelocity seems to be too small'

    //
    // Setup the camera
    //
    {
        hkVector4 from(0.0f, 8.0f, 24.0f);
        hkVector4 to  (0.0f, 0.0f,  0.0f);
        hkVector4 up  (0.0f, 1.0f,  0.0f);
        setupDefaultCameras( env, from, to, up );
    }

    //
    // Create the world
    //
    {
        hkpWorldCinfo info;

        info.m_gravity.set(0.0f, -9.8f, 0.0f);
        info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM);
        info.m_collisionTolerance = 0.01f;
        info.m_contactRestingVelocity = 0.01f;
        //info.m_contactRestingVelocity = 10000.01f;

        m_world = new hkpWorld( info );
        m_world->lock();

        // Register ALL agents (though some may not be necessary)
        hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());

        setupGraphics();
    }


    //
    // Create the base
    //
    {
        hkVector4 baseSize( 15.0f, 0.3f, 15.0f);
        hkpConvexShape* shape = new hkpBoxShape( baseSize , 0 );

        hkpRigidBodyCinfo ci;

        ci.m_shape = shape;
        ci.m_motionType = hkpMotion::MOTION_FIXED;

        m_world->addEntity( new hkpRigidBody( ci ) )->removeReference();
        shape->removeReference();
    }

    {
        //
        //	The dimensions of the boxes etc.
        //

        const hkReal boxDim = 1.0f;				// This is the size of the cubes
        const hkReal extBoxDim = 1.1f * boxDim;	// This is an extended size (used to shorten the pendulums)
        const hkReal heightOffGround = 5.0f;	// This is the height of the fixed box from the ground

        //create the shared properties/attributes for the boxes

        hkVector4 boxRadii(boxDim *.5f, boxDim *.5f, boxDim *.5f);
        hkpShape* boxShape = new hkpBoxShape( boxRadii , 0 );
        hkpMassProperties massProperties;
        hkpInertiaTensorComputer::computeBoxVolumeMassProperties(boxRadii, 100.0f, massProperties);

        hkpRigidBodyCinfo boxInfo;

        boxInfo.m_inertiaTensor = massProperties.m_inertiaTensor;
        boxInfo.m_mass = massProperties.m_mass;
        boxInfo.m_shape = boxShape;
        boxInfo.m_qualityType = HK_COLLIDABLE_QUALITY_CRITICAL;
        boxInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA;


        // create four boxes, one fixed and above the base, two attached by springs
        // to either side of the fixed box, and one below it.
        // one of the pendulums will be in a higher position so that it hits the bottom
        // box later than the first

        // Note: only one of the "pendulum" boxes will be
        // able to influence the box on the ground (achieved
        // with mass changer utility)

        hkVector4 boxPos;

        // the box on the base
        {
            boxPos.set(0.0f,boxDim,0.0f,0.0f);
            boxInfo.m_position = boxPos;
            hkpRigidBody* boxRigidBody = new hkpRigidBody(boxInfo);
            m_bodies[0] = boxRigidBody;

            // Now add to world. Body is "ready to go" as soon as this is called, and display
            // is (as a registered listener) automatically notified to build a new display object.
            m_world->addEntity( boxRigidBody );
            boxRigidBody->removeReference();	// Remove reference, since we no longer want to remember this
        }

        // the pendulum boxes, number 1
        {
            float offset = hkMath::sqrtInverse(2.0f) * (heightOffGround - extBoxDim);
            boxPos.set( offset, heightOffGround + offset , 0.0f, 0.0f );
            boxInfo.m_position = boxPos;
            hkpRigidBody* boxRigidBody = new hkpRigidBody(boxInfo);
            m_bodies[1] = boxRigidBody;

            m_world->addEntity( boxRigidBody );
            boxRigidBody->removeReference();	// Remove reference, since we no longer want to remember this
        }

        // the pendulum boxes, number 2
        {
            boxPos.set(-heightOffGround + extBoxDim,heightOffGround,0.0f,0.0f);
            boxInfo.m_position = boxPos;
            hkpRigidBody* boxRigidBody = new hkpRigidBody(boxInfo);
            m_bodies[2] = boxRigidBody;

            m_world->addEntity( boxRigidBody );
            boxRigidBody->removeReference();	// Remove reference, since we no longer want to remember this
        }

        // the fixed box
        {
            boxPos.set(0.0f,heightOffGround,0.0f,0.0f);
            boxInfo.m_position = boxPos;
            boxInfo.m_motionType = hkpMotion::MOTION_FIXED;
            boxInfo.m_qualityType = HK_COLLIDABLE_QUALITY_FIXED;

            hkpRigidBody* boxRigidBody = new hkpRigidBody(boxInfo);
            m_bodies[3] = boxRigidBody;

            m_world->addEntity( boxRigidBody );
            boxRigidBody->removeReference();	// Remove reference, since we no longer want to remember this
        }

        //
        // create stiff spring constraint for pendulum 1
        //
        {
            hkpStiffSpringConstraintData* spring = new hkpStiffSpringConstraintData();
            // Create constraint
            spring->setInWorldSpace(m_bodies[3]->getTransform(), m_bodies[1]->getTransform(), m_bodies[3]->getPosition(), m_bodies[1]->getPosition());
            m_world->createAndAddConstraintInstance( m_bodies[3], m_bodies[1], spring )->removeReference();

            spring->removeReference();
        }

        //
        // create stiff spring constraint for pendulum 2
        //
        {
            // Create constraint
            hkpStiffSpringConstraintData* spring = new hkpStiffSpringConstraintData();
            spring->setInWorldSpace(m_bodies[3]->getTransform(), m_bodies[2]->getTransform(), m_bodies[3]->getPosition(), m_bodies[2]->getPosition());
            m_world->createAndAddConstraintInstance( m_bodies[3], m_bodies[2], spring )->removeReference();
            spring->removeReference();
        }

        //create a mass changer utility for the object
        const hkReal bodyARelInvMass = 0;
        const hkReal bodyBRelInvMass = 1;
        m_cmcu = new hkpCollisionMassChangerUtil( m_bodies[0], m_bodies[2], bodyARelInvMass, bodyBRelInvMass );

        boxShape->removeReference();
    }

    m_world->unlock();
}
static void CreateStack( hkpWorld* world, int size, float zPos = 0.0f )
{
	const hkReal cubeSize  = 1.0f;	// This is the size of the cube side of the box
	const hkReal boxRadius = cubeSize * 0.01f;
	const hkReal gapx    = cubeSize * 0.05f;		// This is the gap between boxes
	const hkReal gapy    = boxRadius;
	const hkReal heightOffGround = 0.0f;	// This is the height of the BenchmarkSuite off the gound

	hkReal extendedBoxDimX = cubeSize + gapx;
	hkReal extendedBoxDimY = cubeSize + gapy;


	hkVector4 startPos( 0.0f , heightOffGround + gapy + cubeSize * 0.5f, zPos);
	// Build BenchmarkSuite
	{
		hkVector4 boxRadii(cubeSize *.5f, cubeSize *.5f, cubeSize *.5f);

		hkpShape* boxShape = new hkpBoxShape( boxRadii , boxRadius );

		for(int i=0; i<size; i++)
		{
			// This constructs a row, from left to right
			int rowSize = size - i;
			hkVector4 start(-rowSize * extendedBoxDimX * 0.5f + extendedBoxDimX * 0.5f, i * extendedBoxDimY, 0);
			for(int j=0; j< rowSize; j++)
			{
				hkVector4 boxPos(start);
				hkVector4 shift(j * extendedBoxDimX, 0.0f, 0.0f);
				boxPos.setAdd4(boxPos, shift);
				boxPos.setAdd4(boxPos, startPos);

				///
				hkpRigidBodyCinfo boxInfo;

				boxInfo.m_mass = 100.0f;
				// calculate the correct inertia
				hkReal d = boxInfo.m_mass * cubeSize * cubeSize / 6.0f;

				// for small boxes increase inertia slightly
				if ( boxRadius < 0.1f )
				{
					d *= 2.0f;
					if ( boxRadius < 0.03f )
					{
						d *= 2.0f;
					}
				}
				boxInfo.m_inertiaTensor.setDiagonal(d,d,d);

				boxInfo.m_shape = boxShape;
				boxInfo.m_motionType = hkpMotion::MOTION_DYNAMIC;
				boxInfo.m_position = boxPos;
				boxInfo.m_restitution = 0.5f;
				boxInfo.m_friction = 0.6f;
				boxInfo.m_solverDeactivation = hkpRigidBodyCinfo::SOLVER_DEACTIVATION_MAX;
				///>

				hkpRigidBody* boxRigidBody = new hkpRigidBody(boxInfo);

				// Now add to world. Body is "ready to go" as soon as this is called, and display
				// is (as a registered listener) automatically notified to build a new display object.
				world->addEntity( boxRigidBody );
				boxRigidBody->removeReference();	// Remove reference, since we no longer want to remember this
			}
		}
		boxShape->removeReference();
	}
}
SuspendInactiveAgentsDemo::SuspendInactiveAgentsDemo( hkDemoEnvironment* env )
:	hkDefaultPhysicsDemo(env)
{
	
	// Disable warnings:									
	hkError::getInstance().setEnabled(0x7dd65995, false); //'The system has requested a heap allocation on stack overflow.'
	hkError::getInstance().setEnabled(0x86bc014f, false); //'For the default implementation to work the class must be passed in'

	//
	// Setup the camera. Actually overwritten by step function, and when we first add the vehicle.
	//
	{
		hkVector4 from(0.0f, 2.0f, 12.0f);
		hkVector4 to(0.0f, 0.0f, 0.0f);
		hkVector4 up(0.0f, 1.0f, 0.0f);
		setupDefaultCameras( m_env, from, to, up );
	}

	//
	// Create the world.
	//
	{
		hkpWorldCinfo info;
		info.m_collisionTolerance = 0.01f;
		info.m_gravity.set(0.0f, -9.8f, 0.0f);
		info.setBroadPhaseWorldSize(850.0f) ;
		info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM);
		m_world = new hkpWorld( info );
		m_world->lock();

		// Register all agents.
		hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());
		// Graphics.
		m_debugViewerNames.pushBack( hkpSimulationIslandViewer::getName());
		setupGraphics();
	}

	//
	//	Enable deleting inactive agents
	//
	{
		m_suspendInactiveAgentsUtil = new hkpSuspendInactiveAgentsUtil( m_world, hkpSuspendInactiveAgentsUtil::SUSPEND_ALL_COLLECTION_AGENTS );
	}

	//
	// Create a filter, so that the raycasts of car does not collide with the ragdolls
	//
	{
		hkpGroupFilter* filter = new hkpGroupFilter();
		filter->disableCollisionsBetween(1,3);

		m_world->setCollisionFilter( filter );
		filter->removeReference();
	}

	// Build the landscape to drive on and add it to m_world.
	buildLandscape();

	if (getDemoVariant() < 2)
	{
		int gridSize = hkMath::clamp(m_env->m_cpuMhz / 150, 2, 4);
		createRagdollGrid( m_world, gridSize, gridSize, 4.0f, 4.0f );
		m_boxRigidBody = HK_NULL;
	}
	else
	{
		//
		// Warm starting manifold - just illustrate with one box on a simple landscape
		//

		hkVector4 boxRadii( 1, .2f, 1);
		hkpShape* smallBox = new hkpBoxShape(boxRadii, 0 );

		hkpRigidBodyCinfo boxInfo;

		boxInfo.m_mass = 1.0f;
		boxInfo.m_shape = smallBox;
		hkpInertiaTensorComputer::setShapeVolumeMassProperties(boxInfo.m_shape, boxInfo.m_mass, boxInfo);
		boxInfo.m_rotation.setIdentity();
		boxInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA;
		boxInfo.m_position.set(2, 2, 2);
		boxInfo.m_restitution = .3f;
		boxInfo.m_qualityType = HK_COLLIDABLE_QUALITY_CRITICAL; //XXX

		m_boxRigidBody = new hkpRigidBody(boxInfo);
		smallBox->removeReference();

		m_world->addEntity( m_boxRigidBody );
		m_frameCount = 0;

		// Change the camera position to view the box close up

		hkVector4 from(0.91f, 0.87f, 5.52f);
		hkVector4 to(2.66f, -.16f, -.06f);
		hkVector4 up(0.0f, 1.0f, 0.0f);
		setupDefaultCameras( m_env, from, to, up );

	}

	m_world->unlock();
}