void Jumper::StandingJump::update(float dt) { updateAnimation( dt ); _clump->getFrame()->getLTM(); if( _actionTime < _blendTime ) return; if( _actionTime > _blendTime + ( FRAMETIME(245) - FRAMETIME(225) ) ) { if( _phActor->isSleeping() ) { Matrix4f sampleLTM = Jumper::getCollisionFF( _clump )->getFrame()->getLTM(); _phActor->setGlobalPose( wrap( sampleLTM ) ); _phActor->wakeUp(); NxVec3 velH = wrap( _clump->getFrame()->getAt() ); velH.normalize(); velH *= 3.0f; NxVec3 velV = wrap( _clump->getFrame()->getUp() ); velV.normalize(); velV *= 1.5f; _phActor->setLinearVelocity( velH + velV ); _jumper->initOverburdenCalculator( velH + velV ); } else { _clump->getFrame()->setMatrix( _matrixConversion->convert( wrap( _phActor->getGlobalPose() ) ) ); } if( _jumper->getSpinalCord()->modifier) _endOfAction = true; } if( _clump->getAnimationController()->isEndOfAnimation( 0 ) ) { _endOfAction = true; } }
void Jumper::Pull::update(float dt) { updateAnimation( dt ); updateProceduralAnimation( dt ); // synchronize physics & render _clump->getFrame()->setMatrix( _matrixConversion->convert( wrap( _phActor->getGlobalPose() ) ) ); _clump->getFrame()->getLTM(); // update controls if( _pcInHand && _actionTime > _blendTime ) { updateBlending( dt ); } // pull pilot chute if( ( _actionTime - _blendTime >= FRAMETIME(1012) - FRAMETIME(1002) ) && !_pilotchute->isPulled() ) { _pilotchute->pull( Jumper::getLineHandJoint( _clump ) ); return; } if (_jumper->getSpinalCord()->phase || !_pilotchute->isPulled()) return; // drop pilot chute if( /*( _actionTime - _blendTime >= FRAMETIME(1022) - FRAMETIME(1002) ) &&*/ !_pilotchute->isDropped() ) { NxMat34 pose = _phActor->getGlobalPose(); NxVec3 x = pose.M.getColumn(0); NxVec3 y = pose.M.getColumn(1); NxVec3 z = pose.M.getColumn(2); _pilotchute->drop( z * 10.0f - x * 5.0f ); } // look for opening if( _pilotchute->isOpened() ) { _endOfAction = true; } engine::IAnimationController* animCtrl = _clump->getAnimationController(); if( animCtrl->isEndOfAnimation( 0 ) || _pilotchute->isDropped() ) { // blend to second animation track (put hands over head) float weight = animCtrl->getTrackWeight( 0 ); weight -= dt / trackBlendTime; if( weight < 0 ) weight = 0.0f; animCtrl->setTrackWeight( 0, weight ); animCtrl->setTrackWeight( 1, 1.0f - weight ); } }
Jumper::StandingJump::StandingJump(Jumper* jumper, NxActor* actor, MatrixConversion* mc) : JumperAction( jumper ) { // set action properties _actionTime = 0.0f; _blendTime = 0.1f; _endOfAction = false; _phActor = actor; _matrixConversion = mc; engine::IAnimationController* animCtrl = _clump->getAnimationController(); // capture blend source animCtrl->captureBlendSrc(); // reset animation mixer for( unsigned int i=0; i<engine::maxAnimationTracks; i++ ) { if( animCtrl->getTrackAnimation( i ) ) animCtrl->setTrackActivity( i, false ); } bool useWingsuit = database::Suit::getRecord( _jumper->getVirtues()->equipment.suit.id )->wingsuit; // setup animation cycle if( useWingsuit ) { animCtrl->setTrackAnimation( 0, &standingJumpSequenceWings ); } else { animCtrl->setTrackAnimation( 0, &standingJumpSequence ); getCore()->logMessage("animation time: %2.5f", FRAMETIME(251) - FRAMETIME(225)); } animCtrl->setTrackActivity( 0, true ); animCtrl->setTrackSpeed( 0, 0.75f ); animCtrl->setTrackWeight( 0, 1.0f ); animCtrl->resetTrackTime( 0 ); animCtrl->advance( 0.0f ); // capture blend destination animCtrl->captureBlendDst(); animCtrl->blend( 0.0f ); }
void Spectator::Turn::update(float dt) { updateAnimation( dt ); // leave if turn is starting if( _actionTime - _blendTime < FRAMETIME(143) - FRAMETIME(135) ) return; // evaluate end of action float angle = calcAngle( _dir, _clump->getFrame()->getAt(), Vector3f( 0,1,0 ) ); if( fabs( angle ) < 1.0f ) { _endOfAction = true; return; } // evaluate angle to turn float angleToTurn = sgn( angle ) * turnVelocity * dt; if( fabs( angle ) < fabs( angleToTurn ) ) angleToTurn = angle; // rotate frame _clump->getFrame()->rotateRelative( Vector3f(0,1,0), angleToTurn ); }
bool Jumper::CanopyOpening::isCriticalAnimationRange(void) { return ( _actionTime - _blendTime ) < ( FRAMETIME(1062) - FRAMETIME(1038) ); }
#include "headers.h" #include "jumper.h" #include "imath.h" #include "hud.h" /** * related animations */ static engine::AnimSequence openingSequence = { FRAMETIME(1038), //FRAMETIME(1038), FRAMETIME(1112), engine::ltNone, 0.0f }; /** * action */ Jumper::CanopyOpening::CanopyOpening(Jumper* jumper, NxActor* phFreeFall, NxActor* phFlight, MatrixConversion* mcFlight, PilotchuteSimulator* pc, CanopySimulator* c, NxVec3 fla, NxVec3 fra, NxVec3 rla, NxVec3 rra) : JumperAction( jumper ) { // set action properties _actionTime = 0.0f; _blendTime = 0.2f; _endOfAction = false; _phActor = phFlight; _matrixConversion = mcFlight; _pilotchute = pc;
/** * process constants */ const float trackBlendTime = 0.4f; const float trackingBlendTime = 0.5f; const float steeringBackBoneBendLimit = 20.0f; const float legPitchTime = 0.85f; const float legPitchBendLimit = 26.0f; /** * related animations */ static engine::AnimSequence pullAndDropPilotchuteSequence = { FRAMETIME(1002), //FRAMETIME(1033), // put your arms back with the PC in hand? WTF??? FRAMETIME(1030), engine::ltNone, 0.0f }; static engine::AnimSequence putHandsOverHeadSequence = { FRAMETIME(1219), FRAMETIME(1229), engine::ltPeriodic, FRAMETIME(1219) }; static engine::AnimSequence trackForwardSequence = {
void Jumper::WalkForward::update(float dt) { _jumper->_isStuck = false; updateAnimation( dt ); // pass blending phase if( _actionTime < _blendTime ) return; // calculate motion velocity float walkVel; float runVel; if( _actionTime - _blendTime < FRAMETIME(84)-FRAMETIME(60) ) { walkVel = walkVelocity * _actionTime / (FRAMETIME(84)-FRAMETIME(60)); } else { walkVel = walkVelocity; } if( _actionTime - _blendTime < FRAMETIME(281)-FRAMETIME(253) ) { runVel = runVelocity * _actionTime/(FRAMETIME(281)-FRAMETIME(253)); } else { runVel = runVelocity; } engine::IAnimationController* animCtrl = _clump->getAnimationController(); // jumper can run _running = _jumper->getSpinalCord()->modifier && !database::Suit::getRecord( _jumper->getVirtues()->equipment.suit.id )->wingsuit; // speedup & final velocity _velocity = _clump->getFrame()->getAt(); float pitchShiftFactor = 1.0f; if( _running && animCtrl->getTrackWeight( 0 ) == 0 ) { _velocity *= runVel; pitchShiftFactor = 2.0f; } if( _running && animCtrl->getTrackWeight( 0 ) > 0 ) { float weight = animCtrl->getTrackWeight( 0 ) - dt; if( weight < 0 ) weight = 0; animCtrl->setTrackWeight( 0, weight ); animCtrl->setTrackWeight( 1, 1-weight ); pitchShiftFactor += 1-weight; _velocity *= ( walkVel + ( runVel - walkVel ) * ( 1-weight ) ); } if( !_running && animCtrl->getTrackWeight( 1 ) == 0 ) { _velocity *= walkVel; } if( !_running && animCtrl->getTrackWeight( 1 ) > 0 ) { float weight = animCtrl->getTrackWeight( 1 ) - dt; if( weight < 0 ) weight = 0; animCtrl->setTrackWeight( 0, 1-weight ); animCtrl->setTrackWeight( 1, weight ); pitchShiftFactor += weight; _velocity *= ( runVel + ( walkVel - runVel ) * ( 1-weight ) ); } // move along direction Vector3f direction = _velocity * dt; Vector3f pos = _clump->getFrame()->getPos() + Vector3f( 0, jumperRoamingSphereSize, 0 ); Vector3f lastPos = pos; pos = _enclosure->move( pos, direction, jumperRoamingSphereSize ); Vector3f actualDistance = _enclosure->getActualDistance(); // slowly move down until collision direction.set( 0,-1,0 ); unsigned int limit = 200; do { pos = _enclosure->move( pos, direction, jumperRoamingSphereSize ); limit--; } while( limit>0 && _enclosure->getLastNumIntersectedTriangles() == 0 ); if( limit == 0 ) { pos = lastPos; actualDistance.set( 0,0,0 ); } pos += Vector3f( 0, -jumperRoamingSphereSize, 0 ); _clump->getFrame()->setPos( pos ); // check actual velocity of roaming engine if( _velocity.length() > 0 && dt > 0 ) { float braking = actualDistance.length() / ( _velocity * dt ).length(); animCtrl->setTrackSpeed( 0, braking * 0.75f ); animCtrl->setTrackSpeed( 1, braking ); pitchShiftFactor *= braking; if( braking < 0.25f ) { _endOfAction = true; _jumper->_isStuck = true; } } // modify pitch shift factor _jumper->happen( _jumper, EVENT_JUMPER_PITCHSHIFT, &pitchShiftFactor ); // rotate character if( !_endOfAction ) { ActionChannel* left = Gameplay::iGameplay->getActionChannel( iaLeft ); ActionChannel* right = Gameplay::iGameplay->getActionChannel( iaRight ); float turn = -left->getAmplitude() + right->getAmplitude(); float angleToTurn = -walkTurnVelocity * dt * turn; _clump->getFrame()->rotateRelative( Vector3f( 0,1,0 ), angleToTurn ); } }
#include "imath.h" /** * spectatior turn action properties */ const float turnBlendTime = 0.5f; const float turnVelocity = 90.0f; /** * turn animation sequences */ static engine::AnimSequence turnLeftSequence = { FRAMETIME(135), FRAMETIME(168), engine::ltPeriodic, FRAMETIME(144) }; static engine::AnimSequence turnRightSequence = { FRAMETIME(180), FRAMETIME(213), engine::ltPeriodic, FRAMETIME(189) }; /** * turn action for spectator
#include "headers.h" #include "jumper.h" #include "imath.h" /** * related animations */ static engine::AnimSequence linetwistsSequence = { FRAMETIME(2146), FRAMETIME(2169), engine::ltMirror, FRAMETIME(2146) }; /** * class implementation */ Jumper::Linetwists::Linetwists(Jumper* jumper, NxActor* phFlight, MatrixConversion* mcFlight) : JumperAction( jumper ) { // set action properties _actionTime = 0.0f; _blendTime = 0.1f; _endOfAction = false; _phActor = phFlight; _matrixConversion = mcFlight;
#include "headers.h" #include "jumper.h" #include "imath.h" /** * related animations */ static engine::AnimSequence passiveFlightSequence = { FRAMETIME(592), FRAMETIME(652), engine::ltPeriodic, FRAMETIME(592) }; static engine::AnimSequence steerRightSequence = { FRAMETIME(652), FRAMETIME(667), engine::ltNone, 0.0f }; static engine::AnimSequence steerLeftSequence = { FRAMETIME(712), FRAMETIME(721), engine::ltNone, 0.0f
#include "headers.h" #include "jumper.h" #include "imath.h" static engine::AnimSequence flipSequence = { FRAMETIME(491), FRAMETIME(511), engine::ltPeriodic, FRAMETIME(491) }; engine::AnimSequence* Jumper::Flip::getFlipSequence(void) { return &flipSequence; } Jumper::Flip::Flip(Jumper* jumper, NxActor* phActor, MatrixConversion* mc, float blendTime) : Jumper::JumperAction( jumper ) { // set action properties _actionTime = 0.0f; _blendTime = blendTime; _phActor = phActor; _matrixConversion = mc; _endOfAction = false; engine::IAnimationController* animCtrl = _clump->getAnimationController(); // capture blend source
void Spectator::Move::update(float dt) { updateAnimation( dt ); // leave blending phase if( _actionTime < _blendTime ) return; // determine distance to desired position Vector3f distance = _pos - _clump->getFrame()->getPos(); if( distance.length() < movePrecision ) { _endOfAction = true; return; } // calculate motion velocity float vel; if( _fast ) { if( _actionTime - _blendTime < FRAMETIME(281)-FRAMETIME(253) ) { vel = runVelocity * _actionTime/(FRAMETIME(281)-FRAMETIME(253)); } else { vel = runVelocity; } } else { if( _actionTime - _blendTime < FRAMETIME(84)-FRAMETIME(60) ) { vel = walkVelocity * _actionTime / (FRAMETIME(84)-FRAMETIME(60)); } else { vel = walkVelocity; } } // spectator properties float width = 25; float height = 180; // retrieve current clump position, and raise to the height of spectator Vector3f pos = _clump->getFrame()->getPos(); pos += Vector3f( 0,1,0 ) * height; // direction vector Vector3f dir = _clump->getFrame()->getAt() * vel * dt; dir += Vector3f( 0,-900,0 ) * dt; // move it along direction of clump pos = _enclosure->move( pos, dir, width, height ); // lower position to the ground pos -= Vector3f( 0,1,0 ) * height; // determine actual motion distance at this act Vector3f AMD = pos - _clump->getFrame()->getPos(); if( AMD.length() < ( _clump->getFrame()->getAt() * vel * dt * 0.75f ).length() ) { _endOfAction = true; } // setup position for clump _clump->getFrame()->setPos( pos ); // determine direction to destination point dir = _pos - pos; dir[1] = 0.0f; dir.normalize(); // rotate clump if it is needed float angle = calcAngle( dir, _clump->getFrame()->getAt(), Vector3f( 0,1,0 ) ); if( fabs( angle ) > 1.0f ) { _clump->getFrame()->rotateRelative( Vector3f(0,1,0), angle ); } }
#include "headers.h" #include "crowd.h" #include "imath.h" /** * animation sequences */ static engine::AnimSequence walkSequence = { FRAMETIME(60), FRAMETIME(107), engine::ltPeriodic, FRAMETIME(84) }; static engine::AnimSequence runSequence = { FRAMETIME(253), FRAMETIME(300), engine::ltPeriodic, FRAMETIME(281) }; /** * action properties */ const float walkVelocity = 150.0f; const float runVelocity = 500.0f;
#include "headers.h" #include "jumper.h" #include "imath.h" /** * jump animation */ static engine::AnimSequence standingJumpSequence = { FRAMETIME(225), FRAMETIME(251), engine::ltNone, 0.0f }; static engine::AnimSequence standingJumpSequenceWings = { FRAMETIME(1946), FRAMETIME(1985), engine::ltNone, 0.0f }; /** * class implementation */ Jumper::StandingJump::StandingJump(Jumper* jumper, NxActor* actor, MatrixConversion* mc) : JumperAction( jumper )
#include "imath.h" /** * action properties */ const float walkBackVelocity = 55.0f; const float walkTurnVelocity = 60; /** * "walk backward" animation sequences */ static engine::AnimSequence walkBackwardSequence = { FRAMETIME(551), FRAMETIME(589), engine::ltPeriodic, FRAMETIME(566) }; /** * class implementation */ Jumper::WalkBackward::WalkBackward(Jumper* jumper) : JumperAction( jumper ) { // set action properties _enclosure = jumper->getEnclosure(); _actionTime = 0.0f; _blendTime = 0.1f;
void Jumper::WalkBackward::update(float dt) { _jumper->_isStuck = false; updateAnimation( dt ); // pass blending phase if( _actionTime < _blendTime ) return; // calculate motion velocity Vector3f velocity = _clump->getFrame()->getAt(); if( _actionTime - _blendTime < FRAMETIME(566)-FRAMETIME(551) ) { velocity *= walkBackVelocity * _actionTime / (FRAMETIME(566)-FRAMETIME(551)); } else { velocity *= walkBackVelocity; } // move Vector3f direction = velocity * dt * -1; Vector3f pos = _clump->getFrame()->getPos() + Vector3f( 0, jumperRoamingSphereSize, 0 ); Vector3f lastPos = pos; pos = _enclosure->move( pos, direction, jumperRoamingSphereSize ); Vector3f actualDistance = _enclosure->getActualDistance(); // slowly move down until collision direction.set( 0,-1,0 ); unsigned int limit = 200; do { pos = _enclosure->move( pos, direction, jumperRoamingSphereSize ); limit--; } while( limit > 0 && _enclosure->getLastNumIntersectedTriangles() == 0 ); if( limit == 0 ) { pos = lastPos; actualDistance.set( 0,0,0 ); } pos += Vector3f( 0, -jumperRoamingSphereSize, 0 ); _clump->getFrame()->setPos( pos ); engine::IAnimationController* animCtrl = _clump->getAnimationController(); // check actual velocity of roaming engine float pitchShiftFactor = 1.0f; if( velocity.length() > 0 && dt > 0 ) { float braking = actualDistance.length() / (velocity * dt).length(); animCtrl->setTrackSpeed( 0, braking * 0.75f ); if( braking < 0.5f ) { _endOfAction = true; _jumper->_isStuck = true; } pitchShiftFactor *= braking; } // update sound properties _jumper->happen( _jumper, EVENT_JUMPER_PITCHSHIFT, &pitchShiftFactor ); // rotate character if( !_endOfAction ) { float turnSgn = _jumper->getSpinalCord()->right - _jumper->getSpinalCord()->left; float angleToTurn = -walkTurnVelocity * dt * turnSgn; _clump->getFrame()->rotateRelative( Vector3f( 0,1,0 ), angleToTurn ); } }
#include "headers.h" #include "jumper.h" #include "imath.h" /** * related animations */ static engine::AnimSequence landingSequence = { FRAMETIME(911), FRAMETIME(961), engine::ltNone, 0.0f }; static engine::AnimSequence canopySuppressionSequence = { FRAMETIME(1160), FRAMETIME(1207), engine::ltNone, 0.0f }; /** * class implementation */ Jumper::Landing::Landing(Jumper* jumper, PxRigidDynamic* phFlight, MatrixConversion* mcFlight) : JumperAction( jumper )
#include "headers.h" #include "jumper.h" #include "imath.h" /** * jump animation */ static engine::AnimSequence runningJumpSequence = { FRAMETIME(1358), FRAMETIME(1380), engine::ltNone, 0.0f }; static engine::AnimSequence runningJumpSequenceWings = { FRAMETIME(1403), FRAMETIME(1416), engine::ltNone, 0.0f }; /** * class implementation */ Jumper::RunningJump::RunningJump(Jumper* jumper, NxActor* actor, MatrixConversion* mc, float vel) : JumperAction( jumper ) { // set action properties
#include "headers.h" #include "jumper.h" #include "imath.h" static engine::AnimSequence airplaneJumpSequence = { FRAMETIME(1669), // FRAMETIME(1683), FRAMETIME(1678), engine::ltNone, 0.0f }; static engine::AnimSequence airplaneJumpSequenceWings = { FRAMETIME(2104), FRAMETIME(2130), engine::ltNone, 0.0f }; /** * class implementation */ const float trackSpeed = 0.75f; const float trackInvSpeed = 1.0f / trackSpeed; Jumper::AirplaneJump::AirplaneJump(Jumper* jumper, NxActor* actor, MatrixConversion* mc) : JumperAction( jumper )
void Jumper::AirplaneJump::update(float dt) { updateAnimation( dt ); bool useWingsuit = database::Suit::getRecord( _jumper->getVirtues()->equipment.suit.id )->wingsuit; float phaseTime = useWingsuit ? trackInvSpeed * ( FRAMETIME(2113) - FRAMETIME(2104) ) : trackInvSpeed * ( FRAMETIME(1673) - FRAMETIME(1669) ); if( _actionTime > _blendTime + phaseTime ) { if( _phActor->isSleeping() ) { // place jumper to airplane exit Matrix4f clumpLTM = _clump->getFrame()->getLTM(); Vector3f clumpScale = calcScale( clumpLTM ); Matrix4f exitLTM = _jumper->getAirplaneExit()->getLTM(); orthoNormalize( exitLTM ); exitLTM[0][0] *= clumpScale[0], exitLTM[0][1] *= clumpScale[0], exitLTM[0][2] *= clumpScale[0]; exitLTM[1][0] *= clumpScale[1], exitLTM[1][1] *= clumpScale[1], exitLTM[1][2] *= clumpScale[1]; exitLTM[2][0] *= clumpScale[2], exitLTM[2][1] *= clumpScale[2], exitLTM[2][2] *= clumpScale[2]; _clump->getFrame()->setMatrix( exitLTM ); _clump->getFrame()->getLTM(); Matrix4f sampleLTM = Jumper::getCollisionFF( _clump )->getFrame()->getLTM(); _phActor->setGlobalPose( wrap( sampleLTM ) ); _phActor->wakeUp(); NxVec3 velH = wrap( _clump->getFrame()->getAt() ); velH.normalize(); velH *= 3.0f; NxVec3 velV = wrap( _clump->getFrame()->getUp() ); velV.normalize(); velV *= 0.25f; NxVec3 velA = wrap( _jumper->getAirplane()->getVel() ); _phActor->setLinearVelocity( velH + velV + velA ); _jumper->initOverburdenCalculator( velH + velV + velA ); // modified exits (only fixed wing, not heli) bool helicopter = strcmp(_jumper->getAirplane()->getDesc()->templateClump->getName(), "Helicopter01") == 0; if (!helicopter) { if (_jumper->getSpinalCord()->left) { _phActor->addLocalTorque(NxVec3(0,5700.0f,0)); //_phActor->setAngularDamping(2.0f); } else if (_jumper->getSpinalCord()->right) { _phActor->addLocalTorque(NxVec3(0,-5700.0f,0)); //_phActor->setAngularDamping(2.0f); } if (_jumper->getSpinalCord()->up) { // headdown exit _phActor->addLocalTorque(NxVec3(5700.0f,0,0)); } else if (_jumper->getSpinalCord()->down) { // sitfly exit _phActor->addLocalTorque(NxVec3(-8700.0f,0,0)); _phActor->addLocalForce(NxVec3(0,0,10000.0f)); } _phActor->setAngularDamping(2.0f); } } else { if (_jumper->getSpinalCord()->left) { _phActor->addLocalTorque(NxVec3(0,2000.0f*dt,0)); } else if (_jumper->getSpinalCord()->right) { _phActor->addLocalTorque(NxVec3(0,-2000.0f*dt,0)); } _clump->getFrame()->setMatrix( _matrixConversion->convert( wrap( _phActor->getGlobalPose() ) ) ); } } else { // place jumper to airplane exit Matrix4f clumpLTM = _clump->getFrame()->getLTM(); Vector3f clumpScale = calcScale( clumpLTM ); Matrix4f exitLTM = _jumper->getAirplaneExit()->getLTM(); Vector3f pos = _jumper->getAirplaneExit()->getPos(); getCore()->logMessage("exit pos: %2.2f %2.2f %2.2f", pos[0], pos[1], pos[2]); orthoNormalize( exitLTM ); exitLTM[0][0] *= clumpScale[0], exitLTM[0][1] *= clumpScale[0], exitLTM[0][2] *= clumpScale[0]; exitLTM[1][0] *= clumpScale[1], exitLTM[1][1] *= clumpScale[1], exitLTM[1][2] *= clumpScale[1]; exitLTM[2][0] *= clumpScale[2], exitLTM[2][1] *= clumpScale[2], exitLTM[2][2] *= clumpScale[2]; _clump->getFrame()->setMatrix( exitLTM ); } if( _clump->getAnimationController()->isEndOfAnimation( 0 )) // || (_jumper->getSpinalCord()->modifier && _jumper->isPlayer() && _actionTime > _blendTime + phaseTime )) { _endOfAction = true; } }
#include "headers.h" #include "crowd.h" #include "imath.h" #include "../common/istring.h" /** * spectator idle sequence */ static engine::AnimSequence idleSequence = { FRAMETIME(1), FRAMETIME(59), engine::ltPeriodic, FRAMETIME(1) }; /** * spectator idle watching sequence */ static engine::AnimSequence watchSequence = { FRAMETIME(306), FRAMETIME(358), engine::ltMirror, FRAMETIME(329) }; /**