W3DDebrisDraw.cpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. /*
  2. ** Command & Conquer Generals(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) 2001-2003 Electronic Arts Inc. //
  21. // //
  22. ////////////////////////////////////////////////////////////////////////////////
  23. // FILE: W3DDebrisDraw.cpp ////////////////////////////////////////////////////////////////////////
  24. // Author: Colin Day, November 2001
  25. // Desc: Default w3d draw module
  26. ///////////////////////////////////////////////////////////////////////////////////////////////////
  27. // INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
  28. #include "Common/FileSystem.h" // this is only here to pull in LOAD_TEST_ASSETS
  29. #include "Common/GlobalData.h"
  30. #include "Common/ThingTemplate.h"
  31. #include "Common/Xfer.h"
  32. #include "GameClient/Drawable.h"
  33. #include "GameLogic/Object.h"
  34. #include "GameClient/Shadow.h"
  35. #include "GameClient/FXList.h"
  36. #include "GameLogic/TerrainLogic.h"
  37. #include "WW3D2/HAnim.h"
  38. #include "WW3D2/HLod.h"
  39. #include "WW3D2/RendObj.h"
  40. #include "W3DDevice/GameClient/Module/W3DDebrisDraw.h"
  41. #include "W3DDevice/GameClient/W3DAssetManager.h"
  42. #include "W3DDevice/GameClient/W3DDisplay.h"
  43. #include "W3DDevice/GameClient/W3DScene.h"
  44. #include "W3DDevice/GameClient/W3DShadow.h"
  45. //-------------------------------------------------------------------------------------------------
  46. //-------------------------------------------------------------------------------------------------
  47. W3DDebrisDraw::W3DDebrisDraw(Thing *thing, const ModuleData* moduleData) : DrawModule(thing, moduleData)
  48. {
  49. m_renderObject = NULL;
  50. for (int i = 0; i < STATECOUNT; ++i)
  51. m_anims[i] = NULL;
  52. m_fxFinal = NULL;
  53. m_state = INITIAL;
  54. m_frames = 0;
  55. m_shadow = NULL;
  56. m_finalStop = false;
  57. }
  58. //-------------------------------------------------------------------------------------------------
  59. //-------------------------------------------------------------------------------------------------
  60. W3DDebrisDraw::~W3DDebrisDraw(void)
  61. {
  62. if (TheW3DShadowManager && m_shadow)
  63. {
  64. TheW3DShadowManager->removeShadow(m_shadow);
  65. m_shadow = NULL;
  66. }
  67. if (m_renderObject)
  68. {
  69. W3DDisplay::m_3DScene->Remove_Render_Object(m_renderObject);
  70. REF_PTR_RELEASE(m_renderObject);
  71. m_renderObject = NULL;
  72. }
  73. for (int i = 0; i < STATECOUNT; ++i)
  74. {
  75. REF_PTR_RELEASE(m_anims[i]);
  76. m_anims[i] = NULL;
  77. }
  78. }
  79. //-------------------------------------------------------------------------------------------------
  80. void W3DDebrisDraw::setShadowsEnabled(Bool enable)
  81. {
  82. if (m_shadow)
  83. m_shadow->enableShadowRender(enable);
  84. }
  85. //-------------------------------------------------------------------------------------------------
  86. void W3DDebrisDraw::setFullyObscuredByShroud(Bool fullyObscured)
  87. {
  88. if (m_shadow)
  89. m_shadow->enableShadowInvisible(fullyObscured);
  90. }
  91. //-------------------------------------------------------------------------------------------------
  92. //-------------------------------------------------------------------------------------------------
  93. void W3DDebrisDraw::setModelName(AsciiString name, Color color, ShadowType t)
  94. {
  95. if (m_renderObject == NULL && !name.isEmpty())
  96. {
  97. Int hexColor = 0;
  98. if (color != 0)
  99. hexColor = color | 0xFF000000;
  100. m_renderObject = W3DDisplay::m_assetManager->Create_Render_Obj(name.str(), getDrawable()->getScale(), hexColor);
  101. DEBUG_ASSERTCRASH(m_renderObject, ("Debris model %s not found!\n",name.str()));
  102. if (m_renderObject)
  103. {
  104. W3DDisplay::m_3DScene->Add_Render_Object(m_renderObject);
  105. m_renderObject->Set_User_Data(getDrawable()->getDrawableInfo());
  106. Matrix3D transform;
  107. ///@todo: Change back to identity once we figure out why objects show up at 0,0,0
  108. /// OBJECT_PILE
  109. // transform.Set(Vector3(0,0,9999));
  110. transform.Set(Vector3(0,0,0));
  111. m_renderObject->Set_Transform(transform);
  112. }
  113. if (t != SHADOW_NONE)
  114. {
  115. Shadow::ShadowTypeInfo shadowInfo;
  116. shadowInfo.m_type = t;
  117. shadowInfo.m_sizeX=0;
  118. shadowInfo.m_sizeY=0;
  119. m_shadow = TheW3DShadowManager->addShadow(m_renderObject, &shadowInfo);
  120. }
  121. else
  122. {
  123. if (TheW3DShadowManager && m_shadow)
  124. {
  125. TheW3DShadowManager->removeShadow(m_shadow);
  126. m_shadow = NULL;
  127. }
  128. }
  129. // save the model name and color
  130. m_modelName = name;
  131. m_modelColor = color;
  132. }
  133. }
  134. //-------------------------------------------------------------------------------------------------
  135. void W3DDebrisDraw::setAnimNames(AsciiString initial, AsciiString flying, AsciiString final, const FXList* finalFX)
  136. {
  137. int i;
  138. for (i = 0; i < STATECOUNT; ++i)
  139. {
  140. REF_PTR_RELEASE(m_anims[i]);
  141. m_anims[i] = NULL;
  142. }
  143. m_anims[INITIAL] = initial.isEmpty() ? NULL : W3DDisplay::m_assetManager->Get_HAnim(initial.str());
  144. m_anims[FLYING] = flying.isEmpty() ? NULL : W3DDisplay::m_assetManager->Get_HAnim(flying.str());
  145. if (stricmp(final.str(), "STOP") == 0)
  146. {
  147. m_finalStop = true;
  148. final = flying;
  149. }
  150. else
  151. {
  152. m_finalStop = false;
  153. }
  154. m_anims[FINAL] = final.isEmpty() ? NULL : W3DDisplay::m_assetManager->Get_HAnim(final.str());
  155. m_state = 0;
  156. m_frames = 0;
  157. m_fxFinal = finalFX;
  158. m_animInitial = initial;
  159. m_animFlying = flying;
  160. m_animFinal = final;
  161. }
  162. //-------------------------------------------------------------------------------------------------
  163. static Bool isAnimationComplete(RenderObjClass* r)
  164. {
  165. if (r->Class_ID() == RenderObjClass::CLASSID_HLOD)
  166. {
  167. HLodClass *hlod = (HLodClass*)r;
  168. return hlod->Is_Animation_Complete();
  169. }
  170. return true;
  171. }
  172. //-------------------------------------------------------------------------------------------------
  173. static Bool isNearlyZero(const Coord3D* vel)
  174. {
  175. const Real TINY = 0.01f;
  176. return fabs(vel->x) < TINY && fabs(vel->y) < TINY && fabs(vel->z) < TINY;
  177. }
  178. // ------------------------------------------------------------------------------------------------
  179. void W3DDebrisDraw::reactToTransformChange( const Matrix3D *oldMtx,
  180. const Coord3D *oldPos,
  181. Real oldAngle )
  182. {
  183. if( m_renderObject )
  184. m_renderObject->Set_Transform( *getDrawable()->getTransformMatrix() );
  185. }
  186. //-------------------------------------------------------------------------------------------------
  187. void W3DDebrisDraw::doDrawModule(const Matrix3D* transformMtx)
  188. {
  189. if (m_renderObject)
  190. {
  191. Matrix3D scaledTransform;
  192. if (getDrawable()->getInstanceScale() != 1.0f)
  193. { //do custom scaling of the W3D model.
  194. scaledTransform=*transformMtx;
  195. scaledTransform.Scale(getDrawable()->getInstanceScale());
  196. transformMtx = &scaledTransform;
  197. m_renderObject->Set_ObjectScale(getDrawable()->getInstanceScale());
  198. }
  199. m_renderObject->Set_Transform(*transformMtx);
  200. static const RenderObjClass::AnimMode TheAnimModes[STATECOUNT] =
  201. {
  202. RenderObjClass::ANIM_MODE_ONCE,
  203. RenderObjClass::ANIM_MODE_LOOP,
  204. RenderObjClass::ANIM_MODE_ONCE
  205. };
  206. Int oldState = m_state;
  207. Object* obj = getDrawable()->getObject();
  208. const Int MIN_FINAL_FRAMES = 3;
  209. if (m_state != FINAL && obj != NULL && !obj->isAboveTerrain() && m_frames > MIN_FINAL_FRAMES)
  210. {
  211. m_state = FINAL;
  212. }
  213. else if (m_state < FINAL && (isAnimationComplete(m_renderObject)))
  214. {
  215. ++m_state;
  216. }
  217. HAnimClass* hanim = m_anims[m_state];
  218. if (hanim != NULL && (hanim != m_renderObject->Peek_Animation() || oldState != m_state))
  219. {
  220. RenderObjClass::AnimMode m = TheAnimModes[m_state];
  221. if (m_state == FINAL)
  222. {
  223. FXList::doFXPos(m_fxFinal, getDrawable()->getPosition(), getDrawable()->getTransformMatrix(), 0, NULL, 0.0f);
  224. if (m_finalStop)
  225. m = RenderObjClass::ANIM_MODE_MANUAL;
  226. }
  227. m_renderObject->Set_Animation(hanim, 0, m);
  228. }
  229. ++m_frames;
  230. }
  231. }
  232. // ------------------------------------------------------------------------------------------------
  233. /** CRC */
  234. // ------------------------------------------------------------------------------------------------
  235. void W3DDebrisDraw::crc( Xfer *xfer )
  236. {
  237. // extend base class
  238. DrawModule::crc( xfer );
  239. } // end crc
  240. // ------------------------------------------------------------------------------------------------
  241. /** Xfer method
  242. * Version Info:
  243. * 1: Initial version */
  244. // ------------------------------------------------------------------------------------------------
  245. void W3DDebrisDraw::xfer( Xfer *xfer )
  246. {
  247. // version
  248. XferVersion currentVersion = 1;
  249. XferVersion version = currentVersion;
  250. xfer->xferVersion( &version, currentVersion );
  251. // extend base class
  252. DrawModule::xfer( xfer );
  253. // model name
  254. xfer->xferAsciiString( &m_modelName );
  255. // model color
  256. xfer->xferColor( &m_modelColor );
  257. // set the model and color
  258. if( xfer->getXferMode() == XFER_LOAD )
  259. setModelName( m_modelName, m_modelColor, SHADOW_NONE );
  260. // animation initial
  261. xfer->xferAsciiString( &m_animInitial );
  262. // anim flying
  263. xfer->xferAsciiString( &m_animFlying );
  264. // anim final
  265. xfer->xferAsciiString( &m_animFinal );
  266. // when loading, set the animations
  267. if( xfer->getXferMode() == XFER_LOAD )
  268. setAnimNames( m_animInitial, m_animFlying, m_animFinal, NULL );
  269. // state
  270. xfer->xferInt( &m_state );
  271. // frames
  272. xfer->xferInt( &m_frames );
  273. // final stop
  274. xfer->xferBool( &m_finalStop );
  275. } // end xfer
  276. // ------------------------------------------------------------------------------------------------
  277. /** Load post process */
  278. // ------------------------------------------------------------------------------------------------
  279. void W3DDebrisDraw::loadPostProcess( void )
  280. {
  281. // extend base class
  282. DrawModule::loadPostProcess();
  283. } // end loadPostProcess