コード例 #1
0
void KeyframingDemo::createBodies()
{	

	// Each body needs at least one shape
	const hkVector4 halfExtents(1.0f, 0.75f, 1.0f);
	hkpShape* shape = new hkpBoxShape(halfExtents, 0 );

	// Compute the inertia tensor from the shape
	hkpMassProperties massProperties;
	hkpInertiaTensorComputer::computeShapeVolumeMassProperties(shape, 5.0f, massProperties);

	// Assign the rigid body properties
	hkpRigidBodyCinfo bodyInfo;
	bodyInfo.m_mass = massProperties.m_mass;
	bodyInfo.m_centerOfMass = massProperties.m_centerOfMass;
	bodyInfo.m_inertiaTensor = massProperties.m_inertiaTensor;
	bodyInfo.m_shape = shape;
	bodyInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA;


	bodyInfo.m_friction = 0.1f;

	for(int i = 0; i < m_numBodies; i++)
	{
		bodyInfo.m_position.set( hkMath::cos(hkReal(i)) - 2.0f, i * 2.0f, hkMath::sin(hkReal(i)));
		hkpRigidBody* body = new hkpRigidBody(bodyInfo);
		m_world->addEntity(body);
		body->removeReference();
	}	
	shape->removeReference();

}
コード例 #2
0
void SpiderDemo::moveSpider( SpiderLayout& sl, hkReal time, hkReal leftVel, hkReal rightVel )
{
	int legId = 0;
	for (int posId = 0; posId < sl.m_numLegs; posId++ )
	{
		hkReal xf = posId/hkReal(sl.m_numLegs-1)*2.0f - 1.0f;
		hkReal vel = leftVel;
		for (int z = -1; z <= 1; z+=2 )
		{
			Leg& leg = m_legs[legId++];
			moveLeg( sl, leg, hkReal(z), xf, time, vel );
			vel = rightVel;
		}
	}
}
コード例 #3
0
// Raycast from the bottom (Y is up) to make sure that raycasting against the scaled mopp works
void MoppInstancingDemo::checkRayCasts(const hkpMoppBvTreeShape* mopp, const hkTransform& t)
{
	hkAabb aabb; mopp->getAabb(hkTransform::getIdentity(), 1.0f, aabb);
	hkVector4 extents; extents.setSub4(aabb.m_max, aabb.m_min);

	const int numX=10, numZ = 10;
	const hkReal deltaX = extents(0) / hkReal(numX-1);
	const hkReal deltaZ = extents(2) / hkReal(numZ-1);

	for (int x=0; x<numX; x++)
	{
		for (int z=0; z<numZ; z++)
		{
			hkpShapeRayCastInput input;
			hkpShapeRayCastOutput output;
			input.m_from(0) = aabb.m_min(0) + hkReal(x)*deltaX;
			input.m_from(1) = aabb.m_min(1)                   ;
			input.m_from(2) = aabb.m_min(2) + hkReal(z)*deltaZ;
				
			input.m_to = input.m_from;
			input.m_to(1) = aabb.m_max(1);
			input.m_rayShapeCollectionFilter = HK_NULL;

			mopp->castRay(input, output);

			hkVector4 worldFrom, worldTo;
			worldFrom.setTransformedPos(t, input.m_from);
			worldTo.setTransformedPos(t, input.m_to);

			if (output.hasHit())
			{
				hkVector4 hitpoint; hitpoint.setInterpolate4(worldFrom, worldTo, output.m_hitFraction);
				HK_DISPLAY_LINE(worldFrom, hitpoint, hkColor::GREEN);
			}

			// Check that the naive raycast gives the same results
			hkpShapeRayCastOutput testOutput;
			mopp->getShapeCollection()->castRay(input, testOutput);

			HK_ASSERT(0x793171a3, hkMath::equal(testOutput.m_hitFraction, output.m_hitFraction) );
			if ( !hkMath::equal(testOutput.m_hitFraction, 1.0f) )
			{
				HK_ASSERT(0x793171a3, testOutput.m_normal.equals3(output.m_normal) );
			}
		}
	}

}
コード例 #4
0
void CompressionDemo::AddAnimation(const char* name, hkaAnimation* anim, hkaAnimationBinding* binding, int skipOffset )
{
	TestRecord* rec = new TestRecord;

	rec->m_name = name;
	rec->m_bytes = 0;

	// Set up the binding
	rec->m_binding = new hkaAnimationBinding();
	hkString::memCpy(rec->m_binding, binding, sizeof(hkaAnimationBinding) );
	rec->m_binding->m_animation = anim;

	// Create an animation control
	hkaDefaultAnimationControl* ac = new hkaDefaultAnimationControl(rec->m_binding);

	// Create a new animated skeleton
	rec->m_animatedSkeleton = new hkaAnimatedSkeleton( m_skeleton );
	rec->m_animatedSkeleton->setReferencePoseWeightThreshold(0.001f);

	// Bind the control to the skeleton
	rec->m_animatedSkeleton->addAnimationControl( ac );

	// The animated skeleton now owns the control
	ac->removeReference();

	rec->m_offset = OFFSET;
	rec->m_offset.mul4( hkReal(m_animationRecords.getSize() + skipOffset) );

	m_animationRecords.pushBack(rec);
}
コード例 #5
0
ファイル: DemoKeeper.cpp プロジェクト: kevinmore/MyPhysicsLab
void DemoKeeper::createBodies( void )
{
	// Each body needs at least one shape
	const hkVector4 halfExtents(1.0f, 0.75f, 1.0f);
	hkpShape* shape = new hkpBoxShape(halfExtents, 0 );

	// Compute the inertia tensor from the shape
	hkMassProperties massProperties;
	hkpInertiaTensorComputer::computeShapeVolumeMassProperties(shape, 5.0f, massProperties);

	// Assign the rigid body properties
	hkpRigidBodyCinfo bodyInfo;
	bodyInfo.m_mass = massProperties.m_mass;
	bodyInfo.m_centerOfMass = massProperties.m_centerOfMass;
	bodyInfo.m_inertiaTensor = massProperties.m_inertiaTensor;
	bodyInfo.m_shape = shape;
	bodyInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA;


	bodyInfo.m_friction = 0.1f;

	for(int i = 0; i < m_numBodies; i++)
	{
		bodyInfo.m_position.set( hkMath::cos(hkReal(i)) - 2.0f, i * 2.0f + 10, hkMath::sin(hkReal(i)));
		hkpRigidBody* body = new hkpRigidBody(bodyInfo);
		mWorld->addEntity(body);
		body->removeReference();

		//render it with Ogre
		Ogre::SceneNode* boxNode = mSceneMgr->getRootSceneNode()->createChildSceneNode();

		//scale
		boxNode->scale(2, 1.5, 2);

		//display and sync
		Ogre::Entity *ent = mSceneMgr->createEntity(Ogre::StringConverter::toString(mLabMgr->getEntityCount()),"defCube.mesh");
		mLabMgr->setColor(ent, Ogre::Vector3(rand()/(double)RAND_MAX,rand()/(double)RAND_MAX,rand()/(double)RAND_MAX));
		HkOgre::Renderable* rend = new HkOgre::Renderable(boxNode, body,mWorld);
		boxNode->attachObject(ent);

		//register to lab manager
		mLabMgr->registerEnity( boxNode, body);
	}	
	shape->removeReference();
}
コード例 #6
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 );
	}
}
コード例 #7
0
static void CreateListGrid( hkpWorld* world, hkReal bound, int numPerCubeSide, int numPerList )
{
	// Add List Shapes
	{
		hkPseudoRandomGenerator gen(123);

		for (int i = 0; i < numPerCubeSide; i++)
		{
			for (int j = 0; j < numPerCubeSide; j++)
			{
				for (int k = 0; k < numPerCubeSide; k++)
				{
					hkArray<hkpShape*> listElems;
					for (int e = 0; e < numPerList; e++)
					{
						// Make a random convex vertex shape
						hkVector4 cen; gen.getRandomVector11( cen ); cen.mul4( bound / (numPerCubeSide * 4.0f) );
						hkVector4 extent; extent.setAll3( bound /  (numPerCubeSide * 4) );
						listElems.pushBack( GameUtils::createConvexVerticesBoxShape( cen, extent, hkConvexShapeDefaultRadius ) );
					}

					hkpShape* listShape = new hkpListShape( listElems.begin(), listElems.getSize() );
					for (int s=0; s < listElems.getSize(); s++)
					{
						listElems[s]->removeReference();
					}

					hkpRigidBodyCinfo ci;
					ci.m_motionType = hkpMotion::MOTION_BOX_INERTIA;
					ci.m_shape = listShape;
					ci.m_mass = 1.f;

					ci.m_position.set( hkReal(i - numPerCubeSide / 2), hkReal(j + 1), hkReal(k - numPerCubeSide / 2) );
					ci.m_position.mul4( bound / numPerCubeSide );

					hkpRigidBody* body = new hkpRigidBody( ci );
					world->addEntity(body);
					body->removeReference();
					listShape->removeReference();
				}
			}
		}
	}
}
コード例 #8
0
void SpiderDemo::createSpider( hkpWorld* world, SpiderLayout& sl )
{
	hkVector4 center( 0, 1, 0 );

	// center body
	hkpRigidBody* rootBody;
	{
		hkpRigidBodyCinfo ci;
		ci.m_shape = new hkpBoxShape( sl.m_bodyHalfExtents, 0.0f );
		ci.m_friction = 2.0f;
		ci.m_restitution = 0.0f;
		ci.m_collisionFilterInfo = sl.m_filterInfo;
		ci.m_motionType = hkpMotion::MOTION_BOX_INERTIA;
		ci.m_position = center;
		ci.m_angularDamping = 1.0f;

		hkReal mass = 30.0f;
		hkReal inertiaFactor = 1.0f;
		hkpMassProperties mp;
		hkpInertiaTensorComputer::computeBoxVolumeMassProperties( sl.m_legHalfExtents, mass * inertiaFactor, mp );
		ci.m_mass = mass;
		ci.m_inertiaTensor = mp.m_inertiaTensor;

		rootBody = new hkpRigidBody( ci );
		world->addEntity( rootBody );
		rootBody->removeReference();
		ci.m_shape->removeReference();
	}

	// legs
	{
		for (int leg = 0; leg < sl.m_numLegs; leg++ )
		{
			hkReal xf = leg/hkReal(sl.m_numLegs-1)*2.0f - 1.0f;
			for (int z = -1; z <= 1; z+=2 )
			{
				SpiderDemo::calcLegMatrizesIn m;
				m.m_from = center;
				m.m_from(0) += xf * sl.m_bodyHalfExtents(0);
				m.m_from(2) += z  * sl.m_bodyHalfExtents(2);

				m.m_to = center;
				m.m_to(0) += xf * sl.m_legHalfExtents(0);
				m.m_to(1) -= sl.m_legHalfExtents(1);
				m.m_to(2) += z * sl.m_legHalfExtents(2);
				m.m_up.set(0,1,0);
				hkVector4 diff; diff.setSub4( m.m_to, m.m_from );
				hkReal len = diff.length3();
				m.m_lenA = 0.6f * len;
				m.m_lenB = 0.8f * len;
				buildLeg( world, rootBody, m, sl.m_filterInfo, m_legs.expandOne() );
			}
		}
	}
}
コード例 #9
0
KdTreeVsBroadphaseDemo::KdTreeVsBroadphaseDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env), 
	m_flattenRays(false),
	m_rand(1337)
{

	{
		m_worldSizeX = 2.0f * hkMath::sqrt(hkReal(m_env->m_cpuMhz));
		m_worldSizeY = 3;
		m_worldSizeZ = m_worldSizeX;
	}

	// Setup the camera and graphics
	{
		// setup the camera
		hkVector4 from(0.0f, m_worldSizeZ*2.f, -m_worldSizeZ);
		hkVector4 to  (0.0f, 0.0f,  0.0f);
		hkVector4 up  (0.0f, 1.0f,  0.0f);
		setupDefaultCameras( env, from, to, up, 1.0f, 5000.0f );
	}


	{
		hkpWorldCinfo cinfo;
		cinfo.m_gravity.setAll(0);
		cinfo.m_broadPhaseWorldAabb.m_max.set( m_worldSizeX,  10.0f*m_worldSizeY,  m_worldSizeZ);
		cinfo.m_broadPhaseWorldAabb.m_min.setNeg4(	cinfo.m_broadPhaseWorldAabb.m_max );	
		cinfo.m_useKdTree = true;
		m_world = new hkpWorld(cinfo);
		m_world->lock();
	}

	{
		hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());
	}

	//
	// Add a lot of rigid bodies to the world
	//
	{
		hkAabb worldAabb; 
		worldAabb.m_max.set( m_worldSizeX,  10.0f*m_worldSizeY,  m_worldSizeZ);
		worldAabb.m_min.setNeg4( worldAabb.m_max );	

		hkpMotion::MotionType motionType = hkpMotion::MOTION_FIXED;
		KdTreeDemoUtils::createRandomBodies(m_world, worldAabb, numBodies, motionType, &m_rand, m_collidables);

	}


	setupGraphics();
	
	m_world->unlock();
}
コード例 #10
0
hkReal BridgeLand::getHeight( int x, int y )
{
	hkReal percentageX = hkReal(x) / hkReal(m_side);

	// flatten terrain if we are outside of canyon area
	if ( percentageX < (0.5f - m_halfCanyonWidthRatio) || percentageX > (0.5f + m_halfCanyonWidthRatio) )
	{
		return 0.0f;
	}

	// smoothen out slope if flag is set
	if ( m_smoothBreak )
	{
		percentageX = (percentageX - (0.5f - m_halfCanyonWidthRatio)) / (m_halfCanyonWidthRatio*2.0f);
	}

	hkReal adjustedCosinus = (hkMath::cos(percentageX*2.0f*HK_REAL_PI) - 1.0f) * 0.5f;

	return adjustedCosinus * m_maxHeight;
}
コード例 #11
0
void vHavokVisualDebugger::Step()
{
  // Get the local timers to feed to the stats viewer
  // reset our VDB stats list
  if (m_physicsContext)
  {
    m_physicsContext->syncTimers(vHavokPhysicsModule::GetInstance()->GetThreadPool());
  }

  hkReal dt = Vision::GetTimer()->GetTimeDifference();

  // Step the debugger
  m_pVisualDebugger->step(dt*hkReal(1000));

  // Update camera
  hkVector4 pos; 
  vHavokConversionUtils::VisVecToPhysVecWorld(Vision::Camera.GetMainCamera()->GetPosition(),pos);
  hkVector4 dir; 
  vHavokConversionUtils::VisVecToPhysVec_noscale(Vision::Camera.GetMainCamera()->GetDirection(),dir);
  hkVector4 up;
  vHavokConversionUtils::VisVecToPhysVec_noscale(Vision::Camera.GetMainCamera()->GetObjDir_Up(), up);

  hkVector4 lookat;
  lookat.setAdd(pos,dir);

  // Havok visual debugger defaults
  float nearPlane = 0.1f;
  float farPlane = 500.f;
  float fovX = 0.f;
  float fovY = 45.f;


  VisRenderContext_cl::GetMainRenderContext()->GetClipPlanes(nearPlane, farPlane);
  VisRenderContext_cl::GetMainRenderContext()->GetFinalFOV(fovX, fovY);

  // Scale them to Havok space
  nearPlane = float(VIS2HK_FLOAT_SCALED(nearPlane));
  farPlane = float(VIS2HK_FLOAT_SCALED(farPlane));

  HK_UPDATE_CAMERA(pos, lookat, up, nearPlane, farPlane, fovY, "Vision");

  // Reset internal profiling info for next frame
  hkMonitorStream::getInstance().reset();
}
コード例 #12
0
void vHavokTerrain::CreateHkRigidBody()
{
  // Create the Havok shape
  hkpShape *pShape = vHavokShapeFactory::CreateShapeFromTerrain(*m_terrainSector);

  // Create the Havok rigid body
  hkpRigidBodyCinfo rci;
  rci.m_motionType = hkpMotion::MOTION_FIXED;
  rci.m_shape = pShape;

  //subtract the y sample spacing from the original position to make sure that the physical representation and the visible terrain match
  hkvVec3 vSpacing(0, m_terrainSector->m_Config.m_vSampleSpacing.y, 0);
  vHavokConversionUtils::VisVecToPhysVecWorld(hkvVec3(m_terrainSector->GetSectorOrigin() - vSpacing),rci.m_position);
  rci.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(vHavokPhysicsModule::HK_LAYER_COLLIDABLE_TERRAIN);

  // We have two choices here. Heightfields in Havok are on the X,Z local plane, but in Vision they are 
  // X,Y, so some transform is required. We could rotate by -90 and invert the heights but that results 
  // in normals that are the opposite to what you would expect (which is fine though as double sided, but not ideal).
  // The second option is to rotate the opposite way and invert the lookup on Y (Havok local Z)
  // This second option of course shifts the direction of the extends, so we need to also include the translation for that:
  // y, but take into account the single sample edge overlap in the terrain
  hkSimdReal yvOffset; 
  yvOffset.setFromFloat( m_terrainSector->m_Config.m_vSectorSize.y + m_terrainSector->m_Config.m_vSampleSpacing.y );
  yvOffset.mul(vHavokConversionUtils::GetVision2HavokScaleSIMD());
  // Counter act the shift the extent dir
  rci.m_position.addMul( hkVector4::getConstant<HK_QUADREAL_0100>(), yvOffset );  
  rci.m_rotation.setAxisAngle(hkVector4::getConstant<HK_QUADREAL_1000>(),hkSimdReal_PiOver2); // Basis change
  
  rci.m_friction = hkReal(0.2f);

  m_pRigidBody = new hkpRigidBody( rci );

  // Set user data to identify this terrain during collision detection (raycast etc)
  m_pRigidBody->setUserData((hkUlong)vHavokUserDataPointerPair_t::CombineTypeAndPointer(this, V_USERDATA_TERRAIN));

  // Add our instance to the module
  m_module.AddTerrain(this);

  // Remove reference
  pShape->removeReference();   
}
コード例 #13
0
void Vehicle::SetInput(float steering, float acceleration, bool brake, bool reverse, bool fixedControl)
{
	if (m_instance == HK_NULL)
		return;

	if(!this->automated)
	Vision::Message.Print (1, 10, Vision::Video.GetYRes() - 100, "%f   %f  %d", acceleration,GetMPH(), brake);
	// Drive the car with our input
	hkpVehicleDriverInputAnalogStatus* deviceStatus = (hkpVehicleDriverInputAnalogStatus*)m_instance->m_deviceStatus;

	deviceStatus->m_handbrakeButtonPressed = brake;
	deviceStatus->m_reverseButtonPressed = reverse;
	deviceStatus->m_positionY = acceleration;

	if (fixedControl)
	{
		deviceStatus->m_positionX = hkMath::clamp(steering, -1.f, 1.f);
	}
	else
	{
		const hkReal delta = Vision::GetTimer()->GetTimeDifference();
		deviceStatus->m_positionX = hkMath::clamp(deviceStatus->m_positionX + steering * delta, hkReal(-1.0f), hkReal(1.0f));

		if (hkMath::equal(steering, 0.f))
		{
			float difference = 2.0f * delta;
			deviceStatus->m_positionX += difference * (deviceStatus->m_positionX > 0 ? -1 : 1);

			if (hkMath::equal(deviceStatus->m_positionX, 0.f, difference * 1.5f))
			{
				deviceStatus->m_positionX = 0.f;
			}
		}
	}
}
コード例 #14
0
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();
}
コード例 #15
0
BallAndSocketRopeDemo::BallAndSocketRopeDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env, DEMO_FLAGS_NO_SERIALIZE)
{
	const BallAndSocketRopeVariant& variant = g_variants[env->m_variantId];

	//
	// Setup the camera
	//
	{
		hkVector4 from(0.0f, -10.0f, 6.0f);
		hkVector4 to  (0.0f, 0.0f, 1.0f);
		hkVector4 up  (0.0f, 0.0f, 1.0f);
		setupDefaultCameras( env, from, to, up, 0.1f, 500.0f );
	}

	//
	// Create the world
	//
	{
		hkpWorldCinfo info;
		info.setBroadPhaseWorldSize( 1000.0f );
		info.m_gravity.set(0.0f, 0.0f, -9.81f);
		m_world = new hkpWorld( info );
		m_world->lock();
		m_world->m_wantDeactivation = false;

		setupGraphics();

		//
		// Create a group filter to avoid intra-collision for the rope
		//
		{
			hkpGroupFilter* filter = new hkpGroupFilter();
			m_world->setCollisionFilter( filter );
			filter->removeReference();
		}

	}

	hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() );


	//
	// Create debris
	//
	
	{
		int numDebris = 40;

		hkPseudoRandomGenerator generator(0xF14);

		hkpRigidBodyCinfo info;
		hkVector4 top; top.set(0.0f, 0.0f, 0.50f);
		hkVector4 bottom; bottom.set(0.f, 0.f, -0.50f);
		info.m_shape = new hkpCapsuleShape( top, bottom, 0.3f );
		hkpInertiaTensorComputer::setShapeVolumeMassProperties( info.m_shape, 5.0f, info );

		for (int d = 0; d < numDebris; d++)
		{
			hkReal xPos = generator.getRandRange(-10.0f, 10.0f);
			hkReal yPos = generator.getRandRange(-10.0f, 10.0f);

			hkBool isDynamic = (generator.getRand32() % 4) != 0;
			info.m_position.set( xPos, yPos, isDynamic ? 0.8f : 0.5f );

			info.m_motionType = isDynamic ? hkpMotion::MOTION_DYNAMIC : hkpMotion::MOTION_FIXED;

			hkpRigidBody* debris = new hkpRigidBody(info);
			m_world->addEntity(debris);
			debris->removeReference();
		}
		info.m_shape->removeReference();
	}

	//
	// Create ground box
	//
	{
		hkpRigidBodyCinfo info;
		info.m_motionType = hkpMotion::MOTION_FIXED;
		info.m_shape = new hkpBoxShape( hkVector4(100.0f, 100.0f, 0.1f) );
		info.m_position(2) = - 0.1f;

		hkpRigidBody* ground = new hkpRigidBody(info);
		info.m_shape->removeReference();

		m_world->addEntity(ground);
		ground->removeReference();

		HK_SET_OBJECT_COLOR( hkUlong(ground->getCollidable()), 0xff339933);
	}

	//
	// Create fixed peg over the ground
	//
	{
		hkpRigidBodyCinfo info;
		info.m_motionType = hkpMotion::MOTION_FIXED;
		info.m_shape = new hkpCapsuleShape( hkVector4(0.0f, 1.0f, 0.0f), hkVector4( 0,-1.0f, 0), 0.3f );
		info.m_position.set(0.0f, 0.0f, 3.0f);

		hkpRigidBody* peg = new hkpRigidBody(info);
		info.m_shape->removeReference();

		m_world->addEntity(peg);
		peg->removeReference();
	}



	//
	// Create chain
	//
	{
		hkReal elemHalfSize = 0.075f;
		hkpShape* sphereShape = new hkpSphereShape(0.3f); 
		hkpShape* capsuleShape = new hkpCapsuleShape( hkVector4(elemHalfSize, 0.0f, 0.0f), hkVector4(-elemHalfSize, 0.0f, 0.0f), 0.03f );

		hkpRigidBodyCinfo info;

		info.m_linearDamping = 0.0f;
		info.m_angularDamping = 0.3f;
		info.m_friction = 0.0f;
		//info.m_qualityType = HK_COLLIDABLE_QUALITY_MOVING;
		info.m_motionType = hkpMotion::MOTION_SPHERE_INERTIA;
		info.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(1, 1);


		{
			hkArray<hkpRigidBody*> entities;
		
			for (int b = 0; b < variant.m_numBodies; b++)
			{
				info.m_position.set(elemHalfSize * 2.0f * (b - hkReal(variant.m_numBodies-1) / 2.0f), 0.0f, 4.0f);

				hkReal mass;
				hkReal inertiaMultiplier;
				if (0 == b || variant.m_numBodies-1 == b)
				{
					info.m_shape = sphereShape;
					mass  = 10.0f;
					inertiaMultiplier = 1.0f;
				}
				else
				{
					info.m_shape = capsuleShape;
					mass  = 1.0f;
					inertiaMultiplier = 50.0f;
				}
				hkpInertiaTensorComputer::setShapeVolumeMassProperties(info.m_shape, inertiaMultiplier * mass, info);
				info.m_mass = mass;


				{
					hkpRigidBody* body = new hkpRigidBody(info);
					m_world->addEntity(body);
					entities.pushBack(body);
				}
			}
	
			{
				// connect all the bodies
				hkpConstraintChainInstance* chainInstance;
				{
					hkpBallSocketChainData* chainData = new hkpBallSocketChainData();
					chainInstance = new hkpConstraintChainInstance( chainData );

					chainInstance->addEntity( entities[0] );
					for (int e = 1; e < entities.getSize(); e++)
					{
						chainData->addConstraintInfoInBodySpace( hkVector4(elemHalfSize, 0.0f, 0.0f), hkVector4( -elemHalfSize, 0.0f, 0.0f) );
						chainInstance->addEntity( entities[e] );
					}
					chainData->removeReference();
				}

				m_world->addConstraint(chainInstance);
				chainInstance->removeReference();
			}

			for (int i = 0; i < entities.getSize(); i++)
			{
				entities[i]->removeReference();
			}
		}
		sphereShape->removeReference();
		capsuleShape->removeReference();
	}

	m_world->unlock();
}
コード例 #16
0
void TractorSetup::setupVehicleData( const hkpWorld* world, hkpVehicleData& data )
{
    data.m_gravity = world->getGravity();

    //
    // The vehicleData contains information about the chassis.
    //

    // The mass is set in the rigid body.

    // The coordinates of the chassis system, used for steering the vehicle.
    //										up					forward				right
    data.m_chassisOrientation.setCols( hkVector4(0, 1, 0), hkVector4(1, 0, 0), hkVector4(0, 0, 1));

    data.m_frictionEqualizer = 0.5f;

    data.m_torqueRollFactor = 0.5f;
    data.m_torquePitchFactor = 1.25f;
    data.m_torqueYawFactor = 0.5f;

    data.m_chassisUnitInertiaYaw = 1.0f;
    data.m_chassisUnitInertiaRoll = 1.0f;
    data.m_chassisUnitInertiaPitch = 1.0f;

    data.m_extraTorqueFactor = -1.0f;
    data.m_maxVelocityForPositionalFriction = 10.0f;

    //
    // Wheel specifications
    //
    data.m_numWheels = 6;

    data.m_wheelParams.setSize( data.m_numWheels );

    data.m_wheelParams[0].m_axle = 0;
    data.m_wheelParams[1].m_axle = 0;
    data.m_wheelParams[2].m_axle = 1;
    data.m_wheelParams[3].m_axle = 1;
    data.m_wheelParams[4].m_axle = 1;
    data.m_wheelParams[5].m_axle = 1;

    data.m_wheelParams[0].m_friction = 2.3f;
    data.m_wheelParams[1].m_friction = 2.3f;
    data.m_wheelParams[2].m_friction = 4.0f;
    data.m_wheelParams[3].m_friction = 4.0f;
    data.m_wheelParams[4].m_friction = 4.0f;
    data.m_wheelParams[5].m_friction = 4.0f;

    for ( int i = 0 ; i < data.m_numWheels ; i++ )
    {
        // This value is also used to calculate the m_primaryTransmissionRatio.
        data.m_wheelParams[i].m_radius = 0.5f;
        data.m_wheelParams[i].m_width = 0.2f;
        data.m_wheelParams[i].m_mass = 80.0f;

        data.m_wheelParams[i].m_viscosityFriction = 0.2f;
        data.m_wheelParams[i].m_slipAngle   = 0.0f;
        data.m_wheelParams[i].m_maxFriction = 2.0f * data.m_wheelParams[i].m_friction;
        data.m_wheelParams[i].m_forceFeedbackMultiplier = 10.0f;
        data.m_wheelParams[i].m_maxContactBodyAcceleration = hkReal(data.m_gravity.length3()) * 2;
    }
}
コード例 #17
0
hkDemo::Result UnevenTerrainVsDemo::stepDemo()
{
	HK_TIMER_BEGIN( "simulate multiply characters", HK_NULL );

	m_world->lock();

	hkVector4 up;
	up.setNeg4( m_world->getGravity() );
	up.normalize3();

	m_tick++;

	hkpCharacterInput inputRb;
	hkpCharacterInput inputProxy;
	// Fill in the state machine input structure for character rigid body
	{
		inputRb.m_atLadder = false;
		inputRb.m_up = up;

		// Steer the characters
		inputRb.m_inputLR = 0.0f;
		inputRb.m_inputUD = 1.0f;
		{
			// The factor 70.0f gives a turning circle which fits in the level 
			// for the default walk speed of 10.0f.
			hkReal walkSpeedFactor = m_options.m_characterWalkSpeed / 70.0f;
			hkReal time = hkReal(m_tick) * walkSpeedFactor / 60.0f;
			const hkReal x = hkMath::sin(time);
			const hkReal z = hkMath::cos(time);
			inputRb.m_forward.set( x, 0, z );
			inputRb.m_forward.normalize3();
		}

		inputRb.m_wantJump = false;
	
		hkStepInfo stepInfo;
		stepInfo.m_deltaTime = m_timestep;
		stepInfo.m_invDeltaTime = 1.0f/m_timestep;

		inputRb.m_stepInfo = stepInfo;

		inputRb.m_characterGravity.set( 0.0f, m_options.m_characterGravity, 0.0f );
		
		inputProxy = inputRb;

		// character rigid body specific code

		inputRb.m_velocity = m_characterRigidBody->getLinearVelocity();
		inputRb.m_position = m_characterRigidBody->getPosition();
		m_characterRigidBody->checkSupport(stepInfo, inputRb.m_surfaceInfo);

		filterStates( m_filterRigidBody, inputRb.m_surfaceInfo );

		m_supportHistoryRb <<= 1;
		if ( inputRb.m_surfaceInfo.m_supportedState == hkpSurfaceInfo::SUPPORTED )
		{
			++m_supportHistoryRb;
		}
		else
		{
			++m_unsupportedFramesCountRb;
		}


		// character proxy specific code

		inputProxy.m_velocity = m_characterProxy->getLinearVelocity();
		inputProxy.m_position = m_characterProxy->getPosition();
		hkVector4 down;	down.setNeg4(UP);
		m_characterProxy->checkSupport(down, inputProxy.m_surfaceInfo);

		filterStates( m_filterProxy, inputProxy.m_surfaceInfo );
		
		m_supportHistoryProxy <<= 1;
		if ( inputProxy.m_surfaceInfo.m_supportedState == hkpSurfaceInfo::SUPPORTED )
		{
			++m_supportHistoryProxy;
		}
		else
		{
			++m_unsupportedFramesCountProxy;
		}
	}

	hkpCharacterOutput outputRb;
	hkpCharacterOutput outputProxy;
	// Apply the character state machine
	{
		HK_TIMER_BEGIN( "update character state", HK_NULL );

		m_characterContext->update(inputRb, outputRb);
		m_characterProxyContext->update(inputProxy, outputProxy);

		HK_TIMER_END();

	}

	//Apply the character controllers
	{
		HK_TIMER_BEGIN( "simulate character", HK_NULL );

		// Feed the output velocity from state machine into character rigid body
		m_characterRigidBody->setLinearVelocity(outputRb.m_velocity, m_timestep);
		
		m_characterProxy->setLinearVelocity(outputProxy.m_velocity );
		hkStepInfo si;
		si.m_deltaTime = m_timestep;
		si.m_invDeltaTime = 1.0f/m_timestep;
		m_characterProxy->integrate( si, m_world->getGravity() );

		HK_TIMER_END();
	}

	{
		// If the character has fallen off the world we reposition them
		if ( ( m_characterProxy->getPosition()(1) < -10.0f ) || ( m_characterRigidBody->getPosition()(1) < -10.0f ) )
		{
			m_characterProxy->setPosition( characterStart );
			m_characterProxy->setLinearVelocity( hkVector4::getZero() );
			m_characterRigidBody->getRigidBody()->setPosition(characterStart);
			m_characterRigidBody->setLinearVelocity( hkVector4::getZero(), m_timestep );
			m_tick = 0;
		}
	}

	m_world->unlock();
	
	// Display state
	{
		char historyRb[33];
		char historyProxy[33];
		char buffer[255];

		for ( int i = 0; i < 32; ++i )
		{
			historyRb[i] = m_supportHistoryRb & ( 1 << i ) ? '#' : '_';
			historyProxy[i] = m_supportHistoryProxy & ( 1 << i ) ? '#' : '_';
		}
		historyRb[32] = '\0';
		historyProxy[32] = '\0';

		hkString::sprintf( buffer, "Rigid body unsupported frames: %d\n"
								   "Proxy unsupported frames:      %d\n\n"
								   "Rigid body support history:    %s\n"
								   "Proxy support history:         %s\n", m_unsupportedFramesCountRb, m_unsupportedFramesCountProxy, historyRb, historyProxy );

		m_env->m_textDisplay->outputText( buffer, 20, 200, 0xffffffff );
	}

	// Step the world
	{
		hkDefaultPhysicsDemo::stepDemo();
	}

	HK_TIMER_END();

	return hkDemo::DEMO_OK;
}
コード例 #18
0
BenchmarkSuiteDemo::BenchmarkSuiteDemo(hkDemoEnvironment* env)
	:	hkDefaultPhysicsDemo(env)
{
	const BenchmarkSuiteVariant& variant =  g_variants[m_variantId];

	// Disable warnings:									
	hkError::getInstance().setEnabled(0x7dd65995, false); //'The system has requested a heap allocation on stack overflow.'
	hkError::getInstance().setEnabled(0xaf55adde, false); //'No runtime block of size 637136 currently available. Allocating new block from unmanaged memory.'


	//
	// Setup the camera
	//
	{
		hkVector4 from(55.0f, 50.0f, 55.0f);
		hkVector4 to  ( 0.0f,  0.0f,   0.0f);
		hkVector4 up  ( 0.0f,  1.0f,   0.0f);
		setupDefaultCameras(env, from, to, up, 0.1f, 20000.0f);
	}

	//
	// Create the world
	//
	{
		hkpWorldCinfo worldInfo;
		{
			worldInfo.m_gravity.set(-0.0f, -9.81f, -0.0f);
			worldInfo.setBroadPhaseWorldSize(500.0f);
			worldInfo.setupSolverInfo( hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM );

			if (variant.m_type == TYPE_3000_BODY_PILE)
			{
				worldInfo.m_enableSimulationIslands = false;
			}
			worldInfo.m_enableDeactivation = false;
		}
		m_world = new hkpWorld(worldInfo);
		m_world->lock();

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

		setupGraphics();

		// enable instancing (if present on platform). Call this after setup graphics (as it makes the local viewers..)
		hkpShapeDisplayViewer* shapeViewer = (hkpShapeDisplayViewer*)getLocalViewerByName( hkpShapeDisplayViewer::getName() );
		if (shapeViewer)
		{
			shapeViewer->setInstancingEnabled( true );
		}
	}

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




	switch (variant.m_type)
	{
	case TYPE_10x10x1_ON_BOX:
		{
			CreateGroundPlane( m_world );
			CreateStack(m_world, 10);
			break;
		}
	case TYPE_5x5x5_ON_BOX:
		{
			CreateGroundPlane(m_world);
			for (int q = -3; q <= 2; q++  )
			{
				CreateStack(m_world,5, q * 10.0f);
			}
			break;
		}
	case TYPE_300_BODY_PILE:
		{
			CreateGroundPlane(m_world);
			CreateFall(m_world, 5);
			break;
		}
	case TYPE_OBJECTS_ON_MOPP_SMALL:
		{
			CreatePhysicsTerrain(m_world, 16, 1.0f);
			CreateFlatCubeGrid(m_world,8);
			break;
		}
	case TYPE_LIST_PILE_SMALL:
		{
			int side = 16;
			CreatePhysicsTerrain(m_world, side, 1.0f);
			CreateListGrid(m_world, hkReal(side), 3, 3);
			break;
		}
	case TYPE_30x30x1_ON_BOX:
		{
			CreateGroundPlane( m_world );
			CreateStack(m_world, 30);
			break;
		}
	case TYPE_20x20x5_ON_BOX:
		{
			CreateGroundPlane(m_world);
			for (int q = -3; q <= 2; q++  )
			{
				CreateStack(m_world,20, q * 10.0f);
			}
			break;
		}
	case TYPE_12x12x10_ON_BOX:
		{
			CreateGroundPlane(m_world);
			for (int q = -5; q <= 4; q++  )
			{
				CreateStack(m_world,12, q * 2.5f);
			}
			break;
		}
	case TYPE_3000_BODY_PILE:
		{
			CreateGroundPlane(m_world);
			CreateFall(m_world, 50);
			break;
		}
	case TYPE_OBJECTS_ON_MOPP_LARGE:
		{
			CreatePhysicsTerrain(m_world, 64, 1.0f);
			CreateFlatCubeGrid(m_world,30);
			break;
		}
	case TYPE_LIST_PILE_LARGE:
		{
			int side = 16;
			CreatePhysicsTerrain(m_world, side, 1.0f);
			CreateListGrid(m_world, hkReal(side), 5, 5);
			break;
		}
	default:
		{
			CreateGroundPlane(m_world);
			CreateStack(m_world, 20);
			break;
		}
	}

	//
	//	Some values
	//

	m_world->unlock();
}
コード例 #19
0
void VehicleSetup::setupVehicleData( const hkpWorld* world, hkpVehicleData& data )
{
  data.m_gravity = world->getGravity();

  //
  // The vehicleData contains information about the chassis.
  //

  // The coordinates of the chassis system, used for steering the vehicle.
  data.m_chassisOrientation.setCols( m_up, m_forward, m_right);

  data.m_frictionEqualizer = 0.5f; 

  // Inertia tensor for each axis is calculated by using : 
  // (1 / chassis_mass) * (torque(axis)Factor / chassisUnitInertia)
  data.m_torqueRollFactor = 0.525f; 
  data.m_torquePitchFactor = 0.6f; 
  data.m_torqueYawFactor = 0.55f; 

  data.m_chassisUnitInertiaYaw = 1.0f; 
  data.m_chassisUnitInertiaRoll = 1.0f;
  data.m_chassisUnitInertiaPitch = 1.0f; 

  // Adds or removes torque around the yaw axis 
  // based on the current steering angle.  This will 
  // affect steering.
  data.m_extraTorqueFactor = -40000.0f;
  data.m_maxVelocityForPositionalFriction = 10.0f; 

  //
  // Wheel specifications
  //
  data.m_numWheels = 4;
  m_wheelRadius = 0.36479f;

  data.m_wheelParams.setSize( data.m_numWheels );
  data.m_wheelParams[0].m_axle = 0;
  data.m_wheelParams[1].m_axle = 0;
  data.m_wheelParams[2].m_axle = 1;
  data.m_wheelParams[3].m_axle = 1;

  data.m_wheelParams[0].m_friction = 2.1f;
  data.m_wheelParams[1].m_friction = 2.1f;
  data.m_wheelParams[2].m_friction = 2.05f;
  data.m_wheelParams[3].m_friction = 2.05f;

  data.m_wheelParams[0].m_slipAngle = 0.1f;
  data.m_wheelParams[1].m_slipAngle = 0.1f;
  data.m_wheelParams[2].m_slipAngle = 0.0f;
  data.m_wheelParams[3].m_slipAngle = 0.0f;

  for ( int i = 0 ; i < data.m_numWheels ; i++ )
  {
    // This value is also used to calculate the m_primaryTransmissionRatio.
    data.m_wheelParams[i].m_radius = m_wheelRadius;
    data.m_wheelParams[i].m_width = 0.2f;
    data.m_wheelParams[i].m_mass = 10.0f;

    data.m_wheelParams[i].m_viscosityFriction = 0.0f;
    data.m_wheelParams[i].m_maxFriction = 2.0f * data.m_wheelParams[i].m_friction;
    data.m_wheelParams[i].m_forceFeedbackMultiplier = 0.1f;
    data.m_wheelParams[i].m_maxContactBodyAcceleration = hkReal(data.m_gravity.length3()) * 2;
  }
}
コード例 #20
0
LowFrequencyCharactersDemo::LowFrequencyCharactersDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env)
{

	//
	// Setup the camera
	//
	{
		hkVector4 from(  0.0f, 20.0f, -80.0f);
		hkVector4 to  (  0.0f,  0.0f,   0.0f);
		hkVector4 up  (  0.0f,  1.0f,   0.0f);
		setupDefaultCameras( env, from, to, up );

		forceShadowState(false);

	}

	//
	// Create the world
	//
	{
		hkpWorldCinfo info;
		info.setBroadPhaseWorldSize( 350.0f );  
		info.m_gravity.set(0, -9.8f, 0);
		info.m_collisionTolerance = 0.1f;		
		m_world = new hkpWorld( info );
		m_world->lock();

		hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());

		setupGraphics();
	}


	//
	//	Create a terrain 
	//
	TerrainHeightFieldShape* heightFieldShape;
	{
		hkpSampledHeightFieldBaseCinfo ci;
		ci.m_xRes = 64;
		ci.m_zRes = 64;
		ci.m_scale.set(4,1,4);

		//
		// 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_xRes; z++)
			{
				hkReal dx,dz,height = 0;
				int octave = 1;
				// Add togther 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 +=  (5 - (i * 2)) * hkMath::cos(dx * HK_REAL_PI) * hkMath::sin(dz * HK_REAL_PI);
					octave *= 4;
				}

				m_data[x*ci.m_zRes + z] = height;
			}
		}

		heightFieldShape = new TerrainHeightFieldShape( ci , m_data );
		//
		//	Create a fixed rigid body
		//
		{
			hkpRigidBodyCinfo rci;
			rci.m_motionType = hkpMotion::MOTION_FIXED;
			rci.m_position.setMul4( -0.5f, heightFieldShape->m_extents ); // center the heightfield
			rci.m_shape = heightFieldShape;
			rci.m_friction = 0.05f;

			hkpRigidBody* body = new hkpRigidBody( rci );

			m_world->addEntity(body)->removeReference();
		}

		heightFieldShape->removeReference();
	}

	//
	//	Create a character proxy object
	//
	{
		m_numBoxes = 0;
		m_numCapsules = 0;
		m_numSpheres = 0;
		
		// We'll store the simulation frequency in this 
		hkpPropertyValue val;

		// Construct shape phantoms for the characters
		hkPseudoRandomGenerator random(123);
		for (int i=0; i < NUM_CHARACTERS; i++)
		{

			// Create a random shape to represent the character
			hkpConvexShape* shape = HK_NULL;
			{
				hkReal scale = random.getRandReal01() * 0.25f + 0.75f;

				//Set the simulation frequency
				val.setInt( random.getRand32() % 3 );

				switch (val.getInt())
				{
					case 0:
						{
							hkVector4 top(0, scale * 0.4f, 0);
							hkVector4 bottom(0, -scale * 0.4f, 0);					
							shape = new hkpCapsuleShape(top, bottom, scale * 0.6f);
							m_numCapsules++;
						}
						break;
					case 1:
						{
							hkVector4 size(scale * 0.5f, scale , scale * 0.5f);
							shape = new hkpBoxShape(size);
							m_numBoxes++;
						}
						break;
					default:
						{
							shape = new hkpSphereShape(scale);
							m_numSpheres++;
						}
						break;
				}
			}

			hkpShapePhantom* phantom = new hkpSimpleShapePhantom( shape, hkTransform::getIdentity() );
			shape->removeReference();

			// Add the phantom to the world
			m_world->addPhantom(phantom);
			phantom->removeReference();

			HK_SET_OBJECT_COLOR( (hkUlong)phantom->getCollidable(), 0x7fffffff & hkColor::getRandomColor() );

			// Construct a character proxy
			hkpCharacterProxyCinfo cpci;
			random.getRandomVector11( cpci.m_position );
			cpci.m_position.mul4(32);
			cpci.m_position(1) = 10;
			cpci.m_up.setNeg4( m_world->getGravity() );
			cpci.m_up.normalize3();

			cpci.m_shapePhantom = phantom;
			m_characterProxy[i] = new hkpCharacterProxy( cpci );

			// Player is simulated at full frequency
			if (i==0)
			{
				val.setInt(0);
			}

			// Add the schedule property
			phantom->addProperty(HK_SCHEDULE_FREQUENCY, val);
		}
	}
	
	//
	// Create the Character state machine and context
	//
	hkpCharacterStateManager* manager;
	{
		hkpCharacterState* state;
		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();

	}

	// Create a context for each character
	{
		for (int i=0; i < NUM_CHARACTERS; i++)
		{
			m_characterContext[i] = new hkpCharacterContext(manager, HK_CHARACTER_ON_GROUND);
		}
		manager->removeReference();
	}
	
	// Current camera angle about up
	m_currentAngle = 0.0f;

	//Initialised the round robin counter
	m_tick = 0;

	m_world->unlock();
}
コード例 #21
0
hkDemo::Result MirroredMotionDemo::stepDemo()
{
	// Check user input
	{
		if (m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_1 ))
		{
			for ( int i = 0; i < 2; i++ )
			{
				if (( m_control[i]->getEaseStatus() == hkaDefaultAnimationControl::EASING_IN ) ||
					( m_control[i]->getEaseStatus() == hkaDefaultAnimationControl::EASED_IN ))
				{
					m_control[i]->easeOut( .5f );
				}
				else
				{
					m_control[i]->easeIn( .5f );
				}
			}
		}

		if (m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_2 ))
		{
			m_wireframe = !m_wireframe;
			setGraphicsState( HKG_ENABLED_WIREFRAME, m_wireframe );
		}

		if (m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_3 ))
		{
			m_drawSkin = !m_drawSkin;
		}

		if ( m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_0 ) )
		{
			m_useExtractedMotion = !m_useExtractedMotion;
		}

		if ( m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_L1 ) )
		{
			m_accumulatedMotion[0].setIdentity();
			m_accumulatedMotion[1].setIdentity();
		}

		if ( m_env->m_gamePad->wasButtonPressed( HKG_PAD_BUTTON_R1 ) )
		{
			m_paused = !m_paused;

			if ( m_paused )
			{
				m_timestep = 0;
			}
			else
			{
				m_timestep = 1.0f / 60.0f;
			}
		}


	}

	const int boneCount = m_skeleton->m_numBones;

	for ( int j = 0; j < 2; j++ )
	{
		// Grab accumulated motion
		{
			hkQsTransform deltaMotion;
			deltaMotion.setIdentity();
			m_skeletonInstance[j]->getDeltaReferenceFrame( m_timestep, deltaMotion );
			m_accumulatedMotion[j].setMulEq( deltaMotion );
		}

		// Advance the active animations
		m_skeletonInstance[j]->stepDeltaTime( m_timestep );

		// Sample the active animations and combine into a single pose
		hkaPose pose (m_skeleton);
		m_skeletonInstance[j]->sampleAndCombineAnimations( pose.accessUnsyncedPoseLocalSpace().begin(), pose.getFloatSlotValues().begin() );

		hkReal separation = m_separation * hkReal( 2*j-1 );

		hkQsTransform Q( hkQsTransform::IDENTITY );
		Q.m_translation.set( separation, 0, 0 );

		if ( m_useExtractedMotion )
		{
			Q.setMulEq( m_accumulatedMotion[j] );
		}

		pose.syncModelSpace();

		AnimationUtils::drawPose( pose, Q );
		// Test if the skin is to be drawn
		if ( !m_drawSkin )
		{
			Q.m_translation( 2 ) -= 2.0f * m_separation;
		}

		// Construct the composite world transform
		hkLocalArray<hkTransform> compositeWorldInverse( boneCount );
		compositeWorldInverse.setSize( boneCount );

		const hkArray<hkQsTransform>& poseModelSpace = pose.getSyncedPoseModelSpace();

		// Skin the meshes
		for (int i=0; i < m_numSkinBindings[j]; i++)
		{
			// assumes either a straight map (null map) or a single one (1 palette)
			hkInt16* usedBones = m_skinBindings[j][i]->m_mappings? m_skinBindings[j][i]->m_mappings[0].m_mapping : HK_NULL;
			int numUsedBones = usedBones? m_skinBindings[j][i]->m_mappings[0].m_numMapping : boneCount;

			// Multiply through by the bind pose inverse world inverse matrices
			for (int p=0; p < numUsedBones; p++)
			{
				int boneIndex = usedBones? usedBones[p] : p;
				hkTransform tWorld; poseModelSpace[ boneIndex ].copyToTransform(tWorld);
				compositeWorldInverse[p].setMul( tWorld, m_skinBindings[j][i]->m_boneFromSkinMeshTransforms[ boneIndex ] );
			}

			AnimationUtils::skinMesh( *m_skinBindings[j][i]->m_mesh, hkTransform( Q.m_rotation, hkVector4( Q.m_translation(0), Q.m_translation(1), Q.m_translation(2), 1 ) ), compositeWorldInverse.begin(), *m_env->m_sceneConverter );
		}

		// Move the attachments
		{
			HK_ALIGN(float f[16], 16);
			for (int a=0; a < m_numAttachments[j]; a++)
			{
				if (m_attachmentObjects[j][a])
				{
					hkaBoneAttachment* ba = m_attachments[j][a];
					hkQsTransform modelFromBone = pose.getBoneModelSpace( ba->m_boneIndex );
					hkQsTransform worldFromBoneQs;
					worldFromBoneQs.setMul( Q, modelFromBone );
					worldFromBoneQs.get4x4ColumnMajor(f);
					hkMatrix4 worldFromBone; worldFromBone.set4x4ColumnMajor(f);
					hkMatrix4 worldFromAttachment; worldFromAttachment.setMul(worldFromBone, ba->m_boneFromAttachment);
					m_env->m_sceneConverter->updateAttachment(m_attachmentObjects[j][a], worldFromAttachment);
				}
			}
		}


	}

	return hkDemo::DEMO_OK;
}
コード例 #22
0
ActivationCallbacksDemo::ActivationCallbacksDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env)
{
	//
	// Setup the camera
	//
	{
		hkVector4 from(0.0f, 7.0f, 30.0f);
		hkVector4 to  (0.0f, 3.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();

		m_debugViewerNames.pushBack( hkpSimulationIslandViewer::getName()  );

		setupGraphics();
	}

	//
	// Register the agents
	//
	{
		hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher());
	}


	//
	// Create the fixed box
	//
	{
		// Position of the box
		hkVector4 boxPosition(0.0f, 0.0f, 0.0f);

		// Set up the construction info parameters for the box
		hkpRigidBodyCinfo info;
		info.m_motionType = hkpMotion::MOTION_FIXED;

		info.m_friction = 1.0f;

		info.m_shape = new hkpBoxShape( hkVector4(60.0f, 0.2f, 60.0f), 0.05f );
		info.m_position = boxPosition;

		// Create fixed box
		hkpRigidBody* box = new hkpRigidBody(info);
		m_world->addEntity(box);
		box->removeReference();

		info.m_shape->removeReference();
	}

	//
	// Create the moving boxes
	//

	
	for (int i = 0; i < 20; i++)
	{
		// Create some object

		hkpRigidBodyCinfo info;
		info.m_friction = 1.0f;
		info.m_shape = new hkpBoxShape( hkVector4(0.5f, 0.5f, 0.5f), 0.0f );
		hkpInertiaTensorComputer::setShapeVolumeMassProperties( info.m_shape, 1.0f, info );
		info.m_motionType = hkpMotion::MOTION_BOX_INERTIA;

		// Position of the box
		info.m_position.setZero4();
		info.m_position(0) = - hkReal(i) * 1.5f + 2.0f; //left
		info.m_position(1) = 1.0f;
		info.m_position(2) = hkMath::sin( hkReal(i) / 3.0f ) * 0.7f;

		if (i == 0)
		{
			info.m_motionType = hkpMotion::MOTION_KEYFRAMED;
			info.m_linearVelocity = hkVector4( -1.0f, 0.0f, 0.0f );
		}

		// Create a box
		hkpRigidBody* box = new hkpRigidBody(info);
		info.m_shape->removeReference();

		// Create a listener and attach it to the box
		// NOTE: The listener attaches itself to the body as an hkpEntityListener 
		// and deletes itself automatically when the entity is deleted.
		ActivationCallbacksDemoEntityActivationListener* listener = new ActivationCallbacksDemoEntityActivationListener();
		box->addEntityActivationListener(listener);
		box->addEntityListener(listener);

		// Insert the box into the world
		m_world->addEntity(box);
		box->removeReference();
		
	}

	m_world->unlock();
}
コード例 #23
0
hkDemo::Result MultipleCharacterRbsDemo::stepDemo()
{
	HK_TIMER_BEGIN( "simulate multiply characters", HK_NULL );

	m_world->lock();

	hkVector4 up;
	up.setNeg4( m_world->getGravity() );
	up.normalize3();
	int numCharacters = m_characterRigidBodies.getSize();

	m_tick++;

	hkLocalArray<hkpCharacterInput> input( numCharacters ) ;
	input.setSize(numCharacters);

	// Fill in the state machine input structure
	{
		for (int i=0; i < numCharacters; i++)
		{
			input[i].m_atLadder = false;
			input[i].m_up = up;

			// Steer the characters
			hkReal time = hkReal(m_tick) / 60.0f;
			input[i].m_inputLR = hkMath::sin(time + i);
			input[i].m_inputUD = hkMath::cos(time + i);
			input[i].m_wantJump = false;
			input[i].m_forward.set(1,0,0);

			hkStepInfo stepInfo;
			stepInfo.m_deltaTime = m_timestep;
			stepInfo.m_invDeltaTime = 1.0f/m_timestep;
			
			input[i].m_stepInfo = stepInfo;

			input[i].m_characterGravity = m_world->getGravity();
			input[i].m_velocity = m_characterRigidBodies[i]->getLinearVelocity();
			input[i].m_position = m_characterRigidBodies[i]->getPosition();

			hkpSurfaceInfo ground;
			m_characterRigidBodies[i]->checkSupport(stepInfo, ground);

			input[i].m_isSupported = (ground.m_supportedState == hkpSurfaceInfo::SUPPORTED);
			input[i].m_surfaceNormal = ground.m_surfaceNormal;
			input[i].m_surfaceVelocity = ground.m_surfaceVelocity;	
		}
	}


	hkLocalArray<hkpCharacterOutput> output( numCharacters);
	output.setSize(numCharacters);

	// Apply the character state machine
	{
		HK_TIMER_BEGIN( "update character state", HK_NULL );

		for (int i=0; i < numCharacters; i++)
		{
			m_characterContexts[i]->update(input[i], output[i]);
		}

		HK_TIMER_END();

	}

	//Apply the character controllers
	{
		HK_TIMER_BEGIN( "simulate character", HK_NULL );

		for (int i=0; i < numCharacters; i++)
		{

			// Feed the output velocity from state machine into character rigid body
			m_characterRigidBodies[i]->setLinearVelocity(output[i].m_velocity, m_timestep);
			
			// If the character has fallen off the world we reposition them
			hkVector4 pos = m_characterRigidBodies[i]->getRigidBody()->getPosition();
			if (pos(1) < -10.0f)
			{
				pos.setZero4();
				pos(1) = 5;
				m_characterRigidBodies[i]->getRigidBody()->setPosition(pos);
			}

		}

		HK_TIMER_END();

		m_world->unlock();
	}

	// Step the world
	{
		hkDefaultPhysicsDemo::stepDemo();
	}

	HK_TIMER_END();

	return hkDemo::DEMO_OK;
}
コード例 #24
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();
}
コード例 #25
0
void Havok::TestNewFeature()
{
	const float Altitude = 100.0f;

	const SwingingRopeVariant& variant = g_variants[2];
//	const SwingingRopeVariant& variant = g_variants[7];
//	const SwingingRopeVariant& variant = g_variants[1];
//	const SwingingRopeVariant& variant = g_variants[3];

		// Horizontal distance between the attachment points of the strings.
	const hkReal offset = 50.0f;

	//
	// Create the world
	//
	{
/*		hkpWorldCinfo info;
		info.setBroadPhaseWorldSize( 100000.0f );
		info.m_gravity.set(0.0f, 0.0f, -variant.m_gravity);
		info.m_solverTau = variant.m_tau;
		mPhysicsWorld = new hkpWorld( info );*/
		mPhysicsWorld->lock();

//		mPhysicsWorld->m_wantDeactivation = false;
	}

	const float Radius = 1.0f;
	{
		hkpRigidBodyCinfo info;
		info.m_shape = new hkpSphereShape(Radius);
//		info.m_shape = new hkpBoxShape( hkVector4(0.5, 0.5f, 0.5f), 0.01f );
//		hkpInertiaTensorComputer::setShapeVolumeMassProperties(info.m_shape, 10.0f, info);
		hkpInertiaTensorComputer::setShapeVolumeMassProperties(info.m_shape, 1.0f, info);
		info.m_mass = 1.0f;
//		info.m_linearVelocity(2) = -10.0f;


		//
		// Construct string of independent bilateral constraints
		//
		if(0)
		{
			hkpConstraintData* data;
			{
				hkpBallAndSocketConstraintData* bsData = new hkpBallAndSocketConstraintData();
//				bsData->setInBodySpace(hkVector4::getZero(), hkVector4( -1.5f, 0.0f, -0.3f));
				bsData->setInBodySpace(hkVector4::getZero(), hkVector4( -1.5f, -0.3f, 0.0f));
				data = bsData;
			}

			hkpRigidBody* prevBody = HK_NULL;
			for (int b = 0; b < variant.m_numBodies; b++)
			{
				info.m_position.set(1.5f * hkReal(b) - offset / 2.0f, Altitude + 0.3f * hkReal(b), 0.0f);
				info.m_motionType = b ? hkpMotion::MOTION_DYNAMIC : hkpMotion::MOTION_FIXED;

				hkpRigidBody* body = new hkpRigidBody(info);
				mPhysicsWorld->addEntity(body);
//				HK_SET_OBJECT_COLOR( hkUlong(body->getCollidable()), 0xffff0000 );

				mRigidBodies.Add(udword(body));

				if (prevBody)
				{
					// add constraint
					hkpConstraintInstance* instance = new hkpConstraintInstance(prevBody, body, data);
					mPhysicsWorld->addConstraint( instance );
					instance->removeReference();
				}

				prevBody = body;
				// we remove reference, but we know one is still kept by mPhysicsWorld
				body->removeReference();
			}
			data->removeReference();
		}


		//
		// Construct constraint chain
		//
		{
			hkArray<hkpEntity*> entities;

			for (int b = 0; b < variant.m_numBodies; b++)
			{
//				info.m_position.set(1.5f * hkReal(b) + offset / 2.0f, Altitude + 0.3f * hkReal(b), 2.0f);
				info.m_position.set(float(b)*(Radius+0.5f)*2.0f, 0.0f, 0.0f);
				info.m_motionType = b ? hkpMotion::MOTION_DYNAMIC : hkpMotion::MOTION_FIXED;

				hkpRigidBody* body = new hkpRigidBody(info);
				mPhysicsWorld->addEntity(body);
//				HK_SET_OBJECT_COLOR( hkUlong(body->getCollidable()), 0xff00ff00 );

				mRigidBodies.Add(udword(body));

				entities.pushBack(body);
				// we know, a reference is kept by the world
				body->removeReference();
			}
	
			{
				hkpConstraintChainInstance* chainInstance = HK_NULL;

				if (variant.m_type == BALL_AND_SOCKET)
				{
					hkpBallSocketChainData* chainData = new hkpBallSocketChainData();
					chainInstance = new hkpConstraintChainInstance( chainData );

					chainInstance->addEntity( entities[0] );
					for (int e = 1; e < entities.getSize(); e++)
					{
//						chainData->addConstraintInfoInBodySpace( hkVector4::getZero(), hkVector4( -1.5f, 0.0f, -0.3f) );
//						chainData->addConstraintInfoInBodySpace( hkVector4::getZero(), hkVector4( -1.5f, -0.3f, 0.0f) );
						chainData->addConstraintInfoInBodySpace( hkVector4( Radius+0.5f, 0.0f, 0.0f), hkVector4( -Radius-0.5f, 0.0f, 0.0f) );
						chainInstance->addEntity( entities[e] );
					}

					chainData->m_tau = variant.m_tau;
					chainData->removeReference();
				}
				else if(variant.m_type == STIFF_SPRING)
				{
					hkpStiffSpringChainData* chainData = new hkpStiffSpringChainData();
					chainInstance = new hkpConstraintChainInstance( chainData );

					chainInstance->addEntity( entities[0] );
					for (int e = 1; e < entities.getSize(); e++)
					{
//						chainData->addConstraintInfoInBodySpace( hkVector4::getZero(), hkVector4( -1.0f, 0.0f, -0.2f), 0.55f );
						chainData->addConstraintInfoInBodySpace( hkVector4::getZero(), hkVector4( -1.0f, -0.2f, 0.0f), 0.55f );
						chainInstance->addEntity( entities[e] );
					}

					chainData->m_tau = variant.m_tau;
					chainData->removeReference();
				}

				mPhysicsWorld->addConstraint( chainInstance );
				chainInstance->removeReference();
			}

		}

		info.m_shape->removeReference();

	}

	mPhysicsWorld->unlock();

}
コード例 #26
0
OptimizedWorldRaycastDemo::OptimizedWorldRaycastDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env)
{
	{
		m_numRigidBodies = int(m_env->m_cpuMhz);
		m_numBroadphaseMarkers = 64;
		m_rayLength = 5;
		m_worldSizeX = 2.0f * hkMath::sqrt(hkReal(m_env->m_cpuMhz));
		m_worldSizeY = 3;
		m_worldSizeZ = m_worldSizeX;
	}
	//
	// Setup the camera.
	//
	{
		hkVector4 from(30.0f, 8.0f, 25.0f);
		hkVector4 to  ( 4.0f, 0.0f, -3.0f);
		hkVector4 up  ( 0.0f, 1.0f,  0.0f);
		setupDefaultCameras(env, from, to, up);

		// Demo is slow graphicaly as it without shadows
		forceShadowState(false);

	}

	//
	// Create the world.
	//
	{
		hkpWorldCinfo info;
		
		// Set gravity to zero so body floats.
		info.m_gravity.setZero4();

		// make the world big enough to hold all our objects
		// make y larger so that our raycasts stay within the world aabb
		info.m_broadPhaseWorldAabb.m_max.set( m_worldSizeX + 10, 10*m_worldSizeY + 10, m_worldSizeZ + 10 );
		info.m_broadPhaseWorldAabb.m_min.setNeg4( info.m_broadPhaseWorldAabb.m_max );

		// Subdivide the broadphase space into equal sections along the x-axis
		// NOTE: Disabling this until the marker crash issue is fixed.
		//info.m_broadPhaseNumMarkers = m_numBroadphaseMarkers;

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

		setupGraphics();
	}

	// register all agents(however, we put all objects into the some group,
	// so no collision will be detected
	hkpAgentRegisterUtil::registerAllAgents( m_world->getCollisionDispatcher() );

	// Add a collision filter to the world to allow the bodies interpenetrate
	{
		hkpGroupFilter* filter = new hkpGroupFilter();
		filter->disableCollisionsBetween( hkpGroupFilterSetup::LAYER_DEBRIS, hkpGroupFilterSetup::LAYER_DEBRIS );
		m_world->setCollisionFilter( filter );
		filter->removeReference();
	}

	//
	// Set the simulation time to 0
	//
	m_time = 0;


	//
	//	Create our phantom at our origin.
	//  This is a bad hack, we should really create our phantom at it's final position,
	//  but let's keep the demo simple.
	//  If you actually create many phantoms all at the origin, you get a massive CPU spike
	//  as every phantom will collide with every other phantom.
	//
	{
		hkAabb aabb;
		aabb.m_min.setZero4();
		aabb.m_max.setZero4();
		m_phantom = new hkpAabbPhantom( aabb );
		m_world->addPhantom( m_phantom );

		m_phantomUseCache = new hkpAabbPhantom( aabb );
		m_world->addPhantom( m_phantomUseCache );
	}


	//
	// Create some bodies (reuse the ShapeRaycastApi demo)
	//
	createBodies();

	m_world->unlock();
}
コード例 #27
0
WorldLinearCastMultithreadingApiDemo::WorldLinearCastMultithreadingApiDemo(hkDemoEnvironment* env)
	: hkDefaultPhysicsDemo(env, DEMO_FLAGS_NO_SERIALIZE),
	m_time(0.0f)
{
	const WorldLinearCastMultithreadingApiDemoVariant& variant = g_WorldLinearCastMultithreadingApiDemoVariants[m_variantId];

	//
	// Setup the camera.
	//
	{
		hkVector4 from(0.0f, 30.0f, 45.0f);
		hkVector4 to(0.0f, 0.0f, 5.0f);
		hkVector4 up(0.0f, 1.0f, 0.0f);
		setupDefaultCameras( env, from, to, up );
	}

	//
	// Create the world.
	//
	{
		hkpWorldCinfo info;
		{
			info.setBroadPhaseWorldSize( 1000.0f );
			info.m_gravity.setZero4();
		}

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

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

		setupGraphics();
	}

	//
	// Create a simple list shape.
	//

	hkpListShape* listShape;
	{
		hkVector4 boxSize1(1,2,1);
		hkpBoxShape* box1 = new hkpBoxShape(boxSize1);

		hkVector4 boxSize2(2,1,1);
		hkpBoxShape* box2 = new hkpBoxShape(boxSize2);

		hkpShape* list[2] = {box1, box2};
		listShape = new hkpListShape(list, 2);

		box1->removeReference();
		box2->removeReference();
	}

	{
		hkVector4 position(0.0f, 0.0f, 0.0f);
		m_castBody = GameUtils::createRigidBody(listShape, 0.0f, position);
		m_world->addEntity(m_castBody);
		m_castBody->removeReference();
	}

	//
	// Create a circle of simple list shapes.
	//
	{
		

		int numBoxesInCircle = 10;
		hkReal angleStep = (2.0f * HK_REAL_PI) / hkReal(numBoxesInCircle);
		hkReal radius = 15.0f;
		for (float angle = 0.0f; angle < 2.0f * HK_REAL_PI; angle += angleStep)
		{
			hkVector4 position(radius * hkMath::sin(angle), 0.0f, radius * hkMath::cos(angle));
			hkVector4 size(3.0f, 3.0f, 3.0f);
			hkpRigidBody* body = GameUtils::createRigidBody(listShape, 0.0f, position);

			m_world->addEntity(body);
			body->removeReference();
		}

		listShape->removeReference();
	}

	{
		hkpGroupFilter* filter = new hkpGroupFilter();
		m_world->setCollisionFilter(filter);
		filter->removeReference();
	}

	//
	// Some magic to create a second graphical representation of the cast body.
	//
	{
		hkArray<hkDisplayGeometry*> geom;
		hkpShapeDisplayBuilder::hkpShapeDisplayBuilderEnvironment sdbe;
		hkpShapeDisplayBuilder builder(sdbe);
		builder.buildShapeDisplay( m_castBody->getCollidable()->getShape(), hkTransform::getIdentity(), geom );
		m_env->m_displayHandler->addGeometry(geom, m_castBody->getCollidable()->getTransform(), 1 , 0, 0 );
		hkReferencedObject::removeReferences(geom.begin(), geom.getSize());
	}

	m_world->unlock();



	// Special case for this demo variant: we do not allow the # of active SPUs to drop to zero as this can cause a deadlock.
	if ( variant.m_demoType == WorldLinearCastMultithreadingApiDemoVariant::MULTITHREADED_ON_SPU ) m_allowZeroActiveSpus = false;

	// Register the collision query functions
	hkpCollisionQueryJobQueueUtils::registerWithJobQueue(m_jobQueue);
	hkpRayCastQueryJobQueueUtils::registerWithJobQueue(m_jobQueue);

	// register the default addCdPoint() function; you are free to register your own implementation here though
	hkpFixedBufferCdPointCollector::registerDefaultAddCdPointFunction();

}
コード例 #28
0
CenterOfMassChangerDemo::CenterOfMassChangerDemo(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_solverIterations = 1;
		info.m_collisionTolerance = 0.01f;
		info.m_contactRestingVelocity = 0.01f; // simple response
		//info.m_contactRestingVelocity = 10000.01f; // solver-only response
		info.m_enableSimulationIslands = false;
		info.m_gravity.setZero4();

		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( 30.0f, 0.5f, 30.0f);
		hkpConvexShape* shape = new hkpBoxShape( baseSize , 0 );

		hkpRigidBodyCinfo ci;

		ci.m_shape = shape;
		ci.m_motionType = hkpMotion::MOTION_FIXED;
		ci.m_position.set(0.0f, -0.5f, 0.0f);
		ci.m_friction = 0.0f;

		//m_world->addEntity( new hkpRigidBody( ci ) )->removeReference();

		shape->removeReference();
	}	

	hkVector4 rowPositionOffset(0.0f, 0.0f, 2.0f);
	const int numRows = 10;
	for (int p = 0; p < numRows; p++)
	{
		//
		// Create 3 boxes
		//
		{
			hkpRigidBody* body;

			hkpRigidBodyCinfo boxInfo;
			//boxInfo.m_shape = new hkpCylinderShape(hkVector4::getZero(), hkVector4(0.0f, 0.3f, 0.0f), 0.6f, 0.0f);
			boxInfo.m_shape = new hkpSphereShape(0.6f);
			hkpInertiaTensorComputer::setShapeVolumeMassProperties(boxInfo.m_shape, 1.0f, boxInfo);
			boxInfo.m_qualityType = HK_COLLIDABLE_QUALITY_DEBRIS;
			boxInfo.m_motionType = hkpMotion::MOTION_BOX_INERTIA;
			boxInfo.m_friction = 0.0f;
			boxInfo.m_restitution = 1.0f;//hkReal(p)/hkReal(numRows-1);
			
			// box 0
			//
			boxInfo.m_restitution = 0.0f; 
			boxInfo.m_position.set(-5.0f, 0.0f, 0.0f);
			boxInfo.m_position.addMul4(hkReal(p), rowPositionOffset);
			boxInfo.m_rotation.setAxisAngle(hkVector4(0.0f, 0.0f, 1.0f), 180.0f * HK_REAL_DEG_TO_RAD);
			hkpRigidBody* hitBody = body = new hkpRigidBody(boxInfo);
			m_world->addEntity(body)->removeReference();
			boxInfo.m_restitution = 1.0f;//hkReal(p)/hkReal(numRows-1);
			boxInfo.m_rotation.setIdentity();

			// box 1
			//
			boxInfo.m_position.set(0.0f, 0.0f, 0.0f);
			boxInfo.m_position.addMul4(hkReal(p), rowPositionOffset);
			hkpRigidBody* hittingBody = body = new hkpRigidBody(boxInfo);
			m_world->addEntity(body)->removeReference();

			// box 2
			//
			boxInfo.m_position.set( 10.0f, 0.0f, 0.0f);
			boxInfo.m_position.addMul4(hkReal(p), rowPositionOffset);
			boxInfo.m_linearVelocity.set(-10.0f, 0.0f, 0.0f);
			body = new hkpRigidBody(boxInfo);
			m_world->addEntity(body)->removeReference();

			//hkVector4 comDisplacement(0.0f, 1.5f, 1.5f);
			hkVector4 comDisplacement(0.0f, 0.0f + 0.5f * hkReal(p), 0.0f);
			hkpCenterOfMassChangerUtil* cmcu = new hkpCenterOfMassChangerUtil( hittingBody, hitBody, hkVector4::getZero(), comDisplacement );
			m_utils.pushBack(cmcu);

			boxInfo.m_shape->removeReference();
		}

	}

	m_world->unlock();
}
コード例 #29
0
		virtual int read(void* buf, int nbytes)
		{
			m_bytesRead += nbytes;
			m_demo->progressSet(hkReal(m_bytesRead) / m_fileSize);
			return m_child->read(buf, nbytes);
		}
