W3DProjectileStreamDraw.cpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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: W3DProjectileStreamDraw.cpp ////////////////////////////////////////////////////////////
  24. // Tile a texture strung between Projectiles
  25. // Graham Smallwood, May 2002
  26. /////////////////////////////////////////////////////////////////////////////////////////////////
  27. #include "Common/Xfer.h"
  28. #include "GameClient/Drawable.h"
  29. #include "GameLogic/Object.h"
  30. #include "W3DDevice/GameClient/Module/W3DProjectileStreamDraw.h"
  31. #include "W3DDevice/GameClient/W3DDisplay.h"
  32. #include "W3DDevice/GameClient/W3DScene.h"
  33. #include "WW3D2/AssetMgr.h"
  34. #include "WW3D2/Segline.h"
  35. #include "WWMath/Vector3.h"
  36. //-------------------------------------------------------------------------------------------------
  37. W3DProjectileStreamDrawModuleData::W3DProjectileStreamDrawModuleData()
  38. {
  39. m_textureName = "";
  40. m_width = 0.0f;
  41. m_tileFactor = 0.0f;
  42. m_scrollRate = 0.0f;
  43. m_maxSegments = 0;
  44. }
  45. //-------------------------------------------------------------------------------------------------
  46. W3DProjectileStreamDrawModuleData::~W3DProjectileStreamDrawModuleData()
  47. {
  48. }
  49. //-------------------------------------------------------------------------------------------------
  50. void W3DProjectileStreamDrawModuleData::buildFieldParse(MultiIniFieldParse& p)
  51. {
  52. ModuleData::buildFieldParse(p);
  53. static const FieldParse dataFieldParse[] =
  54. {
  55. { "Texture", INI::parseAsciiString, NULL, offsetof(W3DProjectileStreamDrawModuleData, m_textureName) },
  56. { "Width", INI::parseReal, NULL, offsetof(W3DProjectileStreamDrawModuleData, m_width) },
  57. { "TileFactor", INI::parseReal, NULL, offsetof(W3DProjectileStreamDrawModuleData, m_tileFactor) },
  58. { "ScrollRate", INI::parseReal, NULL, offsetof(W3DProjectileStreamDrawModuleData, m_scrollRate) },
  59. { "MaxSegments", INI::parseInt, NULL, offsetof(W3DProjectileStreamDrawModuleData, m_maxSegments) },
  60. { 0, 0, 0, 0 }
  61. };
  62. p.add(dataFieldParse);
  63. }
  64. //-------------------------------------------------------------------------------------------------
  65. //-------------------------------------------------------------------------------------------------
  66. W3DProjectileStreamDraw::~W3DProjectileStreamDraw()
  67. {
  68. for( Int lineIndex = 0; lineIndex < m_linesValid; lineIndex++ )
  69. {
  70. SegmentedLineClass *deadLine = m_allLines[lineIndex];
  71. if (deadLine)
  72. { if (deadLine->Peek_Scene())
  73. W3DDisplay::m_3DScene->Remove_Render_Object( deadLine );
  74. REF_PTR_RELEASE( deadLine );
  75. }
  76. }
  77. REF_PTR_RELEASE( m_texture );
  78. }
  79. //-------------------------------------------------------------------------------------------------
  80. //-------------------------------------------------------------------------------------------------
  81. W3DProjectileStreamDraw::W3DProjectileStreamDraw( Thing *thing, const ModuleData* moduleData ) : DrawModule( thing, moduleData )
  82. {
  83. const W3DProjectileStreamDrawModuleData* d = getW3DProjectileStreamDrawModuleData();
  84. m_texture = WW3DAssetManager::Get_Instance()->Get_Texture( d->m_textureName.str() );
  85. for( Int index = 0; index < MAX_PROJECTILE_STREAM; index++ )
  86. m_allLines[index] = NULL;
  87. m_linesValid = 0;
  88. }
  89. void W3DProjectileStreamDraw::setFullyObscuredByShroud(Bool fullyObscured)
  90. {
  91. if (fullyObscured)
  92. { //we need to remove all our lines from the scene because they are hidden
  93. for( Int lineIndex = 0; lineIndex < m_linesValid; lineIndex++ )
  94. {
  95. SegmentedLineClass *deadLine = m_allLines[lineIndex];
  96. if (deadLine && deadLine->Peek_Scene())
  97. deadLine->Remove();
  98. }
  99. }
  100. else
  101. { //we need to restore lines into scene
  102. for( Int lineIndex = 0; lineIndex < m_linesValid; lineIndex++ )
  103. {
  104. SegmentedLineClass *deadLine = m_allLines[lineIndex];
  105. if (deadLine && !deadLine->Peek_Scene())
  106. W3DDisplay::m_3DScene->Add_Render_Object(deadLine);
  107. }
  108. }
  109. }
  110. //-------------------------------------------------------------------------------------------------
  111. /** Map behavior states into W3D animations. */
  112. //-------------------------------------------------------------------------------------------------
  113. void W3DProjectileStreamDraw::doDrawModule(const Matrix3D* )
  114. {
  115. // get object from logic
  116. Object *me = getDrawable()->getObject();
  117. if (me == NULL)
  118. return;
  119. static NameKeyType key_ProjectileStreamUpdate = NAMEKEY("ProjectileStreamUpdate");
  120. ProjectileStreamUpdate* update = (ProjectileStreamUpdate*)me->findUpdateModule(key_ProjectileStreamUpdate);
  121. const W3DProjectileStreamDrawModuleData *data = getW3DProjectileStreamDrawModuleData();
  122. Vector3 allPoints[MAX_PROJECTILE_STREAM];
  123. Int pointsUsed;
  124. update->getAllPoints( allPoints, &pointsUsed );
  125. Vector3 stagingPoints[MAX_PROJECTILE_STREAM];
  126. Vector3 zeroVector(0, 0, 0);
  127. Int linesMade = 0;
  128. Int currentMasterPoint = 0;
  129. UnsignedInt currentStagingPoint = 0;
  130. if( data->m_maxSegments )
  131. {
  132. // If I have a drawing cap, I need to increase the start point in the array. The furthest (oldest)
  133. // point from the tank is in spot zero.
  134. currentMasterPoint = pointsUsed - data->m_maxSegments;
  135. currentMasterPoint = max( 0, currentMasterPoint ); // (but if they say to draw more than exists, draw all)
  136. }
  137. // Okay. I have an array of ordered points that may have blanks in it. I need to copy to the staging area
  138. // until I hit a blank or the end. Then if I have a line made, I'll overwrite it, otherwise I'll make a new one.
  139. // I'll keep doing this until I run out of valid points.
  140. while( currentMasterPoint < pointsUsed )
  141. {
  142. while( currentMasterPoint < pointsUsed && allPoints[currentMasterPoint] != zeroVector )
  143. {
  144. // While I am not looking at a bad point (off edge or zero)
  145. stagingPoints[currentStagingPoint] = allPoints[currentMasterPoint];// copy to the staging
  146. currentStagingPoint++;// increment how many I have
  147. currentMasterPoint++;// increment what I am looking at
  148. }
  149. // Use or reuse a line
  150. if( currentStagingPoint > 1 )
  151. {
  152. // Don't waste a line on a double hole (0) or a one point line (1)
  153. makeOrUpdateLine( stagingPoints, currentStagingPoint, linesMade );
  154. linesMade++;// keep track of how many are real this frame
  155. }
  156. currentMasterPoint++;//I am either pointed off the edge anyway, or I am pointed at a zero I want to skip
  157. currentStagingPoint = 0;//start over in the staging area
  158. }
  159. Int oldLinesValid = m_linesValid;
  160. for( Int lineIndex = linesMade; lineIndex < oldLinesValid; lineIndex++ )
  161. {
  162. // Delete any line we aren't using anymore.
  163. SegmentedLineClass *deadLine = m_allLines[lineIndex];
  164. if (deadLine->Peek_Scene())
  165. W3DDisplay::m_3DScene->Remove_Render_Object( deadLine );
  166. REF_PTR_RELEASE( deadLine );
  167. m_allLines[lineIndex] = NULL;
  168. m_linesValid--;
  169. }
  170. }
  171. void W3DProjectileStreamDraw::makeOrUpdateLine( Vector3 *points, UnsignedInt pointCount, Int lineIndex )
  172. {
  173. Bool newLine = FALSE;
  174. if( m_allLines[lineIndex] == NULL )
  175. {
  176. //Need a new one if this is blank, otherwise I'll reset the existing one
  177. m_allLines[lineIndex] = NEW SegmentedLineClass;
  178. m_linesValid++;
  179. newLine = TRUE;
  180. }
  181. SegmentedLineClass *line = m_allLines[lineIndex];
  182. line->Set_Points(pointCount, points); //tell the line which points to use
  183. if( newLine )
  184. {
  185. // This is one time stuff we only need to do if this is a new and not a change
  186. const W3DProjectileStreamDrawModuleData *data = getW3DProjectileStreamDrawModuleData();
  187. line->Set_Texture(m_texture); //set the texture
  188. line->Set_Shader(ShaderClass::_PresetAdditiveSpriteShader); //pick the alpha blending mode you want - see shader.h for others.
  189. line->Set_Width(data->m_width); //set line width in world units
  190. line->Set_Texture_Mapping_Mode(SegLineRendererClass::TILED_TEXTURE_MAP); //this tiles the texture across the line
  191. line->Set_Texture_Tile_Factor(data->m_tileFactor); //number of times to tile texture across each segment
  192. line->Set_UV_Offset_Rate(Vector2(0.0f,data->m_scrollRate)); //amount to scroll texture on each draw
  193. W3DDisplay::m_3DScene->Add_Render_Object( line); //add it to our scene so it gets rendered with other objects.
  194. }
  195. }
  196. // ------------------------------------------------------------------------------------------------
  197. /** CRC */
  198. // ------------------------------------------------------------------------------------------------
  199. void W3DProjectileStreamDraw::crc( Xfer *xfer )
  200. {
  201. // extend base class
  202. DrawModule::crc( xfer );
  203. } // end crc
  204. // ------------------------------------------------------------------------------------------------
  205. /** Xfer method
  206. * Version Info:
  207. * 1: Initial version */
  208. // ------------------------------------------------------------------------------------------------
  209. void W3DProjectileStreamDraw::xfer( Xfer *xfer )
  210. {
  211. // version
  212. XferVersion currentVersion = 1;
  213. XferVersion version = currentVersion;
  214. xfer->xferVersion( &version, currentVersion );
  215. // extend base class
  216. DrawModule::xfer( xfer );
  217. // Graham says there is no data that needs saving here
  218. } // end xfer
  219. // ------------------------------------------------------------------------------------------------
  220. /** Load post process */
  221. // ------------------------------------------------------------------------------------------------
  222. void W3DProjectileStreamDraw::loadPostProcess( void )
  223. {
  224. // extend base class
  225. DrawModule::loadPostProcess();
  226. } // end loadPostProcess