Example #1
0
void hk_Matrix3::set_mul3( const hk_Matrix3& Ma, const hk_Matrix3& Mb )
{
	HK_ASSERT(this!=&Ma);
	HK_ASSERT(this!=&Mb);

	for( int i = 0; i < 3; i++ )
	{
		hk_real x = Ma(0,0)*Mb(0,i) + Ma(0,1)*Mb(1,i) + Ma(0,2)*Mb(2,i);
		hk_real y = Ma(1,0)*Mb(0,i) + Ma(1,1)*Mb(1,i) + Ma(1,2)*Mb(2,i);
		hk_real z = Ma(2,0)*Mb(0,i) + Ma(2,1)*Mb(1,i) + Ma(2,2)*Mb(2,i);

		get_column(i).set(x,y,z);
	}
}
Example #2
0
hkBool LowFrequencyCharactersDemo::shouldSimulate(int characterNumber, int currentTick)
{

	HK_ASSERT(0x614cce11, characterNumber < NUM_CHARACTERS);
	HK_ASSERT(0x3ca8a029, m_characterProxy[characterNumber]->getShapePhantom()->hasProperty(HK_SCHEDULE_FREQUENCY));
	hkInt32 slot = m_characterProxy[characterNumber]->getShapePhantom()->getProperty(HK_SCHEDULE_FREQUENCY).getInt();

	switch (slot)
	{
	case 0:	return true;
	case 1: return (currentTick & 1)!=0; // Every second tick (offset by 1)
	case 2: return (currentTick & 3)==0; // Every fourth tick
	default : return false;
	}
}
Example #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) );
			}
		}
	}

}
Example #4
0
void OutOfWorldRaycastDemo::doLinearCast(hkpRigidBody* rb1, hkpRigidBody* rb2)
{
	hkVector4 to, from, midpoint;
	to = rb1->getPosition();
	from = rb2->getPosition();
	midpoint.setInterpolate4(to, from, .5f);

	// try a linear cast
	hkpLinearCastInput lci;
	hkpAllCdPointCollector collector;
	lci.m_to = to;
	m_world->linearCast(rb2->getCollidable(), lci, collector);
		
	int color;
	color = collector.hasHit() ? 0xFF00FF00 : 0xFFFF0000;

	const hkArray<hkpRootCdPoint> &hits = collector.getHits();
	// check for duplicates // HVK-3126
	for( int i = 0; i < hits.getSize(); ++i )
	{
		for( int j = i+1; j < hits.getSize(); ++j )
		{
			HK_ON_DEBUG(const hkpRootCdPoint& pi = hits[i]);
			HK_ON_DEBUG(const hkpRootCdPoint& pj = hits[j]);
			HK_ASSERT(0, (pi.m_shapeKeyA != pj.m_shapeKeyA) || (pi.m_shapeKeyB != pj.m_shapeKeyB) );
		}
	}

	hkVector4 dir;
	dir.setSub4(to, midpoint);

	HK_DISPLAY_ARROW(midpoint,dir, color);
}
  ///
  /// \brief
  ///   Get a Havok Physics world space vector from a Vision render space vector; taking Vision scaling into account.
  ///
  VHAVOK_IMPEXP static HK_FORCE_INLINE void VisVecToPhysVecWorld(const hkvVec4& visV, hkVector4& physV)
  {
	  physV.load<4, HK_IO_NATIVE_ALIGNED>(&visV.data[0]);
	  physV.mul(m_cachedVis2PhysScale);
	  physV.add(*m_cachedWorldPivot);
	  HK_ASSERT(0xdee884, physV.isOk<4>());
  }
  ///
  /// \brief
  ///   Get a Havok Physics object space/scalar vector from a Vision vector; taking Vision scaling into account.
  ///
  VHAVOK_IMPEXP static HK_FORCE_INLINE void VisVecToPhysVecLocal(const hkvVec3& visV, hkVector4& physV)
  {
	  physV.load<3, HK_IO_NATIVE_ALIGNED>(&visV.data[0]);
	  physV.zeroComponent<3>();
	  physV.mul(m_cachedVis2PhysScale);
	  HK_ASSERT(0xdee883, physV.isOk<4>());
  }
