| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- /*
- ** Command & Conquer Generals Zero Hour(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** 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 ***
- ***********************************************************************************************
- * *
- * Project Name : WWPhys *
- * *
- * $Archive:: /Commando/Code/wwphys/camerashakesystem.cpp $*
- * *
- * Original Author:: Greg Hjelstrom *
- * *
- * $Author:: Greg_h $*
- * *
- * $Modtime:: 6/12/01 10:25a $*
- * *
- * $Revision:: 3 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <assetmgr.h>
- #include <texture.h>
- #include <tri.h>
- #include <colmath.h>
- #include <coltest.h>
- #include <rinfo.h>
- #include <camera.h>
- #include <d3dx8core.h>
- #include "Common/GlobalData.h"
- #include "Common/PerfTimer.h"
- #include "GameClient/TerrainVisual.h"
- #include "GameClient/View.h"
- #include "GameClient/Water.h"
- #include "GameLogic/AIPathfind.h"
- #include "GameLogic/TerrainLogic.h"
- #include "W3DDevice/GameClient/TerrainTex.h"
- #include "W3DDevice/GameClient/W3DDynamicLight.h"
- #include "W3DDevice/GameClient/W3DScene.h"
- #include "W3DDevice/GameClient/W3DTerrainTracks.h"
- #include "W3DDevice/GameClient/W3DBibBuffer.h"
- #include "W3DDevice/GameClient/W3DTreeBuffer.h"
- #include "W3DDevice/GameClient/W3DRoadBuffer.h"
- #include "W3DDevice/GameClient/W3DBridgeBuffer.h"
- #include "W3DDevice/GameClient/W3DWaypointBuffer.h"
- #include "W3DDevice/GameClient/W3DCustomEdging.h"
- #include "W3DDevice/GameClient/WorldHeightMap.h"
- #include "W3DDevice/GameClient/W3DShaderManager.h"
- #include "W3DDevice/GameClient/W3DShadow.h"
- #include "W3DDevice/GameClient/W3DWater.h"
- #include "W3DDevice/GameClient/W3DShroud.h"
- #include "WW3D2/DX8Wrapper.h"
- #include "WW3D2/Light.h"
- #include "WW3D2/Scene.h"
- #include "W3DDevice/GameClient/W3DPoly.h"
- #include "W3DDevice/GameClient/W3DCustomScene.h"
- #include "W3DDevice/GameClient/camerashakesystem.h"
- #include "WW3D2/Camera.h"
- //#include "W3DDevice/GameClient/camera.h"
- //#include "W3DDevice/GameClient/wwmemlog.h"
- /*
- ** (gth) According to my "research" the artists say that there are several factors that
- ** go into a good camera shake.
- ** - The motion should be sinusoidal.
- ** - Camera rotation is more effective than camera motion (good, I won't use any translation)
- ** - The camera should pitch up and down a lot more than it yaws left and right.
- */
- DEFINE_AUTO_POOL(CameraShakeSystemClass::CameraShakerClass,256);
- const float MIN_OMEGA = DEG_TO_RADF(12.5f*360.0f);
- const float MAX_OMEGA = DEG_TO_RADF(15.0f*360.0f);
- const float END_OMEGA = DEG_TO_RADF(360.0f);
- const float MIN_PHI = DEG_TO_RADF(0.0f);
- const float MAX_PHI = DEG_TO_RADF(360.0f);
- const Vector3 AXIS_ROTATION = Vector3(DEG_TO_RADF(7.5f),DEG_TO_RADF(15.0f),DEG_TO_RADF(5.0f));
- /************************************************************************************************
- **
- ** CameraShakeSystemClass::CameraShakerClass Implementation
- **
- ************************************************************************************************/
- CameraShakeSystemClass::CameraShakerClass::CameraShakerClass
- (
- const Vector3 & position,
- float radius,
- float duration,
- float intensity
- ) :
- Position(position),
- Radius(radius),
- Duration(duration),
- Intensity(intensity),
- ElapsedTime(0.0f)
- {
- /*
- ** Initialize random sinusoid values
- */
- Omega.X = WWMath::Random_Float(MIN_OMEGA,MAX_OMEGA);
- Omega.Y = WWMath::Random_Float(MIN_OMEGA,MAX_OMEGA);
- Omega.Z = WWMath::Random_Float(MIN_OMEGA,MAX_OMEGA);
- Phi.X = WWMath::Random_Float(MIN_PHI,MAX_PHI);
- Phi.Y = WWMath::Random_Float(MIN_PHI,MAX_PHI);
- Phi.Z = WWMath::Random_Float(MIN_PHI,MAX_PHI);
- }
- CameraShakeSystemClass::CameraShakerClass::~CameraShakerClass(void)
- {
- }
- void CameraShakeSystemClass::CameraShakerClass::Compute_Rotations(const Vector3 & camera_position, Vector3 * set_angles)
- {
- WWASSERT(set_angles != NULL);
- /*
- ** We want several different sinusiods, each with a different phase shift and
- ** frequency. The frequency is a function of time as well, stretching the
- ** sine wave out. These waves are modulated based on the distance from the
- ** center of the "shake", the intensity of the shake, and based on the axis
- ** being affected. The vertical axis should have about 3x the amplitude of
- ** the horizontal axis.
- */
- float len2 = (camera_position - Position).Length2();
- if (len2 > Radius*Radius) {
- return;
- }
- /*
- ** f(t) = intensity(t,pos) * sin( omega(t) * t + phi );
- ** intensity(t,pos) = intensity * (radius/distance) * timeremaing/totaltime
- ** omega(t) = start_omega + (end_omega - start_omega) * t
- ** phi = random(0..start_omega)
- */
- float intensity = Intensity * (1.0f - WWMath::Sqrt(len2) / Radius) * (1.0f - ElapsedTime / Duration);
- for (int i=0; i<3; i++) {
- float omega = Omega[i] + (END_OMEGA - Omega[i]) * ElapsedTime;
- (*set_angles)[i] += AXIS_ROTATION[i] * intensity * WWMath::Sin(omega * ElapsedTime + Phi[i]);
- //WST 11/14/2002. Add in additional random fudge. There seems to be a too mathematical pattern of shake with the above
- Vector3 secondary_angles;
- float minor_intensity = intensity * 0.5f;
- secondary_angles.X = WWMath::Random_Float(-minor_intensity,minor_intensity);
- secondary_angles.Y = WWMath::Random_Float(-minor_intensity,minor_intensity);
- secondary_angles.Z = WWMath::Random_Float(-minor_intensity,minor_intensity);
- (*set_angles) += secondary_angles;
- }
- }
- /************************************************************************************************
- **
- ** CameraShakeSystemClass Implementation
- **
- ************************************************************************************************/
- CameraShakeSystemClass::CameraShakeSystemClass(void)
- {
- }
- CameraShakeSystemClass::~CameraShakeSystemClass(void)
- {
- /*
- ** delete all of the objects out of the list
- */
- while (!CameraShakerList.Is_Empty()) {
- CameraShakerClass * obj = CameraShakerList.Remove_Head();
- CameraShakerList.Remove(obj);
- delete obj;
- }
- }
- void CameraShakeSystemClass::Add_Camera_Shake
- (
- const Vector3 & position,
- float radius,
- float duration,
- float power
- )
- {
- //WWMEMLOG(MEM_PHYSICSDATA);
- /*
- ** Allocate a new camera shaker object. Note that these are mem-pooled so the allocation
- ** is very cheap.
- */
- //Power is in degrees of amplitude.
- power = power * PI/180.0f;
- CameraShakerClass * shaker = new CameraShakerClass(position,radius,duration,power);
- CameraShakerList.Add(shaker);
- }
- bool CameraShakeSystemClass::IsCameraShaking(void)
- {
- /*
- ** Loop through to find if there is any active camera shakers
- */
- MultiListIterator<CameraShakerClass> iterator(&CameraShakerList);
- for (iterator.First(); !iterator.Is_Done(); iterator.Next()) {
- CameraShakerClass * obj = iterator.Peek_Obj();
- if (obj){
- return (true);
- }
- }
- return(false);
- }
- void CameraShakeSystemClass::Timestep(float dt)
- {
- /*
- ** Allow each camera shaker to timestep. Any that expire are added to a temporary
- ** list for deletion.
- */
- MultiListClass<CameraShakerClass> deletelist;
- MultiListIterator<CameraShakerClass> iterator(&CameraShakerList);
- for (iterator.First(); !iterator.Is_Done(); iterator.Next()) {
- CameraShakerClass * obj = iterator.Peek_Obj();
- obj->Timestep(dt);
- if (obj->Is_Expired()) {
- deletelist.Add(obj);
- }
- }
- /*
- ** Remove and delete all the ones that expired
- */
- while (!deletelist.Is_Empty()) {
- CameraShakerClass * obj = deletelist.Remove_Head();
- CameraShakerList.Remove(obj);
- delete obj;
- }
- }
- void CameraShakeSystemClass::Update_Camera_Shaker(Vector3 camera_position, Vector3 *shaker_angle)
- {
- MultiListIterator<CameraShakerClass> iterator(&CameraShakerList);
-
- Vector3 angles(0,0,0);
- Matrix3D camera_transform;
- //camera_transform = camera.Get_Transform();
- //camera_transform.Get_Translation(&camera_position);
- /*
- ** Accumulate the effects of any active camera shakers
- */
- for (iterator.First(); !iterator.Is_Done(); iterator.Next()) {
- iterator.Peek_Obj()->Compute_Rotations(camera_position,&angles);
- }
- /*
- ** Clamp the result
- */
- for (int i=0; i<3; i++) {
- WWMath::Clamp(angles[i],-AXIS_ROTATION[i],AXIS_ROTATION[i]);
- }
-
- *shaker_angle = angles;
- /*
- ** Apply to the camera
- */
- /*
- camera_transform.Rotate_X(angles.X);
- camera_transform.Rotate_Y(angles.Y);
- camera_transform.Rotate_Z(angles.Z);
- camera.Set_Transform(camera_transform);
- */
- }
- // The Instance of the system
- CameraShakeSystemClass CameraShakerSystem; //WST 11/12/2002 This is the new Camera Shaker system upgrade
|