line3d.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514
  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 : G *
  23. * *
  24. * $Archive:: /Commando/Code/ww3d2/line3d.cpp $*
  25. * *
  26. * $Author:: Jani_p $*
  27. * *
  28. * $Modtime:: 7/05/01 4:15p $*
  29. * *
  30. * $Revision:: 11 $*
  31. * *
  32. *-------------------------------------------------------------------------*
  33. * Functions: *
  34. * Line3DClass::Line3DClass -- Constructor *
  35. * Line3DClass::Line3DClass -- Copy constructor. *
  36. * Line3DClass::operator = -- assignment operator *
  37. * Line3DClass::~Line3DClass -- Destructor. *
  38. * Line3DClass::Clone -- Creates a clone of this Line3D *
  39. * Line3DClass::Scale -- Scale object *
  40. * Line3DClass::Scale -- Scale object *
  41. * Line3DClass::Update_Cached_Bounding_Volumes -- update bounding vols *
  42. * Line3DClass::Reset -- Reset line start and end points. *
  43. * Line3DClass::Reset -- Reset line start and end points, and line width.*
  44. * Re_Color -- Reset the line color. *
  45. * Set_Opacity -- Reset the line opacity. *
  46. * Line3DClass::Render -- render the 3d line *
  47. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  48. #include "line3d.h"
  49. #include "vertmaterial.h"
  50. #include "shader.h"
  51. #include "wwdebug.h"
  52. #include "ww3d.h"
  53. #include "rinfo.h"
  54. #include "dx8wrapper.h"
  55. #include "dx8vertexbuffer.h"
  56. #include "dx8indexbuffer.h"
  57. #include "dx8fvf.h"
  58. // 12 Triangles for index buffer
  59. const unsigned short Indices[]=
  60. {
  61. 3,5,1,
  62. 7,5,3,
  63. 1,5,0,
  64. 5,4,0,
  65. 4,2,0,
  66. 4,6,2,
  67. 7,3,2,
  68. 6,7,2,
  69. 7,6,5,
  70. 5,6,4,
  71. 2,3,1,
  72. 2,1,0
  73. };
  74. /**************************************************************************
  75. * Line3DClass::Line3DClass -- Constructor *
  76. * *
  77. * INPUT: Vector3 start, end - start, end points of line (world coords).*
  78. * float width - width of line (in world units). *
  79. * float r, g, b - R, G, B components of line color. *
  80. * float opacity - opacity of line. *
  81. * *
  82. * OUTPUT: none. *
  83. * *
  84. * WARNINGS: *
  85. * *
  86. * HISTORY: *
  87. * 01/15/1998 NH : Created. *
  88. * 04/21/1998 NH : Ported to SR 1.3. *
  89. * 02/16/2001 HY : Ported to DX8 *
  90. *========================================================================*/
  91. Line3DClass::Line3DClass (const Vector3 & start, const Vector3 & end,
  92. float width, float r, float g, float b, float opacity)
  93. {
  94. Length = (end - start).Length();
  95. Width = width;
  96. // Create box model with origin at start point (X is major axis).
  97. // 8 Vertices
  98. float halfw = Width * 0.5f;
  99. vert[0].X = 0.0f;
  100. vert[0].Y = -halfw;
  101. vert[0].Z = -halfw;
  102. vert[1].X = 0.0f;
  103. vert[1].Y = halfw;
  104. vert[1].Z = -halfw;
  105. vert[2].X = 0.0f;
  106. vert[2].Y = -halfw;
  107. vert[2].Z = halfw;
  108. vert[3].X = 0.0f;
  109. vert[3].Y = halfw;
  110. vert[3].Z = halfw;
  111. vert[4].X = Length;
  112. vert[4].Y = -halfw;
  113. vert[4].Z = -halfw;
  114. vert[5].X = Length;
  115. vert[5].Y = halfw;
  116. vert[5].Z = -halfw;
  117. vert[6].X = Length;
  118. vert[6].Y = -halfw;
  119. vert[6].Z = halfw;
  120. vert[7].X = Length;
  121. vert[7].Y = halfw;
  122. vert[7].Z = halfw;
  123. Color.X=r;
  124. Color.Y=g;
  125. Color.Z=b;
  126. Set_Opacity(opacity);
  127. // Set box transform so that the origin is at the start point and it
  128. // 'looks towards' the endpoint.
  129. Matrix3D transform(true);
  130. transform.Obj_Look_At(start, end, 0.0);
  131. Set_Transform(transform);
  132. }
  133. /**************************************************************************
  134. * Line3DClass::Line3DClass -- Copy constructor. *
  135. * *
  136. * INPUT: const Line3DClass & src - source to copy from. *
  137. * *
  138. * OUTPUT: none. *
  139. * *
  140. * WARNINGS: *
  141. * *
  142. * HISTORY: *
  143. * 01/15/1998 NH : Created. *
  144. * 04/21/1998 NH : Ported to SR 1.3. *
  145. * 02/16/2001 HY : Ported to DX8 *
  146. *========================================================================*/
  147. Line3DClass::Line3DClass(const Line3DClass & src) :
  148. RenderObjClass(src),
  149. Length(src.Length),
  150. Width(src.Width),
  151. Shader(src.Shader),
  152. Color(src.Color)
  153. {
  154. for (int i=0; i<8; i++) vert[i]=src.vert[i];
  155. }
  156. /**************************************************************************
  157. * Line3DClass::operator = -- assignment operator *
  158. * *
  159. * INPUT: const Line3DClass & that - source to copy from. *
  160. * *
  161. * OUTPUT: Line3DClass & - result of assignment. *
  162. * *
  163. * WARNINGS: *
  164. * *
  165. * HISTORY: *
  166. * 01/15/1998 NH : Created. *
  167. * 04/21/1998 NH : Ported to SR 1.3. *
  168. * 02/16/2001 HY : Ported to DX8 *
  169. *========================================================================*/
  170. Line3DClass & Line3DClass::operator = (const Line3DClass & that)
  171. {
  172. // Naty: need to add MatInfo and remapper to do this Byon
  173. WWASSERT(0);
  174. RenderObjClass::operator = (that);
  175. if (this != &that) {
  176. Length = that.Length;
  177. Width = that.Width;
  178. Shader=that.Shader;
  179. Color=that.Color;
  180. for (int i=0; i<8; i++)
  181. vert[i]=that.vert[i];
  182. }
  183. return * this;
  184. }
  185. /**************************************************************************
  186. * Line3DClass::~Line3DClass -- Destructor. *
  187. * *
  188. * INPUT: none. *
  189. * *
  190. * OUTPUT: none. *
  191. * *
  192. * WARNINGS: *
  193. * *
  194. * HISTORY: *
  195. * 01/15/1998 NH : Created. *
  196. * 04/21/1998 NH : Ported to SR 1.3. *
  197. * 02/16/2001 HY : Ported to DX8 *
  198. *========================================================================*/
  199. Line3DClass::~Line3DClass(void)
  200. {
  201. }
  202. /**************************************************************************
  203. * Line3DClass::Clone -- Creates a clone of this Line3D *
  204. * *
  205. * INPUT: none. *
  206. * *
  207. * OUTPUT: RenderObjClass * - pointer to cloned object. *
  208. * *
  209. * WARNINGS: *
  210. * *
  211. * HISTORY: *
  212. * 01/15/1998 NH : Created. *
  213. *========================================================================*/
  214. RenderObjClass * Line3DClass::Clone(void) const
  215. {
  216. return NEW_REF( Line3DClass, (*this));
  217. }
  218. /***********************************************************************************************
  219. * Line3DClass::Render -- render the 3d line *
  220. * *
  221. * INPUT: *
  222. * *
  223. * OUTPUT: *
  224. * *
  225. * WARNINGS: *
  226. * *
  227. * HISTORY: *
  228. * 12/8/98 GTH : Created. *
  229. * 02/16/2001 HY : Ported to DX8 *
  230. *=============================================================================================*/
  231. void Line3DClass::Render(RenderInfoClass & rinfo)
  232. {
  233. if (Is_Not_Hidden_At_All() == false) {
  234. return;
  235. }
  236. // If static sort lists are enabled and this mesh has a sort level, put it on the list instead
  237. // of rendering it.
  238. unsigned int sort_level = (unsigned int)Get_Sort_Level();
  239. if (WW3D::Are_Static_Sort_Lists_Enabled() && sort_level != SORT_LEVEL_NONE)
  240. {
  241. WW3D::Add_To_Static_Sort_List(this, sort_level);
  242. return;
  243. }
  244. DX8Wrapper::Set_Shader(Shader);
  245. DX8Wrapper::Set_Texture(0,NULL);
  246. VertexMaterialClass *vm=VertexMaterialClass::Get_Preset(VertexMaterialClass::PRELIT_DIFFUSE);
  247. DX8Wrapper::Set_Material(vm);
  248. REF_PTR_RELEASE(vm);
  249. DX8Wrapper::Set_Transform(D3DTS_WORLD,Transform);
  250. DynamicVBAccessClass vb(BUFFER_TYPE_DYNAMIC_DX8,dynamic_fvf_type,8);
  251. {
  252. DynamicVBAccessClass::WriteLockClass Lock(&vb);
  253. const FVFInfoClass &fi=vb.FVF_Info();
  254. unsigned char *vb=(unsigned char*)Lock.Get_Formatted_Vertex_Array();
  255. int i;
  256. unsigned int color=DX8Wrapper::Convert_Color(Color);
  257. for (i=0; i<8; i++)
  258. {
  259. *(Vector3*)(vb+fi.Get_Location_Offset())=vert[i];
  260. *(unsigned int*)(vb+fi.Get_Diffuse_Offset())=color;
  261. vb+=fi.Get_FVF_Size();
  262. }
  263. }
  264. DynamicIBAccessClass ib(BUFFER_TYPE_DYNAMIC_DX8,36);
  265. {
  266. DynamicIBAccessClass::WriteLockClass Lock(&ib);
  267. unsigned short *mem=Lock.Get_Index_Array();
  268. for (int i=0; i<36; i++)
  269. mem[i]=Indices[i];
  270. }
  271. DX8Wrapper::Set_Vertex_Buffer(vb);
  272. DX8Wrapper::Set_Index_Buffer(ib,0);
  273. DX8Wrapper::Draw_Triangles(0,36/3,0,8);
  274. }
  275. /**************************************************************************
  276. * Line3DClass::Scale -- Scale object *
  277. * *
  278. * INPUT: float scale - uniform scale factor. *
  279. * *
  280. * OUTPUT: none. *
  281. * *
  282. * WARNINGS: *
  283. * *
  284. * HISTORY: *
  285. * 01/27/1998 NH : Created. *
  286. * 04/21/1998 NH : Ported to SR 1.3. *
  287. * 02/16/2001 HY : Ported to DX8 *
  288. *========================================================================*/
  289. void Line3DClass::Scale(float scale)
  290. {
  291. for (int i=0; i<8; i++) vert[i]*=scale;
  292. Length *= scale;
  293. Width *= scale;
  294. Invalidate_Cached_Bounding_Volumes();
  295. // Now update the object space bounding volumes of this object's container:
  296. RenderObjClass *container = Get_Container();
  297. if (container) container->Update_Obj_Space_Bounding_Volumes();
  298. }
  299. /**************************************************************************
  300. * Line3DClass::Scale -- Scale object *
  301. * *
  302. * INPUT: float scalex, scaley, scalez - axis scale factors. *
  303. * *
  304. * OUTPUT: none. *
  305. * *
  306. * WARNINGS: *
  307. * *
  308. * HISTORY: *
  309. * 01/27/1998 NH : Created. *
  310. * 04/21/1998 NH : Ported to SR 1.3. *
  311. * 02/16/2001 HY : Ported to DX8 *
  312. *========================================================================*/
  313. void Line3DClass::Scale(float scalex, float scaley, float scalez)
  314. {
  315. // The line width is always the same in the y and z axes (the line
  316. // approximates a cylinder).
  317. Vector3 scale(scalex,scaley,scalez);
  318. for (int i=0; i<8; i++) vert[i].Scale(scale);
  319. Length *= scalex;
  320. Width *= scaley;
  321. Invalidate_Cached_Bounding_Volumes();
  322. // Now update the object space bounding volumes of this object's container:
  323. RenderObjClass *container = Get_Container();
  324. if (container) container->Update_Obj_Space_Bounding_Volumes();
  325. }
  326. void Line3DClass::Get_Obj_Space_Bounding_Sphere(SphereClass & sphere) const
  327. {
  328. float half_l = Length * 0.5f;
  329. sphere.Center.Set(half_l, 0.0f, 0.0f);
  330. sphere.Radius = half_l;
  331. }
  332. void Line3DClass::Get_Obj_Space_Bounding_Box(AABoxClass & box) const
  333. {
  334. float half_l = Length * 0.5f;
  335. box.Center.Set(half_l, 0.0f, 0.0f);
  336. box.Extent.Set(half_l, 0.0f, 0.0f);
  337. }
  338. /**************************************************************************
  339. * Line3DClass::Reset -- Reset line start and end points. *
  340. * *
  341. * INPUT: *
  342. * *
  343. * OUTPUT: *
  344. * *
  345. * WARNINGS: *
  346. * *
  347. * HISTORY: *
  348. * 01/19/1998 NH : Created. *
  349. * 04/21/1998 NH : Ported to SR 1.3. *
  350. *========================================================================*/
  351. void Line3DClass::Reset(const Vector3 & new_start, const Vector3 & new_end)
  352. {
  353. // Adjust length of line:
  354. float new_length = (new_end - new_start).Length();
  355. if (new_length == 0) {
  356. new_length = 0.001f; // make sure we don't have a zero length BMG
  357. }
  358. Scale((new_length / Length), 1.0f, 1.0f);
  359. Length = new_length;
  360. // Adjust transform of line:
  361. Matrix3D transform(true);
  362. transform.Obj_Look_At(new_start, new_end, 0.0);
  363. Set_Transform(transform);
  364. Invalidate_Cached_Bounding_Volumes();
  365. // Now update the object space bounding volumes of this object's container:
  366. RenderObjClass *container = Get_Container();
  367. if (container) container->Update_Obj_Space_Bounding_Volumes();
  368. }
  369. /**************************************************************************
  370. * Line3DClass::Reset -- Reset line start and end points, and line width. *
  371. * *
  372. * INPUT: *
  373. * *
  374. * OUTPUT: *
  375. * *
  376. * WARNINGS: *
  377. * *
  378. * HISTORY: *
  379. * 01/19/1998 NH : Created. *
  380. * 04/21/1998 NH : Ported to SR 1.3. *
  381. *========================================================================*/
  382. void Line3DClass::Reset(const Vector3 & new_start, const Vector3 & new_end, float new_width)
  383. {
  384. // Adjust length and width of line:
  385. float new_length = (new_end - new_start).Length();
  386. if (new_length == 0) {
  387. new_length = 0.001f; // make sure we don't have a zero length BMG
  388. }
  389. float width_scale = new_width / Width;
  390. Scale((new_length / Length), width_scale, width_scale);
  391. Length = new_length;
  392. Width = new_width;
  393. // Adjust transform of line:
  394. Matrix3D transform(true);
  395. transform.Obj_Look_At(new_start, new_end, 0.0);
  396. Set_Transform(transform);
  397. Matrix3D inv;
  398. transform.Get_Orthogonal_Inverse(inv);
  399. #ifdef ALLOW_TEMPORARIES
  400. // Vector3 test = inv * Vector3(new_end);
  401. #else
  402. // Vector3 test;
  403. // inv.mulVector3(new_end, test);
  404. #endif
  405. Invalidate_Cached_Bounding_Volumes();
  406. // Now update the object space bounding volumes of this object's container:
  407. RenderObjClass *container = Get_Container();
  408. if (container) container->Update_Obj_Space_Bounding_Volumes();
  409. }
  410. /**************************************************************************
  411. * Re_Color -- Reset the line color. *
  412. * *
  413. * INPUT: float r, g, b - components of the new color. *
  414. * *
  415. * OUTPUT: none. *
  416. * *
  417. * WARNINGS: *
  418. * *
  419. * HISTORY: *
  420. * 01/26/1998 NH : Created. *
  421. * 04/21/1998 NH : Ported to SR 1.3. *
  422. *========================================================================*/
  423. void Line3DClass::Re_Color(float r, float g, float b)
  424. {
  425. Color=Vector4(r,g,b,Color.W);
  426. }
  427. /**************************************************************************
  428. * Set_Opacity -- Reset the line opacity. *
  429. * *
  430. * INPUT: float opacity - new opacity. *
  431. * *
  432. * OUTPUT: none. *
  433. * *
  434. * WARNINGS: *
  435. * *
  436. * HISTORY: *
  437. * 11/03/1998 NH : Created. *
  438. *========================================================================*/
  439. void Line3DClass::Set_Opacity(float opacity)
  440. {
  441. if (opacity < 1.0f)
  442. { Shader=ShaderClass::_PresetAlphaSolidShader;
  443. Set_Sort_Level(1);
  444. }
  445. else
  446. { Shader=ShaderClass::_PresetOpaqueSolidShader;
  447. Set_Sort_Level(SORT_LEVEL_NONE);
  448. }
  449. Color.W=opacity;
  450. }
  451. /*
  452. **
  453. */
  454. int Line3DClass::Get_Num_Polys(void) const
  455. {
  456. return 12;
  457. }