Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
camerashakesystem.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : WWPhys *
24 * *
25 * $Archive:: /Commando/Code/wwphys/camerashakesystem.cpp $*
26 * *
27 * Original Author:: Greg Hjelstrom *
28 * *
29 * $Author:: Greg_h $*
30 * *
31 * $Modtime:: 6/12/01 10:25a $*
32 * *
33 * $Revision:: 3 $*
34 * *
35 *---------------------------------------------------------------------------------------------*
36 * Functions: *
37 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
38
39#include <stdio.h>
40#include <stdlib.h>
41#include <string.h>
42#include <assetmgr.h>
43#include <texture.h>
44#include <tri.h>
45#include <colmath.h>
46#include <coltest.h>
47#include <rinfo.h>
48#include <camera.h>
49#include <d3dx8core.h>
50#include "Common/GlobalData.h"
51#include "Common/PerfTimer.h"
52
54#include "GameClient/View.h"
55#include "GameClient/Water.h"
56
74#include "WW3D2/DX8Wrapper.h"
75#include "WW3D2/Light.h"
76#include "WW3D2/Scene.h"
79
81#include "WW3D2/Camera.h"
82
83//#include "W3DDevice/GameClient/camera.h"
84//#include "W3DDevice/GameClient/wwmemlog.h"
85
86/*
87** (gth) According to my "research" the artists say that there are several factors that
88** go into a good camera shake.
89** - The motion should be sinusoidal.
90** - Camera rotation is more effective than camera motion (good, I won't use any translation)
91** - The camera should pitch up and down a lot more than it yaws left and right.
92*/
93
95
96const float MIN_OMEGA = DEG_TO_RADF(12.5f*360.0f);
97const float MAX_OMEGA = DEG_TO_RADF(15.0f*360.0f);
98const float END_OMEGA = DEG_TO_RADF(360.0f);
99const float MIN_PHI = DEG_TO_RADF(0.0f);
100const float MAX_PHI = DEG_TO_RADF(360.0f);
102
103
104/************************************************************************************************
105**
106** CameraShakeSystemClass::CameraShakerClass Implementation
107**
108************************************************************************************************/
110(
111 const Vector3 & position,
112 float radius,
113 float duration,
114 float intensity
115) :
116 Position(position),
117 Radius(radius),
118 Duration(duration),
119 Intensity(intensity),
120 ElapsedTime(0.0f)
121{
122 /*
123 ** Initialize random sinusoid values
124 */
131}
132
136
137
139{
140 WWASSERT(set_angles != NULL);
141
142 /*
143 ** We want several different sinusiods, each with a different phase shift and
144 ** frequency. The frequency is a function of time as well, stretching the
145 ** sine wave out. These waves are modulated based on the distance from the
146 ** center of the "shake", the intensity of the shake, and based on the axis
147 ** being affected. The vertical axis should have about 3x the amplitude of
148 ** the horizontal axis.
149 */
150
151 float len2 = (camera_position - Position).Length2();
152
153
154 if (len2 > Radius*Radius) {
155 return;
156 }
157
158
159 /*
160 ** f(t) = intensity(t,pos) * sin( omega(t) * t + phi );
161 ** intensity(t,pos) = intensity * (radius/distance) * timeremaing/totaltime
162 ** omega(t) = start_omega + (end_omega - start_omega) * t
163 ** phi = random(0..start_omega)
164 */
165 float intensity = Intensity * (1.0f - WWMath::Sqrt(len2) / Radius) * (1.0f - ElapsedTime / Duration);
166 for (int i=0; i<3; i++) {
167 float omega = Omega[i] + (END_OMEGA - Omega[i]) * ElapsedTime;
168 (*set_angles)[i] += AXIS_ROTATION[i] * intensity * WWMath::Sin(omega * ElapsedTime + Phi[i]);
169
170 //WST 11/14/2002. Add in additional random fudge. There seems to be a too mathematical pattern of shake with the above
171 Vector3 secondary_angles;
172 float minor_intensity = intensity * 0.5f;
173 secondary_angles.X = WWMath::Random_Float(-minor_intensity,minor_intensity);
174 secondary_angles.Y = WWMath::Random_Float(-minor_intensity,minor_intensity);
175 secondary_angles.Z = WWMath::Random_Float(-minor_intensity,minor_intensity);
176 (*set_angles) += secondary_angles;
177 }
178}
179
180
181/************************************************************************************************
182**
183** CameraShakeSystemClass Implementation
184**
185************************************************************************************************/
189
191{
192 /*
193 ** delete all of the objects out of the list
194 */
195 while (!CameraShakerList.Is_Empty()) {
196 CameraShakerClass * obj = CameraShakerList.Remove_Head();
197 CameraShakerList.Remove(obj);
198 delete obj;
199 }
200}
201
203(
204 const Vector3 & position,
205 float radius,
206 float duration,
207 float power
208)
209{
210 //WWMEMLOG(MEM_PHYSICSDATA);
211 /*
212 ** Allocate a new camera shaker object. Note that these are mem-pooled so the allocation
213 ** is very cheap.
214 */
215
216 //Power is in degrees of amplitude.
217 power = power * PI/180.0f;
218
219 CameraShakerClass * shaker = new CameraShakerClass(position,radius,duration,power);
220 CameraShakerList.Add(shaker);
221}
222
224{
225 /*
226 ** Loop through to find if there is any active camera shakers
227 */
229 for (iterator.First(); !iterator.Is_Done(); iterator.Next()) {
230 CameraShakerClass * obj = iterator.Peek_Obj();
231 if (obj){
232 return (true);
233 }
234 }
235 return(false);
236}
237
238
240{
241 /*
242 ** Allow each camera shaker to timestep. Any that expire are added to a temporary
243 ** list for deletion.
244 */
247 for (iterator.First(); !iterator.Is_Done(); iterator.Next()) {
248 CameraShakerClass * obj = iterator.Peek_Obj();
249 obj->Timestep(dt);
250 if (obj->Is_Expired()) {
251 deletelist.Add(obj);
252 }
253 }
254
255 /*
256 ** Remove and delete all the ones that expired
257 */
258 while (!deletelist.Is_Empty()) {
259 CameraShakerClass * obj = deletelist.Remove_Head();
260 CameraShakerList.Remove(obj);
261 delete obj;
262 }
263}
264
266{
268
269 Vector3 angles(0,0,0);
270 Matrix3D camera_transform;
271
272 //camera_transform = camera.Get_Transform();
273 //camera_transform.Get_Translation(&camera_position);
274
275 /*
276 ** Accumulate the effects of any active camera shakers
277 */
278
279 for (iterator.First(); !iterator.Is_Done(); iterator.Next()) {
280 iterator.Peek_Obj()->Compute_Rotations(camera_position,&angles);
281 }
282
283 /*
284 ** Clamp the result
285 */
286 for (int i=0; i<3; i++) {
287 WWMath::Clamp(angles[i],-AXIS_ROTATION[i],AXIS_ROTATION[i]);
288 }
289
290 *shaker_angle = angles;
291
292 /*
293 ** Apply to the camera
294 */
295 /*
296 camera_transform.Rotate_X(angles.X);
297 camera_transform.Rotate_Y(angles.Y);
298 camera_transform.Rotate_Z(angles.Z);
299 camera.Set_Transform(camera_transform);
300 */
301}
302
303// The Instance of the system
304CameraShakeSystemClass CameraShakerSystem; //WST 11/12/2002 This is the new Camera Shaker system upgrade
305
#define NULL
Definition BaseType.h:92
#define PI
Definition BaseType.h:86
#define WWASSERT
#define DEG_TO_RADF(x)
Definition wwmath.h:87
const float MAX_PHI
const float MIN_OMEGA
const Vector3 AXIS_ROTATION
const float END_OMEGA
const float MIN_PHI
const float MAX_OMEGA
CameraShakeSystemClass CameraShakerSystem
void Compute_Rotations(const Vector3 &pos, Vector3 *set_angles)
CameraShakerClass(const Vector3 &position, float radius, float duration, float power)
void Add_Camera_Shake(const Vector3 &position, float radius=50.0f, float duration=1.5f, float power=1.0f)
MultiListClass< CameraShakerClass > CameraShakerList
void Update_Camera_Shaker(Vector3 camera_position, Vector3 *shaker_angles)
void First(GenericMultiListClass *list)
Definition multilist.h:182
bool Add(ObjectType *obj, bool onlyonce=true)
Definition multilist.h:234
ObjectType * Remove_Head()
Definition multilist.h:264
ObjectType * Peek_Obj(void)
Definition multilist.h:306
float X
Definition vector3.h:90
float Z
Definition vector3.h:92
float Y
Definition vector3.h:91
static float Sqrt(float val)
Definition wwmath.h:568
static float Clamp(float val, float min=0.0f, float max=1.0f)
Definition wwmath.h:208
static float Random_Float(void)
Definition wwmath.cpp:78
static float Sin(float val)
Definition wwmath.h:378
#define DEFINE_AUTO_POOL(T, BLOCKSIZE)
Definition mempool.h:160