projectormanager.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. /*
  2. ** Command & Conquer Renegade(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. *** 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 ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WWPhys *
  23. * *
  24. * $Archive:: /Commando/Code/wwphys/projectormanager.cpp $*
  25. * *
  26. * Original Author:: Greg Hjelstrom *
  27. * *
  28. * $Author:: Greg_h $*
  29. * *
  30. * $Modtime:: 5/14/01 7:58p $*
  31. * *
  32. * $Revision:: 17 $*
  33. * *
  34. *---------------------------------------------------------------------------------------------*
  35. * Functions: *
  36. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  37. #include "projectormanager.h"
  38. #include "colmathaabox.h"
  39. #include "pscene.h"
  40. #include "assetmgr.h"
  41. #include "chunkio.h"
  42. #include "phystexproject.h"
  43. #include "phys.h"
  44. #include "texture.h"
  45. /*
  46. ** load up a texture. also strips off the path since the game has everything
  47. ** on one place
  48. */
  49. TextureClass * create_projector_texture_from_filename( const char * filename )
  50. {
  51. StringClass tex_name = filename;
  52. if (::strchr(tex_name, '\\') != 0) {
  53. tex_name = ::strrchr(filename, '\\') + 1;
  54. }
  55. TextureClass * texture = WW3DAssetManager::Get_Instance()->Get_Texture(tex_name,TextureClass::MIP_LEVELS_1);
  56. if (texture == NULL) {
  57. WWDEBUG_SAY(("Failed to create %s from %s\n", (const char *)tex_name, filename));
  58. }
  59. return texture;
  60. }
  61. /********************************************************************************************
  62. **
  63. ** ProjectorManagerClass Implementation
  64. **
  65. ********************************************************************************************/
  66. ProjectorManagerClass::ProjectorManagerClass(void) :
  67. Projector(NULL),
  68. ProjectorBoneIndex(0)
  69. {
  70. }
  71. ProjectorManagerClass::~ProjectorManagerClass(void)
  72. {
  73. Free();
  74. }
  75. void ProjectorManagerClass::Free(void)
  76. {
  77. if (Projector) {
  78. PhysicsSceneClass::Get_Instance()->Remove_Texture_Projector(Projector);
  79. Projector->Release_Ref();
  80. Projector = NULL;
  81. }
  82. ProjectorBoneIndex = 0;
  83. }
  84. void ProjectorManagerClass::Init(const ProjectorManagerDefClass & def,RenderObjClass * model)
  85. {
  86. Free();
  87. WWASSERT(Projector == NULL);
  88. if (model == NULL) {
  89. return;
  90. }
  91. if (def.IsEnabled) {
  92. /*
  93. ** Create the projector
  94. */
  95. Projector = NEW_REF(PhysTexProjectClass, ());
  96. Projector->Peek_Material_Pass()->Enable_On_Translucent_Meshes(false);
  97. if (Projector != NULL) {
  98. /*
  99. ** Set up projection parameters
  100. */
  101. if (def.IsPerspective) {
  102. Projector->Set_Perspective_Projection( def.HorizontalFOV,
  103. def.VerticalFOV,
  104. def.NearZ,
  105. def.FarZ);
  106. } else {
  107. Projector->Set_Ortho_Projection( -def.OrthoWidth * 0.5f,def.OrthoWidth * 0.5f,
  108. -def.OrthoHeight * 0.5f,def.OrthoHeight * 0.5f,
  109. def.NearZ,def.FarZ);
  110. }
  111. /*
  112. ** Set up the blending
  113. */
  114. if (def.IsAdditive) {
  115. Projector->Init_Additive();
  116. } else {
  117. Projector->Init_Multiplicative();
  118. }
  119. Projector->Set_Intensity(def.Intensity);
  120. /*
  121. ** Install the texture
  122. */
  123. TextureClass * tex = create_projector_texture_from_filename(def.TextureName);
  124. if (tex != NULL) {
  125. tex->Set_U_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
  126. tex->Set_V_Addr_Mode(TextureClass::TEXTURE_ADDRESS_CLAMP);
  127. Projector->Set_Texture(tex);
  128. tex->Release_Ref();
  129. } else {
  130. Projector->Release_Ref();
  131. Projector = NULL;
  132. }
  133. }
  134. /*
  135. ** If the projector is animated, resolve the bone name into a bone index and install it into the scene
  136. ** If it is not animated, add it as a static projector (for more efficient culling)
  137. */
  138. if (Projector != NULL) {
  139. /*
  140. ** Find the bone
  141. */
  142. ProjectorBoneIndex = model->Get_Bone_Index(def.BoneName);
  143. if (ProjectorBoneIndex == 0xFFFF) {
  144. ProjectorBoneIndex = 0;
  145. }
  146. Projector->Set_Transform(model->Get_Bone_Transform(ProjectorBoneIndex));
  147. Set_Flag(IS_ANIMATED,(def.IsAnimated) && (ProjectorBoneIndex != 0));
  148. if (Get_Flag(IS_ANIMATED)) {
  149. PhysicsSceneClass::Get_Instance()->Add_Dynamic_Texture_Projector(Projector);
  150. } else {
  151. PhysicsSceneClass::Get_Instance()->Add_Static_Texture_Projector(Projector);
  152. }
  153. }
  154. }
  155. }
  156. void ProjectorManagerClass::Update_From_Model(RenderObjClass * model)
  157. {
  158. if ((Projector != NULL) && (ProjectorBoneIndex != -1)) {
  159. const Matrix3D & tm = model->Get_Bone_Transform(ProjectorBoneIndex);
  160. Projector->Set_Transform(tm);
  161. }
  162. }
  163. /********************************************************************************************
  164. **
  165. ** ProjectorManagerDefClass Implementation
  166. ** Note, ProjectorManagerDef is not a full-fleged definition class. It is meant to be
  167. ** embedded inside another real definition.
  168. **
  169. ********************************************************************************************/
  170. enum
  171. {
  172. PROJECTORMANAGERDEF_CHUNK_VARIABLES = 0x01110004,
  173. PROJECTORMANAGERDEF_VARIABLE_ISENABLED = 0x00,
  174. PROJECTORMANAGERDEF_VARIABLE_ISPERSPECTIVE,
  175. PROJECTORMANAGERDEF_VARIABLE_ISADDITIVE,
  176. PROJECTORMANAGERDEF_VARIABLE_ISANIMATED,
  177. PROJECTORMANAGERDEF_VARIABLE_ORTHOWIDTH,
  178. PROJECTORMANAGERDEF_VARIABLE_ORTHOHEIGHT,
  179. PROJECTORMANAGERDEF_VARIABLE_HORIZONTALFOV,
  180. PROJECTORMANAGERDEF_VARIABLE_VERTICALFOV,
  181. PROJECTORMANAGERDEF_VARIABLE_NEARZ,
  182. PROJECTORMANAGERDEF_VARIABLE_FARZ,
  183. PROJECTORMANAGERDEF_VARIABLE_TEXTURENAME,
  184. PROJECTORMANAGERDEF_VARIABLE_BONENAME,
  185. PROJECTORMANAGERDEF_VARIABLE_INTENSITY,
  186. };
  187. ProjectorManagerDefClass::ProjectorManagerDefClass(void) :
  188. IsEnabled(false),
  189. IsPerspective(false),
  190. IsAdditive(false),
  191. IsAnimated(false),
  192. OrthoWidth(10.0f),
  193. OrthoHeight(10.0f),
  194. HorizontalFOV(DEG_TO_RADF(10.0f)),
  195. VerticalFOV(DEG_TO_RADF(10.0f)),
  196. NearZ(5.0f),
  197. FarZ(20.0f),
  198. Intensity(1.0f)
  199. {
  200. }
  201. ProjectorManagerDefClass::~ProjectorManagerDefClass(void)
  202. {
  203. }
  204. void ProjectorManagerDefClass::Validate_Parameters(void)
  205. {
  206. if (HorizontalFOV <= 0.0f) { HorizontalFOV = DEG_TO_RADF(10.0f); }
  207. if (VerticalFOV <= 0.0f) { VerticalFOV = DEG_TO_RADF(10.0f); }
  208. if (OrthoWidth <= 0.0f) { OrthoWidth = 10.0f; }
  209. if (OrthoHeight <= 0.0f) { OrthoHeight = 10.0f; }
  210. if (NearZ < 0.0f) { NearZ = 0.0f; }
  211. if (FarZ < NearZ) { FarZ = NearZ + 10.0f; }
  212. }
  213. bool ProjectorManagerDefClass::Save(ChunkSaveClass &csave)
  214. {
  215. Validate_Parameters();
  216. csave.Begin_Chunk(PROJECTORMANAGERDEF_CHUNK_VARIABLES);
  217. WRITE_MICRO_CHUNK(csave,PROJECTORMANAGERDEF_VARIABLE_ISENABLED,IsEnabled);
  218. WRITE_MICRO_CHUNK(csave,PROJECTORMANAGERDEF_VARIABLE_ISPERSPECTIVE,IsPerspective);
  219. WRITE_MICRO_CHUNK(csave,PROJECTORMANAGERDEF_VARIABLE_ISADDITIVE,IsAdditive);
  220. WRITE_MICRO_CHUNK(csave,PROJECTORMANAGERDEF_VARIABLE_ISANIMATED,IsAnimated);
  221. WRITE_MICRO_CHUNK(csave,PROJECTORMANAGERDEF_VARIABLE_ORTHOWIDTH,OrthoWidth);
  222. WRITE_MICRO_CHUNK(csave,PROJECTORMANAGERDEF_VARIABLE_ORTHOHEIGHT,OrthoHeight);
  223. WRITE_MICRO_CHUNK(csave,PROJECTORMANAGERDEF_VARIABLE_HORIZONTALFOV,HorizontalFOV);
  224. WRITE_MICRO_CHUNK(csave,PROJECTORMANAGERDEF_VARIABLE_VERTICALFOV,VerticalFOV);
  225. WRITE_MICRO_CHUNK(csave,PROJECTORMANAGERDEF_VARIABLE_NEARZ,NearZ);
  226. WRITE_MICRO_CHUNK(csave,PROJECTORMANAGERDEF_VARIABLE_FARZ,FarZ);
  227. WRITE_MICRO_CHUNK_WWSTRING(csave,PROJECTORMANAGERDEF_VARIABLE_TEXTURENAME,TextureName);
  228. WRITE_MICRO_CHUNK_WWSTRING(csave,PROJECTORMANAGERDEF_VARIABLE_BONENAME,BoneName);
  229. WRITE_MICRO_CHUNK(csave,PROJECTORMANAGERDEF_VARIABLE_INTENSITY,Intensity);
  230. csave.End_Chunk();
  231. return true;
  232. }
  233. bool ProjectorManagerDefClass::Load(ChunkLoadClass &cload)
  234. {
  235. while (cload.Open_Chunk()) {
  236. switch(cload.Cur_Chunk_ID()) {
  237. case PROJECTORMANAGERDEF_CHUNK_VARIABLES:
  238. while (cload.Open_Micro_Chunk()) {
  239. switch(cload.Cur_Micro_Chunk_ID()) {
  240. READ_MICRO_CHUNK(cload,PROJECTORMANAGERDEF_VARIABLE_ISENABLED,IsEnabled);
  241. READ_MICRO_CHUNK(cload,PROJECTORMANAGERDEF_VARIABLE_ISPERSPECTIVE,IsPerspective);
  242. READ_MICRO_CHUNK(cload,PROJECTORMANAGERDEF_VARIABLE_ISADDITIVE,IsAdditive);
  243. READ_MICRO_CHUNK(cload,PROJECTORMANAGERDEF_VARIABLE_ISANIMATED,IsAnimated);
  244. READ_MICRO_CHUNK(cload,PROJECTORMANAGERDEF_VARIABLE_ORTHOWIDTH,OrthoWidth);
  245. READ_MICRO_CHUNK(cload,PROJECTORMANAGERDEF_VARIABLE_ORTHOHEIGHT,OrthoHeight);
  246. READ_MICRO_CHUNK(cload,PROJECTORMANAGERDEF_VARIABLE_HORIZONTALFOV,HorizontalFOV);
  247. READ_MICRO_CHUNK(cload,PROJECTORMANAGERDEF_VARIABLE_VERTICALFOV,VerticalFOV);
  248. READ_MICRO_CHUNK(cload,PROJECTORMANAGERDEF_VARIABLE_NEARZ,NearZ);
  249. READ_MICRO_CHUNK(cload,PROJECTORMANAGERDEF_VARIABLE_FARZ,FarZ);
  250. READ_MICRO_CHUNK_WWSTRING(cload,PROJECTORMANAGERDEF_VARIABLE_TEXTURENAME,TextureName);
  251. READ_MICRO_CHUNK_WWSTRING(cload,PROJECTORMANAGERDEF_VARIABLE_BONENAME,BoneName);
  252. READ_MICRO_CHUNK(cload,PROJECTORMANAGERDEF_VARIABLE_INTENSITY,Intensity);
  253. }
  254. cload.Close_Micro_Chunk();
  255. }
  256. break;
  257. default:
  258. WWDEBUG_SAY(("Unhandled Chunk: 0x%X File: %s Line: %d\r\n",cload.Cur_Chunk_ID(),__FILE__,__LINE__));
  259. break;
  260. }
  261. cload.Close_Chunk();
  262. }
  263. return true;
  264. }