void noBlendMatrixSetDX9::addMatrix( const float* m, int referenceID )
{
	D3DMATRIX* newM = m_matrices.expandBy(1);
	hkgMat4Copy( (float*)newM, m );
	m_referenceIDs.pushBack((int16)referenceID);
	HK_ASSERT(0x0, m_referenceIDs.getSize() == m_matrices.getSize());
}
static void extractKeyTimes(FbxNode* fbxChildNode, FbxAnimLayer* fbxAnimLayer, const char* channel, hkxNode* node, hkReal startTime, hkReal endTime)
{
	HK_ASSERT(0x0, startTime <= endTime || endTime < 0.f);
	startTime = hkMath::max2(startTime, 0.f);
	FbxAnimCurve* lAnimCurve = fbxChildNode->LclTranslation.GetCurve(fbxAnimLayer, channel);
	if (lAnimCurve)
	{
		int lKeyCount = lAnimCurve->KeyGetCount();
		hkReal lKeyTime;

		// Store keyframe times in seconds(from [0, endTime])
		for(int lCount = 0; lCount < lKeyCount; lCount++)
		{
			lKeyTime = hkMath::max2((hkReal)lAnimCurve->KeyGetTime(lCount).GetSecondDouble(), 0.f);
			if (lKeyTime >= startTime && (lKeyTime <= endTime || endTime < 0.f))
			{
				if (node->m_linearKeyFrameHints.indexOf(lKeyTime) < 0)
				{
					node->m_linearKeyFrameHints.pushBack(lKeyTime - startTime);
				}
			}
			else // handle case of [EXP-2436], where no keys in the range but range is affected by keys outside, so have to mark at start and end
			{
				if ((lKeyTime < startTime) &&(node->m_linearKeyFrameHints.indexOf(0.f) < 0))
				{
					node->m_linearKeyFrameHints.pushBack(0.f);
				}
				else if (endTime >= 0.f &&(lKeyTime - startTime > endTime) &&(node->m_linearKeyFrameHints.indexOf(endTime - startTime) < 0))
				{
					node->m_linearKeyFrameHints.pushBack(endTime - startTime);
				}
			}
		}
	}
}
//
// This method loads a rigid body from an xml file. The allocated memory used for loading has to be
// kept using a reference. Note that this method expects the xml file to contain exactly one physics
// system and at least one rigid body. Although it will only return the first rigid body (as we don't
// need more for this demo), this could easily be extended to handle more.
//
hkpRigidBody* MeshWeldingDemo::loadRigidBodyFromXmlFile(const hkString& path, hkPackfileReader::AllocatedData*& allocatedData) const
{
	hkIstream infile(path.cString());
	HK_ASSERT(0xaf639672, infile.isOk());

	hkpPhysicsData* physicsData = hkpHavokSnapshot::load(infile.getStreamReader(), &allocatedData);
	hkArray<hkpPhysicsSystem*> physicsSystems;
	physicsSystems = physicsData->getPhysicsSystems();
	HK_ASSERT(0xaf836275, physicsSystems.getSize() == 1);

	hkArray<hkpRigidBody*> rigidBodies;
	rigidBodies = physicsSystems[0]->getRigidBodies();
	HK_ASSERT(0xaf836271, rigidBodies.getSize() >= 1);

	return rigidBodies[0];
}
  ///
  /// \brief
  ///   Converts a Vision rotation matrix to a Havok Physics quaternion.
  ///
  /// \param visRotMatrix
  ///   Incoming Vision transformation
  ///
  /// \param hkQuatOut
  ///   Resulting Havok Physics quaternion instance [out]
  ///
  VHAVOK_IMPEXP static HK_FORCE_INLINE void VisMatrixToHkQuat(const hkvMat3 &visRotMatrix, hkQuaternion &hkQuatOut)
  {
	  hkRotation hkRotMtx;
	  VisMatrixToHkRotation(visRotMatrix, hkRotMtx);
	  hkQuatOut.set(hkRotMtx); // out-of line!
	  hkQuatOut.normalize(); // strip scale
	  HK_ASSERT(0xdee888, hkQuatOut.isOk());
  }
