/* ============ idClip::DrawClipModels ============ */ void idClip::DrawClipModels( const idVec3& eye, const float radius, const idEntity* passEntity ) { int i, num; idBounds bounds; idClipModel* clipModelList[MAX_GENTITIES]; idClipModel* clipModel; bounds = idBounds( eye ).Expand( radius ); num = idClip::ClipModelsTouchingBounds( bounds, -1, clipModelList, MAX_GENTITIES ); for( i = 0; i < num; i++ ) { clipModel = clipModelList[i]; if( clipModel->GetEntity() == passEntity ) { continue; } if( clipModel->renderModelHandle != -1 ) { gameRenderWorld->DebugBounds( colorCyan, clipModel->GetAbsBounds() ); } else { collisionModelManager->DrawModel( clipModel->Handle(), clipModel->GetOrigin(), clipModel->GetAxis(), eye, radius ); } } }
/* ============ idAASSettings::idAASSettings ============ */ idAASSettings::idAASSettings( void ) { numBoundingBoxes = 1; boundingBoxes[0] = idBounds( idVec3( -16, -16, 0 ), idVec3( 16, 16, 72 ) ); usePatches = false; writeBrushMap = false; playerFlood = false; noOptimize = false; allowSwimReachabilities = false; allowFlyReachabilities = false; fileExtension = "aas48"; // physics settings gravity = idVec3( 0, 0, -1066 ); gravityDir = gravity; gravityValue = gravityDir.Normalize(); invGravityDir = -gravityDir; maxStepHeight = 14.0f; maxBarrierHeight = 32.0f; maxWaterJumpHeight = 20.0f; maxFallHeight = 64.0f; minFloorCos = 0.7f; // fixed travel times tt_barrierJump = 100; tt_startCrouching = 100; tt_waterJump = 100; tt_startWalkOffLedge = 100; }
/* =============== idClip::Init =============== */ void idClip::Init( void ) { cmHandle_t h; idVec3 size, maxSector = vec3_origin; // clear clip sectors clipSectors = new clipSector_t[MAX_SECTORS]; memset( clipSectors, 0, MAX_SECTORS * sizeof( clipSector_t ) ); numClipSectors = 0; touchCount = -1; // get world map bounds h = collisionModelManager->LoadModel( "worldMap", false ); collisionModelManager->GetModelBounds( h, worldBounds ); // create world sectors CreateClipSectors_r( 0, worldBounds, maxSector ); size = worldBounds[1] - worldBounds[0]; gameLocal.Printf( "map bounds are (%1.1f, %1.1f, %1.1f)\n", size[0], size[1], size[2] ); gameLocal.Printf( "max clip sector is (%1.1f, %1.1f, %1.1f)\n", maxSector[0], maxSector[1], maxSector[2] ); // initialize a default clip model defaultClipModel.LoadModel( idTraceModel( idBounds( idVec3( 0, 0, 0 ) ).Expand( 8 ) ) ); // set counters to zero numRotations = numTranslations = numMotions = numRenderModelTraces = numContents = numContacts = 0; }
/* ================ idThread::Event_Trace ================ */ void idThread::Event_Trace( const idVec3 &start, const idVec3 &end, const idVec3 &mins, const idVec3 &maxs, int contents_mask, idEntity *passEntity ) { if ( mins == vec3_origin && maxs == vec3_origin ) { gameLocal.clip.TracePoint( trace, start, end, contents_mask, passEntity ); } else { gameLocal.clip.TraceBounds( trace, start, end, idBounds( mins, maxs ), contents_mask, passEntity ); } ReturnFloat( trace.fraction ); }
/* ================ idMoveableItem::Spawn ================ */ void idMoveableItem::Spawn( void ) { idTraceModel trm; float density, friction, bouncyness, tsize; idStr clipModelName; idBounds bounds; // create a trigger for item pickup spawnArgs.GetFloat( "triggersize", "16.0", tsize ); trigger = new idClipModel( idTraceModel( idBounds( vec3_origin ).Expand( tsize ) ) ); trigger->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); trigger->SetContents( CONTENTS_TRIGGER ); // check if a clip model is set spawnArgs.GetString( "clipmodel", "", clipModelName ); if ( !clipModelName[0] ) { clipModelName = spawnArgs.GetString( "model" ); // use the visual model } // load the trace model if ( !collisionModelManager->TrmFromModel( clipModelName, trm ) ) { gameLocal.Error( "idMoveableItem '%s': cannot load collision model %s", name.c_str(), clipModelName.c_str() ); return; } // if the model should be shrinked if ( spawnArgs.GetBool( "clipshrink" ) ) { trm.Shrink( CM_CLIP_EPSILON ); } // get rigid body properties spawnArgs.GetFloat( "density", "0.5", density ); density = idMath::ClampFloat( 0.001f, 1000.0f, density ); spawnArgs.GetFloat( "friction", "0.05", friction ); friction = idMath::ClampFloat( 0.0f, 1.0f, friction ); spawnArgs.GetFloat( "bouncyness", "0.6", bouncyness ); bouncyness = idMath::ClampFloat( 0.0f, 1.0f, bouncyness ); // setup the physics physicsObj.SetSelf( this ); physicsObj.SetClipModel( new idClipModel( trm ), density ); physicsObj.SetOrigin( GetPhysics()->GetOrigin() ); physicsObj.SetAxis( GetPhysics()->GetAxis() ); physicsObj.SetBouncyness( bouncyness ); physicsObj.SetFriction( 0.6f, 0.6f, friction ); physicsObj.SetGravity( gameLocal.GetGravity() ); physicsObj.SetContents( CONTENTS_RENDERMODEL ); physicsObj.SetClipMask( MASK_SOLID | CONTENTS_MOVEABLECLIP ); SetPhysics( &physicsObj ); smoke = NULL; smokeTime = 0; const char *smokeName = spawnArgs.GetString( "smoke_trail" ); if ( *smokeName != '\0' ) { smoke = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, smokeName ) ); smokeTime = gameLocal.time; BecomeActive( TH_UPDATEPARTICLES ); } }
/* ================ idDeclParticle::Parse ================ */ bool idDeclParticle::Parse( const char *text, const int textLength ) { idLexer src; idToken token; src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); src.SetFlags( DECL_LEXER_FLAGS ); src.SkipUntilString( "{" ); depthHack = 0.0f; while (1) { if ( !src.ReadToken( &token ) ) { break; } if ( !token.Icmp( "}" ) ) { break; } if ( !token.Icmp( "{" ) ) { idParticleStage *stage = ParseParticleStage( src ); if ( !stage ) { src.Warning( "Particle stage parse failed" ); MakeDefault(); return false; } stages.Append( stage ); continue; } if ( !token.Icmp( "depthHack" ) ) { depthHack = src.ParseFloat(); continue; } src.Warning( "bad token %s", token.c_str() ); MakeDefault(); return false; } // // calculate the bounds // bounds.Clear(); for( int i = 0; i < stages.Num(); i++ ) { GetStageBounds( stages[i] ); bounds.AddBounds( stages[i]->bounds ); } if ( bounds.GetVolume() <= 0.1f ) { bounds = idBounds( vec3_origin ).Expand( 8.0f ); } return true; }
/* ============ idClip::Contacts ============ */ int idClip::Contacts( contactInfo_t *contacts, const int maxContacts, const idVec3 &start, const idVec6 &dir, const float depth, const idClipModel *mdl, const idMat3 &trmAxis, int contentMask, const idEntity *passEntity ) { int i, j, num, n, numContacts; idClipModel *touch, *clipModelList[MAX_GENTITIES]; idBounds traceBounds; const idTraceModel *trm; trm = TraceModelForClipModel( mdl ); if( !passEntity || passEntity->entityNumber != ENTITYNUM_WORLD ) { // test world idClip::numContacts++; numContacts = collisionModelManager->Contacts( contacts, maxContacts, start, dir, depth, trm, trmAxis, contentMask, 0, vec3_origin, mat3_default ); } else { numContacts = 0; } for( i = 0; i < numContacts; i++ ) { contacts[i].entityNum = ENTITYNUM_WORLD; contacts[i].id = 0; } if( numContacts >= maxContacts ) { return numContacts; } if( !trm ) { traceBounds = idBounds( start ).Expand( depth ); } else { traceBounds.FromTransformedBounds( trm->bounds, start, trmAxis ); traceBounds.ExpandSelf( depth ); } num = GetTraceClipModels( traceBounds, contentMask, passEntity, clipModelList ); for( i = 0; i < num; i++ ) { touch = clipModelList[i]; if( !touch ) { continue; } // no contacts with render models if( touch->renderModelHandle != -1 ) { continue; } idClip::numContacts++; n = collisionModelManager->Contacts( contacts + numContacts, maxContacts - numContacts, start, dir, depth, trm, trmAxis, contentMask, touch->Handle(), touch->origin, touch->axis ); for( j = 0; j < n; j++ ) { contacts[numContacts].entityNum = touch->entity->entityNumber; contacts[numContacts].id = touch->id; numContacts++; } if( numContacts >= maxContacts ) { break; } } return numContacts; }
/* ================ hhCameraInterpolator::hhCameraInterpolator ================ */ hhCameraInterpolator::hhCameraInterpolator() : clipBounds( idBounds(idVec3(-1, -1, 10), idVec3(1, 1, 12)) ) { ClearFuncList(); RegisterFunc( NoInterpEvaluate, IT_None ); RegisterFunc( VariableMidPointSinusoidalEvaluate, IT_VariableMidPointSinusoidal ); RegisterFunc( LinearEvaluate, IT_Linear ); RegisterFunc( InverseEvaluate, IT_Inverse ); SetSelf( NULL ); Setup( 0.0f, IT_None ); Reset( vec3_origin, mat3_identity[2], 0.0f ); }
/* ================ idItem::Spawn ================ */ void idItem::Spawn(void) { idStr giveTo; idEntity *ent; float tsize; if (spawnArgs.GetBool("dropToFloor")) { PostEventMS(&EV_DropToFloor, 0); } if (spawnArgs.GetFloat("triggersize", "0", tsize)) { GetPhysics()->GetClipModel()->LoadModel(idTraceModel(idBounds(vec3_origin).Expand(tsize))); GetPhysics()->GetClipModel()->Link(gameLocal.clip); } if (spawnArgs.GetBool("start_off")) { GetPhysics()->SetContents(0); Hide(); } else { GetPhysics()->SetContents(CONTENTS_TRIGGER); } giveTo = spawnArgs.GetString("owner"); if (giveTo.Length()) { ent = gameLocal.FindEntity(giveTo); if (!ent) { gameLocal.Error("Item couldn't find owner '%s'", giveTo.c_str()); } PostEventMS(&EV_Touch, 0, ent, 0); } if (spawnArgs.GetBool("spin") || gameLocal.isMultiplayer) { spin = true; BecomeActive(TH_THINK); } //pulse = !spawnArgs.GetBool( "nopulse" ); //temp hack for tim pulse = false; orgOrigin = GetPhysics()->GetOrigin(); canPickUp = !(spawnArgs.GetBool("triggerFirst") || spawnArgs.GetBool("no_touch")); inViewTime = -1000; lastCycle = -1; itemShellHandle = -1; shellMaterial = declManager->FindMaterial("itemHighlightShell"); }
/* ============ idAASLocal::ShowWallEdges ============ */ void idAASLocal::ShowWallEdges( const idVec3 &origin ) const { int i, areaNum, numEdges, edges[1024]; idVec3 start, end; idPlayer *player; player = gameLocal.GetLocalPlayer(); if( !player ) { return; } areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), ( AREA_REACHABLE_WALK | AREA_REACHABLE_FLY ) ); numEdges = GetWallEdges( areaNum, idBounds( origin ).Expand( 256.0f ), TFL_WALK, edges, 1024 ); for( i = 0; i < numEdges; i++ ) { GetEdge( edges[i], start, end ); gameRenderWorld->DebugLine( colorRed, start, end ); gameRenderWorld->DrawText( va( "%d", edges[i] ), ( start + end ) * 0.5f, 0.1f, colorWhite, player->viewAxis ); } }
/* ============ idAASLocal::ShowHideArea ============ */ void idAASLocal::ShowHideArea( const idVec3 &origin, int targetAreaNum ) const { int areaNum, numObstacles; idVec3 target; aasGoal_t goal; aasObstacle_t obstacles[10]; areaNum = PointReachableAreaNum( origin, DefaultSearchBounds(), ( AREA_REACHABLE_WALK | AREA_REACHABLE_FLY ) ); target = AreaCenter( targetAreaNum ); // consider the target an obstacle obstacles[0].absBounds = idBounds( target ).Expand( 16 ); numObstacles = 1; DrawCone( target, idVec3( 0, 0, 1 ), 16.0f, colorYellow ); idAASFindCover findCover( target ); if( FindNearestGoal( goal, areaNum, origin, target, TFL_WALK | TFL_AIR, obstacles, numObstacles, findCover ) ) { DrawArea( goal.areaNum ); ShowWalkPath( origin, goal.areaNum, goal.origin ); DrawCone( goal.origin, idVec3( 0, 0, 1 ), 16.0f, colorWhite ); } }
//-------------------------------- // hhProxDoor::Spawn //-------------------------------- void hhProxDoor::Spawn() { proxState = PROXSTATE_Inactive; doorSndState = PDOORSND_Closed; spawnArgs.GetBool( "startlocked", "0", doorLocked ); SetShaderParm( SHADERPARM_MODE, GetDoorShaderParm( doorLocked, true ) ); // 2=locked, 1=unlocked, 0=never locked if( !spawnArgs.GetFloat("trigger_distance", "0.0", maxDistance) ) { common->Warning( "No 'trigger_distance' specified for entityDef '%s'", this->GetEntityDefName() ); } if( !spawnArgs.GetFloat("movement_distance", "0.0", movementDistance) ) { common->Warning( "No 'movement_distance' specified for entityDef '%s'", this->GetEntityDefName() ); } lastDistance = movementDistance + 1.0f; // Safe default -mdl if( !spawnArgs.GetFloat("stop_distance", "0.0", stopDistance) ) { common->Warning( "No 'stop_distance' specificed for entityDef '%s'", this->GetEntityDefName() ); } spawnArgs.GetBool( "openForMonsters", "1", openForMonsters ); spawnArgs.GetFloat( "damage", "1", damage ); //Find any portal boundary we are on areaPortal = gameRenderWorld->FindPortal( GetPhysics()->GetAbsBounds() ); if (gameLocal.isMultiplayer) { fl.networkSync = true; if (gameLocal.isClient) { doorTrigger = new idClipModel( idTraceModel(idBounds(vec3_origin).Expand(maxDistance)) ); doorTrigger->Link( gameLocal.clip, this, 255, GetOrigin(), GetAxis() ); doorTrigger->SetContents( CONTENTS_TRIGGER ); SetAASAreaState( doorLocked ); //close the area state if we are locked... SetDoorState( PROXSTATE_Inactive ); } else { PostEventMS( &EV_PostSpawn, 50 ); //rww - this must be delayed or it will happen on the first server frame and we DON'T want that. } } else { //just call it now. some sp maps might target a door piece in the spawn function of an entity or something crazy like that. Event_PostSpawn(); } }
//-------------------------------- // hhProxDoor::Event_PostSpawn //-------------------------------- void hhProxDoor::Event_PostSpawn( void ) { int numSubObjs; int i; const char* objDef; //Parse and spawn our door sections numSubObjs = spawnArgs.GetInt( "num_doorobjs", "0" ); for( i = 0; i < numSubObjs; i++ ) { if( !spawnArgs.GetString( va("doorobject%i", i+1), "", &objDef ) ) { common->Warning( "failed to find doorobject%i", i+1 ); } else { //Set our default rotation/origin. idDict args; args.SetVector( "origin", this->GetOrigin() ); args.SetMatrix( "rotation", this->GetAxis() ); hhProxDoorSection* ent = static_cast<hhProxDoorSection*> ( gameLocal.SpawnObject(objDef, &args) ); if( !ent ) { common->Warning( "failed to spawn doorobject%i for entityDef '%s'", i+1, GetEntityDefName() ); } else { ent->proxyParent = this; doorPieces.Append( ent ); } } } //Spawn our trigger and link it up // if( doorLocked && !spawnArgs.GetBool("locktrigger") ) { //we would never be able to open the door, so don't spawn a trigger // } // else { doorTrigger = new idClipModel( idTraceModel(idBounds(vec3_origin).Expand(maxDistance)) ); doorTrigger->Link( gameLocal.clip, this, 255, GetOrigin(), GetAxis() ); doorTrigger->SetContents( CONTENTS_TRIGGER ); // } SpawnSoundTrigger(); SetAASAreaState( doorLocked ); //close the area state if we are locked... SetDoorState( PROXSTATE_Inactive ); }
/* ================ rvCTF_AssaultPoint::InitializeLinks ================ */ void rvCTF_AssaultPoint::Event_InitializeLinks( void ) { if( linked ) { return; } // pull in our targets toStrogg = gameLocal.FindEntity( spawnArgs.GetString( "targetStroggAP" ) ); toMarine = gameLocal.FindEntity( spawnArgs.GetString( "targetMarineAP" ) ); ResetIndices(); trigger = new idClipModel( idTraceModel( idBounds( vec3_origin ).Expand( 16.0f ) ) ); // RAVEN BEGIN // ddynerman: multiple clip worlds trigger->Link( this, 0, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); // RAVEN END trigger->SetContents ( CONTENTS_TRIGGER ); GetPhysics()->SetClipModel( NULL, 1.0f ); linked = true; }
/* ============= idEditEntities::DisplayEntities ============= */ void idEditEntities::DisplayEntities( void ) { idEntity *ent; if ( !gameLocal.GetLocalPlayer() ) { return; } selectableEntityClasses.Clear(); selectedTypeInfo_t sit; switch( g_editEntityMode.GetInteger() ) { case 1: sit.typeInfo = &idLight::Type; sit.textKey = "texture"; selectableEntityClasses.Append( sit ); break; case 2: sit.typeInfo = &idSound::Type; sit.textKey = "s_shader"; selectableEntityClasses.Append( sit ); sit.typeInfo = &idLight::Type; sit.textKey = "texture"; selectableEntityClasses.Append( sit ); break; case 3: sit.typeInfo = &idAFEntity_Base::Type; sit.textKey = "articulatedFigure"; selectableEntityClasses.Append( sit ); break; case 4: sit.typeInfo = &idFuncEmitter::Type; sit.textKey = "model"; selectableEntityClasses.Append( sit ); break; case 5: sit.typeInfo = &idAI::Type; sit.textKey = "name"; selectableEntityClasses.Append( sit ); break; case 6: sit.typeInfo = &idEntity::Type; sit.textKey = "name"; selectableEntityClasses.Append( sit ); break; case 7: sit.typeInfo = &idEntity::Type; sit.textKey = "model"; selectableEntityClasses.Append( sit ); break; default: return; } idBounds viewBounds( gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() ); idBounds viewTextBounds( gameLocal.GetLocalPlayer()->GetPhysics()->GetOrigin() ); idMat3 axis = gameLocal.GetLocalPlayer()->viewAngles.ToMat3(); viewBounds.ExpandSelf( 512 ); viewTextBounds.ExpandSelf( 128 ); idStr textKey; for( ent = gameLocal.spawnedEntities.Next(); ent != NULL; ent = ent->spawnNode.Next() ) { idVec4 color; textKey = ""; if ( !EntityIsSelectable( ent, &color, &textKey ) ) { continue; } bool drawArrows = false; if ( ent->GetType() == &idAFEntity_Base::Type ) { if ( !static_cast<idAFEntity_Base *>(ent)->IsActiveAF() ) { continue; } } else if ( ent->GetType() == &idSound::Type ) { if ( ent->fl.selected ) { drawArrows = true; } const idSoundShader * ss = declManager->FindSound( ent->spawnArgs.GetString( textKey ) ); if ( ss->HasDefaultSound() || ss->base->GetState() == DS_DEFAULTED ) { color.Set( 1.0f, 0.0f, 1.0f, 1.0f ); } } else if ( ent->GetType() == &idFuncEmitter::Type ) { if ( ent->fl.selected ) { drawArrows = true; } } if ( !viewBounds.ContainsPoint( ent->GetPhysics()->GetOrigin() ) ) { continue; } gameRenderWorld->DebugBounds( color, idBounds( ent->GetPhysics()->GetOrigin() ).Expand( 8 ) ); if ( drawArrows ) { idVec3 start = ent->GetPhysics()->GetOrigin(); idVec3 end = start + idVec3( 1, 0, 0 ) * 20.0f; gameRenderWorld->DebugArrow( colorWhite, start, end, 2 ); gameRenderWorld->DrawText( "x+", end + idVec3( 4, 0, 0 ), 0.15f, colorWhite, axis ); end = start + idVec3( 1, 0, 0 ) * -20.0f; gameRenderWorld->DebugArrow( colorWhite, start, end, 2 ); gameRenderWorld->DrawText( "x-", end + idVec3( -4, 0, 0 ), 0.15f, colorWhite, axis ); end = start + idVec3( 0, 1, 0 ) * +20.0f; gameRenderWorld->DebugArrow( colorGreen, start, end, 2 ); gameRenderWorld->DrawText( "y+", end + idVec3( 0, 4, 0 ), 0.15f, colorWhite, axis ); end = start + idVec3( 0, 1, 0 ) * -20.0f; gameRenderWorld->DebugArrow( colorGreen, start, end, 2 ); gameRenderWorld->DrawText( "y-", end + idVec3( 0, -4, 0 ), 0.15f, colorWhite, axis ); end = start + idVec3( 0, 0, 1 ) * +20.0f; gameRenderWorld->DebugArrow( colorBlue, start, end, 2 ); gameRenderWorld->DrawText( "z+", end + idVec3( 0, 0, 4 ), 0.15f, colorWhite, axis ); end = start + idVec3( 0, 0, 1 ) * -20.0f; gameRenderWorld->DebugArrow( colorBlue, start, end, 2 ); gameRenderWorld->DrawText( "z-", end + idVec3( 0, 0, -4 ), 0.15f, colorWhite, axis ); } if ( textKey.Length() ) { const char *text = ent->spawnArgs.GetString( textKey ); if ( viewTextBounds.ContainsPoint( ent->GetPhysics()->GetOrigin() ) ) { gameRenderWorld->DrawText( text, ent->GetPhysics()->GetOrigin() + idVec3(0, 0, 12), 0.25, colorWhite, axis, 1 ); } } } }
/* ===================== idCameraAnim::GetViewParms ===================== */ void idCameraAnim::GetViewParms( renderView_t *view ) { int realFrame; int frame; int frameTime; float lerp; float invlerp; cameraFrame_t *camFrame; int i; int cut; idQuat q1, q2, q3; assert( view ); if ( !view ) { return; } if ( camera.Num() == 0 ) { // we most likely are in the middle of a restore // FIXME: it would be better to fix it so this doesn't get called during a restore return; } if ( frameRate == USERCMD_HZ ) { frameTime = gameLocal.time - starttime; frame = frameTime / gameLocal.msec; lerp = 0.0f; } else { frameTime = ( gameLocal.time - starttime ) * frameRate; frame = frameTime / 1000; lerp = ( frameTime % 1000 ) * 0.001f; } // skip any frames where camera cuts occur realFrame = frame; cut = 0; for( i = 0; i < cameraCuts.Num(); i++ ) { if ( frame < cameraCuts[ i ] ) { break; } frame++; cut++; } if ( g_debugCinematic.GetBool() ) { int prevFrameTime = ( gameLocal.time - starttime - gameLocal.msec ) * frameRate; int prevFrame = prevFrameTime / 1000; int prevCut; prevCut = 0; for( i = 0; i < cameraCuts.Num(); i++ ) { if ( prevFrame < cameraCuts[ i ] ) { break; } prevFrame++; prevCut++; } if ( prevCut != cut ) { gameLocal.Printf( "%d: '%s' cut %d\n", gameLocal.framenum, GetName(), cut ); } } // clamp to the first frame. also check if this is a one frame anim. one frame anims would end immediately, // but since they're mainly used for static cams anyway, just stay on it infinitely. if ( ( frame < 0 ) || ( camera.Num() < 2 ) ) { view->viewaxis = camera[ 0 ].q.ToQuat().ToMat3(); view->vieworg = camera[ 0 ].t + offset; view->fov_x = camera[ 0 ].fov; } else if ( frame > camera.Num() - 2 ) { if ( cycle > 0 ) { cycle--; } if ( cycle != 0 ) { // advance start time so that we loop starttime += ( ( camera.Num() - cameraCuts.Num() ) * 1000 ) / frameRate; GetViewParms( view ); return; } Stop(); if ( gameLocal.GetCamera() != NULL ) { // we activated another camera when we stopped, so get it's viewparms instead gameLocal.GetCamera()->GetViewParms( view ); return; } else { // just use our last frame camFrame = &camera[ camera.Num() - 1 ]; view->viewaxis = camFrame->q.ToQuat().ToMat3(); view->vieworg = camFrame->t + offset; view->fov_x = camFrame->fov; } } else if ( lerp == 0.0f ) { camFrame = &camera[ frame ]; view->viewaxis = camFrame[ 0 ].q.ToMat3(); view->vieworg = camFrame[ 0 ].t + offset; view->fov_x = camFrame[ 0 ].fov; } else { camFrame = &camera[ frame ]; invlerp = 1.0f - lerp; q1 = camFrame[ 0 ].q.ToQuat(); q2 = camFrame[ 1 ].q.ToQuat(); q3.Slerp( q1, q2, lerp ); view->viewaxis = q3.ToMat3(); view->vieworg = camFrame[ 0 ].t * invlerp + camFrame[ 1 ].t * lerp + offset; view->fov_x = camFrame[ 0 ].fov * invlerp + camFrame[ 1 ].fov * lerp; } gameLocal.CalcFov( view->fov_x, view->fov_x, view->fov_y ); // setup the pvs for this frame UpdatePVSAreas( view->vieworg ); #if 0 static int lastFrame = 0; static idVec3 lastFrameVec( 0.0f, 0.0f, 0.0f ); if ( gameLocal.time != lastFrame ) { gameRenderWorld->DebugBounds( colorCyan, idBounds( view->vieworg ).Expand( 16.0f ), vec3_origin, gameLocal.msec ); gameRenderWorld->DebugLine( colorRed, view->vieworg, view->vieworg + idVec3( 0.0f, 0.0f, 2.0f ), 10000, false ); gameRenderWorld->DebugLine( colorCyan, lastFrameVec, view->vieworg, 10000, false ); gameRenderWorld->DebugLine( colorYellow, view->vieworg + view->viewaxis[ 0 ] * 64.0f, view->vieworg + view->viewaxis[ 0 ] * 66.0f, 10000, false ); gameRenderWorld->DebugLine( colorOrange, view->vieworg + view->viewaxis[ 0 ] * 64.0f, view->vieworg + view->viewaxis[ 0 ] * 64.0f + idVec3( 0.0f, 0.0f, 2.0f ), 10000, false ); lastFrameVec = view->vieworg; lastFrame = gameLocal.time; } #endif if ( g_showcamerainfo.GetBool() ) { gameLocal.Printf( "^5Frame: ^7%d/%d\n\n\n", realFrame + 1, camera.Num() - cameraCuts.Num() ); } }
/* ================ idThread::Event_DebugBounds ================ */ void idThread::Event_DebugBounds( const idVec3 &color, const idVec3 &mins, const idVec3 &maxs, const float lifetime ) { gameRenderWorld->DebugBounds( idVec4( color.x, color.y, color.z, 0.0f ), idBounds( mins, maxs ), vec3_origin, SEC2MS( lifetime ) ); }
/* ================ idDeclParticle::Parse ================ */ bool idDeclParticle::Parse( const char* text, const int textLength, bool allowBinaryVersion ) { if( cvarSystem->GetCVarBool( "fs_buildresources" ) ) { fileSystem->AddParticlePreload( GetName() ); } idLexer src; idToken token; unsigned int sourceChecksum = 0; idStrStatic< MAX_OSPATH > generatedFileName; if( allowBinaryVersion ) { // Try to load the generated version of it // If successful, // - Create an MD5 of the hash of the source // - Load the MD5 of the generated, if they differ, create a new generated generatedFileName = "generated/particles/"; generatedFileName.AppendPath( GetName() ); generatedFileName.SetFileExtension( ".bprt" ); idFileLocal file( fileSystem->OpenFileReadMemory( generatedFileName ) ); sourceChecksum = MD5_BlockChecksum( text, textLength ); if( binaryLoadParticles.GetBool() && LoadBinary( file, sourceChecksum ) ) { return true; } } src.LoadMemory( text, textLength, GetFileName(), GetLineNum() ); src.SetFlags( DECL_LEXER_FLAGS ); src.SkipUntilString( "{" ); depthHack = 0.0f; while( 1 ) { if( !src.ReadToken( &token ) ) { break; } if( !token.Icmp( "}" ) ) { break; } if( !token.Icmp( "{" ) ) { if( stages.Num() >= MAX_PARTICLE_STAGES ) { src.Error( "Too many particle stages" ); MakeDefault(); return false; } idParticleStage* stage = ParseParticleStage( src ); if( !stage ) { src.Warning( "Particle stage parse failed" ); MakeDefault(); return false; } stages.Append( stage ); continue; } if( !token.Icmp( "depthHack" ) ) { depthHack = src.ParseFloat(); continue; } src.Warning( "bad token %s", token.c_str() ); MakeDefault(); return false; } // don't calculate bounds or write binary files for defaulted ( non-existent ) particles in resource builds if( fileSystem->UsingResourceFiles() ) { bounds = idBounds( vec3_origin ).Expand( 8.0f ); return true; } // // calculate the bounds // bounds.Clear(); for( int i = 0; i < stages.Num(); i++ ) { GetStageBounds( stages[i] ); bounds.AddBounds( stages[i]->bounds ); } if( bounds.GetVolume() <= 0.1f ) { bounds = idBounds( vec3_origin ).Expand( 8.0f ); } if( allowBinaryVersion && binaryLoadParticles.GetBool() ) { idLib::Printf( "Writing %s\n", generatedFileName.c_str() ); idFileLocal outputFile( fileSystem->OpenFileWrite( generatedFileName, "fs_basepath" ) ); WriteBinary( outputFile, sourceChecksum ); } return true; }
/* ================ idItem::Spawn ================ */ void idItem::Spawn( void ) { idStr giveTo; idEntity * ent; float tsize; if ( spawnArgs.GetBool( "dropToFloor" ) ) { PostEventMS( &EV_DropToFloor, 0 ); } if ( spawnArgs.GetFloat( "triggersize", "0", tsize ) ) { GetPhysics()->GetClipModel()->LoadModel( idTraceModel( idBounds( vec3_origin ).Expand( tsize ) ) ); GetPhysics()->GetClipModel()->Link( gameLocal.clip ); } if ( spawnArgs.GetBool( "start_off" ) ) { GetPhysics()->SetContents( 0 ); Hide(); } else { GetPhysics()->SetContents( CONTENTS_TRIGGER ); } giveTo = spawnArgs.GetString( "owner" ); if ( giveTo.Length() ) { ent = gameLocal.FindEntity( giveTo ); if ( !ent ) { gameLocal.Error( "Item couldn't find owner '%s'", giveTo.c_str() ); } PostEventMS( &EV_Touch, 0, ent, NULL ); } if ( spawnArgs.GetBool( "spin" ) ) { spin = true; BecomeActive( TH_THINK ); } // pulse = !spawnArgs.GetBool( "nopulse" ); //temp hack for tim pulse = false; orgOrigin = GetPhysics()->GetOrigin(); canPickUp = !( spawnArgs.GetBool( "triggerFirst" ) || spawnArgs.GetBool( "no_touch" ) ); inViewTime = -1000; lastCycle = -1; itemShellHandle = -1; shellMaterial = declManager->FindMaterial( "itemHighlightShell" ); // ---> sikk - Modifier System // this is used for modifiers but can be specified for any item int removeDelay = spawnArgs.GetInt( "removeDelay" ); if ( removeDelay > 0 ) { PostEventSec( &EV_Remove, removeDelay ); } // <--- sikk - Modifier System // ---> sikk - Crumb Light idStr shaderName; idVec3 light_color; idVec3 light_offset; memset( &renderLight, 0, sizeof( renderLight ) ); shaderName = spawnArgs.GetString( "mtr_light_shader" ); if ( *(const char *)shaderName ) { renderLight.shader = declManager->FindMaterial( shaderName, false ); renderLight.pointLight = true; renderLight.lightRadius[0] = renderLight.lightRadius[1] = renderLight.lightRadius[2] = spawnArgs.GetFloat( "light_radius" ); spawnArgs.GetVector( "light_color", "1 1 1", light_color ); renderLight.shaderParms[0] = light_color[0]; renderLight.shaderParms[1] = light_color[1]; renderLight.shaderParms[2] = light_color[2]; renderLight.shaderParms[3] = spawnArgs.GetFloat( "light_brightness", "1.0" ); // sikk - alpha holds light brightness } spawnArgs.GetVector( "light_offset", "0 0 0", lightOffset ); // <--- sikk - Crumb Light // ---> sikk - Crumb count if ( spawnArgs.GetBool( "inv_crumb" ) ) { gameLocal.numCrumbs++; } // <--- sikk - Crumb count }
/* ================ idAF::LoadBody ================ */ bool idAF::LoadBody( const idDeclAF_Body *fb, const idJointMat *joints ) { int id, i; float length, mass; idTraceModel trm; idClipModel *clip; idAFBody *body; idMat3 axis, inertiaTensor; idVec3 centerOfMass, origin; idBounds bounds; idList<jointHandle_t> jointList; origin = fb->origin.ToVec3(); axis = fb->angles.ToMat3(); bounds[0] = fb->v1.ToVec3(); bounds[1] = fb->v2.ToVec3(); switch( fb->modelType ) { case TRM_BOX: { trm.SetupBox( bounds ); break; } case TRM_OCTAHEDRON: { trm.SetupOctahedron( bounds ); break; } case TRM_DODECAHEDRON: { trm.SetupDodecahedron( bounds ); break; } case TRM_CYLINDER: { trm.SetupCylinder( bounds, fb->numSides ); break; } case TRM_CONE: { // place the apex at the origin bounds[0].z -= bounds[1].z; bounds[1].z = 0.0f; trm.SetupCone( bounds, fb->numSides ); break; } case TRM_BONE: { // direction of bone axis[2] = fb->v2.ToVec3() - fb->v1.ToVec3(); length = axis[2].Normalize(); // axis of bone trace model axis[2].NormalVectors( axis[0], axis[1] ); axis[1] = -axis[1]; // create trace model to cover the bone idVec3 halfBounds( fb->width * 0.5f, fb->width * 0.5f, length * 0.5f ); trm.SetupBox( idBounds( -halfBounds, halfBounds ) ); // old way uses a tetrahedron kind of thing, but it doesn't even come close to covering the render model :( // trm.SetupBone( length, fb->width ); break; } default: assert( 0 ); break; } trm.GetMassProperties( 1.0f, mass, centerOfMass, inertiaTensor ); trm.Translate( -centerOfMass ); origin += centerOfMass * axis; body = physicsObj.GetBody( fb->name ); if ( body ) { clip = body->GetClipModel(); if ( !clip->IsEqual( trm ) ) { clip = new idClipModel( trm, false ); clip->SetContents( fb->contents ); clip->Link( gameLocal.clip, self, 0, origin, axis ); body->SetClipModel( clip ); } clip->SetContents( fb->contents ); body->SetDensity( fb->density, fb->inertiaScale ); body->SetWorldOrigin( origin ); body->SetWorldAxis( axis ); id = physicsObj.GetBodyId( body ); } else { clip = new idClipModel( trm, false ); clip->SetContents( fb->contents ); clip->Link( gameLocal.clip, self, 0, origin, axis ); body = new idAFBody( fb->name, clip, fb->density ); if ( fb->inertiaScale != mat3_identity ) { body->SetDensity( fb->density, fb->inertiaScale ); } id = physicsObj.AddBody( body ); } if ( fb->linearFriction != -1.0f ) { body->SetFriction( fb->linearFriction, fb->angularFriction, fb->contactFriction ); } body->SetClipMask( fb->clipMask ); body->SetSelfCollision( fb->selfCollision ); if ( fb->jointName == "origin" ) { SetBase( body, joints ); } else { AFJointModType_t mod; if ( fb->jointMod == DECLAF_JOINTMOD_AXIS ) { mod = AF_JOINTMOD_AXIS; } else if ( fb->jointMod == DECLAF_JOINTMOD_ORIGIN ) { mod = AF_JOINTMOD_ORIGIN; } else if ( fb->jointMod == DECLAF_JOINTMOD_BOTH ) { mod = AF_JOINTMOD_BOTH; } else { mod = AF_JOINTMOD_AXIS; } AddBody( body, joints, fb->jointName, mod ); } if ( fb->frictionDirection.ToVec3() != vec3_origin ) { body->SetFrictionDirection( fb->frictionDirection.ToVec3() ); } if ( fb->contactMotorDirection.ToVec3() != vec3_origin ) { body->SetContactMotorDirection( fb->contactMotorDirection.ToVec3() ); } // update table to find the nearest articulated figure body for a joint of the skeletal model animator->GetJointList( fb->containedJoints, jointList ); for( i = 0; i < jointList.Num(); i++ ) { if ( jointBody[ jointList[ i ] ] != -1 ) { gameLocal.Warning( "%s: joint '%s' is already contained by body '%s'", name.c_str(), animator->GetJointName( (jointHandle_t)jointList[i] ), physicsObj.GetBody( jointBody[ jointList[ i ] ] )->GetName().c_str() ); } jointBody[ jointList[ i ] ] = id; } return true; }