コード例 #30
0
void DetailedTimersDemo::timeDemo( hkDemo* demo, int iterations, const char* fileName )
{

	//
	//	Time the demo
	//
	hkMonitorStreamFrameInfo frameInfo;
#	ifdef HK_PS2
		frameInfo.m_indexOfTimer0 = 1;
		frameInfo.m_indexOfTimer1 = 0;
			// Assume that each instruction cache miss cost around 35 cycles.
			// So we can see how much of our overall time is spent waiting for the
			// memory system
		frameInfo.m_timerFactor0 = 35.0f / 300.f;
		frameInfo.m_timerFactor1 = 1.0f / 300.f;
		frameInfo.m_heading = "usec: IcachePenalty (assuming 35 cycle penalty)";
#	else
		frameInfo.m_indexOfTimer0 = 0;
		frameInfo.m_indexOfTimer1 = -1;
		frameInfo.m_heading = "usecs";
		frameInfo.m_timerFactor0 = 1e6f / hkReal(hkStopwatch::getTicksPerSecond());
#	endif

	int demoIdx = hkDemoDatabase::getInstance().findDemo( TEST_DEMO_FULLPATH );
	HK_ASSERT2(0x654e432e, demoIdx != -1, "Demo does not exist" );

	const bool isPhysicsDemo = (HK_DEMO_TYPE_PHYSICS == hkDemoDatabase::getInstance().getDemos()[ demoIdx ].m_demoTypeFlags);


	//
	//	Setup some memory to store all the timer information 
	//  for all frames
	//
	int numThreads = 1;

	if( isPhysicsDemo )
	{
		hkCpuJobThreadPool* mtUtil = (hkCpuJobThreadPool*)static_cast<hkDefaultPhysicsDemo*>(demo)->m_jobThreadPool;
		if (mtUtil)
		{
			numThreads += mtUtil->getNumThreads();
		}
	}

	hkMonitorStreamAnalyzer streamAnalyzer( 10000000, numThreads );

	for (int i = 0; i < iterations; i++ )
	{

		//
		//	Setup the timerinfo and memory on a per frame bases
		//
		hkMonitorStream& stream = hkMonitorStream::getInstance();
		stream.resize( 2 * 1024 * 1024  );	// 2 meg for timer info per frame
		stream.reset();

		//
		//	Start timers
		//
#		ifdef HK_PS2
			scePcStart( SCE_PC_CTE | SCE_PC_U0 | SCE_PC_U1 | SCE_PC0_ICACHE_MISS | SCE_PC1_CPU_CYCLE, 0 ,0 );
#		endif

		//
		//	Step the demo
		//
		demo->stepDemo();

		//
		//	Stop timers. This is necessary as a timer overflow on PlayStation(R)2 causes an exception
		//
#		ifdef HK_PS2
		scePcStop() ;
#		endif

		//
		//	Analyze the per frame info and copy the data over to the multi frame buffer
		//

		if( numThreads > 1 )
		{
			hkCpuJobThreadPool* mtUtil = (hkCpuJobThreadPool*)static_cast<hkDefaultPhysicsDemo*>(demo)->m_jobThreadPool;

			// Loop through each thread. Capture the frame details from the local
			// stream analyzer in each thread.
			for (int t = 0; t < mtUtil->getNumThreads(); ++t)
			{
				hkCpuJobThreadPool::WorkerThreadData& data = mtUtil->m_workerThreads[t];

				if (data.m_monitorStreamBegin != data.m_monitorStreamEnd )
				{
					frameInfo.m_threadId = t + 1;
					streamAnalyzer.captureFrameDetails( data.m_monitorStreamBegin,data.m_monitorStreamEnd, frameInfo );
				}
			}
		}
		frameInfo.m_threadId = 0;
		streamAnalyzer.captureFrameDetails(stream.getStart(), stream.getEnd(), frameInfo );
	}

	//
	// Write the results to a file
	//
	{
		// Disable double conversion check - we know this will fail
		pushDoubleConversionCheck(false);
		hkReferencedObject::lockAll();
		
		hkOstream ostr (fileName);
		ostr << TEST_DEMO_NAME "   Timers: \n";

		streamAnalyzer.writeStatistics( ostr );
		hkReferencedObject::unlockAll();
		
		popDoubleConversionCheck();
	}

}