hkBool hkDefaultAnimationDemo::objectPicked( const hkgDisplayObject* displayObject, const hkVector4& worldPosition, int geomIndex )
{
	HK_ASSERT(0x65b2643b, m_env->m_displayHandler);

	/* hkgDisplayHandler* dhandler = m_env->m_displayHandler; */

	return false;
}
Example #12
0
FbxToHkxConverter::Options::Options(FbxManager *fbxSdkManager) :
	m_fbxSdkManager(fbxSdkManager),
	m_exportMeshes(true), m_exportAttributes(true), m_exportLights(true), m_exportCameras(true),
	m_exportSplines(true), m_visibleOnly(false), m_selectedOnly(false), 
	m_exportMaterials(true), m_storeKeyframeSamplePoints(true), m_exportAnnotations(true)
{
	HK_ASSERT(0x0, m_fbxSdkManager);
}
void WorldLinearCastMultithreadedDemo::displayRootCdBody( hkpWorld* world, const hkpCollidable* collidable, hkpShapeKey key)
{
	hkpShapeCollection::ShapeBuffer shapeBuffer;

	//	Check, whether we have a triangle from the landscape or a single object
	if ( key == HK_INVALID_SHAPE_KEY )
	{
		// now we have a single object as we are not part of a hkpShapeCollection
		HK_SET_OBJECT_COLOR((hkUlong)collidable, hkColor::rgbFromChars(160,160,160));
	}
	else
	{
		// now we need to get our triangle.
		// Attention: The next lines make certain assumptions about how the landscape is constructed:
		//   1. The landscape is a single hkMoppShape with wraps a hkpShapeCollection, which
		//      produces only triangles.
		//   2. All hkShapeCollections are wrapped with a hkpBvTreeShape

		HK_ASSERT(0x3e93321f,  world->getCollisionDispatcher()->hasAlternateType( collidable->getShape()->getType(), HK_SHAPE_BV_TREE ) );

		const hkpBvTreeShape* bvTreeShape = static_cast<const hkpBvTreeShape*>(collidable->getShape());

		hkpShapeKey triangleId = key;

		const hkpShape* childShape = bvTreeShape->getContainer()->getChildShape( triangleId, shapeBuffer );

		HK_ASSERT(0x23f67112,  childShape->getType() == HK_SHAPE_TRIANGLE );
		const hkpTriangleShape* triangle = static_cast<const hkpTriangleShape*>( childShape );

		hkVector4 vertex[3];
		vertex[0].setTransformedPos(collidable->getTransform(), triangle->getVertex(0));
		vertex[1].setTransformedPos(collidable->getTransform(), triangle->getVertex(1));
		vertex[2].setTransformedPos(collidable->getTransform(), triangle->getVertex(2));

		//	Draw the border of the triangle
		HK_DISPLAY_LINE(vertex[0], vertex[1], hkColor::WHITE);
		HK_DISPLAY_LINE(vertex[2], vertex[1], hkColor::WHITE);
		HK_DISPLAY_LINE(vertex[0], vertex[2], hkColor::WHITE);

		if ( (const void*)childShape != (const void*)shapeBuffer && shapeBuffer[10] == 0 )
		{
			HK_ASSERT(0x20b8765d, 0);
		}
	}
}
static hkpWorld* loadWorld( const char* path, hkpPhysicsData** physicsData, hkPackfileReader::AllocatedData** memData )
{
	hkIstream infile( path );
	HK_ASSERT( 0x215d080c, infile.isOk() );
	*physicsData = hkpHavokSnapshot::load(infile.getStreamReader(), memData);

	hkpWorld* w = (*physicsData)->createWorld();
	return w;
}
Example #15
0
BackfacesCulledRayHitCollectorDemo::BackfacesCulledRayHitCollectorDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env)
{
	//
	// Setup the camera.
	//
	{
		hkVector4 from( -9.0f, 6.0f, -6.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.
	//
	{
		hkString filename; // We have a different binary file depending on the compiler and platform
		filename.printf("Resources/Physics/Objects/hemisphere_L%d%d%d%d.hkx",
			hkStructureLayout::HostLayoutRules.m_bytesInPointer,
			hkStructureLayout::HostLayoutRules.m_littleEndian? 1 : 0,
			hkStructureLayout::HostLayoutRules.m_reusePaddingOptimization? 1 : 0,
			hkStructureLayout::HostLayoutRules.m_emptyBaseClassOptimization? 1 : 0);
		hkIstream infile( filename.cString() );
		HK_ASSERT( 0x215d080c, infile.isOk() );
		m_physicsData = hkpHavokSnapshot::load(infile.getStreamReader(), &m_loadedData);

		m_hemisphereRb = m_physicsData->findRigidBodyByName("hemisphere");
		m_boxRb = m_physicsData->findRigidBodyByName("box");

		hkpWorldCinfo *info = m_physicsData->getWorldCinfo();
 		info->setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM);
 		info->m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_CONTINUOUS;

		// Set gravity to zero so body floats.
		info->m_gravity.set(0.0f, 0.0f, 0.0f);	
		info->setBroadPhaseWorldSize( 1000.0f );
		info->m_broadPhaseBorderBehaviour = hkpWorldCinfo::BROADPHASE_BORDER_DO_NOTHING;

		m_world = m_physicsData->createWorld();
		m_world->lock();

		hkpConstraintCollisionFilter* collisionFilter = new hkpConstraintCollisionFilter();
		m_world->setCollisionFilter(collisionFilter);
		collisionFilter->removeReference();
		
		// for drawing purposes
		hkpBroadPhaseBorder* border = new hkpBroadPhaseBorder( m_world, hkpWorldCinfo::BROADPHASE_BORDER_DO_NOTHING );
		m_world->setBroadPhaseBorder(border);
		border->removeReference();

		setupGraphics();

		m_world->unlock();
	}	
}
  ///
  /// \brief
  ///   Get a Havok Physics object space/scalar vector from a Vision vector; taking Vision scaling into account.
  ///
  VHAVOK_IMPEXP static HK_FORCE_INLINE void VisVecToPhysVecLocal(const hkvVec3d& visV, hkVector4& physV)
  {
	  /*! Work around, see [SIM-41] */
	  AlignedArray array(visV);

	  physV.load<3, HK_IO_NATIVE_ALIGNED>(array.m_array);
	  physV.zeroComponent<3>();
	  physV.mul(m_cachedVis2PhysScale);
	  HK_ASSERT(0xdee883, physV.isOk<4>());
  }
  ///
  /// \brief
  ///   Converts a Vision rotation matrix to a Havok Physics rotation matrix.
  ///
  VHAVOK_IMPEXP static HK_FORCE_INLINE void VisMatrixToHkRotation(const hkvMat3 &visRotMatrix, hkRotation &hkRotOut)
  {
	  // Extract matrix columns from Vision
	  const float* visRot = (const float*)visRotMatrix.getPointer();
	  hkRotOut.getColumn<0>().load<3,HK_IO_NATIVE_ALIGNED>(visRot  );
	  hkRotOut.getColumn<0>().zeroComponent<3>();
	  hkRotOut.getColumn<1>().load<3,HK_IO_NATIVE_ALIGNED>(visRot+3);
	  hkRotOut.getColumn<1>().zeroComponent<3>();
	  hkRotOut.getColumn<2>().load<3,HK_IO_NATIVE_ALIGNED>(visRot+6);
	  hkRotOut.getColumn<2>().zeroComponent<3>();
	  HK_ASSERT(0xdee887, hkRotOut.isOk() /*&& hkRotOut.isOrthonormal()*/);
  }
Example #18
0
AttrType* hkExtractAttribute(Object* objPtr, const char* attrName, const char* attrType)
{
	if( objPtr )
	{
		if( const hkVariant* v = objPtr->getAttribute(attrName) )
		{
			HK_ASSERT( 0x0, hkString::strCmp( v->m_class->getName(), attrType ) == 0 );
			return static_cast<AttrType*>(v->m_object); \
		}
	}
	return HK_NULL;
}
Example #19
0
LandscapeContainer::~LandscapeContainer()
{ 
	HK_ASSERT(0, m_shape != HK_NULL);
	if (m_shape)
	{
		m_shape->removeReference();
	}
	
	if ( m_packfileData )
	{
		m_packfileData->removeReference();
	}
}
Example #20
0
hkDemoEntryRegister::hkDemoEntryRegister( DemoCreationFunction func, int type, const char* path,
										 hkDemoEntryRegister* entries, int numEntries,
										 const hkClassEnum& cenum, 
										 const char* help, const char* details, bool actuallyReg )
{
	int nitems = cenum.getNumItems();
	HK_ASSERT(0x7d4ed233, numEntries >= nitems );
 	for( int i = 0; i < nitems; i++ )
	{
		const hkClassEnum::Item& item = cenum.getItem(i);
		new (&entries[i]) hkDemoEntryRegister( func, type, path, item.getValue(), item.getName(), help, details, actuallyReg );
	}
}
WindChimesDemo::WindChimesDemo(hkDemoEnvironment* env)
:	hkDefaultPhysicsDemo(env),
	m_loader(HK_NULL)
{
	const WindChimesVariant& variant =  g_variants[m_variantId];

	//
	// Create the sound manager.
	//

	//
	// Set up the camera
	//
	{
		hkVector4 from(6.0f, 0.0f, 3.0f);
		hkVector4 to  (0.0f, 0.0f, 0.0f);
		hkVector4 up  (0.0f, 0.0f, 1.0f);
		setupDefaultCameras( env, from, to, up );
	}

	hkString assetFile = hkAssetManagementUtil::getFilePath(variant.m_assetName);
	m_loader = new hkLoader();
	hkRootLevelContainer* container = m_loader->load( assetFile.cString() );
	HK_ASSERT2(0xaefe9356, container != HK_NULL , "Could not load asset");

	hkpPhysicsData* physics = static_cast<hkpPhysicsData*>( container->findObjectByType( hkpPhysicsDataClass.getName() ) );
	HK_ASSERT2(0x245982ae, physics != HK_NULL, "Could not find physics data in root level object" );
	{
		m_world = new hkpWorld( *physics->getWorldCinfo() );

		m_world->lock();

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

		setupGraphics();
	}

	m_world->addPhysicsSystem( physics->getPhysicsSystems()[0] );

	// There are 5 pipes in the circular chimes asset, called Chime0, Chime1...etc.
	for( int i = 0; i < variant.m_numChimes; i++ )
	{
		hkString chimeName;
		chimeName.printf( "Chime%d", i );
		hkpRigidBody* chime = physics->findRigidBodyByName( chimeName.cString() );
		HK_ASSERT(0x99862353, chime);

		new WindChimesCollisionListener( chime, i % variant.m_numDifferentChimeSizes );
	}
	m_world->unlock();
}
Example #22
0
hkDemo::Result MoppInstancingDemo::stepDemo()
{
	m_world->markForRead();

	for (int i=0; i<3; i++)
	{
		HK_ASSERT(0x79151c48, m_fixedBodies[i]->getCollidable()->getShape()->getType() == HK_SHAPE_MOPP);
		const hkpMoppBvTreeShape* mopp = static_cast<const hkpMoppBvTreeShape*> (m_fixedBodies[i]->getCollidable()->getShape());
		checkRayCasts(mopp, m_fixedBodies[i]->getTransform() );
	}
	m_world->unmarkForRead();

	return hkDefaultPhysicsDemo::stepDemo();
	
}
// should be called at plugin initialization time
void vHavokBehaviorModule::OneTimeInit()
{
	// Set up the behavior world
	if( m_behaviorWorld == HK_NULL )
	{
		// Register callbacks
		Vision::Callbacks.OnUpdateSceneBegin += this;
		Vision::Callbacks.OnUpdateSceneFinished += &g_HavokBehaviorOnUpdateSceneFinishedHandler;
		Vision::Callbacks.OnAfterSceneLoaded += this;
		vHavokPhysicsModule::OnAfterInitializePhysics += this;
		vHavokPhysicsModule::OnBeforeDeInitializePhysics += this;
	}

	// Create a VDB context
	HK_ASSERT(0x25427eb1, m_behaviorContext == HK_NULL );
	m_behaviorContext = new hkbBehaviorContext( getAssetLoader() );
}
Example #24
0
void hkDefaultDemo::mouseDown()
{
	HK_ASSERT(0x499454e1, m_mouseActive == false);

	// see if the user is picking - only if
	//   there is a display world!
	//   and we're not already picking
	hkgDisplayWorld* dw = m_env->m_displayWorld;
	if( m_env->m_mousePickingEnabled && dw )
	{
		hkgWindow* w = m_env->m_window;
		hkgViewport* v = w->getCurrentViewport();
		hkgCamera* c = v->getCamera();
		int vx, vy;
		v->getLowerLeftCoord(vx, vy);

		hkgViewportPickData pd;

		const int x = w->getMouse().getPosX() - vx;
		const int y = w->getMouse().getPosY() - vy;

		if (v->pick( x, y, dw, pd ))
		{
   			const int objectNum = pd.m_objectIndex;
			hkVector4 mousePosWorldSpace; mousePosWorldSpace.set( pd.m_worldPos[0], pd.m_worldPos[1], pd.m_worldPos[2]);

			float result[3];
			c->project( pd.m_worldPos[0], pd.m_worldPos[1], pd.m_worldPos[2], v->getWidth(), v->getHeight(), result );
			m_mousePosDepth = result[2];	// remember the z value

			//hkprintf( "GM: Try pick at [%d %d (%f)] ", x, y, m_mousePosDepth );
			//hkprintf( "World mouse pos: [%f %f %f]\n", pd.m_worldPos[0], pd.m_worldPos[1], pd.m_worldPos[2]);

			// find out if there is a (the first one) demo that has a rigid body attached
			// to this display object
			const hkgDisplayObject* dobject = dw->getDisplayObject( objectNum );
			m_mouseActive = objectPicked( dobject, mousePosWorldSpace, pd.m_objectPickData.m_geomIndex  );
		}
		else
		{
			m_mouseActive = objectPicked( HK_NULL, hkVector4::getZero(), 0  );
		}
	}
}
hkpStepResult hkDefaultPhysicsDemo::stepAsynchronously(hkpWorld* world, hkReal frameDeltaTime, hkReal physicsDeltaTime)
{

	hkpStepResult result;

	if (  m_world->m_simulationType == hkpWorldCinfo::SIMULATION_TYPE_MULTITHREADED )
	{

		world->setFrameTimeMarker( frameDeltaTime );

		world->advanceTime();
		while ( !world->isSimulationAtMarker() ) 
		{
			HK_ASSERT( 0x11179564, world->isSimulationAtPsi() );

			{
				// Interact from game to physics
			}

			hkCheckDeterminismUtil::workerThreadStartFrame(true);

			m_world->initMtStep( m_jobQueue, m_timestep );

			m_jobThreadPool->processAllJobs( m_jobQueue );
			m_jobQueue->processAllJobs( );

			m_jobThreadPool->waitForCompletion();

			m_world->finishMtStep( m_jobQueue, m_jobThreadPool );

			hkCheckDeterminismUtil::workerThreadFinishFrame();
		}

		result = HK_STEP_RESULT_SUCCESS;
	}
	else
	{
		hkAsynchronousTimestepper::stepAsynchronously(world, frameDeltaTime, physicsDeltaTime);
		result = HK_STEP_RESULT_SUCCESS;
	}

	return result;
}
Example #26
0
void ExplosionParticleSystem::initParticles(int numParticles, void* particleData, hkReal timestep, const void* emitParams)
{
	HK_ASSERT(0x6750a79f, emitParams);
	const EmitParams* params = static_cast<const EmitParams*>(emitParams);

	for(int i = 0; i < numParticles; ++i)
	{
		Particle& p = *reinterpret_cast<Particle*>(static_cast<char*>(particleData) + i*m_particleStride);

		p.m_position = params->m_position;
		p.m_position(3) = m_pseudoRandomGenerator.getRandReal01() * 2.f * HK_REAL_PI;

		// Uniformly sample a particle emission direction from the sphere
		// (see http://mathworld.wolfram.com/SpherePointPicking.html)
		hkReal theta = m_pseudoRandomGenerator.getRandReal01() * 2.f * HK_REAL_PI;
		hkReal u = m_pseudoRandomGenerator.getRandReal11();
		hkReal s = hkMath::sqrt(1.f - u*u);
		p.m_velocity.set(s*cosf(theta), u, s*sinf(theta));

		// Force the particle to be emitted from the hemisphere oriented by m_direction
		hkReal speed = m_pseudoRandomGenerator.getRandRange(params->m_minSpeed, params->m_maxSpeed);
		if(params->m_useDirection && p.m_velocity.dot3(params->m_direction) < 0.f)
		{
			speed = -speed;
		}
		p.m_velocity.mul4(speed);

		// Set the spin direction based on whether the particle is moving towards the left or right.
		hkReal spinRate = m_pseudoRandomGenerator.getRandRange(5.f*HK_REAL_DEG_TO_RAD, 30.f*HK_REAL_DEG_TO_RAD);
		if(params->m_planeNormal.dot3(p.m_velocity) > 0.f)
			spinRate = -spinRate;
		p.m_velocity(3) = spinRate;

		p.m_lifeTime = m_pseudoRandomGenerator.getRandRange(params->m_minLifeTime, params->m_maxLifeTime);
		p.m_age = m_pseudoRandomGenerator.getRandReal01() * timestep;
		p.m_size = m_pseudoRandomGenerator.getRandRange(params->m_minSize, params->m_maxSize);

		// Particle positions are initially integrated by a random amount to make it seem as
		// though they are emitted continuously over time instead of at discrete time steps.
		p.m_position.addMul4(p.m_age, p.m_velocity);
	}
}
Example #27
0
hkpWorld* FileManager::loadWorld( hkpPhysicsData** physicsData, hkResource** memData )
{
	hkIstream infile( SCRATCH_FILE );
	HK_ASSERT( 0x215d080c, infile.isOk() );
	*physicsData = hkpHavokSnapshot::load(infile.getStreamReader(), memData);
	if ( ! *physicsData )
	{
		HK_WARN_ALWAYS(0x3e65b887, "Failed to load asset " << SCRATCH_FILE);
		return HK_NULL;
	}

	// Ensure non-multi threaded simulation for non-multi threaded platforms
#if !defined(HK_PLATFORM_MULTI_THREAD) || (HK_CONFIG_THREAD == HK_CONFIG_SINGLE_THREADED)
	(*physicsData)->getWorldCinfo()->m_simulationType = hkpWorldCinfo::SIMULATION_TYPE_CONTINUOUS;
#endif

	hkpWorld* w = (*physicsData)->createWorld();


	return w;
}
static void saveWorld( hkpWorld* world, const char* path, bool binary )
{
	hkStructureLayout::LayoutRules layouts[] =   {	hkStructureLayout::MsvcWin32LayoutRules, 
													hkStructureLayout::MsvcXboxLayoutRules,
													hkStructureLayout::Xbox360LayoutRules, 
													hkStructureLayout::Sn31Ps2LayoutRules,
													hkStructureLayout::Gcc32Ps2LayoutRules, 
													hkStructureLayout::GccPs3LayoutRules 
												  };

	const int numLayouts = sizeof(layouts) /  sizeof (hkStructureLayout);

	const bool saveContactPoints = true;

	for (int i = 0; i < numLayouts; i++)
	{
		hkString filename = hkAssetManagementUtil::getFilePath( path, layouts[i] );
		hkOstream outfile( filename.cString() );
		HK_ON_DEBUG( hkBool res = ) hkpHavokSnapshot::save(world, outfile.getStreamWriter(), binary, &layouts[i], saveContactPoints );
		HK_ASSERT( 0x215d080d, res );
	}
}
	void updatePackfileDataVersion(hkArray<char>& ioBuf)
	{
		hkArray<char> origBuf;
		origBuf.swap(ioBuf);

		// Load the entire file inplace
		hkBinaryPackfileReader reader;
		reader.loadEntireFileInplace(origBuf.begin(), origBuf.getSize());

		// check versioning
		if( hkVersionUtil::updateToCurrentVersion( reader, hkVersionRegistry::getInstance() ) != HK_SUCCESS )
		{
			HK_WARN_ALWAYS(0, "Couldn't update version, skipping.\n");
		}
		// Get the top level object in the file
		hkRootLevelContainer* container = static_cast<hkRootLevelContainer*>( reader.getContents( hkRootLevelContainerClass.getName() ) );
		HK_ASSERT2(0xa6451543, container != HK_NULL, "Could not load root level obejct" );

		hkOstream nativeFile(ioBuf);
		hkBool success = hkpHavokSnapshot::save(container, hkRootLevelContainerClass, nativeFile.getStreamWriter(), true);
		HK_ASSERT(0xa6451545, success == true);
	}
void loadEntireFileIntoBuffer(const char* filepath, hkArray<char>& outBuf)
{
	// Load the entire file
	// Open a stream to read the file
	hkIstream infile( filepath );
	HK_ASSERT( 0x215d080c, infile.isOk() );

	if( infile.getStreamReader()->seekTellSupported() )
	{
		infile.getStreamReader()->seek(0, hkStreamReader::STREAM_END);
		outBuf.reserve( infile.getStreamReader()->tell() );
		infile.getStreamReader()->seek(0, hkStreamReader::STREAM_SET);
	}

	// read entire file into local buffer
	int nread = 1;
	while( nread )
	{
		const int CSIZE = 8192;
		char* b = outBuf.expandBy( CSIZE ); // outBuf.reserve( outBuf.getSize() + CSIZE ); b = outBuf.begin() + outBuf.getSize();
		nread = infile.read( b, CSIZE );
		outBuf.setSize( outBuf.getSize() + nread - CSIZE );
	}
}