hkDefaultAnimationDemo::hkDefaultAnimationDemo(hkDemoEnvironment* env) : hkDefaultDemo (env) //m_animationViewersContext(HK_NULL) { // eg: // m_animationViewersContext= new hkAnimationContext; // hkAnimationContext::registerAllAnimationProcesses(); // all physics only ones // Most of the default animations hover above the ground, so we don't want shadows // until they are reauthored forceShadowState(false); setupLights(m_env); // after we decide if we want shadows // Disable compression & mapping reports if(m_env->m_reportingLevel < hkDemoEnvironment::REPORT_INFO ) { hkError::getInstance().setEnabled(0x432434a4, false); // Track analysis report hkError::getInstance().setEnabled(0x432434a5, false); // Delta/wavelet constructor report hkError::getInstance().setEnabled(0x54e4323e, false); // hkaSkeletonMapperUtils::createMapping report hkError::getInstance().setEnabled(0xf0d1e423, false); // 'Could not realize an inplace texture of type PNG.' hkError::getInstance().setEnabled(0x36118e94, false); // Spline constructor report } }
MultipleCharacterRbsDemo::MultipleCharacterRbsDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env) { // Setup the graphics { forceShadowState(false); } // Create the world { hkpWorldCinfo info; info.setBroadPhaseWorldSize( 350.0f ); info.m_gravity.set(0, -9.8f, 0); info.m_contactPointGeneration = hkpWorldCinfo::CONTACT_POINT_ACCEPT_ALWAYS; info.m_collisionTolerance = 0.1f; // faster, but better 0.01f for accuracy m_world = new hkpWorld( info ); m_world->lock(); hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher()); setupGraphics(); } // Create the ground using the landscape repository { int landscapeIndex = LandscapeRepository::getInstance().getLandscapeIndexByName("simpleFlatLandOneMetreTris"); m_landscapeContainer = LandscapeRepository::getInstance().getLandscape(landscapeIndex); hkpRigidBodyCinfo groundInfo; groundInfo.m_motionType = hkpMotion::MOTION_FIXED; groundInfo.m_shape = m_landscapeContainer->m_shape; hkpRigidBody* groundbody = new hkpRigidBody(groundInfo); m_world->addEntity(groundbody)->removeReference(); setupDefaultCameras( env, m_landscapeContainer->m_cameraFrom, m_landscapeContainer->m_cameraTo, hkVector4(0,1,0) ); } AabbSpawnUtil spawnUtil( m_landscapeContainer->m_spawnVolumes ); // Create character rigid bodies const int numCharacters = 100; { m_characterRigidBodies.setSize( numCharacters ); // Create a capsule to represent the character standing hkVector4 top(0, .4f, 0); hkVector4 bottom(0,-.4f, 0); hkpShape* characterShape = new hkpCapsuleShape(top, bottom, .6f); // Construct characters for (int i=0; i < numCharacters; i++) { // Construct a character rigid body hkpCharacterRigidBodyCinfo info; info.m_mass = 100.0f; info.m_shape = characterShape; info.m_maxForce = 2000.0f; info.m_up = UP; spawnUtil.getNewSpawnPosition( hkVector4(1, 2, 1), info.m_position ); info.m_maxSlope = 90.0f * HK_REAL_DEG_TO_RAD; m_characterRigidBodies[i] = new hkpCharacterRigidBody( info ); m_world->addEntity( m_characterRigidBodies[i]->getRigidBody() ); } characterShape->removeReference(); } // 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 { m_characterContexts.setSize(numCharacters); for (int i=0; i < numCharacters; i++) { m_characterContexts[i] = new hkpCharacterContext(manager, HK_CHARACTER_ON_GROUND); m_characterContexts[i]->setCharacterType(hkpCharacterContext::HK_CHARACTER_RIGIDBODY); } manager->removeReference(); } //Initialized the round robin counter m_tick = 0; m_world->unlock(); }
UnevenTerrainVsDemo::UnevenTerrainVsDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env) { // Setup the graphics { forceShadowState(false); } // Create the world { hkpWorldCinfo info; info.setBroadPhaseWorldSize( 350.0f ); info.m_gravity.set(0, -9.8f, 0); info.m_contactPointGeneration = hkpWorldCinfo::CONTACT_POINT_ACCEPT_ALWAYS; info.m_collisionTolerance = m_options.m_worldCollisionTolerance; m_world = new hkpWorld( info ); m_world->lock(); hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher()); setupGraphics(); } // Setup layer collision { // Replace filter hkpGroupFilter* groupFilter = new hkpGroupFilter(); // We disable collisions between characters groupFilter->disableCollisionsBetween(LAYER_CHARACTER_PROXY, LAYER_CHARACTER_RIGIDBODY); m_world->setCollisionFilter( groupFilter, true); groupFilter->removeReference(); } // Create the ground using the landscape repository { int landscapeIndex = LandscapeRepository::getInstance().getLandscapeIndexByName("simpleFlatLandOneMetreTris"); m_landscapeContainer = LandscapeRepository::getInstance().getLandscape(landscapeIndex); hkpRigidBodyCinfo groundInfo; groundInfo.m_motionType = hkpMotion::MOTION_FIXED; groundInfo.m_shape = m_landscapeContainer->m_shape; hkpRigidBody* groundbody = new hkpRigidBody(groundInfo); m_world->addEntity(groundbody)->removeReference(); setupDefaultCameras( env, m_landscapeContainer->m_cameraFrom, m_landscapeContainer->m_cameraTo, hkVector4(0,1,0) ); } AabbSpawnUtil spawnUtil( m_landscapeContainer->m_spawnVolumes ); const hkReal characterMass = 100.0f; hkpShape* characterShape; { // Create a capsule to represent the character standing hkVector4 top( 0, m_options.m_characterCylinderHeight * 0.5f, 0 ); hkVector4 bottom( 0, -m_options.m_characterCylinderHeight * 0.5f, 0 ); characterShape = new hkpCapsuleShape( top, bottom, m_options.m_characterRadius ); } { // Construct a character rigid body hkpCharacterRigidBodyCinfo info; info.m_mass = characterMass; info.m_shape = characterShape; info.m_up = UP; info.m_position = characterStart; info.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo( LAYER_CHARACTER_RIGIDBODY, 0 ); info.m_supportDistance = m_options.m_rbSupportDistance; info.m_hardSupportDistance = m_options.m_rbHardSupportDistance; info.m_allowedPenetrationDepth = m_options.m_rbAllowedPenetrationDepth; m_characterRigidBody = new hkpCharacterRigidBody( info ); hkpCharacterRigidBodyListener* listener = new hkpCharacterRigidBodyListener(); m_characterRigidBody->setListener( listener ); listener->removeReference(); m_world->addEntity( m_characterRigidBody->getRigidBody() ); characterShape->removeReference(); } // Create the Character state machine and context { hkpCharacterStateManager* manager; hkpCharacterState* state; manager = new hkpCharacterStateManager(); static_cast<hkpCharacterStateOnGround*>( state = new hkpCharacterStateOnGround() )->setSpeed( m_options.m_characterWalkSpeed ); 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_ON_GROUND); m_characterContext->setCharacterType(hkpCharacterContext::HK_CHARACTER_RIGIDBODY); manager->removeReference(); } // Create a character proxy object { // Construct a shape phantom m_phantom = new hkpSimpleShapePhantom( characterShape, hkTransform::getIdentity(), hkpGroupFilter::calcFilterInfo( LAYER_CHARACTER_PROXY, 0 ) ); // Add the phantom to the world m_world->addPhantom(m_phantom); m_phantom->removeReference(); // Construct a character proxy hkpCharacterProxyCinfo cpci; cpci.m_position = characterStart; cpci.m_staticFriction = 0.0f; cpci.m_dynamicFriction = 1.0f; cpci.m_up = UP; cpci.m_userPlanes = 4; cpci.m_shapePhantom = m_phantom; m_characterProxy = new hkpCharacterProxy( cpci ); } // Create the character proxy state machine and context { hkpCharacterState* state; hkpCharacterStateManager* manager = new hkpCharacterStateManager(); static_cast<hkpCharacterStateOnGround*>( state = new hkpCharacterStateOnGround() )->setSpeed( m_options.m_characterWalkSpeed ); 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_characterProxyContext = new hkpCharacterContext(manager, HK_CHARACTER_ON_GROUND); manager->removeReference(); } //Initialized the round robin counter m_tick = 0; m_unsupportedFramesCountRb = 0; m_unsupportedFramesCountProxy = 0; m_filterRigidBody.m_framesInAir = m_options.m_clientStateFiltering; m_filterProxy.m_framesInAir = m_options.m_clientStateFiltering; m_world->unlock(); }
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(); }
PlatformsCharacterRbDemo::PlatformsCharacterRbDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env) { // Setup the graphics { // Disable back face culling setGraphicsState(HKG_ENABLED_CULLFACE, false); // don't really want shadows as makes it too dark forceShadowState(false); setupLights(m_env); // so that the extra lights are added // allow color change on precreated objects m_env->m_displayHandler->setAllowColorChangeOnPrecreated(true); } // Create the world { hkpWorldCinfo info; info.setBroadPhaseWorldSize( 350.0f ); info.m_gravity.set(0,0,-9.8f); info.m_collisionTolerance = 0.01f; m_world = new hkpWorld( info ); m_world->lock(); hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher()); setupGraphics(); } // Load the level { m_loader = new hkLoader(); hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Physics/levels/test_platform.hkx"); hkRootLevelContainer* container = m_loader->load( assetFile.cString() ); HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset"); hkxScene* scene = reinterpret_cast<hkxScene*>( container->findObjectByType( hkxSceneClass.getName() )); HK_ASSERT2(0x27343635, scene, "No scene loaded"); env->m_sceneConverter->convert( scene, hkgAssetConverter::CONVERT_ALL ); hkpPhysicsData* physics = reinterpret_cast<hkpPhysicsData*>( container->findObjectByType( hkpPhysicsDataClass.getName() )); HK_ASSERT2(0x27343635, physics, "No physics loaded"); // Physics if (physics) { const hkArray<hkpPhysicsSystem*>& psys = physics->getPhysicsSystems(); // Tie the two together for (int i=0; i<psys.getSize(); i++) { hkpPhysicsSystem* system = psys[i]; // Change the layer of the rigid bodies for (int rb=0; rb < system->getRigidBodies().getSize(); rb++) { const hkUlong id = hkUlong(system->getRigidBodies()[rb]->getCollidable()); HK_SET_OBJECT_COLOR(id,NORMAL_GRAY); m_objectIds.pushBack(id); } // Associate the display and physics (by name) if (scene) { addPrecreatedDisplayObjectsByName( psys[i]->getRigidBodies(), scene ); } // add the lot to the world m_world->addPhysicsSystem(system); } } } // Add horizontal keyframed platform { hkpShape* platform = new hkpBoxShape(hkVector4(1.5,2.5,0.25)); hkpRigidBodyCinfo rbci; rbci.m_shape = platform; rbci.m_motionType = hkpMotion::MOTION_KEYFRAMED; rbci.m_position.set(2.5f, 0.0f, 0.25f); rbci.m_friction = 1.0f; rbci.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(hkpGroupFilter::calcFilterInfo(1)); m_horPlatform = new hkpRigidBody(rbci); platform->removeReference(); m_world->addEntity(m_horPlatform); m_horPlatform->removeReference(); } // Add vertical keyframed platform { hkpShape* platform = new hkpBoxShape(hkVector4(1.5,2.5,0.25)); hkpRigidBodyCinfo rbci; rbci.m_shape = platform; rbci.m_motionType = hkpMotion::MOTION_KEYFRAMED; rbci.m_position.set(-3.5f, 0.0f, 3.25f); rbci.m_friction = 1.0f; rbci.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo(hkpGroupFilter::calcFilterInfo(1)); m_verPlatform = new hkpRigidBody(rbci); platform->removeReference(); m_world->addEntity(m_verPlatform); m_verPlatform->removeReference(); } // Create a character rigid body { // Create a capsule to represent the character standing hkVector4 vertexA(0,0, 0.4f); hkVector4 vertexB(0,0,-0.4f); m_standShape = new hkpCapsuleShape(vertexA, vertexB, .6f); // Construct a character rigid body hkpCharacterRigidBodyCinfo info; info.m_mass = 100.0f; info.m_shape = m_standShape; info.m_maxForce = 1000.0f; info.m_up = UP; info.m_position.set(0.0f, 5.0f, 1.5f); info.m_maxSlope = HK_REAL_PI/2.0f; m_characterRigidBody = new hkpCharacterRigidBody( info ); m_world->addEntity( m_characterRigidBody->getRigidBody() ); } // Create the character state machine { 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_ON_GROUND); m_characterContext->setCharacterType(hkpCharacterContext::HK_CHARACTER_RIGIDBODY); manager->removeReference(); } // Set colors of platforms HK_SET_OBJECT_COLOR(hkUlong(m_verPlatform->getCollidable()),hkColor::BLUE); HK_SET_OBJECT_COLOR(hkUlong(m_horPlatform->getCollidable()),hkColor::GREEN); // Set global time m_time = 0.0f; // Initialize hkpSurfaceInfo for previous ground m_previousGround = new hkpSurfaceInfo(); m_framesInAir = 0; // Current camera angle about up m_currentAngle = HK_REAL_PI * 0.5f; m_world->unlock(); }
PlanetGravityDemo::PlanetGravityDemo( hkDemoEnvironment* env ) : hkDefaultPhysicsDemo(env) { hkString filename; // We have a different binary file depending on the compiler and platform filename.printf( "Resources/Physics/Levels/planetgravity_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() ); hkpWorld::IgnoreForceMultithreadedSimulation ignoreForceMultithreaded; // Disable warning: 'm_contactRestingVelocity not set, setting it to REAL_MAX, so that the new collision restitution code will be disabled' hkError::getInstance().setEnabled( 0xf03243ed, false ); // Load the startup scene { m_worldUp.set( 0.0f, 0.0f, 1.0f ); m_characterForward.set( 1.0f, 0.0f, 0.0f ); // Initialize hkpSurfaceInfo for storing the old ground info m_previousGround = new hkpSurfaceInfo(); m_framesInAir = 0; m_cameraForward.set( 1.0f, 0.0f, 0.0f ); m_cameraUp = m_cameraForward; m_cameraPosition.set( 20.0f, 1.0f, 35.0f ); m_detachedCamera = false; // Load the world. m_world = loadWorld( filename.cString(), &m_physicsData, &m_loadedData ); m_world->markForWrite(); setupDefaultCameras( env, m_cameraPosition, m_characterRigidBody->getPosition(), m_worldUp ); // Setup graphics setupGraphics(); forceShadowState(false); // Disable shadows setupSkyBox(env); { removeLights( m_env ); float v[] = { 0.941f, 0.941f, 0.784f }; m_flashLight = hkgLight::create(); m_flashLight->setType( HKG_LIGHT_DIRECTIONAL ); m_flashLight->setDiffuse( v ); v[0] = 0; v[1] = 1; v[2] = -0.5; m_flashLight->setDirection( v ); v[0] = 0; v[1] = -1000; v[2] = 0; m_flashLight->setPosition( v ); m_flashLight->setDesiredEnabledState( true ); env->m_displayWorld->getLightManager()->addLight( m_flashLight ); env->m_displayWorld->getLightManager()->computeActiveSet( HKG_VEC3_ZERO ); } // Set up the collision filter { hkpGroupFilter* filter = new hkpGroupFilter(); filter->disableCollisionsBetween(1, 1); m_world->setCollisionFilter(filter); filter->removeReference(); } // Go through all loaded rigid bodies for( int i = 0; i < m_physicsData->getPhysicsSystems().getSize(); i++ ) { const hkArray<hkpRigidBody*>& bodies = m_physicsData->getPhysicsSystems()[i]->getRigidBodies(); for( int j = 0; j < bodies.getSize(); j++ ) { hkString rbName( bodies[j]->getName() ); // If the rb is a planet (name is "planet*") if( rbName.beginsWith( "planet" ) ) { // If the body is a representation of a gravitational field (name: "*GravField"), // remove it from the simulation. if( rbName.endsWith( "GravField" ) ) { m_world->removeEntity( bodies[j] ); } // Otherwise, it's actually a planet. else { hkAabb currentAabb; const hkpCollidable* hullCollidable = HK_NULL; // Find the planet's gravity field hkpRigidBody* planetRigidBody = bodies[j]; hkString gravFieldRbName; gravFieldRbName.printf( "%sGravField", rbName.cString() ); hkpRigidBody* gravFieldRigidBody = m_physicsData->findRigidBodyByName( gravFieldRbName.cString() ); // If there's a GravField rigid body, then grab its collidable to be used for gravity calculation. if( gravFieldRigidBody ) { hullCollidable = gravFieldRigidBody->getCollidable(); gravFieldRigidBody->getCollidable()->getShape()->getAabb( gravFieldRigidBody->getTransform(), 0.0f, currentAabb ); } else { planetRigidBody->getCollidable()->getShape()->getAabb( planetRigidBody->getTransform(), 0.0f, currentAabb ); } // Scale up the planet's gravity field's AABB so it goes beyond the planet hkVector4 extents; extents.setSub4( currentAabb.m_max, currentAabb.m_min ); hkInt32 majorAxis = extents.getMajorAxis(); hkReal maxExtent = extents( majorAxis ); maxExtent *= 0.4f; // Scale the AABB's extents hkVector4 extension; extension.setAll( maxExtent ); currentAabb.m_max.add4( extension ); currentAabb.m_min.sub4( extension ); // Attach a gravity phantom to the planet so it can catch objects which come close SimpleGravityPhantom* gravityAabbPhantom = new SimpleGravityPhantom( planetRigidBody, currentAabb, hullCollidable ); m_world->addPhantom( gravityAabbPhantom ); gravityAabbPhantom->removeReference(); // Add a tracking action to the phantom so it follows the planet. This allows support for non-fixed motion type planets if (planetRigidBody->getMotion()->getType() != hkpMotion::MOTION_FIXED) { PhantomTrackAction* trackAction = new PhantomTrackAction( planetRigidBody, gravityAabbPhantom ); m_world->addAction( trackAction ); trackAction->removeReference(); } } } // if the rigid body is a launchpad (name: "launchPadSource*") else if( rbName.beginsWith("launchPadSource" ) ) { hkString targetName; // Find launchpad "target" (used to calculate trajectory when launching) targetName.printf( "launchPadTarget%s", rbName.substr( hkString::strLen("launchPadSource") ).cString() ); hkpRigidBody* target = m_physicsData->findRigidBodyByName( targetName.cString() ); HK_ASSERT2( 0x0, target, "All launchPadSource rigid bodies must have associated launchPadTargets." ); // Add a collision listener to the launchpad so it can apply forces to colliding rbs LaunchPadListener* launchPadListener = new LaunchPadListener( target->getPosition() ); bodies[j]->addCollisionListener( launchPadListener ); bodies[j]->setMotionType( hkpMotion::MOTION_FIXED ); HK_SET_OBJECT_COLOR( reinterpret_cast<hkUlong>( bodies[j]->getCollidable() ), hkColor::RED ); m_world->removeEntity( target ); } // A "basic" launchpad just applies a force in the direction of the collision normal else if( rbName.beginsWith( "launchPadBasic" ) ) { LaunchPadListener* launchPadListener = new LaunchPadListener( bodies[j]->getMass() ); bodies[j]->addCollisionListener( launchPadListener ); bodies[j]->setMotionType( hkpMotion::MOTION_FIXED ); HK_SET_OBJECT_COLOR( reinterpret_cast<hkUlong>( bodies[j]->getCollidable() ), hkColor::RED ); } else if( rbName.beginsWith( "teleporterSource" ) ) { hkString targetName; // Find the teleportation destination of the teleporter targetName.printf( "teleporterTarget%s", rbName.substr( hkString::strLen("teleporterSource") ).cString() ); hkpRigidBody* target = m_physicsData->findRigidBodyByName( targetName.cString() ); HK_ASSERT2( 0, target, "All teleporterSource rigid bodies must have associated teleporterTargets." ); // Replace the rb with a callback shape phantom. Colliding rbs will be teleported to the destination. TeleporterPhantomCallbackShape* phantomCallbackShape = new TeleporterPhantomCallbackShape( target->getTransform() ); hkpBvShape* phantom = new hkpBvShape( bodies[j]->getCollidable()->getShape(), phantomCallbackShape ); phantomCallbackShape->removeReference(); bodies[j]->getCollidable()->getShape()->removeReference(); bodies[j]->setShape( phantom ); phantom->removeReference(); m_world->removeEntity( target ); } else if( rbName.beginsWith( "TurretTop" ) ) { // Create a place to store state information for this turret. Turret& turret = m_turrets.expandOne(); turret.constraint = bodies[j]->getConstraint(0); turret.hinge = static_cast<hkpLimitedHingeConstraintData*>( const_cast<hkpConstraintData*>( turret.constraint->getData() ) ); turret.turretRigidBody = bodies[j]; turret.cooldown = 0.0f; // Allow the hinge to spin infinitely and start the motor up turret.hinge->disableLimits(); turret.hinge->setMotorActive( turret.constraint, true ); // Do not allow the turret's simulation island deactivate. // If it does, it will stop spinning. turret.turretRigidBody->setDeactivator( hkpRigidBodyDeactivator::DEACTIVATOR_NEVER ); } // Update collision filter so that needless CollColl3 agents are not created. // For example, turrets and geometry marked as "static" (such as the swing) // should never collide with a planet, nor each other. if( ( rbName.beginsWith( "planet" ) && !rbName.endsWith( "GravField" ) ) || rbName.beginsWith( "Turret" ) || rbName.endsWith( "_static" ) ) { bodies[j]->setCollisionFilterInfo( hkpGroupFilter::calcFilterInfo( 1 ) ); // Destroy or create agents (according to new quality type). This also removes Toi events. m_world->updateCollisionFilterOnEntity(bodies[j], HK_UPDATE_FILTER_ON_ENTITY_FULL_CHECK, HK_UPDATE_COLLECTION_FILTER_PROCESS_SHAPE_COLLECTIONS); } } } m_world->unmarkForWrite(); } }
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(); }
CharacterDemo::CharacterDemo(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 ); // disable back face culling setGraphicsState(HKG_ENABLED_CULLFACE, false); // don't really want shadows as makes it too dark forceShadowState(false); setupLights(m_env); // so that the extra lights are added // float lightDir[] = { 0, -0.5f, -1 }; // setSoleDirectionLight(m_env, lightDir, 0xffffffff ); } // // Create the world // { hkpWorldCinfo info; info.setBroadPhaseWorldSize( 350.0f ); info.m_gravity.set(0,0,-9.8f); info.m_collisionTolerance = 0.1f; m_world = new hkpWorld( info ); m_world->lock(); hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher()); setupGraphics(); } // Load the level { hkVector4 tkScaleFactor(.32f,.32f,.32f); hkString fullname("Resources/Physics/Tk/CharacterController/"); // We load our test case level. //fullname += "testcases.tk"; fullname += "level.tk"; hkpShape* moppShape = GameUtils::loadTK2MOPP(fullname.cString(),tkScaleFactor, -1.0f); HK_ASSERT2(0x64232cc0, moppShape,"TK file failed to load to MOPP in GameUtils::loadTK2MOPP."); hkpRigidBodyCinfo ci; ci.m_shape = moppShape; ci.m_motionType = hkpMotion::MOTION_FIXED; ci.m_collisionFilterInfo = hkpGroupFilter::calcFilterInfo( 0, 1 ); hkpRigidBody* entity = new hkpRigidBody(ci); moppShape->removeReference(); m_world->addEntity(entity); entity->removeReference(); } // Add a ladder hkVector4 baseSize( 1.0f, 0.5f, 3.6f); { hkpRigidBodyCinfo rci; rci.m_shape = new hkpBoxShape( baseSize ); rci.m_position.set(3.4f, 8.f, 2); rci.m_motionType = hkpMotion::MOTION_FIXED; hkpRigidBody* ladder = new hkpRigidBody(rci); rci.m_shape->removeReference(); m_world->addEntity(ladder)->removeReference(); // Add a property so we can identify this as a ladder hkpPropertyValue val(1); ladder->addProperty(HK_OBJECT_IS_LADDER, val); // Color the ladder so we can see it clearly HK_SET_OBJECT_COLOR((hkUlong)ladder->getCollidable(), 0x7f1f3f1f); } // // Create a character proxy object // { // Construct a shape hkVector4 vertexA(0,0, 0.4f); hkVector4 vertexB(0,0,-0.4f); // Create a capsule to represent the character standing m_standShape = new hkpCapsuleShape(vertexA, vertexB, .6f); // Create a capsule to represent the character crouching // Note that we create the smaller capsule with the base at the same position as the larger capsule. // This means we can simply swap the shapes without having to reposition the character proxy, // and if the character is standing on the ground, it will still be on the ground. vertexA.setZero4(); m_crouchShape = new hkpCapsuleShape(vertexA, vertexB, .6f); // Construct a Shape Phantom m_phantom = new hkpSimpleShapePhantom( m_standShape, hkTransform::getIdentity(), hkpGroupFilter::calcFilterInfo(0,2) ); // Add the phantom to the world m_world->addPhantom(m_phantom); m_phantom->removeReference(); // Construct a character proxy hkpCharacterProxyCinfo cpci; cpci.m_position.set(-9.1f, 35, .4f); cpci.m_staticFriction = 0.0f; cpci.m_dynamicFriction = 1.0f; cpci.m_up.setNeg4( m_world->getGravity() ); cpci.m_up.normalize3(); cpci.m_userPlanes = 4; cpci.m_maxSlope = HK_REAL_PI / 3.f; cpci.m_shapePhantom = m_phantom; m_characterProxy = new hkpCharacterProxy( cpci ); } // // Add in a custom friction model // { hkVector4 up( 0.f, 0.f, 1.f ); m_listener = new MyCharacterListener(); m_characterProxy->addCharacterProxyListener(m_listener); } // // 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_ON_GROUND); manager->removeReference(); } // Current camera angle about up m_currentAngle = HK_REAL_PI * 0.5f; m_world->unlock(); }