cpConstraint *cpSpaceSerializer::createPivotJoint(TiXmlElement *elm) { cpConstraint *constraint; cpBody *a; cpBody *b; createBodies(elm, &a, &b); if (elm->FirstChildElement("worldAnchor")) { cpVect worldPt = createPoint("worldAnchor", elm); constraint = cpPivotJointNew(a, b, worldPt); } else { cpVect anchr1 = createPoint("anchr1", elm); cpVect anchr2 = createPoint("anchr2", elm); constraint = cpPivotJointNew2(a, b, anchr1, anchr2); } //((cpPivotJoint*)constraint)->jAcc = createPoint("jAcc", elm); return constraint; }
// Method reads all bodies in the Iges input file. // Returns the number of the bodies read. bool InputIges::readCadGeometry() { bool result; //--Read directory section and find the start position of the // of parameters-section in the file. // Paramter-section line-counter is set to 0. // NOTE: This counter is updated by: readDataLine and // locateParamEntry functions. paramSecStart = readDirectory(); //--If model type is unknown if (modelDimension == ECIF_ND) { modelDimension = findCadModelDimension(); } //--Update entry references ans states checkEntryReferences(); //--Create bodies in each entry which defines a body createBodies(); //--Read body elements readBodyElements(); // After reading all body-information, data can be checked! //result = this->model->checkBodies(); // if (!modelIsOk) // exit(1); return true; }
/** \brief Starts the kinect-dedicated reading thread. Does the following: 1. Notify the start of the initialization and initialize 2. Notify the initialization outcomes (error, or running if initialization was successful) 3. If successful, does a continous: 3.1. Wait/update kinect data 3.2. Protected by a mutex, generate the images and data structures, made available to the user 3.3. Check if a stop has been requested 4. Stop the kinect reading and release resources, notify. The variable accessed outside of this thread are protected by mutexes. This includes: - The status - The QImages for depth, camera - The bodies - etc. **/ void QKinectWrapper::run() { mutex.lock(); status=QKinect::Initializing; emit statusNotification(status); mutex.unlock(); bool ok = initialize(); if(!ok) { mutex.lock(); status = QKinect::ErrorStop; emit statusNotification(status); mutex.unlock(); return; } mutex.lock(); status = QKinect::OkRun; emit statusNotification(status); mutex.unlock(); frameid=0; while(!t_requeststop) { //double t1,t2; //t1 = PreciseTimer::QueryTimer(); XnStatus status = g_Context.WaitAndUpdateAll(); //msleep(100+(rand()%100)); // simulate some shit delay //if( (frameid%100) > 50) // msleep(((frameid%100)-50)*10); // simulate some slowing down delay delay //t2 = PreciseTimer::QueryTimer(); //printf("Waitandupdate: %lf. %s\n",(t2-t1)*1000.0,xnGetStatusString(status)); // Prepare the data to export outside of the thread mutex.lock(); xn::DepthMetaData depthMD; g_DepthGenerator.GetMetaData(depthMD); //frameid = depthMD.FrameID(); frameid++; //printf("frame id: %d %d\n",frameid,depthMD.FrameID()); timestamp = (double)depthMD.Timestamp()/1000000.0; // Must create the bodies first bodies = createBodies(); // Then can create the images, which may overlay the bodies imageCamera = createCameraImage(); imageDepth = createDepthImage(); emit dataNotification(); mutex.unlock(); } g_Context.Shutdown(); mutex.lock(); status = QKinect::Idle; emit statusNotification(status); mutex.unlock(); }
WorldRaycastDemo::WorldRaycastDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env) { // // 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); } // // Create the world. // { hkpWorldCinfo info; info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM); // Set gravity to zero so body floats. info.m_gravity.set(0.0f, 0.0f, 0.0f); info.setBroadPhaseWorldSize( 100.0f ); m_world = new hkpWorld(info); m_world->lock(); // Disable backface culling, since we have mopp's etc. setGraphicsState(HKG_ENABLED_CULLFACE, false); 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 some bodies (reuse the ShapeRaycastApi demo) // createBodies(); m_world->unlock(); }
AddRemoveBodiesDemo::AddRemoveBodiesDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env), m_frameCount(0), m_currentBody(0) { for( int i = 0; i < NUM_BODIES; i++ ) { m_bodies[i] = HK_NULL; } // // Setup the camera // { hkVector4 from(0.0f, 30.0f, 50.0f); hkVector4 to (0.0f, 0.0f, 0.0f); hkVector4 up (0.0f, 1.0f, 0.0f); setupDefaultCameras(env, from, to, up); float lightDir[] = { -1, -0.5f , -0.25f}; float lightAabbMin[] = { -15, -15, -15}; float lightAabbMax[] = { 15, 15, 15}; setLightAndFixedShadow(lightDir, lightAabbMin, lightAabbMax ); } // // Setup and create the hkpWorld // { hkpWorldCinfo info; info.m_gravity = hkVector4(0.0f, -9.8f, 0.0f); info.setBroadPhaseWorldSize(1000.0f); info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_8ITERS_MEDIUM); info.m_collisionTolerance = 0.01f; m_world = new hkpWorld( info ); m_world->lock(); setupGraphics(); } // Register the single agent required (a hkpBoxBoxAgent) { hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher()); } // Create the rigid bodies createBodies(); // Create the ground createGround(); m_world->unlock(); }
cpConstraint *cpSpaceSerializer::createRotarySpringJoint(TiXmlElement *elm) { cpConstraint *constraint; cpBody *a; cpBody *b; createBodies(elm, &a, &b); cpFloat restAngle = createValue<cpFloat>("restAngle", elm); cpFloat stiffness = createValue<cpFloat>("stiffness", elm); cpFloat damping = createValue<cpFloat>("damping", elm); constraint = cpDampedRotarySpringNew(a, b, restAngle, stiffness, damping); return constraint; }
cpConstraint *cpSpaceSerializer::createMotorJoint(TiXmlElement *elm) { cpConstraint *constraint; cpBody *a; cpBody *b; createBodies(elm, &a, &b); cpFloat rate = createValue<cpFloat>("rate", elm); constraint = cpSimpleMotorNew(a, b, rate); //((cpSimpleMotor*)constraint)->jMax = createValue<cpFloat>("jMax", elm); return constraint; }
cpConstraint *cpSpaceSerializer::createGearJoint(TiXmlElement *elm) { cpConstraint *constraint; cpBody *a; cpBody *b; createBodies(elm, &a, &b); cpFloat phase = createValue<cpFloat>("phase", elm); cpFloat ratio = createValue<cpFloat>("ratio", elm); constraint = cpGearJointNew(a, b, phase, ratio); //((cpGearJoint*)constraint)->jAcc = createValue<cpFloat>("jAcc", elm); return constraint; }
cpConstraint *cpSpaceSerializer::createRotaryLimitJoint(TiXmlElement *elm) { cpConstraint *constraint; cpBody *a; cpBody *b; createBodies(elm, &a, &b); cpFloat min = createValue<cpFloat>("min", elm); cpFloat max = createValue<cpFloat>("max", elm); constraint = cpRotaryLimitJointNew(a, b, min, max); //((cpRotaryLimitJoint*)constraint)->jAcc = createValue<cpFloat>("jAcc", elm); return constraint; }
cpConstraint *cpSpaceSerializer::createPinJoint(TiXmlElement *elm) { cpConstraint *constraint; cpVect anchr1 = createPoint("anchr1", elm); cpVect anchr2 = createPoint("anchr2", elm); cpBody *a; cpBody *b; createBodies(elm, &a, &b); constraint = cpPinJointNew(a, b, anchr1, anchr2); ((cpPinJoint*)constraint)->dist = createValue<cpFloat>("dist", elm); //((cpPinJoint*)constraint)->jnAcc = createValue<cpFloat>("jnAcc", elm); return constraint; }
cpConstraint *cpSpaceSerializer::createSpringJoint(TiXmlElement *elm) { cpConstraint *constraint; cpVect anchr1 = createPoint("anchr1", elm); cpVect anchr2 = createPoint("anchr2", elm); cpBody *a; cpBody *b; createBodies(elm, &a, &b); cpFloat restLen = createValue<cpFloat>("restLength", elm); cpFloat stiffness = createValue<cpFloat>("stiffness", elm); cpFloat damping = createValue<cpFloat>("damping", elm); constraint = cpDampedSpringNew(a, b, anchr1, anchr2, restLen, stiffness, damping); return constraint; }
cpConstraint *cpSpaceSerializer::createGrooveJoint(TiXmlElement *elm) { cpConstraint *constraint; cpVect grv_a = createPoint("grv_a", elm); cpVect grv_b = createPoint("grv_b", elm); cpVect anchr2 = createPoint("anchr2", elm); cpBody *a; cpBody *b; createBodies(elm, &a, &b); constraint = cpGrooveJointNew(a, b, grv_a, grv_b, anchr2); //((cpGrooveJoint*)constraint)->jAcc = createPoint("jAcc", elm); //((cpGrooveJoint*)constraint)->jMaxLen = createValue<cpFloat>("jMaxLen", elm); return constraint; }
cpConstraint *cpSpaceSerializer::createSlideJoint(TiXmlElement *elm) { cpConstraint *constraint; cpVect anchr1 = createPoint("anchr1", elm); cpVect anchr2 = createPoint("anchr2", elm); cpBody *a; cpBody *b; createBodies(elm, &a, &b); cpFloat min = createValue<cpFloat>("min", elm); cpFloat max = createValue<cpFloat>("max", elm); constraint = cpSlideJointNew(a, b, anchr1, anchr2, min, max); //((cpSlideJoint*)constraint)->jnAcc = createValue<cpFloat>("jnAcc", elm); return constraint; }
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(); }
Eigen::Matrix< StateScalarType, 6, 1 > propagateForwardBackwards( const int integratorCase ) { //Load spice kernels. spice_interface::loadStandardSpiceKernels( ); // Define bodies in simulation. std::vector< std::string > bodyNames; bodyNames.push_back( "Earth" ); bodyNames.push_back( "Moon" ); bodyNames.push_back( "Sun" ); bodyNames.push_back( "Mars" ); bodyNames.push_back( "Venus" ); // Specify initial time double initialEphemerisTime = 1.0E7; double finalEphemerisTime = initialEphemerisTime + 86400.0; double buffer = 3600.0; // Create bodies needed in simulation std::map< std::string, boost::shared_ptr< BodySettings > > bodySettings = getDefaultBodySettings( bodyNames, initialEphemerisTime - 2.0 * buffer, finalEphemerisTime + 2.0 * buffer ); boost::dynamic_pointer_cast< InterpolatedSpiceEphemerisSettings >( bodySettings[ "Moon" ]->ephemerisSettings )-> resetFrameOrigin( "Earth" ); NamedBodyMap bodyMap = createBodies( bodySettings ); setGlobalFrameBodyEphemerides( bodyMap, "Earth", "ECLIPJ2000" ); // Set accelerations between bodies that are to be taken into account. SelectedAccelerationMap accelerationMap; std::map< std::string, std::vector< boost::shared_ptr< AccelerationSettings > > > accelerationsOfMoon; accelerationsOfMoon[ "Earth" ].push_back( boost::make_shared< AccelerationSettings >( central_gravity ) ); accelerationsOfMoon[ "Sun" ].push_back( boost::make_shared< AccelerationSettings >( central_gravity ) ); accelerationMap[ "Moon" ] = accelerationsOfMoon; // Propagate the moon only std::vector< std::string > bodiesToIntegrate; bodiesToIntegrate.push_back( "Moon" ); std::vector< std::string > centralBodies; centralBodies.push_back( "Earth" ); // Define settings for numerical integrator. boost::shared_ptr< IntegratorSettings< TimeType > > integratorSettings = getIntegrationSettings< TimeType >( integratorCase, initialEphemerisTime, true ); // Propagate forwards { // Create acceleration models and propagation settings. Eigen::Matrix< StateScalarType, 6, 1 > systemInitialState = spice_interface::getBodyCartesianStateAtEpoch( bodiesToIntegrate[ 0 ], centralBodies[ 0 ], "ECLIPJ2000", "NONE", initialEphemerisTime ). template cast< StateScalarType >( ); AccelerationMap accelerationModelMap = createAccelerationModelsMap( bodyMap, accelerationMap, bodiesToIntegrate, centralBodies ); boost::shared_ptr< TranslationalStatePropagatorSettings< StateScalarType > > propagatorSettings = boost::make_shared< TranslationalStatePropagatorSettings< StateScalarType > > ( centralBodies, accelerationModelMap, bodiesToIntegrate, systemInitialState, finalEphemerisTime + buffer ); // Create dynamics simulation object. SingleArcDynamicsSimulator< StateScalarType, TimeType > dynamicsSimulator( bodyMap, integratorSettings, propagatorSettings, true, true, true ); } double testTime = initialEphemerisTime + ( finalEphemerisTime - initialEphemerisTime ) / 2.0; Eigen::Vector6d forwardState = bodyMap.at( "Moon" )->getEphemeris( )->getCartesianState( testTime ); // Re-define settings for numerical integrator. integratorSettings = getIntegrationSettings< TimeType >( integratorCase, finalEphemerisTime, false ); // Propagate backwards { // Create acceleration models and propagation settings. Eigen::Matrix< StateScalarType, 6, 1 > systemInitialState = spice_interface::getBodyCartesianStateAtEpoch( bodiesToIntegrate[ 0 ], centralBodies[ 0 ], "ECLIPJ2000", "NONE", finalEphemerisTime ). template cast< StateScalarType >( ); AccelerationMap accelerationModelMap = createAccelerationModelsMap( bodyMap, accelerationMap, bodiesToIntegrate, centralBodies ); boost::shared_ptr< TranslationalStatePropagatorSettings< StateScalarType > > propagatorSettings = boost::make_shared< TranslationalStatePropagatorSettings< StateScalarType > > ( centralBodies, accelerationModelMap, bodiesToIntegrate, systemInitialState, initialEphemerisTime - buffer ); // Create dynamics simulation object. SingleArcDynamicsSimulator< StateScalarType, TimeType > dynamicsSimulator( bodyMap, integratorSettings, propagatorSettings, true, true, true ); } Eigen::Vector6d backwardState = bodyMap.at( "Moon" )->getEphemeris( )->getCartesianState( testTime ); return forwardState - backwardState; }
KeyframingDemo::KeyframingDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env) { // // Set parameters for keyframes, and number of bodies // m_speed = 0.2f; m_radius = 5.0f; m_numBodies = 15; m_time = 0.0f; // // Setup the camera // { hkVector4 from(0, 40, 40); hkVector4 to(0, 0, 0); hkVector4 up(0, 1, 0); setupDefaultCameras(env, from, to, up); } // // Setup and create the hkpWorld. // { hkpWorldCinfo info; info.m_gravity = hkVector4(0.0f, -9.8f, 0.0f); info.setBroadPhaseWorldSize(150.0f); info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM); m_world = new hkpWorld( info ); m_world->lock(); setupGraphics(); } // // Register the single agent required (a hkpBoxBoxAgent). // { hkpAgentRegisterUtil::registerAllAgents(m_world->getCollisionDispatcher()); } // // Create the rigid bodies. // createBodies(); // // Create the ground. // createGround(); // // Create the keyframed body. // { const hkVector4 halfExtents(3.0f, 1.75f, 0.3f); hkpBoxShape* shape = new hkpBoxShape(halfExtents, 0 ); // Assign the rigid body properties hkpRigidBodyCinfo bodyInfo; bodyInfo.m_shape = shape; // By setting the motion type to hkpMotion::MOTION_KEYFRAMED we are essentially telling Havok that this // body has infinite mass. Thus neither applying forces nor impulses can change the velocity of the body and // as a result, the body is considered totally immovable during interactions (collisions) with other bodies. // This means that the user can force the body to follow a set of keyframes by directly setting the // velocity required to move to the next keyframe before each world step. // The body is guaranteed to reach the next keyframe, even if other bodies collide with it. // To help convert keyframes to velocities we have provided some useful methods in hkpKeyFrameUtility. // To create a keyframed object simply set the motion type as follows: bodyInfo.m_motionType = hkpMotion::MOTION_KEYFRAMED; { // Get inital keyframe. getKeyframePositionAndRotation(0.0f, bodyInfo.m_position, bodyInfo.m_rotation); } // Add our keyframed body. m_keyframedBody = new hkpRigidBody(bodyInfo); m_world->addEntity(m_keyframedBody); m_keyframedBody->removeReference(); shape->removeReference(); } m_world->unlock(); }
WorldRayCastMultithreadedDemo::WorldRayCastMultithreadedDemo(hkDemoEnvironment* env) : hkDefaultPhysicsDemo(env), m_semaphore(0,1000) { const WorldRayCastMultithreadedDemoVariant& variant = g_WorldRayCastMultithreadedDemoVariants[m_variantId]; // // 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); } // // Create the world. // { hkpWorldCinfo info; info.setupSolverInfo(hkpWorldCinfo::SOLVER_TYPE_4ITERS_MEDIUM); // Set gravity to zero so body floats. info.m_gravity.set(0.0f, 0.0f, 0.0f); info.setBroadPhaseWorldSize( 100.0f ); m_world = new hkpWorld(info); m_world->lock(); // Disable backface culling, since we have mopp's etc. setGraphicsState(HKG_ENABLED_CULLFACE, false); 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 some bodies (reuse the ShapeRayCastApi demo) // createBodies(); m_world->unlock(); hkpCollisionQueryJobQueueUtils::registerWithJobQueue(m_jobQueue); // Special case for this demo variant: we do not allow the # of active SPUs to drop to zero as this can cause a deadlock. if ( variant.m_demoType == WorldRayCastMultithreadedDemoVariant::MULTITHREADED_ON_SPU ) { m_allowZeroActiveSpus = false; } }
void DemoKeeper::KeyframingDemo( void ) { mWorld->markForWrite(); // // Set parameters for keyframes, and number of bodies // m_speed = 0.2f; m_radius = 5.0f; m_numBodies = 15; m_time = 0.0f; // // Create the rigid bodies. // createBodies(); // // Create the ground. // createGround(); // // Create the keyframed body. // { const hkVector4 halfExtents(3.0f, 1.75f, 0.3f); hkpBoxShape* shape = new hkpBoxShape(halfExtents, 0 ); // Assign the rigid body properties hkpRigidBodyCinfo bodyInfo; bodyInfo.m_shape = shape; // By setting the motion type to hkpMotion::MOTION_KEYFRAMED we are essentially telling Havok that this // body has infinite mass. Thus neither applying forces nor impulses can change the velocity of the body and // as a result, the body is considered totally immovable during interactions (collisions) with other bodies. // This means that the user can force the body to follow a set of keyframes by directly setting the // velocity required to move to the next keyframe before each world step. // The body is guaranteed to reach the next keyframe, even if other bodies collide with it. // To help convert keyframes to velocities we have provided some useful methods in hkpKeyFrameUtility. // To create a keyframed object simply set the motion type as follows: bodyInfo.m_motionType = hkpMotion::MOTION_KEYFRAMED; { // Get inital keyframe. getKeyframePositionAndRotation(0.0f, bodyInfo.m_position, bodyInfo.m_rotation); } // Add our keyframed body. m_keyframedBody = new hkpRigidBody(bodyInfo); mWorld->addEntity(m_keyframedBody); m_keyframedBody->removeReference(); shape->removeReference(); //render it with Ogre Ogre::SceneNode* boxNode = mSceneMgr->getRootSceneNode()->createChildSceneNode(); //scale boxNode->scale(6, 3.5, 0.6); //display and sync Ogre::Entity *ent = mSceneMgr->createEntity(Ogre::StringConverter::toString(mLabMgr->getEntityCount()),"defCube.mesh"); mLabMgr->setColor(ent, Ogre::Vector3(rand()/(double)RAND_MAX,rand()/(double)RAND_MAX,rand()/(double)RAND_MAX)); HkOgre::Renderable* rend = new HkOgre::Renderable(boxNode, m_keyframedBody,mWorld); boxNode->attachObject(ent); //register to lab manager mLabMgr->registerEnity( boxNode, m_keyframedBody); } mWorld->unmarkForWrite(); Keyframe_demoRunning = true; }