LookAtDemo::LookAtDemo( hkDemoEnvironment* env ) : hkDefaultAnimationDemo(env) { // Disable warnings: if no renderer if( hkString::strCmp( m_env->m_options->m_renderer, "n" ) == 0 ) { hkError::getInstance().setEnabled(0xf0d1e423, false); //'Could not realize an inplace texture of type PNG.' } // // Setup the camera // { hkVector4 from( -1, -1, 1 ); hkVector4 to ( 0,0,0.75 ); hkVector4 up ( 0.0f, 0.0f, 1.0f ); setupDefaultCameras( env, from, to, up, 0.1f, 100 ); } m_loader = new hkLoader(); // Convert the scene { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/Scene/hkScene.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"); removeLights(m_env); env->m_sceneConverter->convert( scene ); } // Get the rig { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkRig.hkx"); hkRootLevelContainer* container = m_loader->load( assetFile.cString() ); HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numSkeletons > 0), "No skeleton loaded"); m_skeleton = ac->m_skeletons[0]; } // Get the idle animation and the binding { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkIdle.hkx"); hkRootLevelContainer* container = m_loader->load( assetFile.cString() ); HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numAnimations > 0 ), "No animation loaded"); m_animation = ac->m_animations[0]; HK_ASSERT2(0x27343435, ac && (ac->m_numBindings > 0), "No binding loaded"); m_binding = ac->m_bindings[0]; } // Convert the skin { const char* skinFile = "Resources/Animation/HavokGirl/hkLowResSkinWithEyes.hkx"; hkString assetFile = hkAssetManagementUtil::getFilePath( skinFile ); 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(0x27343435, scene , "No scene loaded"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numSkins > 0), "No skins loaded"); m_numSkinBindings = ac->m_numSkins; m_skinBindings = ac->m_skins; m_numAttachments = ac->m_numAttachments; m_attachments = ac->m_attachments; // Make graphics output buffers for the skins env->m_sceneConverter->convert( scene ); for (int a=0; a < m_numAttachments; ++a) { hkaBoneAttachment* ba = m_attachments[a]; hkgDisplayObject* hkgObject = HK_NULL; //Check the attachment is a mesh if ( hkString::strCmp(ba->m_attachment.m_class->getName(), hkxMeshClass.getName()) == 0) { hkgObject = env->m_sceneConverter->findFirstDisplayObjectUsingMesh((hkxMesh*)ba->m_attachment.m_object); if (hkgObject) { hkgObject->setStatusFlags(hkgObject->getStatusFlags() | HKG_DISPLAY_OBJECT_DYNAMIC); } } m_attachmentObjects.pushBack(hkgObject); } } m_skeletonInstance = new hkaAnimatedSkeleton( m_skeleton ); // Set the fill threshold m_skeletonInstance->setReferencePoseWeightThreshold( 0.05f ); // animation controller { m_control = new hkaDefaultAnimationControl( m_binding ); m_control->setPlaybackSpeed( 1.0f ); m_skeletonInstance->addAnimationControl( m_control ); m_control->removeReference(); } // setup the graphics setupGraphics( ); // find the bone indices for the neck, head and eyes. m_neckIndex = hkaSkeletonUtils::findBoneWithName( *m_skeleton, "HavokBipedRig Neck" ); m_headIndex = hkaSkeletonUtils::findBoneWithName( *m_skeleton, "HavokBipedRig Head" ); m_lEyeIndex = hkaSkeletonUtils::findBoneWithName( *m_skeleton, "LowEyeL" ); m_rEyeIndex = hkaSkeletonUtils::findBoneWithName( *m_skeleton, "LowEyeR" ); }
MotionExtractionDemo::MotionExtractionDemo( hkDemoEnvironment* env ) : hkDefaultAnimationDemo(env) { // Disable warnings: if no renderer if( hkString::strCmp( m_env->m_options->m_renderer, "n" ) == 0 ) { hkError::getInstance().setEnabled(0xf0d1e423, false); //'Could not realize an inplace texture of type PNG.' } // want to do software skinning always in this demo // see HardwareSkinningDemo for how to setup hardware palettes etc m_env->m_sceneConverter->setAllowHardwareSkinning(false); // // Setup the camera // { hkVector4 from( 3,3,1 ); hkVector4 to ( 0,0,0 ); hkVector4 up ( 0.0f, 0.0f, 1.0f ); setupDefaultCameras( env, from, to, up, 0.1f, 100 ); // so we can use the sticks on consoles if (m_env->m_options->m_trackballMode == 0) { m_forcedOnTrackball = true; m_env->m_window->getViewport(0)->setNavigationMode(HKG_CAMERA_NAV_TRACKBALL); } } m_loader = new hkLoader(); // Convert the scene { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/Scene/hkScene.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"); removeLights(m_env); env->m_sceneConverter->convert( scene ); } // Get the rig { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkRig.hkx"); hkRootLevelContainer* container = m_loader->load( assetFile.cString() ); HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numSkeletons > 0), "No skeleton loaded"); m_skeleton = ac->m_skeletons[0]; } // Get the animation and the binding { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkWalkLoop.hkx"); hkRootLevelContainer* container = m_loader->load( assetFile.cString() ); HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numAnimations > 0 ), "No animation loaded"); m_animation[0] = ac->m_animations[0]; HK_ASSERT2(0x27343435, ac && (ac->m_numBindings > 0), "No binding loaded"); m_binding[0] = ac->m_bindings[0]; assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkWalkTurnLLoop.hkx"); container = m_loader->load( assetFile.cString() ); ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numAnimations > 0 ), "No animation loaded"); m_animation[1] = ac->m_animations[0]; HK_ASSERT2(0x27343435, ac && (ac->m_numBindings > 0), "No binding loaded"); m_binding[1] = ac->m_bindings[0]; assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkWalkTurnRLoop.hkx"); container = m_loader->load( assetFile.cString() ); ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numAnimations > 0 ), "No animation loaded"); m_animation[2] = ac->m_animations[0]; HK_ASSERT2(0x27343435, ac && (ac->m_numBindings > 0), "No binding loaded"); m_binding[2] = ac->m_bindings[0]; } // Convert the skin { const char* skinFile = "Resources/Animation/HavokGirl/hkLowResSkin.hkx"; hkString assetFile = hkAssetManagementUtil::getFilePath( skinFile ); 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(0x27343435, scene , "No scene loaded"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numSkins > 0), "No skins loaded"); m_numSkinBindings = ac->m_numSkins; m_skinBindings = ac->m_skins; // Make graphics output buffers for the skins env->m_sceneConverter->convert( scene ); } // Create the skeleton m_skeletonInstance = new hkaAnimatedSkeleton( m_skeleton ); m_skeletonInstance->setReferencePoseWeightThreshold( 0.01f ); float weights[NUM_ANIMS]; weights[0] = 0.1f; weights[1] = 0.0f; weights[2] = 0.0f; // Grab the animations for (int i=0; i < NUM_ANIMS; i++) { m_control[i] = new hkaDefaultAnimationControl( m_binding[i] ); m_control[i]->setMasterWeight( weights[i] ); m_control[i]->setPlaybackSpeed( 1.0f ); m_skeletonInstance->addAnimationControl( m_control[i] ); m_control[i]->removeReference(); } // make a world so that we can auto create a display world to hold the skin setupGraphics( ); m_currentMotion.setIdentity(); }
HardwareSkinningDemo::HardwareSkinningDemo( hkDemoEnvironment* env ) : hkDefaultAnimationDemo(env) { // Disable warnings: if no renderer if( hkString::strCmp( m_env->m_options->m_renderer, "n" ) == 0 ) { hkError::getInstance().setEnabled(0xf0d1e423, false); //'Could not realize an inplace texture of type PNG.' } // // Setup the camera // { hkVector4 from( -0.92f, -1.2f, 0.63f ); hkVector4 to ( 0.35f,-0.35f, 0.30f ); hkVector4 up ( 0.0f, 0.0f, 1.0f); setupDefaultCameras( env, from, to, up, 0.01f, 10000.0f ); } m_loader = new hkLoader(); // We want to use this demo to do the skinning, so we don't let our graphics engine do it. m_canSkin = (hkgSystem::g_RendererType != hkgSystem::HKG_RENDERER_NULL); if (hkgSystem::g_RendererType != hkgSystem::HKG_RENDERER_CONSOLE) { m_canSkin = m_env->m_window->shaderSupportGreaterOrEqualTo(1); // has shaders.. } env->m_sceneConverter->setAllowHardwareSkinning(m_canSkin); // Convert the scene { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/Scene/hkScene.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"); removeLights(m_env); // assume we have some in the file env->m_sceneConverter->convert( scene ); } // Get the rig { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkRig.hkx"); hkRootLevelContainer* container = m_loader->load( assetFile.cString() ); HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numSkeletons > 0), "No skeleton loaded"); m_skeleton = ac->m_skeletons[0]; } // Get the animation and the binding { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkIdle.hkx"); hkRootLevelContainer* container = m_loader->load( assetFile.cString() ); HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numAnimations > 0), "No animation loaded"); m_animation = ac->m_animations[0]; HK_ASSERT2(0x27343435, ac && (ac->m_numBindings > 0), "No binding loaded"); m_binding = ac->m_bindings[0]; } // Convert the skin { const char* skinFile = "Resources/Animation/HavokGirl/hkLowResSkin18Bones.hkx"; hkString assetFile = hkAssetManagementUtil::getFilePath( skinFile ); 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(0x27343435, scene , "No scene loaded"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numSkins > 0), "No skins loaded"); m_numSkinBindings = ac->m_numSkins; m_skinBindings = ac->m_skins; // Make graphics output buffers for the skins env->m_sceneConverter->convert( scene ); // If we are hardware skinning, we need to inform the graphics of the // mappings between the skeleton bones and the primitive subsets with // possibly limited palettes. Looks worse than it is as our scene converter // has no dependancy on the animation system, so we need to cast a bit. if (m_canSkin) { hkgShaderCollection* platformShader; if (m_env->m_window->supportsShaderCompilation()) { platformShader = compileShader(); } else { platformShader = loadPrecompiledShader(); } for (int ms=0; ms < m_numSkinBindings; ++ms) { hkaMeshBinding* skinBinding = m_skinBindings[ms]; if ( m_env->m_sceneConverter->setupHardwareSkin( m_env->m_window->getContext(), skinBinding->m_mesh, reinterpret_cast<hkgAssetConverter::IndexMapping*>( skinBinding->m_mappings ), skinBinding->m_numMappings, (hkInt16)skinBinding->m_skeleton->m_numBones ) ) { // based on the hkxMesh will find the hkg object and set the shader in the material(s) setShader( skinBinding->m_mesh, platformShader ); } } platformShader->release(); } } // Create the skeleton m_skeletonInstance = new hkaAnimatedSkeleton( m_skeleton ); { hkaDefaultAnimationControl* ac = new hkaDefaultAnimationControl( m_binding ); ac->setPlaybackSpeed(1.0f); m_skeletonInstance->addAnimationControl( ac ); ac->removeReference(); } // set up the vdb setupGraphics(); }
NormalBlendingDemo::NormalBlendingDemo( hkDemoEnvironment* env ) : hkDefaultAnimationDemo(env) { // Disable warnings: if no renderer if( hkString::strCmp( m_env->m_options->m_renderer, "n" ) == 0 ) { hkError::getInstance().setEnabled(0xf0d1e423, false); //'Could not realize an inplace texture of type PNG.' } // // Setup the camera // { hkVector4 from( -2,-2,2 ); hkVector4 to ( 0,0,0 ); hkVector4 up ( 0.0f, 0.0f, 1.0f ); setupDefaultCameras( env, from, to, up, 0.1f, 100 ); } m_loader = new hkLoader(); // Convert the scene { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/Scene/hkScene.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"); removeLights(m_env); env->m_sceneConverter->convert( scene ); } // Get the rig { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkRig.hkx"); hkRootLevelContainer* container = m_loader->load( assetFile.cString() ); HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numSkeletons > 0), "No skeleton loaded"); m_skeleton = ac->m_skeletons[0]; } // Get the animation and the binding { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkRunLoop.hkx"); hkRootLevelContainer* container = m_loader->load( assetFile.cString() ); HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numAnimations > 0 ), "No animation loaded"); m_animation[HK_RUN_ANIM] = ac->m_animations[0]; HK_ASSERT2(0x27343435, ac && (ac->m_numBindings > 0), "No binding loaded"); m_binding[HK_RUN_ANIM] = ac->m_bindings[0]; assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkWalkLoop.hkx"); container = m_loader->load( assetFile.cString() ); ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numAnimations > 0 ), "No animation loaded"); m_animation[HK_WALK_ANIM] = ac->m_animations[0]; HK_ASSERT2(0x27343435, ac && (ac->m_numBindings > 0), "No binding loaded"); m_binding[HK_WALK_ANIM] = ac->m_bindings[0]; } // Convert the skin { const char* skinFile = "Resources/Animation/HavokGirl/hkLowResSkin.hkx"; hkString assetFile = hkAssetManagementUtil::getFilePath( skinFile ); 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(0x27343435, scene , "No scene loaded"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numSkins > 0), "No skins loaded"); m_numSkinBindings = ac->m_numSkins; m_skinBindings = ac->m_skins; // Make graphics output buffers for the skins env->m_sceneConverter->convert( scene ); } // Create the skeleton m_skeletonInstance = new hkaAnimatedSkeleton( m_skeleton ); // Set the fill threshold m_skeletonInstance->setReferencePoseWeightThreshold( 0.05f ); // Grab the animations for (int i=0; i < NUM_ANIMS; i++) { m_control[i] = new hkaDefaultAnimationControl( m_binding[i] ); m_control[i]->setMasterWeight( 0.0f ); m_control[i]->setPlaybackSpeed( 1.0f ); m_skeletonInstance->addAnimationControl( m_control[i] ); m_control[i]->removeReference(); } setupGraphics( ); }
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(); } }
EaseCurvesDemo::EaseCurvesDemo( hkDemoEnvironment* env ) : hkDefaultAnimationDemo(env) { // Disable warnings: if no renderer if( hkString::strCmp( m_env->m_options->m_renderer, "n" ) == 0 ) { hkError::getInstance().setEnabled(0xf0d1e423, false); //'Could not realize an inplace texture of type PNG.' } // // Setup the camera // { hkVector4 from( 2,-2,1 ); hkVector4 to ( 0,0,0 ); hkVector4 up ( 0.0f, 0.0f, 1.0f ); setupDefaultCameras( env, from, to, up, 0.1f, 100 ); } m_loader = new hkLoader(); // Convert the scene { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/Scene/hkScene.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"); removeLights(m_env); env->m_sceneConverter->convert( scene ); } // Get the rig { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkRig.hkx"); hkRootLevelContainer* container = m_loader->load( assetFile.cString() ); HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numSkeletons > 0), "No skeleton loaded"); m_skeleton = ac->m_skeletons[0]; } // Get the animation and the binding { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkRunLoop.hkx"); hkRootLevelContainer* container = m_loader->load( assetFile.cString() ); HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numAnimations > 0 ), "No animation loaded"); m_animation[0] = ac->m_animations[0]; HK_ASSERT2(0x27343435, ac && (ac->m_numBindings > 0), "No binding loaded"); m_binding[0] = ac->m_bindings[0]; assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkWaveLoop.hkx"); container = m_loader->load( assetFile.cString() ); ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numAnimations > 0 ), "No animation loaded"); m_animation[1] = ac->m_animations[0]; HK_ASSERT2(0x27343435, ac && (ac->m_numBindings > 0), "No binding loaded"); m_binding[1] = ac->m_bindings[0]; assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkIdle.hkx"); container = m_loader->load( assetFile.cString() ); ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numAnimations > 0 ), "No animation loaded"); m_animation[2] = ac->m_animations[0]; HK_ASSERT2(0x27343435, ac && (ac->m_numBindings > 0), "No binding loaded"); m_binding[2] = ac->m_bindings[0]; } // Convert the skin { const char* skinFile = "Resources/Animation/HavokGirl/hkLowResSkin.hkx"; hkString assetFile = hkAssetManagementUtil::getFilePath( skinFile ); 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(0x27343435, scene , "No scene loaded"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numSkins > 0), "No skins loaded"); m_numSkinBindings = ac->m_numSkins; m_skinBindings = ac->m_skins; // Make graphics output buffers for the skins env->m_sceneConverter->convert( scene ); } // Create the skeleton m_skeletonInstance = new hkaAnimatedSkeleton( m_skeleton ); m_skeletonInstance->setReferencePoseWeightThreshold( 0.1f ); // Grab the animations for (int i=0; i < NUM_ANIMS; i++) { const hkBool startEasedIn = ( i == 2 ); // Start with hands on hips only m_control[i] = new hkaDefaultAnimationControl( m_binding[i], startEasedIn ); m_control[i]->setMasterWeight( 1.0f ); m_control[i]->setPlaybackSpeed( 1.0f ); m_skeletonInstance->addAnimationControl( m_control[i] ); m_control[i]->removeReference(); } // Set ease curves explicitly m_control[0]->setEaseInCurve(0, 0, 1, 1); // Smooth m_control[0]->setEaseOutCurve(1, 1, 0, 0); // Smooth m_control[1]->setEaseInCurve(0, 0.33f, 0.66f, 1); // Linear m_control[1]->setEaseOutCurve(1, 0.66f, 0.33f, 0); // Linear m_control[2]->setEaseInCurve(0, 0, 0, 1); // Fast m_control[2]->setEaseOutCurve(1, 0, 0, 0); // Fast // make a world so that we can auto create a display world to hold the skin setupGraphics( ); // // Create the texture // { m_graphCanvasData = hkAllocate<unsigned char> (GRAPH_CANVAS_HEIGHT*GRAPH_CANVAS_WIDTH*4, HK_MEMORY_CLASS_DEMO); m_context = env->m_window->getContext(); m_texture = hkgTexture::create( m_context ); m_texture->allocateSurface( GRAPH_CANVAS_WIDTH, GRAPH_CANVAS_HEIGHT, true, false, m_graphCanvasData ); m_textureRealized = false; } }
AdditiveBlendingDemo::AdditiveBlendingDemo( hkDemoEnvironment* env ) : hkDefaultAnimationDemo(env) { // Disable warnings: if no renderer if( hkString::strCmp( m_env->m_options->m_renderer, "n" ) == 0 ) { hkError::getInstance().setEnabled(0xf0d1e423, false); //'Could not realize an inplace texture of type PNG.' } // // Setup the camera // { hkVector4 from( 0.3f, -1, 1 ); hkVector4 to ( 0, 0, 0.5f ); hkVector4 up ( 0.0f, 0.0f, 1.0f ); setupDefaultCameras( env, from, to, up, 0.1f, 100 ); } m_loader = new hkLoader(); // Convert the scene { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/Scene/hkScene.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"); removeLights(m_env); env->m_sceneConverter->convert( scene ); } // Get the rig { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkRig.hkx"); hkRootLevelContainer* container = m_loader->load( assetFile.cString() ); HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numSkeletons > 0), "No skeleton loaded"); m_skeleton = ac->m_skeletons[0]; } // Get the animations and the binding { hkString assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkWalkLoop.hkx"); hkRootLevelContainer* container = m_loader->load( assetFile.cString() ); HK_ASSERT2(0x27343437, container != HK_NULL , "Could not load asset"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numAnimations > 0 ), "No animation loaded"); m_animation[HK_WALK_ANIM] = ac->m_animations[0]; HK_ASSERT2(0x27343435, ac && (ac->m_numBindings > 0), "No binding loaded"); m_binding[HK_WALK_ANIM] = ac->m_bindings[0]; assetFile = hkAssetManagementUtil::getFilePath("Resources/Animation/HavokGirl/hkHeadMovement.hkx"); container = m_loader->load( assetFile.cString() ); ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numAnimations > 0 ), "No animation loaded"); m_animation[HK_ADDITIVE_ANIM] = ac->m_animations[0]; HK_ASSERT2(0x27343435, ac && (ac->m_numBindings > 0), "No binding loaded"); m_binding[HK_ADDITIVE_ANIM] = ac->m_bindings[0]; } // Create an additive animation // This can also be done offline in the toolchain using the CreateAdditiveAnimation filter // See the Additive configuration of hkHeadMovement.max { hkaInterleavedUncompressedAnimation* interleavedAnim = static_cast< hkaInterleavedUncompressedAnimation* >(m_animation[ HK_ADDITIVE_ANIM ]); hkaAdditiveAnimationUtility::Input input; input.m_originalData = interleavedAnim->m_transforms; input.m_numberOfPoses = interleavedAnim->m_numTransforms / interleavedAnim->m_numberOfTransformTracks; input.m_numberOfTransformTracks = interleavedAnim->m_numberOfTransformTracks; input.m_baseData = interleavedAnim->m_transforms; // We create an additive animation by subtracting off the iniital pose for the first frame of the animation // This is done by passing the same animation for both the originalData and the baseData // Note that only the first frame of the basedata is used so this initial frame is subtracted // from each of the frames in the animation hkaAdditiveAnimationUtility::createAdditiveFromPose( input, interleavedAnim->m_transforms ); // Switch the binding to additive so this animation will be blended differently in sample and combine. m_binding[HK_ADDITIVE_ANIM]->m_blendHint = hkaAnimationBinding::ADDITIVE; } // Convert the skin { const char* skinFile = "Resources/Animation/HavokGirl/hkLowResSkinWithEyes.hkx"; hkString assetFile = hkAssetManagementUtil::getFilePath( skinFile ); 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(0x27343435, scene , "No scene loaded"); hkaAnimationContainer* ac = reinterpret_cast<hkaAnimationContainer*>( container->findObjectByType( hkaAnimationContainerClass.getName() )); HK_ASSERT2(0x27343435, ac && (ac->m_numSkins > 0), "No animation loaded"); m_numSkinBindings = ac->m_numSkins; m_skinBindings = ac->m_skins; m_numAttachments = ac->m_numAttachments; m_attachments = ac->m_attachments; // Make graphics output buffers for the skins env->m_sceneConverter->convert( scene ); for (int a=0; a < m_numAttachments; ++a) { hkaBoneAttachment* ba = m_attachments[a]; hkgDisplayObject* hkgObject = HK_NULL; //Check the attachment is a mesh if ( hkString::strCmp(ba->m_attachment.m_class->getName(), hkxMeshClass.getName()) == 0) { hkgObject = env->m_sceneConverter->findFirstDisplayObjectUsingMesh((hkxMesh*)ba->m_attachment.m_object); if (hkgObject) { hkgObject->setStatusFlags( hkgObject->getStatusFlags() | HKG_DISPLAY_OBJECT_DYNAMIC); } } m_attachmentObjects.pushBack(hkgObject); } } // Create the animated skeleton m_skeletonInstance = new hkaAnimatedSkeleton( m_skeleton ); // Set the fill threshold m_skeletonInstance->setReferencePoseWeightThreshold( 0.05f ); // Grab the animations and build controls for (int i=0; i < NUM_ANIMS; i++) { m_control[i] = new hkaDefaultAnimationControl( m_binding[i] ); m_control[i]->setMasterWeight( 1.0f ); m_control[i]->setPlaybackSpeed( 1.0f ); m_skeletonInstance->addAnimationControl( m_control[i] ); m_control[i]->removeReference(); } // We initially turn the additive animation off and allow the user to ramp it in m_control[HK_ADDITIVE_ANIM]->setMasterWeight( 0.0f ); m_control[HK_ADDITIVE_ANIM]->setPlaybackSpeed( 1.0f ); setupGraphics( ); }