Force_Grab.cpp (4901B)
1 /* 2 =========================================================================== 3 4 Doom 3 BFG Edition GPL Source Code 5 Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company. 6 7 This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code"). 8 9 Doom 3 BFG Edition Source Code is free software: you can redistribute it and/or modify 10 it under the terms of the GNU General Public License as published by 11 the Free Software Foundation, either version 3 of the License, or 12 (at your option) any later version. 13 14 Doom 3 BFG Edition Source Code is distributed in the hope that it will be useful, 15 but WITHOUT ANY WARRANTY; without even the implied warranty of 16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 GNU General Public License for more details. 18 19 You should have received a copy of the GNU General Public License 20 along with Doom 3 BFG Edition Source Code. If not, see <http://www.gnu.org/licenses/>. 21 22 In addition, the Doom 3 BFG Edition Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 BFG Edition Source Code. If not, please request a copy in writing from id Software at the address below. 23 24 If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. 25 26 =========================================================================== 27 */ 28 29 #pragma hdrstop 30 #include "../../idlib/precompiled.h" 31 32 33 #include "../Game_local.h" 34 35 CLASS_DECLARATION( idForce, idForce_Grab ) 36 END_CLASS 37 38 39 /* 40 ================ 41 idForce_Grab::Save 42 ================ 43 */ 44 void idForce_Grab::Save( idSaveGame *savefile ) const { 45 46 savefile->WriteFloat( damping ); 47 savefile->WriteVec3( goalPosition ); 48 savefile->WriteFloat( distanceToGoal ); 49 savefile->WriteInt( id ); 50 } 51 52 /* 53 ================ 54 idForce_Grab::Restore 55 ================ 56 */ 57 void idForce_Grab::Restore( idRestoreGame *savefile ) { 58 59 //Note: Owner needs to call set physics 60 savefile->ReadFloat( damping ); 61 savefile->ReadVec3( goalPosition ); 62 savefile->ReadFloat( distanceToGoal ); 63 savefile->ReadInt( id ); 64 } 65 66 /* 67 ================ 68 idForce_Grab::idForce_Grab 69 ================ 70 */ 71 idForce_Grab::idForce_Grab() { 72 damping = 0.5f; 73 physics = NULL; 74 id = 0; 75 } 76 77 /* 78 ================ 79 idForce_Grab::~idForce_Grab 80 ================ 81 */ 82 idForce_Grab::~idForce_Grab() { 83 } 84 85 /* 86 ================ 87 idForce_Grab::Init 88 ================ 89 */ 90 void idForce_Grab::Init( float damping ) { 91 if ( damping >= 0.0f && damping < 1.0f ) { 92 this->damping = damping; 93 } 94 } 95 96 /* 97 ================ 98 idForce_Grab::SetPhysics 99 ================ 100 */ 101 void idForce_Grab::SetPhysics( idPhysics *phys, int id, const idVec3 &goal ) { 102 this->physics = phys; 103 this->id = id; 104 this->goalPosition = goal; 105 } 106 107 /* 108 ================ 109 idForce_Grab::SetGoalPosition 110 ================ 111 */ 112 void idForce_Grab::SetGoalPosition( const idVec3 &goal ) { 113 this->goalPosition = goal; 114 } 115 116 /* 117 ================= 118 idForce_Grab::GetDistanceToGoal 119 ================= 120 */ 121 float idForce_Grab::GetDistanceToGoal() { 122 return distanceToGoal; 123 } 124 125 /* 126 ================ 127 idForce_Grab::Evaluate 128 ================ 129 */ 130 void idForce_Grab::Evaluate( int time ) { 131 if ( !physics ) { 132 return; 133 } 134 idVec3 forceDir, v, objectCenter; 135 float forceAmt; 136 float mass = physics->GetMass(id); 137 138 objectCenter = physics->GetAbsBounds(id).GetCenter(); 139 140 if ( g_grabberRandomMotion.GetBool() && !common->IsMultiplayer() ) { 141 // Jitter the objectCenter around so it doesn't remain stationary 142 float SinOffset = idMath::Sin( (float)(gameLocal.time)/66.f ); 143 float randScale1 = gameLocal.random.RandomFloat(); 144 float randScale2 = gameLocal.random.CRandomFloat(); 145 objectCenter.x += ( SinOffset * 3.5f * randScale1 ) + ( randScale2 * 1.2f ); 146 objectCenter.y += ( SinOffset * -3.5f * randScale1 ) + ( randScale2 * 1.4f ); 147 objectCenter.z += ( SinOffset * 2.4f * randScale1 ) + ( randScale2 * 1.6f ); 148 } 149 150 forceDir = goalPosition - objectCenter; 151 distanceToGoal = forceDir.Normalize(); 152 153 float temp = distanceToGoal; 154 if ( temp > 12.f && temp < 32.f ) { 155 temp = 32.f; 156 } 157 forceAmt = (1000.f * mass) + (500.f * temp * mass); 158 159 if ( forceAmt/mass > 120000.f ) { 160 forceAmt = 120000.f * mass; 161 } 162 physics->AddForce( id, objectCenter, forceDir * forceAmt ); 163 164 if ( distanceToGoal < 196.f ) { 165 v = physics->GetLinearVelocity( id ); 166 physics->SetLinearVelocity( v * damping, id ); 167 } 168 if ( distanceToGoal < 16.f ) { 169 v = physics->GetAngularVelocity(id); 170 if ( v.LengthSqr() > Square(8) ) { 171 physics->SetAngularVelocity( v * 0.99999f, id ); 172 } 173 } 174 } 175 176 /* 177 ================ 178 idForce_Grab::RemovePhysics 179 ================ 180 */ 181 void idForce_Grab::RemovePhysics( const idPhysics *phys ) { 182 if ( physics == phys ) { 183 physics = NULL; 184 } 185 } 186