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); } }
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; } }
// 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) ); } } } }
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; }
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; }
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()*/); }
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; }
LandscapeContainer::~LandscapeContainer() { HK_ASSERT(0, m_shape != HK_NULL); if (m_shape) { m_shape->removeReference(); } if ( m_packfileData ) { m_packfileData->removeReference(); } }
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(); }
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() ); }
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; }
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); } }
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 ); } }