/* ================= idEntityFx::ClientPredictionThink ================= */ void idEntityFx::ClientPredictionThink( void ) { if ( gameLocal.isNewFrame ) { Run( gameLocal.time ); } RunPhysics(); Present(); }
void hhProjectileSoulCannon::Think( void ) { // run physics RunPhysics(); // Thrust toward enemy if ( thinkFlags & TH_THINK && thrustDir != vec3_origin ) { idVec3 vel = GetPhysics()->GetLinearVelocity(); vel += thrustDir * spawnArgs.GetFloat( "soulThrust", "5.0" ); if ( vel.Length() > maxVelocity ) { // Cap the velocity vel.Normalize(); vel *= maxVelocity; } GetPhysics()->SetLinearVelocity( vel ); GetPhysics()->SetAxis( vel.ToMat3() ); } //HUMANHEAD: aob if (thinkFlags & TH_TICKER) { Ticker(); } //HUMANHEAD Present(); }
/* ================= rvEffect::ClientPredictionThink ================= */ void rvEffect::ClientPredictionThink( void ) { if ( gameLocal.isNewFrame ) { Think ( ); } RunPhysics(); Present(); }
/* ================ idLight::Think ================ */ void idLight::Think( void ) { idVec4 color; if ( thinkFlags & TH_THINK ) { if ( fadeEnd > 0 ) { if ( gameLocal.time < fadeEnd ) { color.Lerp( fadeFrom, fadeTo, ( float )( gameLocal.time - fadeStart ) / ( float )( fadeEnd - fadeStart ) ); } else { color = fadeTo; fadeEnd = 0; BecomeInactive( TH_THINK ); } SetColor( color ); } } RunPhysics(); Present(); }
/* ================ idSound::Think ================ */ void idSound::Think( void ) { idAngles ang; // run physics RunPhysics(); // clear out our update visuals think flag since we never call Present BecomeInactive( TH_UPDATEVISUALS ); }
/* ================ idEntityFx::Think Clears any visual fx started when {item,mob,player} was spawned ================ */ void idEntityFx::Think(void) { if (g_skipFX.GetBool()) { return; } if (thinkFlags & TH_THINK) { Run(gameLocal.time); } RunPhysics(); Present(); }
void rvVehicleSpline::Event_SetSpline ( idEntity * spline ) { if ( spline && spline->IsType( idSplinePath::GetClassType() ) ) { physicsObj.SetSplineEntity( static_cast< idSplinePath * >( spline ) ); //HACK: force an intitial physics update so that the object orients itself with the spline //TEMP: this should be fixed after the build on friday (Jan 28, 2005) physicsObj.SetSpeed( 0.1f ); RunPhysics(); //END HACK } }
/* ================ idBrittleFracture::Think ================ */ void idBrittleFracture::Think( void ) { int i, startTime, endTime, droppedTime; shard_t *shard; bool atRest = true, fading = false; // remove overdue shards for( i = 0; i < shards.Num(); i++ ) { droppedTime = shards[i]->droppedTime; if( droppedTime != -1 ) { if( gameLocal.time - droppedTime > SHARD_ALIVE_TIME ) { RemoveShard( i ); i--; } fading = true; } } // remove the entity when nothing is visible if( !shards.Num() ) { PostEventMS( &EV_Remove, 0 ); return; } if( thinkFlags & TH_PHYSICS ) { startTime = gameLocal.previousTime; endTime = gameLocal.time; // run physics on shards for( i = 0; i < shards.Num(); i++ ) { shard = shards[i]; if( shard->droppedTime == -1 ) { continue; } shard->physicsObj.Evaluate( endTime - startTime, endTime ); if( !shard->physicsObj.IsAtRest() ) { atRest = false; } } if( atRest ) { BecomeInactive( TH_PHYSICS ); } else { BecomeActive( TH_PHYSICS ); } } if( !atRest || bounds.IsCleared() ) { bounds.Clear(); for( i = 0; i < shards.Num(); i++ ) { bounds.AddBounds( shards[i]->clipModel->GetAbsBounds() ); } } if( fading ) { BecomeActive( TH_UPDATEVISUALS | TH_THINK ); } else { BecomeInactive( TH_THINK ); } RunPhysics(); Present(); }
/* ================ idBarrel::BarrelThink ================ */ void idBarrel::BarrelThink(void) { bool wasAtRest, onGround; float movedDistance, rotatedDistance, angle; idVec3 curOrigin, gravityNormal, dir; idMat3 curAxis, axis; wasAtRest = IsAtRest(); // run physics RunPhysics(); // only need to give the visual model an additional rotation if the physics were run if (!wasAtRest) { // current physics state onGround = GetPhysics()->HasGroundContacts(); curOrigin = GetPhysics()->GetOrigin(); curAxis = GetPhysics()->GetAxis(); // if the barrel is on the ground if (onGround) { gravityNormal = GetPhysics()->GetGravityNormal(); dir = curOrigin - lastOrigin; dir -= gravityNormal * dir * gravityNormal; movedDistance = dir.LengthSqr(); // if the barrel moved and the barrel is not aligned with the gravity direction if (movedDistance > 0.0f && idMath::Fabs(gravityNormal * curAxis[barrelAxis]) < 0.7f) { // barrel movement since last think frame orthogonal to the barrel axis movedDistance = idMath::Sqrt(movedDistance); dir *= 1.0f / movedDistance; movedDistance = (1.0f - idMath::Fabs(dir * curAxis[barrelAxis])) * movedDistance; // get rotation about barrel axis since last think frame angle = lastAxis[(barrelAxis + 1) % 3] * curAxis[(barrelAxis + 1) % 3]; angle = idMath::ACos(angle); // distance along cylinder hull rotatedDistance = angle * radius; // if the barrel moved further than it rotated about it's axis if (movedDistance > rotatedDistance) { // additional rotation of the visual model to make it look // like the barrel rolls instead of slides angle = 180.0f * (movedDistance - rotatedDistance) / (radius * idMath::PI); if (gravityNormal.Cross(curAxis[barrelAxis]) * dir < 0.0f) { additionalRotation += angle; } else { additionalRotation -= angle; } dir = vec3_origin; dir[barrelAxis] = 1.0f; additionalAxis = idRotation(vec3_origin, dir, additionalRotation).ToMat3(); } } } // save state for next think lastOrigin = curOrigin; lastAxis = curAxis; } Present(); }
/* ================ idSecurityCamera::Think ================ */ void idSecurityCamera::Think( void ) { float pct; float travel; if( thinkFlags & TH_THINK ) { if( g_showEntityInfo.GetBool() ) { DrawFov(); } if( health <= 0 ) { BecomeInactive( TH_THINK ); return; } } // run physics RunPhysics(); if( thinkFlags & TH_THINK ) { if( CanSeePlayer() ) { if( alertMode == SCANNING ) { float sightTime; SetAlertMode( ALERT ); stopSweeping = gameLocal.time; if( sweeping ) { CancelEvents( &EV_SecurityCam_Pause ); } else { CancelEvents( &EV_SecurityCam_ReverseSweep ); } sweeping = false; StopSound( SND_CHANNEL_ANY, false ); StartSound( "snd_sight", SND_CHANNEL_BODY, 0, false, NULL ); sightTime = spawnArgs.GetFloat( "sightTime", "5" ); PostEventSec( &EV_SecurityCam_Alert, sightTime ); } } else { if( alertMode == ALERT ) { float sightResume; SetAlertMode( LOSINGINTEREST ); CancelEvents( &EV_SecurityCam_Alert ); sightResume = spawnArgs.GetFloat( "sightResume", "1.5" ); PostEventSec( &EV_SecurityCam_ContinueSweep, sightResume ); } if( sweeping ) { idAngles a = GetPhysics()->GetAxis().ToAngles(); pct = ( gameLocal.time - sweepStart ) / ( sweepEnd - sweepStart ); travel = pct * sweepAngle; if( negativeSweep ) { a.yaw = angle + travel; } else { a.yaw = angle - travel; } SetAngles( a ); } } } Present(); }
void hhControlHand::ClientPredictionThink( void ) { RunPhysics(); // HUMANHEAD pdm if (thinkFlags & TH_TICKER) { Ticker(); } UpdateAnimation(); UpdateVisuals(); Present(); }
/* ================ idMoveableItem::Think ================ */ void idMoveableItem::Think( void ) { RunPhysics(); if ( thinkFlags & TH_PHYSICS ) { // update trigger position trigger->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), mat3_identity ); } // ---> sikk - Moveable Item Spinning if ( thinkFlags & TH_THINK ) { if ( spawnArgs.GetBool( "spin" ) || spawnArgs.GetBool( "fixedAxis" ) ) { idMat3 axis; axis.Identity(); GetPhysics()->SetAngularVelocity( vec3_zero ); GetPhysics()->SetAxis( axis ); if ( spawnArgs.GetBool( "spin" ) ) { idAngles ang; idVec3 org; // item rotation ang.pitch = ang.roll = 0.0f; ang.yaw = ( gameLocal.time & 4095 ) * 360.0f / -4096.0f; renderEntity.axis = ang.ToMat3(); // item bobbing float scale = 0.005f; org = GetPhysics()->GetOrigin(); org.z += 4.0f + cos( ( gameLocal.time * scale + entityNumber ) ) * 4.0f; renderEntity.origin = org; } } } // <--- sikk - Moveable Item Spinning if ( thinkFlags & TH_UPDATEPARTICLES ) { if ( !gameLocal.smokeParticles->EmitSmoke( smoke, smokeTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ) ) { // ---> sikk - continuous smoke particles (for gibs) if ( repeatSmoke && GetPhysics()->GetLinearVelocity().Length() > 100.0f ) { smokeTime = gameLocal.time; } else { smokeTime = 0; BecomeInactive( TH_UPDATEPARTICLES ); } // <--- sikk - continuous smoke particles (for gibs) } } Present(); }
void idActor::Think( void ) { if ( thinkFlags & TH_THINK ) { // clear the ik before we do anything else so the skeleton doesn't get updated twice walkIK.ClearJointMods(); RunPhysics(); } UpdateAnimation(); Present(); }
/* ================ idEntityFx::Think Clears any visual fx started when {item,mob,player} was spawned ================ */ void idEntityFx::Think( void ) { if ( g_skipFX.GetBool() ) { return; } //gameLocal.Printf( "idEntityFx::Think of '%s'\n", GetName() ); if ( thinkFlags & TH_THINK ) { Run( gameLocal.time ); } RunPhysics(); Present(); }
void World::Simulate(bool simRunning) { float frame_dt = CalculateNewDT(); //system updates #if !ANGEL_MOBILE theControllerManager.UpdateState(); _console->Update( (float)frame_dt ); #endif // Must be called once per frame. theSound.Update(); //make sure the game manager gets updates first, if we have one if (_gameManager) { _gameManager->Update(frame_dt); } if (simRunning) { // Deliver any messages that have been queued from the last frame. theSwitchboard.SendAllMessages(); RunPhysics(frame_dt); //Flag that the _elements array is locked so we don't try to add any // new actors during the update. _elementsLocked = true; UpdateRenderables(frame_dt); CleanupRenderables(); _elementsLocked = false; // Now that we're done updating the list, allow any deferred Adds to be processed. ProcessDeferredAdds(); ProcessDeferredLayerChanges(); ProcessDeferredRemoves(); theSwitchboard.Update(frame_dt); UpdateDebugItems(frame_dt); //if there are any system updates that still need to be run, put them here } //making this the last update so we can accurately lock on position for rendering theCamera.Update(frame_dt); }
/* ================ idMoveableItem::Think ================ */ void idMoveableItem::Think( void ) { RunPhysics(); if ( thinkFlags & TH_PHYSICS ) { // update trigger position trigger->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), mat3_identity ); } if ( thinkFlags & TH_UPDATEPARTICLES ) { if ( !gameLocal.smokeParticles->EmitSmoke( smoke, smokeTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ) ) { smokeTime = 0; BecomeInactive( TH_UPDATEPARTICLES ); } } Present(); }
/* ================ rvClientMoveable::Think ================ */ void rvClientMoveable::Think ( void ) { bool runPhysics = true; if ( gameLocal.SetupClientAoR() ) { int aorFlags = gameLocal.aorManager.GetFlagsForPoint( aorLayout, worldOrigin ); if ( ( aorFlags & AOR_INHIBIT_PHYSICS ) != 0 ) { runPhysics = false; } } if ( runPhysics ) { RunPhysics(); } // Special case the sound update to use the center mass since the origin may be in an odd place if ( refSound.referenceSound ) { refSound.origin = worldOrigin; refSound.referenceSound->UpdateEmitter( refSound.origin, refSound.listenerId, &refSound.parms ); } renderEntity.origin = worldOrigin; renderEntity.axis = worldAxis; // Keep the trail effect following if ( trailEffect ) { float speed; speed = idMath::ClampFloat ( 0, trailAttenuateSpeed, physicsObj.GetLinearVelocity ( ).LengthFast ( ) ); if ( physicsObj.IsAtRest ( ) ) { trailEffect->Stop ( ); trailEffect = NULL; } else { idVec3 center = physicsObj.GetBounds().GetCenter() * worldAxis + worldOrigin; trailEffect->SetOrigin ( center ); trailEffect->SetAxis ( worldAxis ); trailEffect->Attenuate ( speed / trailAttenuateSpeed ); } } // add to refresh list if ( entityDefHandle == -1 ) { entityDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); } else { gameRenderWorld->UpdateEntityDef( entityDefHandle, &renderEntity ); } }
/* ================ rvClientMoveable::Think ================ */ void rvClientMoveable::Think ( void ) { if( bindMaster && (bindMaster->GetRenderEntity()->hModel && bindMaster->GetModelDefHandle() == -1) ) { return; } RunPhysics ( ); // Special case the sound update to use the center mass since the origin may be in an odd place idSoundEmitter *emitter = soundSystem->EmitterForIndex( SOUNDWORLD_GAME, refSound.referenceSoundHandle ); if ( emitter ) { refSound.origin = worldOrigin; refSound.velocity = worldVelocity; emitter->UpdateEmitter( refSound.origin, refSound.velocity, refSound.listenerId, &refSound.parms ); } // Keep the trail effect following if ( trailEffect ) { float speed; speed = idMath::ClampFloat ( 0, trailAttenuateSpeed, worldVelocity.LengthFast ( ) ); if ( physicsObj.IsAtRest ( ) ) { trailEffect->Stop ( ); trailEffect = NULL; } else { trailEffect->SetOrigin ( worldOrigin ); trailEffect->SetAxis ( worldAxis ); trailEffect->Attenuate ( speed / trailAttenuateSpeed ); } } renderEntity.origin = worldOrigin; renderEntity.axis = worldAxis * scale.GetCurrentValue( gameLocal.GetTime() ); // add to refresh list if ( entityDefHandle == -1 ) { entityDefHandle = gameRenderWorld->AddEntityDef( &renderEntity ); } else { gameRenderWorld->UpdateEntityDef( entityDefHandle, &renderEntity ); } }
void hhHarvesterSimple::AnimMove( void ) { idVec3 goalPos; idVec3 delta; idVec3 goalDelta; float goalDist; monsterMoveResult_t moveResult; idVec3 newDest; // Turn on physics to prevent flying harvesters BecomeActive(TH_PHYSICS); idVec3 oldorigin = physicsObj.GetOrigin(); #ifdef HUMANHEAD //jsh wallwalk idMat3 oldaxis = GetGravViewAxis(); #else idMat3 oldaxis = viewAxis; #endif AI_BLOCKED = false; if ( move.moveCommand < NUM_NONMOVING_COMMANDS ){ move.lastMoveOrigin.Zero(); move.lastMoveTime = gameLocal.time; } move.obstacle = NULL; if ( ( move.moveCommand == MOVE_FACE_ENEMY ) && enemy.GetEntity() ) { TurnToward( lastVisibleEnemyPos ); goalPos = oldorigin; } else if ( ( move.moveCommand == MOVE_FACE_ENTITY ) && move.goalEntity.GetEntity() ) { TurnToward( move.goalEntity.GetEntity()->GetPhysics()->GetOrigin() ); goalPos = oldorigin; } else if ( GetMovePos( goalPos ) ) { if ( move.moveCommand != MOVE_WANDER ) { CheckObstacleAvoidance( goalPos, newDest ); TurnToward( newDest ); } else { TurnToward( goalPos ); } } Turn(); if ( move.moveCommand == MOVE_SLIDE_TO_POSITION ) { if ( gameLocal.time < move.startTime + move.duration ) { goalPos = move.moveDest - move.moveDir * MS2SEC( move.startTime + move.duration - gameLocal.time ); delta = goalPos - oldorigin; delta.z = 0.0f; } else { delta = move.moveDest - oldorigin; delta.z = 0.0f; StopMove( MOVE_STATUS_DONE ); } } else if ( allowMove ) { #ifdef HUMANHEAD //jsh wallwalk GetMoveDelta( oldaxis, GetGravViewAxis(), delta ); #else GetMoveDelta( oldaxis, viewAxis, delta ); #endif } else { delta.Zero(); } if ( move.moveCommand == MOVE_TO_POSITION ) { goalDelta = move.moveDest - oldorigin; goalDist = goalDelta.LengthFast(); if ( goalDist < delta.LengthFast() ) { delta = goalDelta; } } #ifdef HUMANHEAD //shrink functionality float scale = renderEntity.shaderParms[SHADERPARM_ANY_DEFORM_PARM1]; if ( scale > 0.0f && scale < 2.0f ) { delta *= scale; } #endif physicsObj.SetDelta( delta ); physicsObj.ForceDeltaMove( disableGravity ); RunPhysics(); if ( ai_debugMove.GetBool() ) { // HUMANHEAD JRM - so we can see if grav is on or off if(disableGravity) { gameRenderWorld->DebugLine( colorRed, oldorigin, physicsObj.GetOrigin(), 5000 ); } else { gameRenderWorld->DebugLine( colorCyan, oldorigin, physicsObj.GetOrigin(), 5000 ); } } moveResult = physicsObj.GetMoveResult(); if ( !af_push_moveables && attack.Length() && TestMelee() ) { DirectDamage( attack, enemy.GetEntity() ); } else { idEntity *blockEnt = physicsObj.GetSlideMoveEntity(); if ( blockEnt && blockEnt->IsType( hhHarvesterSimple::Type ) ) { StopMove( MOVE_STATUS_BLOCKED_BY_MONSTER ); return; } if ( blockEnt && blockEnt->IsType( idMoveable::Type ) && blockEnt->GetPhysics()->IsPushable() ) { KickObstacles( viewAxis[ 0 ], kickForce, blockEnt ); } } BlockedFailSafe(); AI_ONGROUND = physicsObj.OnGround(); idVec3 org = physicsObj.GetOrigin(); if ( oldorigin != org ) { TouchTriggers(); } if ( ai_debugMove.GetBool() ) { gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), org, gameLocal.msec ); gameRenderWorld->DebugBounds( colorMagenta, physicsObj.GetBounds(), move.moveDest, gameLocal.msec ); gameRenderWorld->DebugLine( colorYellow, org + EyeOffset(), org + EyeOffset() + viewAxis[ 0 ] * physicsObj.GetGravityAxis() * 16.0f, gameLocal.msec, true ); DrawRoute(); } }
// Game loop that updates the scene void VisionApp_cl::OnUpdateScene() { VISION_PROFILE_FUNCTION(VIS_PROFILE_GAMELOOP); IVisSceneManager_cl *pSceneManager = Vision::GetSceneManager(); VASSERT(pSceneManager); // Check whether we should use async physics IVisPhysicsModule_cl *pPhysicsModule = Vision::GetApplication()->GetPhysicsModule(); bool bAsyncPhysics; if (pPhysicsModule != NULL && pPhysicsModule->GetUseAsynchronousPhysics()) bAsyncPhysics = true; else bAsyncPhysics = false; //Timer is not longer updated here, because it needs to be updated right after the frame flip float fElapsedTime = Vision::GetTimer()->GetTimeDifference(); // Advance the scene update counter Vision::Game.SetUpdateSceneCount( Vision::Game.GetUpdateSceneCount() + 1 ); Vision::Callbacks.OnUpdateSceneBegin.TriggerCallbacks(); //Send any queued messages before we remove entities Vision::Game.ProcessMessageQueue(); // Delete "dead" entities from previous frame { VISION_PROFILE_FUNCTION( VIS_PROFILE_GAMELOOP_UPDATELOOP ); Vision::Game.FreeRemovedEntities(); } // Run the pre-physics loop: statistics, prethink, events & animations if ( Vision::Editor.IsPlaying() ) RunPreThink(fElapsedTime); //Process animation messages after processing animations Vision::Game.ProcessMessageQueue(); // Run the physics simulation (if physics simulation is set to synchronous) if ( Vision::Editor.IsPlaying() && !bAsyncPhysics) { RunPhysics(fElapsedTime); FetchPhysicsResults(); } // Run the post-physics loop: posthink if ( Vision::Editor.IsPlaying() ) RunThink(fElapsedTime); // for the editor, we call the EditorThinkFunction function in every mode for every entity: if (Vision::Editor.IsInEditor()) { const int iCount = VisBaseEntity_cl::ElementManagerGetSize(); for (int i=0;i<iCount;i++) { VisBaseEntity_cl *pEntity = VisBaseEntity_cl::ElementManagerGet(i); if (pEntity) pEntity->EditorThinkFunction(); } } // handle the lightsources (e.g. color animation) if (Vision::Editor.IsAnimatingOrPlaying()) VisLightSource_cl::HandleAllLightSources(fElapsedTime); // update the core engine and module system RunUpdateLoop(); Vision::Game.ResetUpdatedEntitiesList(); // Kick off asynchronous physics simulation if ( Vision::Editor.IsPlaying() && bAsyncPhysics ) { RunPhysics(fElapsedTime); } // Handle portal/visibility zone transitions VisObject3DVisData_cl::HandleAllNodeTransitions(); //Handle render contexts VisRenderContext_cl::HandleAllRenderContexts(fElapsedTime); //Animate textures (in animate mode) VisTextureAnimInstance_cl::HandleAllAnims(Vision::Editor.IsAnimatingOrPlaying() ? fElapsedTime : 0.f); // scroll sky only when animating scene IVSky *pSky = Vision::World.GetActiveSky(); if (pSky != NULL && Vision::Editor.IsAnimatingOrPlaying()) pSky->Tick(fElapsedTime); Vision::Callbacks.OnUpdateSceneFinished.TriggerCallbacks(); }
/* ================ idTestModel::Think ================ */ void idTestModel::Think() { idVec3 pos; idMat3 axis; idAngles ang; int i; if( thinkFlags & TH_THINK ) { if( anim && ( gameLocal.testmodel == this ) && ( mode != g_testModelAnimate.GetInteger() ) ) { StopSound( SND_CHANNEL_ANY, false ); if( head.GetEntity() ) { head.GetEntity()->StopSound( SND_CHANNEL_ANY, false ); } switch( g_testModelAnimate.GetInteger() ) { default: case 0: // cycle anim with origin reset if( animator.NumFrames( anim ) <= 1 ) { // single frame animations end immediately, so just cycle it since it's the same result animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); if( headAnim ) { headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); } } else { animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); if( headAnim ) { headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); if( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) ) { // loop the body anim when the head anim is longer animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 ); } } } animator.RemoveOriginOffset( false ); break; case 1: // cycle anim with fixed origin animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); animator.RemoveOriginOffset( true ); if( headAnim ) { headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); } break; case 2: // cycle anim with continuous origin animator.CycleAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); animator.RemoveOriginOffset( false ); if( headAnim ) { headAnimator->CycleAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); } break; case 3: // frame by frame with continuous origin animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); animator.RemoveOriginOffset( false ); if( headAnim ) { headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); } break; case 4: // play anim once animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); animator.RemoveOriginOffset( false ); if( headAnim ) { headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); } break; case 5: // frame by frame with fixed origin animator.SetFrame( ANIMCHANNEL_ALL, anim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); animator.RemoveOriginOffset( true ); if( headAnim ) { headAnimator->SetFrame( ANIMCHANNEL_ALL, headAnim, frame, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); } break; } mode = g_testModelAnimate.GetInteger(); } if( ( mode == 0 ) && ( gameLocal.time >= starttime + animtime ) ) { starttime = gameLocal.time; StopSound( SND_CHANNEL_ANY, false ); animator.PlayAnim( ANIMCHANNEL_ALL, anim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); if( headAnim ) { headAnimator->PlayAnim( ANIMCHANNEL_ALL, headAnim, gameLocal.time, FRAME2MS( g_testModelBlend.GetInteger() ) ); if( headAnimator->AnimLength( headAnim ) > animator.AnimLength( anim ) ) { // loop the body anim when the head anim is longer animator.CurrentAnim( ANIMCHANNEL_ALL )->SetCycleCount( -1 ); } } } if( headAnimator ) { // copy the animation from the body to the head for( i = 0; i < copyJoints.Num(); i++ ) { if( copyJoints[ i ].mod == JOINTMOD_WORLD_OVERRIDE ) { idMat3 mat = head.GetEntity()->GetPhysics()->GetAxis().Transpose(); GetJointWorldTransform( copyJoints[ i ].from, gameLocal.time, pos, axis ); pos -= head.GetEntity()->GetPhysics()->GetOrigin(); headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos * mat ); headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis * mat ); } else { animator.GetJointLocalTransform( copyJoints[ i ].from, gameLocal.time, pos, axis ); headAnimator->SetJointPos( copyJoints[ i ].to, copyJoints[ i ].mod, pos ); headAnimator->SetJointAxis( copyJoints[ i ].to, copyJoints[ i ].mod, axis ); } } } // update rotation RunPhysics(); physicsObj.GetAngles( ang ); physicsObj.SetAngularExtrapolation( extrapolation_t( EXTRAPOLATION_LINEAR | EXTRAPOLATION_NOSTOP ), gameLocal.time, 0, ang, idAngles( 0, g_testModelRotate.GetFloat() * 360.0f / 60.0f, 0 ), ang_zero ); idClipModel* clip = physicsObj.GetClipModel(); if( clip != NULL && animator.ModelDef() ) { idVec3 neworigin; idMat3 axis; jointHandle_t joint; joint = animator.GetJointHandle( "origin" ); animator.GetJointTransform( joint, gameLocal.time, neworigin, axis ); neworigin = ( ( neworigin - animator.ModelDef()->GetVisualOffset() ) * physicsObj.GetAxis() ) + GetPhysics()->GetOrigin(); clip->Link( gameLocal.clip, this, 0, neworigin, clip->GetAxis() ); } } UpdateAnimation(); Present(); if( ( gameLocal.testmodel == this ) && g_showTestModelFrame.GetInteger() && anim ) { gameLocal.Printf( "^5 Anim: ^7%s ^5Frame: ^7%d/%d Time: %.3f\n", animator.AnimFullName( anim ), animator.CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ), animator.CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - animator.CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) ); if( headAnim ) { gameLocal.Printf( "^5 Head: ^7%s ^5Frame: ^7%d/%d Time: %.3f\n\n", headAnimator->AnimFullName( headAnim ), headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetFrameNumber( gameLocal.time ), headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->NumFrames(), MS2SEC( gameLocal.time - headAnimator->CurrentAnim( ANIMCHANNEL_ALL )->GetStartTime() ) ); } else { gameLocal.Printf( "\n\n" ); } } }
/* ===================== rvMonsterStroggHover::DeadMove ===================== */ void rvMonsterStroggHover::DeadMove( void ) { DeathPush ( ); physicsObj.UseVelocityMove( true ); RunPhysics(); }
/* ================ bmVehicle_Jeep::Think ================ */ void bmVehicle_Jeep::Think( void ) { int i; float force = 0.0f, velocity = 0.0f, steerAngle = 0.0f; idVec3 origin; idMat3 axis; idRotation wheelRotation, steerRotation; bmVehicle_Base::Think(); if ( thinkFlags & TH_THINK ) { if ( player ) { if (player->usercmd.forwardmove != 0 && isEmergencyLightsActive) { if(!siren->IsPlaying()) { siren->DoSound( true ); } } // capture the input from a player velocity = g_vehicleVelocity.GetFloat(); if ( player->usercmd.forwardmove < 0 ) { velocity = -velocity; } force = idMath::Fabs( player->usercmd.forwardmove * g_vehicleForce.GetFloat() ) * (1.0f / 128.0f); steerAngle = GetSteerAngle(); } renderEntity.gui[0]->SetStateFloat( "speed", force ); // update the wheel motor force and steering for ( i = 0; i < 2; i++ ) { // front wheel drive if ( velocity != 0.0f ) { suspension[i]->EnableMotor( true ); } else { suspension[i]->EnableMotor( false ); } suspension[i]->SetMotorVelocity( velocity ); suspension[i]->SetMotorForce( force ); // update the wheel steering suspension[i]->SetSteerAngle( steerAngle ); } // adjust wheel velocity for better steering because there are no differentials between the wheels if ( steerAngle < 0.0f ) { suspension[0]->SetMotorVelocity( velocity * 0.5f ); } else if ( steerAngle > 0.0f ) { suspension[1]->SetMotorVelocity( velocity * 0.5f ); } // update suspension with latest cvar settings for ( i = 0; i < 4; i++ ) { suspension[i]->SetSuspension( g_vehicleSuspensionUp.GetFloat(), g_vehicleSuspensionDown.GetFloat(), g_vehicleSuspensionKCompress.GetFloat(), g_vehicleSuspensionDamping.GetFloat(), g_vehicleTireFriction.GetFloat() ); } // run the physics RunPhysics(); // move and rotate the wheels visually for ( i = 0; i < 4; i++ ) { idAFBody *body = af.GetPhysics()->GetBody( 0 ); origin = suspension[i]->GetWheelOrigin(); velocity = body->GetPointVelocity( origin ) * body->GetWorldAxis()[0]; wheelAngles[i] += velocity * MS2SEC( gameLocal.msec ) / wheelRadius; // additional rotation about the wheel axis wheelRotation.SetAngle( RAD2DEG( wheelAngles[i] ) ); wheelRotation.SetVec( 0, -1, 0 ); if ( i < 2 ) { // rotate the wheel for steering steerRotation.SetAngle( steerAngle ); steerRotation.SetVec( 0, 0, 1 ); // set wheel rotation animator.SetJointAxis( wheelJoints[i], JOINTMOD_WORLD, wheelRotation.ToMat3() * steerRotation.ToMat3() ); } else { // set wheel rotation animator.SetJointAxis( wheelJoints[i], JOINTMOD_WORLD, wheelRotation.ToMat3() ); } // set wheel position for suspension origin = ( origin - renderEntity.origin ) * renderEntity.axis.Transpose(); GetAnimator()->SetJointPos( wheelJoints[i], JOINTMOD_WORLD_OVERRIDE, origin ); } // Set the steering wheel rotation. steerRotation.SetVec( -1, 0, 0 ); GetAnimator()->SetJointAxis( steeringWheelJoint, JOINTMOD_WORLD, steerRotation.ToMat3() ); /* // spawn dust particle effects if ( force != 0.0f && !( gameLocal.framenum & 7 ) ) { int numContacts; idAFConstraint_Contact *contacts[2]; for ( i = 0; i < 4; i++ ) { numContacts = af.GetPhysics()->GetBodyContactConstraints( wheels[i]->GetClipModel()->GetId(), contacts, 2 ); for ( int j = 0; j < numContacts; j++ ) { gameLocal.smokeParticles->EmitSmoke( dustSmoke, gameLocal.time, gameLocal.random.RandomFloat(), contacts[j]->GetContact().point, contacts[j]->GetContact().normal.ToMat3() ); } } } */ } UpdateAnimation(); if ( thinkFlags & TH_UPDATEVISUALS ) { Present(); LinkCombat(); } }
/* ================= sdClientProjectile_Parabolic::Think ================= */ void sdClientProjectile_Parabolic::Think( void ) { RunPhysics(); sdClientProjectile::Think(); }