ringobj.cpp 66 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517
  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. *** 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 : WW3D *
  23. * *
  24. * $Archive:: /Commando/Code/ww3d2/ringobj.cpp $*
  25. * *
  26. * Author:: Greg Hjelstrom *
  27. * *
  28. * $Modtime:: 7/05/01 4:15p $*
  29. * *
  30. * $Revision:: 26 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * RingRenderObjClass::RingRenderObjClass -- Constructor *
  35. * RingRenderObjClass::RingRenderObjClass -- Constructor - init from a definition *
  36. * RingRenderObjClass::RingRenderObjClass -- Copy constructor *
  37. * RingRenderObjClass::~RingRenderObjClass -- destructor *
  38. * RingRenderObjClass::operator -- assignment operator *
  39. * RingRenderObjClass::Get_Num_Polys -- returns number of polygons *
  40. * RingRenderObjClass::Get_Name -- returns name *
  41. * RingRenderObjClass::Set_Name -- sets the name *
  42. * RingRenderObjClass::Set_Color -- Sets the color of the Ring *
  43. * RingRenderObjClass::Init_Ring_Render_System -- global initialization needed for Ring *
  44. * RingRenderObjClass::Shutdown_Ring_Render_System -- cleanup Ring render system *
  45. * RingRenderObjClass::Set_Ring_Display_Mask -- Sets global display mask for all Ringes *
  46. * RingRenderObjClass::Get_Ring_Display_Mask -- returns the display mask *
  47. * RingRenderObjClass::update_mesh_data -- Updates vertex positions, etc *
  48. * RingRenderObjClass::render_Ring -- submits the Ring to the GERD *
  49. * RingRenderObjClass::vis_render_Ring -- submits Ring to the GERD for VIS *
  50. * RingRenderObjClass::RingRenderObjClass -- constructor *
  51. * RingRenderObjClass::RingRenderObjClass -- Constructor - init from a definition *
  52. * RingRenderObjClass::RingRenderObjClass -- copy constructor *
  53. * RingRenderObjClass::RingRenderObjClass -- Constructor from a wwmath aaRing *
  54. * RingRenderObjClass::operator -- assignment operator *
  55. * RingRenderObjClass::Clone -- clones the Ring *
  56. * RingRenderObjClass::Class_ID -- returns the class-id for AARing's *
  57. * RingRenderObjClass::Render -- render this Ring *
  58. * RingRenderObjClass::Special_Render -- special render this Ring (vis) *
  59. * RingRenderObjClass::Set_Transform -- set the transform for this Ring *
  60. * RingRenderObjClass::Set_Position -- Set the position of this Ring *
  61. * RingRenderObjClass::update_cached_Ring -- update the world-space version of this Ring *
  62. * RingRenderObjClass::Cast_Ray -- cast a ray against this Ring *
  63. * RingRenderObjClass::Cast_AARing -- cast an AARing against this Ring *
  64. * RingRenderObjClass::Cast_OBRing -- cast an OBRing against this Ring *
  65. * RingRenderObjClass::Get_Obj_Space_Bounding_Ring -- return the object-space bounding sp *
  66. * RingRenderObjClass::Get_Obj_Space_Bounding_Ring -- returns the obj-space bounding Sphe *
  67. * RingRenderObjClass::Update_Cached_Bounding_Volumes -- Updates world-space bounding volum *
  68. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  69. #include "ringobj.h"
  70. #include "w3d_util.h"
  71. #include "wwdebug.h"
  72. #include "vertmaterial.h"
  73. #include "ww3d.h"
  74. #include "chunkio.h"
  75. #include "rinfo.h"
  76. #include "coltest.h"
  77. #include "inttest.h"
  78. #include "matrix3.h"
  79. #include "wwmath.h"
  80. #include "assetmgr.h"
  81. #include "wwstring.h"
  82. #include "camera.h"
  83. #include "statistics.h"
  84. #include "dx8wrapper.h"
  85. #include "dx8indexbuffer.h"
  86. #include "dx8vertexbuffer.h"
  87. #include "sortingrenderer.h"
  88. #include "vector3i.h"
  89. #include "visrasterizer.h"
  90. #define RING_NUM_LOD (20)
  91. #define RING_LOWEST_LOD (3)
  92. #define RING_HIGHEST_LOD (30)
  93. #define STATIC_SORT_RINGS 1 // makes all ring use a static sort level rather than per-poly sorting
  94. #define RING_SORT_LEVEL 1 // the static sort level for all rings (when enabled)
  95. static bool Ring_Array_Valid = false;
  96. /**
  97. ** RingMeshClass
  98. ** A set of LODs of RingMeshes are re-used by all RingRenderObjClasses.
  99. */
  100. class RingMeshClass
  101. {
  102. friend class RingRenderObjClass;
  103. public:
  104. // Constructor
  105. RingMeshClass(void);
  106. RingMeshClass(float radius, int slices);
  107. // Destructor
  108. ~RingMeshClass(void);
  109. void Generate(float radius, int slices);
  110. int Get_Num_Polys(void) { return face_ct; };
  111. void Scale (const Vector2 &inner_scale, const Vector2 &outer_scale);
  112. void Set_Tiling (int count);
  113. private:
  114. void Free(void);
  115. float Radius;
  116. int Slices;
  117. int face_ct; //# of faces
  118. int TileCount;
  119. Vector2 InnerScale;
  120. Vector2 OuterScale;
  121. int Vertex_ct; // vertex count
  122. Vector3 *vtx; // array of vertices
  123. Vector2 *orig_vtx; // array of vertices representing a 'unit' ring
  124. Vector3 *vtx_normal; // array of vertex normals
  125. Vector2 *vtx_uv; // array of vertex uv coordinates
  126. Vector3i *tri_poly; // array of triangle polys, vertex indices (can be discard if switch to fan renderer)
  127. };
  128. RingMeshClass RingMeshArray[RING_NUM_LOD];
  129. /*
  130. ** RingRenderObjClass Implementation
  131. */
  132. /***********************************************************************************************
  133. * RingRenderObjClass::RingRenderObjClass -- Constructor *
  134. * *
  135. * INPUT: *
  136. * *
  137. * OUTPUT: *
  138. * *
  139. * WARNINGS: *
  140. * *
  141. * HISTORY: *
  142. * 1/19/00 gth : Created. *
  143. *=============================================================================================*/
  144. RingRenderObjClass::RingRenderObjClass(void)
  145. : anim_time (0.0F),
  146. IsAnimating(false),
  147. AnimDuration (0.0F),
  148. RingMaterial (NULL),
  149. RingTexture (NULL),
  150. Color (0.75F,0.75F,0.75F),
  151. InnerScale (1, 1),
  152. OuterScale (1, 1),
  153. Alpha (1.0F),
  154. Flags(0),
  155. TextureTileCount(5),
  156. ObjSpaceCenter (0, 0, 0),
  157. ObjSpaceExtent (1, 1, 1),
  158. InnerExtent (0.5F, 0.5F),
  159. OuterExtent (1.0F, 1.0F),
  160. CurrentLOD (RING_NUM_LOD - 1)
  161. {
  162. Generate_Shared_Mesh_Arrays ();
  163. memset(Name,0,sizeof(Name));
  164. Init_Material () ;
  165. #if (STATIC_SORT_RINGS)
  166. // (gth) testing whether we can get away without poly-sorting rings and spheres
  167. Set_Sort_Level(RING_SORT_LEVEL);
  168. #endif
  169. }
  170. /***********************************************************************************************
  171. * RingRenderObjClass::RingRenderObjClass -- Constructor - init from a definition *
  172. * *
  173. * INPUT: *
  174. * *
  175. * OUTPUT: *
  176. * *
  177. * WARNINGS: *
  178. * *
  179. * HISTORY: *
  180. * 1/19/00 gth : Created. *
  181. *=============================================================================================*/
  182. RingRenderObjClass::RingRenderObjClass(const W3dRingStruct & def)
  183. : anim_time (0.0F),
  184. IsAnimating(false),
  185. AnimDuration (0.0F),
  186. RingMaterial (NULL),
  187. RingTexture (NULL),
  188. Color (0.75F,0.75F,0.75F),
  189. InnerScale (1, 1),
  190. OuterScale (1, 1),
  191. Alpha (1.0F),
  192. Flags(0),
  193. TextureTileCount(5),
  194. ObjSpaceCenter (0, 0, 0),
  195. ObjSpaceExtent (1, 1, 1),
  196. InnerExtent (0.5F, 0.5F),
  197. OuterExtent (1.0F, 1.0F),
  198. CurrentLOD (RING_NUM_LOD - 1)
  199. {
  200. Generate_Shared_Mesh_Arrays ();
  201. Init_Material ();
  202. //
  203. // Initialize from the defintion
  204. //
  205. Set_Name(def.Name);
  206. Set_Local_Center_Extent ( Vector3 (def.Center.X, def.Center.Y, def.Center.Z),
  207. Vector3 (def.Extent.X, def.Extent.Y, def.Extent.Z));
  208. if (def.TextureName[0] != 0) {
  209. RingTexture = WW3DAssetManager::Get_Instance ()->Get_Texture (def.TextureName);
  210. }
  211. #if (STATIC_SORT_RINGS)
  212. // (gth) testing whether we can get away without poly-sorting rings and spheres
  213. Set_Sort_Level(RING_SORT_LEVEL);
  214. #endif
  215. }
  216. /***********************************************************************************************
  217. * RingRenderObjClass::RingRenderObjClass -- Copy constructor *
  218. * *
  219. * INPUT: *
  220. * *
  221. * OUTPUT: *
  222. * *
  223. * WARNINGS: *
  224. * *
  225. * HISTORY: *
  226. * 1/19/00 gth : Created. *
  227. *=============================================================================================*/
  228. RingRenderObjClass::RingRenderObjClass(const RingRenderObjClass & src)
  229. : anim_time (0.0F),
  230. IsAnimating(false),
  231. AnimDuration (0.0F),
  232. RingMaterial (NULL),
  233. RingTexture (NULL),
  234. Color (0.75F,0.75F,0.75F),
  235. InnerScale (1, 1),
  236. OuterScale (1, 1),
  237. Alpha (1.0F),
  238. Flags(0),
  239. TextureTileCount(5),
  240. ObjSpaceCenter (0, 0, 0),
  241. ObjSpaceExtent (1, 1, 1),
  242. InnerExtent (0.5F, 0.5F),
  243. OuterExtent (1.0F, 1.0F),
  244. CurrentLOD (RING_NUM_LOD - 1)
  245. {
  246. Generate_Shared_Mesh_Arrays ();
  247. Init_Material ();
  248. *this = src;
  249. #if (STATIC_SORT_RINGS)
  250. // (gth) testing whether we can get away without poly-sorting rings and spheres
  251. Set_Sort_Level(RING_SORT_LEVEL);
  252. #endif
  253. }
  254. /***********************************************************************************************
  255. * RingRenderObjClass::~RingRenderObjClass -- destructor *
  256. * *
  257. * INPUT: *
  258. * *
  259. * OUTPUT: *
  260. * *
  261. * WARNINGS: *
  262. * *
  263. * HISTORY: *
  264. * 2/7/2001 gth : Created. *
  265. *=============================================================================================*/
  266. RingRenderObjClass::~RingRenderObjClass()
  267. {
  268. REF_PTR_RELEASE(RingMaterial);
  269. REF_PTR_RELEASE(RingTexture);
  270. } // destructor
  271. /***********************************************************************************************
  272. * RingRenderObjClass::operator -- assignment operator *
  273. * *
  274. * INPUT: *
  275. * *
  276. * OUTPUT: *
  277. * *
  278. * WARNINGS: *
  279. * *
  280. * HISTORY: *
  281. * 1/19/00 gth : Created. *
  282. *=============================================================================================*/
  283. RingRenderObjClass & RingRenderObjClass::operator = (const RingRenderObjClass & that)
  284. {
  285. if (this != &that) {
  286. RenderObjClass::operator = (that);
  287. Set_Name(that.Get_Name());
  288. Color = that.Color;
  289. Alpha = that.Alpha;
  290. InnerScale = that.InnerScale;
  291. OuterScale = that.OuterScale;
  292. Flags = that.Flags;
  293. RingShader = that.RingShader;
  294. CachedBox = that.CachedBox;
  295. anim_time = that.anim_time;
  296. AnimDuration = that.AnimDuration;
  297. ObjSpaceCenter = that.ObjSpaceCenter;
  298. ObjSpaceExtent = that.ObjSpaceExtent;
  299. ColorChannel = that.ColorChannel;
  300. AlphaChannel = that.AlphaChannel;
  301. InnerScaleChannel = that.InnerScaleChannel;
  302. OuterScaleChannel = that.OuterScaleChannel;
  303. InnerExtent = that.InnerExtent;
  304. OuterExtent = that.OuterExtent;
  305. TextureTileCount = that.TextureTileCount;
  306. Set_Texture (that.RingTexture);
  307. }
  308. return *this;
  309. }
  310. /***********************************************************************************************
  311. * RingRenderObjClass::Generate_Shared_Mesh_Arrays -- Generates mesh LOD arrays. *
  312. * *
  313. * INPUT: *
  314. * *
  315. * OUTPUT: *
  316. * *
  317. * WARNINGS: *
  318. * *
  319. * HISTORY: *
  320. * 03/08/00 pds : Created. *
  321. *=============================================================================================*/
  322. void RingRenderObjClass::Generate_Shared_Mesh_Arrays (void)
  323. {
  324. // Generate shared Mesh Arrays
  325. if (!Ring_Array_Valid) {
  326. float size = RING_LOWEST_LOD;
  327. float step = (RING_HIGHEST_LOD - RING_LOWEST_LOD);
  328. step /= RING_NUM_LOD;
  329. for(int i=0; i < RING_NUM_LOD; i++) {
  330. RingMeshArray[i].Generate(1.0f, size);
  331. size+=step;
  332. }
  333. Ring_Array_Valid = true;
  334. }
  335. return ;
  336. }
  337. /***********************************************************************************************
  338. * RingRenderObjClass::Init_Material -- Sets up the material and default shader for the Ring.*
  339. * *
  340. * INPUT: *
  341. * *
  342. * OUTPUT: *
  343. * *
  344. * WARNINGS: *
  345. * *
  346. * HISTORY: *
  347. * 03/08/00 pds : Created. *
  348. *=============================================================================================*/
  349. void RingRenderObjClass::Init_Material (void)
  350. {
  351. REF_PTR_RELEASE (RingMaterial);
  352. RingMaterial = NEW_REF(VertexMaterialClass,());
  353. RingMaterial->Set_Ambient(0,0,0);
  354. RingMaterial->Set_Diffuse(0,0,0);
  355. RingMaterial->Set_Specular(0,0,0);
  356. RingMaterial->Set_Emissive(1,1,1);
  357. RingMaterial->Set_Opacity(0.25f);
  358. RingMaterial->Set_Shininess(0.0f);
  359. // Texturing, zbuffer, primary gradient, alpha blending
  360. RingShader = ShaderClass::_PresetAlphaShader;
  361. } // Init_Material
  362. /***********************************************************************************************
  363. * RingRenderObjClass::Get_Num_Polys -- returns number of polygons *
  364. * *
  365. * INPUT: *
  366. * *
  367. * OUTPUT: *
  368. * *
  369. * WARNINGS: *
  370. * *
  371. * HISTORY: *
  372. * 1/19/00 gth : Created. *
  373. *=============================================================================================*/
  374. int RingRenderObjClass::Get_Num_Polys(void) const
  375. {
  376. return RingMeshArray[ CurrentLOD ].Get_Num_Polys();
  377. }
  378. /***********************************************************************************************
  379. * RingRenderObjClass::Set_Texture *
  380. * *
  381. * INPUT: *
  382. * *
  383. * OUTPUT: *
  384. * *
  385. * WARNINGS: *
  386. * *
  387. * HISTORY: *
  388. * 1/19/00 gth : Created. *
  389. *=============================================================================================*/
  390. void RingRenderObjClass::Set_Texture(TextureClass *tf)
  391. {
  392. REF_PTR_SET(RingTexture,tf);
  393. }
  394. /***********************************************************************************************
  395. * RingRenderObjClass::Get_Name -- returns name *
  396. * *
  397. * INPUT: *
  398. * *
  399. * OUTPUT: *
  400. * *
  401. * WARNINGS: *
  402. * *
  403. * HISTORY: *
  404. * 1/19/00 gth : Created. *
  405. *=============================================================================================*/
  406. const char * RingRenderObjClass::Get_Name(void) const
  407. {
  408. return Name;
  409. }
  410. /***********************************************************************************************
  411. * RingRenderObjClass::Set_Name -- sets the name *
  412. * *
  413. * INPUT: *
  414. * *
  415. * OUTPUT: *
  416. * *
  417. * WARNINGS: *
  418. * *
  419. * HISTORY: *
  420. * 1/19/00 gth : Created. *
  421. *=============================================================================================*/
  422. void RingRenderObjClass::Set_Name(const char * name)
  423. {
  424. WWASSERT(name != NULL);
  425. WWASSERT(strlen(name) < 2*W3D_NAME_LEN);
  426. strcpy(Name,name);
  427. }
  428. /***********************************************************************************************
  429. * RingRenderObjClass::render_ring -- submits the box to the GERD *
  430. * *
  431. * INPUT: *
  432. * *
  433. * OUTPUT: *
  434. * *
  435. * WARNINGS: *
  436. * *
  437. * HISTORY: *
  438. * 1/19/00 gth : Created. *
  439. *=============================================================================================*/
  440. void RingRenderObjClass::render_ring(RenderInfoClass & rinfo,const Vector3 & center,const Vector3 & extent)
  441. {
  442. RingMeshClass & ring = RingMeshArray[ CurrentLOD ];
  443. if (RingTexture) {
  444. RingShader.Set_Texturing (ShaderClass::TEXTURING_ENABLE);
  445. } else {
  446. RingShader.Set_Texturing (ShaderClass::TEXTURING_DISABLE);
  447. }
  448. DX8Wrapper::Set_Shader(RingShader);
  449. DX8Wrapper::Set_Texture(0,RingTexture);
  450. DX8Wrapper::Set_Material(RingMaterial);
  451. DynamicVBAccessClass vb(BUFFER_TYPE_DYNAMIC_SORTING,dynamic_fvf_type,ring.Vertex_ct);
  452. {
  453. DynamicVBAccessClass::WriteLockClass Lock(&vb);
  454. VertexFormatXYZNDUV2 *vb = Lock.Get_Formatted_Vertex_Array();
  455. //
  456. // set up the vertex color+alpha
  457. //
  458. unsigned color;
  459. if (RingShader.Get_Dst_Blend_Func () == ShaderClass::DSTBLEND_ONE) {
  460. color = DX8Wrapper::Convert_Color(Alpha * Color,1.0f);
  461. } else {
  462. color = DX8Wrapper::Convert_Color(Color,Alpha);
  463. }
  464. for (int i=0; i<ring.Vertex_ct; i++)
  465. {
  466. vb->x = ring.vtx[i].X;
  467. vb->y = ring.vtx[i].Y;
  468. vb->z = ring.vtx[i].Z;
  469. vb->nx = ring.vtx_normal[i].X; // may not need this!
  470. vb->ny = ring.vtx_normal[i].Y;
  471. vb->nz = ring.vtx_normal[i].Z;
  472. vb->diffuse = color;
  473. if (RingTexture) {
  474. vb->u1 = ring.vtx_uv[i].X;
  475. vb->v1 = ring.vtx_uv[i].Y;
  476. }
  477. vb++;
  478. }
  479. }
  480. DynamicIBAccessClass ib(BUFFER_TYPE_DYNAMIC_SORTING,ring.face_ct*3);
  481. {
  482. DynamicIBAccessClass::WriteLockClass Lock(&ib);
  483. unsigned short *mem=Lock.Get_Index_Array();
  484. for (int i=0; i<ring.face_ct; i++)
  485. {
  486. mem[3*i]=ring.tri_poly[i].I;
  487. mem[3*i+1]=ring.tri_poly[i].J;
  488. mem[3*i+2]=ring.tri_poly[i].K;
  489. }
  490. }
  491. DX8Wrapper::Set_Vertex_Buffer(vb);
  492. DX8Wrapper::Set_Index_Buffer(ib,0);
  493. #if (STATIC_SORT_RINGS)
  494. DX8Wrapper::Draw_Triangles(0,ring.face_ct,0,ring.Vertex_ct);
  495. #else
  496. SortingRendererClass::Insert_Triangles(
  497. Get_Bounding_Sphere(),
  498. 0,
  499. ring.face_ct,
  500. 0,
  501. ring.Vertex_ct);
  502. #endif
  503. } // render_ring
  504. /***********************************************************************************************
  505. * RingRenderObjClass::vis_render_ring -- submits box to the GERD for VIS *
  506. * *
  507. * this renders the ring with the specified VIS-ID. *
  508. * *
  509. * INPUT: *
  510. * *
  511. * OUTPUT: *
  512. * *
  513. * WARNINGS: *
  514. * *
  515. * HISTORY: *
  516. * 1/19/00 gth : Created. *
  517. *=============================================================================================*/
  518. void RingRenderObjClass::vis_render_ring(SpecialRenderInfoClass & rinfo,const Vector3 & center,const Vector3 & extent)
  519. {
  520. WWASSERT(0);
  521. } // vis_render_ring
  522. /***********************************************************************************************
  523. * RingRenderObjClass::Clone -- clones the ring *
  524. * *
  525. * INPUT: *
  526. * *
  527. * OUTPUT: *
  528. * *
  529. * WARNINGS: *
  530. * *
  531. * HISTORY: *
  532. * 1/19/00 gth : Created. *
  533. *=============================================================================================*/
  534. RenderObjClass * RingRenderObjClass::Clone(void) const
  535. {
  536. return W3DNEW RingRenderObjClass(*this);
  537. }
  538. /***********************************************************************************************
  539. * RingRenderObjClass::Class_ID -- returns the class-id for Rings's *
  540. * *
  541. * INPUT: *
  542. * *
  543. * OUTPUT: *
  544. * *
  545. * WARNINGS: *
  546. * *
  547. * HISTORY: *
  548. * 1/19/00 gth : Created. *
  549. *=============================================================================================*/
  550. int RingRenderObjClass::Class_ID(void) const
  551. {
  552. return RenderObjClass::CLASSID_RING;
  553. }
  554. /***********************************************************************************************
  555. * RingRenderObjClass::Render -- render this box *
  556. * *
  557. * INPUT: *
  558. * *
  559. * OUTPUT: *
  560. * *
  561. * WARNINGS: *
  562. * *
  563. * HISTORY: *
  564. * 1/19/00 gth : Created. *
  565. *=============================================================================================*/
  566. void RingRenderObjClass::Render(RenderInfoClass & rinfo)
  567. {
  568. if (Is_Not_Hidden_At_All() == false) {
  569. return;
  570. }
  571. // If static sort lists are enabled and this mesh has a sort level, put it on the list instead
  572. // of rendering it.
  573. unsigned int sort_level = (unsigned int)Get_Sort_Level();
  574. if (WW3D::Are_Static_Sort_Lists_Enabled() && sort_level != SORT_LEVEL_NONE) {
  575. WW3D::Add_To_Static_Sort_List(this, sort_level);
  576. } else {
  577. // Process texture reductions:
  578. // if (RingTexture) RingTexture->Process_Reduction();
  579. // Determine LOD
  580. float screen_size = Get_Screen_Size (rinfo.Camera);
  581. // This code assumes that screen_size returns back the percentage of the screen, 0.0 = 0%, 1.0f = 100%
  582. // Currently it will use Linear interpolation over 0.0 to 1.0, with the RING_NUM_LOD
  583. // to set the CurrentLOD
  584. screen_size = sqrtf(screen_size);
  585. float lod = screen_size * ((float) RING_NUM_LOD);
  586. int lod_int = lod;
  587. lod-=lod_int;
  588. if (lod >= 0.5f) lod_int++;
  589. if (lod_int < 0) lod_int = 0;
  590. if (lod_int >= RING_NUM_LOD) lod_int = RING_NUM_LOD-1;
  591. CurrentLOD = lod_int;
  592. // End LOD Determination
  593. Matrix3D temp = Transform;
  594. // Do Time Based Animation
  595. animate ();
  596. //
  597. // Scale the inner and outer parts of the ring.
  598. //
  599. Vector2 inner_scale (InnerExtent.X * InnerScale.X, InnerExtent.Y * InnerScale.Y);
  600. Vector2 outer_scale (OuterExtent.X * OuterScale.X, OuterExtent.Y * OuterScale.Y);
  601. RingMeshArray[CurrentLOD].Scale (inner_scale, outer_scale);
  602. //
  603. // Make sure this mesh uses the correct UV tiling
  604. //
  605. if (RingTexture != NULL) {
  606. RingMeshArray[CurrentLOD].Set_Tiling (TextureTileCount);
  607. }
  608. //
  609. // Should we force the ring to be camera aligned?
  610. //
  611. if (Flags & USE_CAMERA_ALIGN) {
  612. #ifdef WW3D_DX8
  613. srMatrix4 srtm;
  614. rinfo.Gerd.matrixMode (srGERD::MODELVIEW);
  615. rinfo.Gerd.pushMatrix ();
  616. rinfo.Gerd.getMatrix (srGERD::MODELVIEW, srtm);
  617. srVector3 wpos(Transform[0][3],Transform[1][3],Transform[2][3]);
  618. srVector4 cpos = srtm.transform (wpos);
  619. Matrix3D tm(1.0f, 0.0f, 0.0f, cpos.x,
  620. 0.0f, 1.0f, 0.0f, cpos.y,
  621. 0.0f, 0.0f, 1.0f, cpos.z);
  622. Convert_Westwood_Matrix (tm, &srtm);
  623. rinfo.Gerd.loadMatrix (srtm);
  624. #endif //WW3D_DX8
  625. } else {
  626. DX8Wrapper::Set_Transform(D3DTS_WORLD,temp);
  627. }
  628. //
  629. // Pass the geometry onto Surrender
  630. //
  631. render_ring (rinfo, ObjSpaceCenter, ObjSpaceExtent);
  632. }
  633. } // Render
  634. /***********************************************************************************************
  635. * RingRenderObjClass::Get_Default_Color - get the default (or first frame) value *
  636. * *
  637. * INPUT: *
  638. * *
  639. * OUTPUT: *
  640. * *
  641. * WARNINGS: *
  642. * *
  643. * HISTORY: *
  644. * 3/13/2000 pds : Created. *
  645. *=============================================================================================*/
  646. Vector3 RingRenderObjClass::Get_Default_Color(void) const
  647. {
  648. Vector3 value;
  649. if (ColorChannel.Get_Key_Count () > 0) {
  650. value = ColorChannel.Get_Key (0).Get_Value ();
  651. } else {
  652. value = Color;
  653. }
  654. return value;
  655. }
  656. /***********************************************************************************************
  657. * RingRenderObjClass::Get_Default_Alpha - get the default (or first frame) value *
  658. * *
  659. * INPUT: *
  660. * *
  661. * OUTPUT: *
  662. * *
  663. * WARNINGS: *
  664. * *
  665. * HISTORY: *
  666. * 3/13/2000 pds : Created. *
  667. *=============================================================================================*/
  668. float RingRenderObjClass::Get_Default_Alpha(void) const
  669. {
  670. float value;
  671. if (AlphaChannel.Get_Key_Count () > 0) {
  672. value = AlphaChannel.Get_Key (0).Get_Value ();
  673. } else {
  674. value = Alpha;
  675. }
  676. return value;
  677. }
  678. /***********************************************************************************************
  679. * RingRenderObjClass::Get_Default_Inner_Scale - get the default (or first frame) value *
  680. * *
  681. * INPUT: *
  682. * *
  683. * OUTPUT: *
  684. * *
  685. * WARNINGS: *
  686. * *
  687. * HISTORY: *
  688. * 3/13/2000 pds : Created. *
  689. *=============================================================================================*/
  690. Vector2 RingRenderObjClass::Get_Default_Inner_Scale(void) const
  691. {
  692. Vector2 value;
  693. if (InnerScaleChannel.Get_Key_Count () > 0) {
  694. value = InnerScaleChannel.Get_Key (0).Get_Value ();
  695. } else {
  696. value = InnerScale;
  697. }
  698. return value;
  699. }
  700. /***********************************************************************************************
  701. * RingRenderObjClass::Get_Default_Outer_Scale - get the default (or first frame) value *
  702. * *
  703. * INPUT: *
  704. * *
  705. * OUTPUT: *
  706. * *
  707. * WARNINGS: *
  708. * *
  709. * HISTORY: *
  710. * 3/13/2000 pds : Created. *
  711. *=============================================================================================*/
  712. Vector2 RingRenderObjClass::Get_Default_Outer_Scale(void) const
  713. {
  714. Vector2 value;
  715. if (OuterScaleChannel.Get_Key_Count () > 0) {
  716. value = OuterScaleChannel.Get_Key (0).Get_Value ();
  717. } else {
  718. value = OuterScale;
  719. }
  720. return value;
  721. }
  722. /***********************************************************************************************
  723. * RingRenderObjClass::Special_Render -- special render this box (vis) *
  724. * *
  725. * INPUT: *
  726. * *
  727. * OUTPUT: *
  728. * *
  729. * WARNINGS: *
  730. , * *
  731. * HISTORY: *
  732. * 1/19/00 gth : Created. *
  733. *=============================================================================================*/
  734. void RingRenderObjClass::Special_Render(SpecialRenderInfoClass & rinfo)
  735. {
  736. Matrix3D temp(1);
  737. temp.Translate(Transform.Get_Translation());
  738. if (rinfo.RenderType == SpecialRenderInfoClass::RENDER_VIS) {
  739. WWASSERT(rinfo.VisRasterizer != NULL);
  740. rinfo.VisRasterizer->Set_Model_Transform(temp);
  741. vis_render_ring(rinfo,ObjSpaceCenter,ObjSpaceExtent);
  742. }
  743. }
  744. /***********************************************************************************************
  745. * RingRenderObjClass::Set_Transform -- set the transform for this box *
  746. * *
  747. * INPUT: *
  748. * *
  749. * OUTPUT: *
  750. * *
  751. * WARNINGS: *
  752. * *
  753. * HISTORY: *
  754. * 1/19/00 gth : Created. *
  755. *=============================================================================================*/
  756. void RingRenderObjClass::Set_Transform(const Matrix3D &m)
  757. {
  758. RenderObjClass::Set_Transform(m);
  759. update_cached_box();
  760. }
  761. /***********************************************************************************************
  762. * RingRenderObjClass::Set_Position -- Set the position of this box *
  763. * *
  764. * INPUT: *
  765. * *
  766. * OUTPUT: *
  767. * *
  768. * WARNINGS: *
  769. * *
  770. * HISTORY: *
  771. * 1/19/00 gth : Created. *
  772. *=============================================================================================*/
  773. void RingRenderObjClass::Set_Position(const Vector3 &v)
  774. {
  775. RenderObjClass::Set_Position(v);
  776. update_cached_box();
  777. }
  778. /***********************************************************************************************
  779. * RingRenderObjClass::update_cached_box -- update the world-space version of this box *
  780. * *
  781. * INPUT: *
  782. * *
  783. * OUTPUT: *
  784. * *
  785. * WARNINGS: *
  786. * *
  787. * HISTORY: *
  788. * 1/19/00 gth : Created. *
  789. *=============================================================================================*/
  790. void RingRenderObjClass::update_cached_box(void)
  791. {
  792. CachedBox.Center = Transform.Get_Translation() + ObjSpaceCenter;
  793. CachedBox.Extent = ObjSpaceExtent;
  794. }
  795. /***********************************************************************************************
  796. * RingRenderObjClass::Get_Obj_Space_Bounding_Ring -- return the object-space bounding sphe *
  797. * *
  798. * INPUT: *
  799. * *
  800. * OUTPUT: *
  801. * *
  802. * WARNINGS: *
  803. * *
  804. * HISTORY: *
  805. * 1/19/00 gth : Created. *
  806. *=============================================================================================*/
  807. void RingRenderObjClass::Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const
  808. {
  809. sphere.Center = ObjSpaceCenter;
  810. sphere.Radius = ObjSpaceExtent.Length();
  811. }
  812. /***********************************************************************************************
  813. * RingRenderObjClass::Get_Obj_Space_Bounding_Box -- returns the obj-space bounding box *
  814. * *
  815. * INPUT: *
  816. * *
  817. * OUTPUT: *
  818. * *
  819. * WARNINGS: *
  820. * *
  821. * HISTORY: *
  822. * 1/19/00 gth : Created. *
  823. *=============================================================================================*/
  824. void RingRenderObjClass::Get_Obj_Space_Bounding_Box(AABoxClass & box) const
  825. {
  826. box.Center = ObjSpaceCenter;
  827. box.Extent = ObjSpaceExtent;
  828. }
  829. /***********************************************************************************************
  830. * SphereRenderObjClass::Update_On_Visibilty -- Either starts or stops the animation based on visibility*
  831. * *
  832. * INPUT: *
  833. * *
  834. * OUTPUT: *
  835. * *
  836. * WARNINGS: *
  837. * *
  838. * HISTORY: *
  839. * 4/04/00 pds : Created. *
  840. *=============================================================================================*/
  841. void RingRenderObjClass::Update_On_Visibilty(void)
  842. {
  843. // Simply start or stop the animation based on
  844. // the visibility state of the primitive.
  845. if (Is_Not_Hidden_At_All () && Is_Animating () == false) {
  846. Start_Animating ();
  847. } else if ((Is_Not_Hidden_At_All () == false) && Is_Animating ()) {
  848. Stop_Animating ();
  849. }
  850. return ;
  851. }
  852. /***********************************************************************************************
  853. * RingRenderObjClass::animate -- Update Current Display state *
  854. * *
  855. * INPUT: *
  856. * *
  857. * OUTPUT: *
  858. * *
  859. * WARNINGS: *
  860. * *
  861. * HISTORY: *
  862. * 3/07/00 jga : Created. *
  863. *=============================================================================================*/
  864. void RingRenderObjClass::animate()
  865. {
  866. if (Is_Animating ()) {
  867. if ( ColorChannel.Get_Key_Count () > 0 ||
  868. AlphaChannel.Get_Key_Count () > 0 ||
  869. InnerScaleChannel.Get_Key_Count () > 0 ||
  870. OuterScaleChannel.Get_Key_Count () > 0)
  871. {
  872. //
  873. // Convert from milliseconds to seconds and normalize the time
  874. //
  875. if (AnimDuration > 0) {
  876. float frametime = WW3D::Get_Frame_Time();
  877. frametime = (frametime * 0.001F) / AnimDuration;
  878. anim_time += frametime;
  879. } else {
  880. anim_time = 1.0F;
  881. }
  882. WWASSERT (anim_time >= 0.0F);
  883. if ((Flags & USE_ANIMATION_LOOP) && anim_time > 1.0F) {
  884. anim_time -= 1.0F;
  885. }
  886. if (ColorChannel.Get_Key_Count () > 0) {
  887. Color = ColorChannel.Evaluate (anim_time);
  888. }
  889. if (AlphaChannel.Get_Key_Count () > 0) {
  890. Alpha = AlphaChannel.Evaluate (anim_time);
  891. }
  892. if (InnerScaleChannel.Get_Key_Count () > 0) {
  893. InnerScale = InnerScaleChannel.Evaluate (anim_time);
  894. }
  895. if (OuterScaleChannel.Get_Key_Count () > 0) {
  896. OuterScale = OuterScaleChannel.Evaluate (anim_time);
  897. ObjSpaceExtent.X = OuterScale.X * OuterExtent.X;
  898. ObjSpaceExtent.Y = OuterScale.Y * OuterExtent.Y;
  899. ObjSpaceExtent.Z = 0;
  900. Update_Cached_Bounding_Volumes ();
  901. }
  902. }
  903. }
  904. return ;
  905. } // animate
  906. /*
  907. ** RingLoaderClass Implementation
  908. */
  909. PrototypeClass * RingLoaderClass::Load_W3D(ChunkLoadClass & cload)
  910. {
  911. RingPrototypeClass *prototype = W3DNEW RingPrototypeClass ();
  912. prototype->Load (cload);
  913. return prototype;
  914. }
  915. /*
  916. ** RingPrototypeClass Implementation
  917. */
  918. RingPrototypeClass::RingPrototypeClass (void)
  919. {
  920. ::memset (&Definition, 0, sizeof (Definition));
  921. return ;
  922. }
  923. RingPrototypeClass::RingPrototypeClass(RingRenderObjClass *ring)
  924. {
  925. ::memset (&Definition, 0, sizeof (Definition));
  926. ::strcpy (Definition.Name, ring->Get_Name ());
  927. Definition.AnimDuration = ring->AnimDuration;
  928. Definition.Attributes = ring->Get_Flags ();
  929. Definition.DefaultAlpha = ring->Get_Default_Alpha ();
  930. Definition.DefaultInnerScale = ring->Get_Default_Inner_Scale ();
  931. Definition.DefaultOuterScale = ring->Get_Default_Outer_Scale ();
  932. Definition.TextureTileCount = ring->Get_Texture_Tiling ();
  933. Definition.InnerExtent = ring->Get_Inner_Extent ();
  934. Definition.OuterExtent = ring->Get_Outer_Extent ();
  935. Vector3 def_color = ring->Get_Default_Color ();
  936. W3dUtilityClass::Convert_Vector (def_color, &Definition.DefaultColor);
  937. W3dUtilityClass::Convert_Vector (ring->Get_Box ().Center, &Definition.Center);
  938. W3dUtilityClass::Convert_Vector (ring->Get_Box ().Extent, &Definition.Extent);
  939. W3dUtilityClass::Convert_Shader (ring->RingShader, &Definition.Shader);
  940. //
  941. // Determine the texture name for this sphere
  942. //
  943. if (ring->RingTexture != NULL) {
  944. StringClass name = ring->RingTexture->Get_Full_Path();
  945. const char *filename = ::strrchr (name, '\\');
  946. if (filename != NULL) {
  947. filename ++;
  948. } else {
  949. filename = name;
  950. }
  951. ::strcpy (Definition.TextureName, filename);
  952. }
  953. //
  954. // Save the animateable channels
  955. //
  956. ColorChannel = ring->Peek_Color_Channel ();
  957. AlphaChannel = ring->Peek_Alpha_Channel ();
  958. InnerScaleChannel = ring->Peek_Inner_Scale_Channel ();
  959. OuterScaleChannel = ring->Peek_Outer_Scale_Channel ();
  960. return ;
  961. }
  962. RingPrototypeClass::~RingPrototypeClass (void)
  963. {
  964. return ;
  965. }
  966. const char * RingPrototypeClass::Get_Name(void) const
  967. {
  968. return Definition.Name;
  969. }
  970. int RingPrototypeClass::Get_Class_ID(void) const
  971. {
  972. return RenderObjClass::CLASSID_RING;
  973. }
  974. enum
  975. {
  976. CHUNKID_RING_DEF = 1,
  977. CHUNKID_COLOR_CHANNEL,
  978. CHUNKID_ALPHA_CHANNEL,
  979. CHUNKID_INNER_SCALE_CHANNEL,
  980. CHUNKID_OUTER_SCALE_CHANNEL
  981. };
  982. bool RingPrototypeClass::Load (ChunkLoadClass &cload)
  983. {
  984. ColorChannel.Reset ();
  985. AlphaChannel.Reset ();
  986. InnerScaleChannel.Reset ();
  987. OuterScaleChannel.Reset ();
  988. while (cload.Open_Chunk ()) {
  989. switch (cload.Cur_Chunk_ID ()) {
  990. case CHUNKID_RING_DEF:
  991. cload.Read (&Definition, sizeof (Definition));
  992. break;
  993. case CHUNKID_COLOR_CHANNEL:
  994. ColorChannel.Load (cload);
  995. break;
  996. case CHUNKID_ALPHA_CHANNEL:
  997. AlphaChannel.Load (cload);
  998. break;
  999. case CHUNKID_INNER_SCALE_CHANNEL:
  1000. InnerScaleChannel.Load (cload);
  1001. break;
  1002. case CHUNKID_OUTER_SCALE_CHANNEL:
  1003. OuterScaleChannel.Load (cload);
  1004. break;
  1005. }
  1006. cload.Close_Chunk ();
  1007. }
  1008. return true;
  1009. }
  1010. bool RingPrototypeClass::Save (ChunkSaveClass &csave)
  1011. {
  1012. csave.Begin_Chunk (W3D_CHUNK_RING);
  1013. csave.Begin_Chunk (CHUNKID_RING_DEF);
  1014. csave.Write (&Definition, sizeof (Definition));
  1015. csave.End_Chunk ();
  1016. if (ColorChannel.Get_Key_Count () > 0) {
  1017. csave.Begin_Chunk (CHUNKID_COLOR_CHANNEL);
  1018. ColorChannel.Save (csave);
  1019. csave.End_Chunk ();
  1020. }
  1021. if (AlphaChannel.Get_Key_Count () > 0) {
  1022. csave.Begin_Chunk (CHUNKID_ALPHA_CHANNEL);
  1023. AlphaChannel.Save (csave);
  1024. csave.End_Chunk ();
  1025. }
  1026. if (InnerScaleChannel.Get_Key_Count () > 0) {
  1027. csave.Begin_Chunk (CHUNKID_INNER_SCALE_CHANNEL);
  1028. InnerScaleChannel.Save (csave);
  1029. csave.End_Chunk ();
  1030. }
  1031. if (OuterScaleChannel.Get_Key_Count () > 0) {
  1032. csave.Begin_Chunk (CHUNKID_OUTER_SCALE_CHANNEL);
  1033. OuterScaleChannel.Save (csave);
  1034. csave.End_Chunk ();
  1035. }
  1036. csave.End_Chunk ();
  1037. return true;
  1038. }
  1039. RenderObjClass * RingPrototypeClass::Create(void)
  1040. {
  1041. //
  1042. // Create the new render object
  1043. //
  1044. RingRenderObjClass *ring = W3DNEW RingRenderObjClass (Definition);
  1045. //
  1046. // Configure the ring
  1047. //
  1048. W3dUtilityClass::Convert_Shader (Definition.Shader, &ring->RingShader);
  1049. if (WW3DAssetManager::Get_Instance()->Get_Activate_Fog_On_Load()) {
  1050. ring->RingShader.Enable_Fog ("RingPrototypeClass");
  1051. ring->RingShader.Set_Cull_Mode(ShaderClass::CULL_MODE_DISABLE);
  1052. }
  1053. W3dUtilityClass::Convert_Vector (Definition.DefaultColor, &ring->Color);
  1054. ring->InnerScale = Definition.DefaultInnerScale;
  1055. ring->OuterScale = Definition.DefaultOuterScale;
  1056. ring->Set_Animation_Duration (Definition.AnimDuration);
  1057. ring->Alpha = Definition.DefaultAlpha;
  1058. ring->Set_Flags (Definition.Attributes);
  1059. ring->Set_Inner_Extent (Definition.InnerExtent);
  1060. ring->Set_Outer_Extent (Definition.OuterExtent);
  1061. ring->Set_Texture_Tiling (Definition.TextureTileCount);
  1062. //
  1063. // Initialize the render object with the keyframe arrays
  1064. //
  1065. ring->Set_Color_Channel (ColorChannel);
  1066. ring->Set_Alpha_Channel (AlphaChannel);
  1067. ring->Set_Inner_Scale_Channel (InnerScaleChannel);
  1068. ring->Set_Outer_Scale_Channel (OuterScaleChannel);
  1069. return ring;
  1070. }
  1071. /*
  1072. ** Global instance of the box loader
  1073. */
  1074. RingLoaderClass _RingLoader;
  1075. //
  1076. // Vertices are ordered as such
  1077. // center, followed by outer ring
  1078. //
  1079. /***********************************************************************************************
  1080. * RingMeshClass::RingMeshClass -- Constructor *
  1081. * *
  1082. * INPUT: *
  1083. * *
  1084. * OUTPUT: *
  1085. * *
  1086. * WARNINGS: *
  1087. * *
  1088. * HISTORY: *
  1089. * 3/07/00 jga : Created. *
  1090. *=============================================================================================*/
  1091. RingMeshClass::RingMeshClass(float radius, int slices):
  1092. Radius(radius),
  1093. Slices(slices),
  1094. Vertex_ct(0), // 1 vertex minimum, for center
  1095. vtx(NULL),
  1096. orig_vtx(NULL),
  1097. vtx_normal(NULL),
  1098. vtx_uv(NULL),
  1099. face_ct(0),
  1100. tri_poly(NULL),
  1101. TileCount (5),
  1102. InnerScale (1.0F, 1.0F),
  1103. OuterScale (1.0F, 1.0F)
  1104. {
  1105. Generate(radius, slices);
  1106. }
  1107. /***********************************************************************************************
  1108. * RingMeshClass::RingMeshClass -- Constructor *
  1109. * *
  1110. * INPUT: *
  1111. * *
  1112. * OUTPUT: *
  1113. * *
  1114. * WARNINGS: *
  1115. * *
  1116. * HISTORY: *
  1117. * 3/07/00 jga : Created. *
  1118. *=============================================================================================*/
  1119. RingMeshClass::RingMeshClass(void):
  1120. Radius(0.0f),
  1121. Slices(0),
  1122. Vertex_ct(0), // 1 vertex minimum, for center
  1123. vtx(NULL),
  1124. orig_vtx(NULL),
  1125. vtx_normal(NULL),
  1126. vtx_uv(NULL),
  1127. face_ct(0),
  1128. tri_poly(NULL),
  1129. TileCount (5),
  1130. InnerScale (1.0F, 1.0F),
  1131. OuterScale (1.0F, 1.0F)
  1132. {
  1133. } // empty ringmesh Constructor
  1134. void RingMeshClass::Set_Tiling (int count)
  1135. {
  1136. if (TileCount != count) {
  1137. TileCount = count;
  1138. //
  1139. // Calculate the increment 'u' increment value (as in UV).
  1140. //
  1141. float u_inc = ((float)TileCount) / ((float)(Slices));
  1142. float u_value = 0.0F;
  1143. //
  1144. // Reassign the UVs
  1145. //
  1146. for (int index = 0; index < Vertex_ct; index += 2) {
  1147. vtx_uv[index].Set (u_value, 0.0F);
  1148. vtx_uv[index + 1].Set (u_value, 1.0F);
  1149. u_value += u_inc;
  1150. }
  1151. }
  1152. return ;
  1153. }
  1154. void RingMeshClass::Scale (const Vector2 &inner_scale, const Vector2 &outer_scale)
  1155. {
  1156. bool do_inner = (inner_scale != InnerScale);
  1157. bool do_outer = (outer_scale != OuterScale);
  1158. //
  1159. // Only scale the inner ring if necessary
  1160. //
  1161. if (do_inner) {
  1162. for (int index = 0; index < Vertex_ct; index += 2) {
  1163. vtx[index].X = orig_vtx[index].X * inner_scale.X;
  1164. vtx[index].Y = orig_vtx[index].Y * inner_scale.Y;
  1165. vtx[index].Z = 0;
  1166. }
  1167. InnerScale = inner_scale;
  1168. }
  1169. //
  1170. // Only scale the outer ring if necessary
  1171. //
  1172. if (do_outer) {
  1173. for (int index = 1; index < Vertex_ct; index += 2) {
  1174. vtx[index].X = orig_vtx[index].X * outer_scale.X;
  1175. vtx[index].Y = orig_vtx[index].Y * outer_scale.Y;
  1176. vtx[index].Z = 0;
  1177. }
  1178. OuterScale = outer_scale;
  1179. }
  1180. return ;
  1181. }
  1182. /***********************************************************************************************
  1183. * RingMeshClass::Generate - Create Ring Geometry *
  1184. * *
  1185. * INPUT: *
  1186. * *
  1187. * OUTPUT: *
  1188. * *
  1189. * WARNINGS: *
  1190. * *
  1191. * HISTORY: *
  1192. * 3/07/00 jga : Created. *
  1193. *=============================================================================================*/
  1194. void RingMeshClass::Generate(float radius, int slices)
  1195. {
  1196. Free ();
  1197. Slices = slices;
  1198. Radius = radius;
  1199. face_ct = (Slices * 2);
  1200. Vertex_ct = (Slices * 2) + 2;
  1201. vtx = W3DNEWARRAY Vector3[Vertex_ct];
  1202. orig_vtx = W3DNEWARRAY Vector2[Vertex_ct];
  1203. vtx_normal = W3DNEWARRAY Vector3[Vertex_ct];
  1204. vtx_uv = W3DNEWARRAY Vector2[Vertex_ct];
  1205. tri_poly = W3DNEWARRAY Vector3i[face_ct];
  1206. //
  1207. // Generate vertices, normals, and uv's
  1208. //
  1209. float angle_inc = DEG_TO_RADF (360) / ((float)Slices);
  1210. float u_inc = ((float)TileCount) / ((float)(Slices));
  1211. float u_value = 0.0F;
  1212. float angle = 0;
  1213. int index = 0;
  1214. for (index = 0; index < Vertex_ct; index += 2) {
  1215. float x_pos = -WWMath::Sin (angle);
  1216. float y_pos = WWMath::Cos (angle);
  1217. //
  1218. // Place the inner index
  1219. //
  1220. vtx[index].X = orig_vtx[index].X = x_pos;
  1221. vtx[index].Y = orig_vtx[index].Y = y_pos;
  1222. vtx[index].Z = 0;
  1223. //
  1224. // Place the outer index
  1225. //
  1226. vtx[index+1].X = orig_vtx[index+1].X = x_pos;
  1227. vtx[index+1].Y = orig_vtx[index+1].Y = y_pos;
  1228. vtx[index+1].Z = 0;
  1229. //
  1230. // Normals will just point straight up from the ring...
  1231. //
  1232. vtx_normal[index].Set (0, 0, 1);
  1233. vtx_normal[index + 1].Set (0, 0, 1);
  1234. //
  1235. // Assign the UVs
  1236. //
  1237. vtx_uv[index].Set (u_value, 0.0F);
  1238. vtx_uv[index + 1].Set (u_value, 1.0F);
  1239. u_value += u_inc;
  1240. angle += angle_inc;
  1241. }
  1242. //
  1243. // Make the triangle strip...
  1244. //
  1245. for (index = 0; index < face_ct; index ++) {
  1246. tri_poly[index].I = index;
  1247. tri_poly[index].J = index+1;
  1248. tri_poly[index].K = index+2;
  1249. }
  1250. return ;
  1251. }
  1252. /***********************************************************************************************
  1253. * RingMeshClass::~RingMeshClass -- Destructor *
  1254. * *
  1255. * INPUT: *
  1256. * *
  1257. * OUTPUT: *
  1258. * *
  1259. * WARNINGS: *
  1260. * *
  1261. * HISTORY: *
  1262. * 3/07/00 jga : Created. *
  1263. *=============================================================================================*/
  1264. RingMeshClass::~RingMeshClass(void)
  1265. {
  1266. Free();
  1267. }
  1268. /***********************************************************************************************
  1269. * RingMeshClass::Free - Release Memory, that the ring mesh is using *
  1270. * *
  1271. * INPUT: *
  1272. * *
  1273. * OUTPUT: *
  1274. * *
  1275. * WARNINGS: *
  1276. * *
  1277. * HISTORY: *
  1278. * 3/07/00 jga : Created. *
  1279. *=============================================================================================*/
  1280. void RingMeshClass::Free(void)
  1281. {
  1282. if (vtx) delete vtx;
  1283. if (orig_vtx) delete orig_vtx;
  1284. if (vtx_normal) delete vtx_normal;
  1285. if (vtx_uv) delete vtx_uv;
  1286. if (tri_poly) delete tri_poly;
  1287. vtx = NULL;
  1288. orig_vtx = NULL;
  1289. vtx_normal = NULL;
  1290. vtx_uv = NULL;
  1291. tri_poly = NULL;
  1292. } // Free
  1293. // EOF - ringobj.cpp