widgetuser.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432
  1. /*
  2. ** Command & Conquer Renegade(tm)
  3. ** Copyright 2025 Electronic Arts Inc.
  4. **
  5. ** This program is free software: you can redistribute it and/or modify
  6. ** it under the terms of the GNU General Public License as published by
  7. ** the Free Software Foundation, either version 3 of the License, or
  8. ** (at your option) any later version.
  9. **
  10. ** This program is distributed in the hope that it will be useful,
  11. ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. ** GNU General Public License for more details.
  14. **
  15. ** You should have received a copy of the GNU General Public License
  16. ** along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /***********************************************************************************************
  19. *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
  20. ***********************************************************************************************
  21. * *
  22. * Project Name : WWPhys *
  23. * *
  24. * $Archive:: /Commando/Code/wwphys/widgetuser.cpp $*
  25. * *
  26. * Author:: Greg Hjelstrom *
  27. * *
  28. * $Modtime:: 10/11/01 2:29p $*
  29. * *
  30. * $Revision:: 5 $*
  31. * *
  32. *---------------------------------------------------------------------------------------------*
  33. * Functions: *
  34. * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
  35. #include "widgetuser.h"
  36. #include "widgets.h"
  37. #include "mempool.h"
  38. #include "vertmaterial.h"
  39. #include "matinfo.h"
  40. #include "boxrobj.h"
  41. #include "ww3d.h"
  42. /*
  43. ** WidgetRenderOpClass
  44. ** This class encapsulates the instructions from a physics object to render
  45. ** a debug widget. Each physics object has a list of these hanging off it
  46. ** for rendering vectors, points, etc.
  47. ** Since instances of this class are constantly allocated and deallocated
  48. ** each frame they are derived from AutoPoolClass.
  49. */
  50. class WidgetRenderOpClass : public AutoPoolClass<WidgetRenderOpClass,256>
  51. {
  52. public:
  53. WidgetRenderOpClass(void);
  54. void Set_Color(const Vector3 & color);
  55. void Set_Opacity(float opacity);
  56. void Init_Point(const Vector3 & point);
  57. void Init_Vector(const Vector3 & point,const Vector3 & vector);
  58. void Init_AABox(const AABoxClass & box);
  59. void Init_OBBox(const OBBoxClass & box);
  60. void Init_Coord_Axes(const Matrix3D & tm);
  61. void Render(RenderInfoClass & rinfo);
  62. void Set_Next(WidgetRenderOpClass * next) { Next = next; }
  63. WidgetRenderOpClass * Get_Next(void) { return Next; }
  64. protected:
  65. void render_point(RenderInfoClass & rinfo);
  66. void render_vector(RenderInfoClass & rinfo);
  67. void render_aabox(RenderInfoClass & rinfo);
  68. void render_obbox(RenderInfoClass & rinfo);
  69. void render_axes(RenderInfoClass & rinfo);
  70. enum { RENDER_NONE = 0, RENDER_POINT, RENDER_VECTOR, RENDER_AABOX, RENDER_OBBOX, RENDER_AXES };
  71. int RenderOp;
  72. Vector3 Color;
  73. float Opacity;
  74. Vector3 V0; // these are all re-used depending on the render op
  75. Vector3 V1;
  76. Vector3 V2;
  77. Matrix3D Transform;
  78. WidgetRenderOpClass * Next;
  79. };
  80. /*
  81. ** declare the instance of the pool object for all WidgetRenderOpClass's
  82. */
  83. DEFINE_AUTO_POOL(WidgetRenderOpClass,256);
  84. /*******************************************
  85. **
  86. ** WidgetRenderOpClass Implementation
  87. **
  88. *******************************************/
  89. WidgetRenderOpClass::WidgetRenderOpClass(void) :
  90. RenderOp(RENDER_NONE),
  91. Next(NULL)
  92. {
  93. }
  94. void WidgetRenderOpClass::Set_Color(const Vector3 & color)
  95. {
  96. Color = color;
  97. }
  98. void WidgetRenderOpClass::Set_Opacity(float opacity)
  99. {
  100. Opacity = opacity;
  101. }
  102. void WidgetRenderOpClass::Init_Point(const Vector3 & p0)
  103. {
  104. RenderOp = RENDER_POINT;
  105. V0 = p0;
  106. }
  107. void WidgetRenderOpClass::Init_Vector(const Vector3 & point,const Vector3 & vector)
  108. {
  109. RenderOp = RENDER_VECTOR;
  110. V0 = point;
  111. V1 = vector;
  112. }
  113. void WidgetRenderOpClass::Init_AABox(const AABoxClass & box)
  114. {
  115. RenderOp = RENDER_AABOX;
  116. V0 = box.Center;
  117. V1 = box.Extent;
  118. }
  119. void WidgetRenderOpClass::Init_OBBox(const OBBoxClass & box)
  120. {
  121. RenderOp = RENDER_OBBOX;
  122. V0 = Vector3(0,0,0);
  123. V1 = box.Extent;
  124. Transform.Set(box.Basis,box.Center);
  125. }
  126. void WidgetRenderOpClass::Init_Coord_Axes(const Matrix3D & tm)
  127. {
  128. RenderOp = RENDER_AXES;
  129. Transform = tm;
  130. }
  131. void WidgetRenderOpClass::Render(RenderInfoClass & rinfo)
  132. {
  133. switch(RenderOp)
  134. {
  135. case RENDER_NONE:
  136. break;
  137. case RENDER_POINT:
  138. render_point(rinfo);
  139. break;
  140. case RENDER_VECTOR:
  141. render_vector(rinfo);
  142. break;
  143. case RENDER_AABOX:
  144. render_aabox(rinfo);
  145. break;
  146. case RENDER_OBBOX:
  147. render_obbox(rinfo);
  148. break;
  149. case RENDER_AXES:
  150. render_axes(rinfo);
  151. break;
  152. };
  153. }
  154. void WidgetRenderOpClass::render_point(RenderInfoClass & rinfo)
  155. {
  156. #ifdef WWDEBUG
  157. // Get the point model
  158. RenderObjClass * model = WidgetSystem::Get_Debug_Widget(WidgetSystem::WIDGET_POINT);
  159. if (model == NULL) return;
  160. if (model->Class_ID() != RenderObjClass::CLASSID_MESH) {
  161. model->Release_Ref();
  162. return;
  163. }
  164. // Set its color
  165. MaterialInfoClass * matinfo = model->Get_Material_Info();
  166. if (matinfo) {
  167. VertexMaterialClass * vmat = matinfo->Peek_Vertex_Material(0);
  168. if (vmat) {
  169. vmat->Set_Emissive(Color);
  170. }
  171. matinfo->Release_Ref();
  172. }
  173. // Render it
  174. model->Set_Transform(Matrix3D(V0));
  175. model->Render(rinfo);
  176. model->Release_Ref();
  177. #endif
  178. }
  179. void WidgetRenderOpClass::render_vector(RenderInfoClass & rinfo)
  180. {
  181. #ifdef WWDEBUG
  182. if (V1.Length2() < WWMATH_EPSILON) return;
  183. RenderObjClass * vecmodel = WidgetSystem::Get_Debug_Widget(WidgetSystem::WIDGET_VECTOR);
  184. if (vecmodel) {
  185. // set the color, the vector model is a skin so we have to get the
  186. // first sub-object, get its material info, then get the first vertex material
  187. RenderObjClass * subobj = vecmodel->Get_Sub_Object(0);
  188. if (subobj) {
  189. MaterialInfoClass * matinfo = subobj->Get_Material_Info();
  190. if (matinfo) {
  191. VertexMaterialClass * vmat = matinfo->Peek_Vertex_Material(0);
  192. if (vmat) {
  193. vmat->Set_Emissive(Color);
  194. }
  195. matinfo->Release_Ref();
  196. }
  197. subobj->Release_Ref();
  198. }
  199. // set the transform to be at p0, pointing -z at p1
  200. Matrix3D tm0;
  201. Matrix3D tm1(1);
  202. tm0.Look_At(V0,V0+V1,0.0f); // point -z from pt along vec
  203. tm1.Translate(Vector3(0,0,1.0f - V1.Length())); // p1 is along -z (Point1 starts at -1)
  204. vecmodel->Set_Transform(tm0);
  205. // set bone "Point1" to be at p1
  206. int p1index = vecmodel->Get_Bone_Index("Point1");
  207. vecmodel->Capture_Bone(p1index);
  208. vecmodel->Control_Bone(p1index,tm1);
  209. vecmodel->Render(rinfo);
  210. vecmodel->Release_Ref();
  211. }
  212. #endif
  213. }
  214. void WidgetRenderOpClass::render_aabox(RenderInfoClass & rinfo)
  215. {
  216. #ifdef WWDEBUG
  217. RenderObjClass * model = WidgetSystem::Get_Debug_Widget(WidgetSystem::WIDGET_AABOX);
  218. if (model == NULL) return;
  219. if (model->Class_ID() != RenderObjClass::CLASSID_AABOX) {
  220. model->Release_Ref();
  221. return;
  222. }
  223. // force this box to get rendered (bypass the built in collision bit masking)
  224. int oldmask = WW3D::Get_Collision_Box_Display_Mask();
  225. int newmask = oldmask | 0x01;
  226. WW3D::Set_Collision_Box_Display_Mask(newmask);
  227. AABoxRenderObjClass * boxmodel = (AABoxRenderObjClass *)model;
  228. boxmodel->Set_Local_Center_Extent(V0,V1);
  229. boxmodel->Set_Transform(Matrix3D(1));
  230. boxmodel->Set_Color(Color);
  231. boxmodel->Set_Opacity(Opacity);
  232. boxmodel->Render(rinfo);
  233. boxmodel->Release_Ref();
  234. // restore the old mask
  235. WW3D::Set_Collision_Box_Display_Mask(oldmask);
  236. #endif
  237. }
  238. void WidgetRenderOpClass::render_obbox(RenderInfoClass & rinfo)
  239. {
  240. #ifdef WWDEBUG
  241. RenderObjClass * model = WidgetSystem::Get_Debug_Widget(WidgetSystem::WIDGET_OBBOX);
  242. if (model == NULL) return;
  243. if (model->Class_ID() != RenderObjClass::CLASSID_OBBOX) {
  244. model->Release_Ref();
  245. return;
  246. }
  247. // force this box to get rendered (bypass the built in collision bit masking)
  248. int oldmask = WW3D::Get_Collision_Box_Display_Mask();
  249. int newmask = oldmask | 0x01;
  250. WW3D::Set_Collision_Box_Display_Mask(newmask);
  251. OBBoxRenderObjClass * boxmodel = (OBBoxRenderObjClass *)model;
  252. boxmodel->Set_Collision_Type(0xFF);
  253. boxmodel->Set_Transform(Transform);
  254. boxmodel->Set_Local_Center_Extent(V0,V1);
  255. boxmodel->Set_Color(Color);
  256. boxmodel->Set_Opacity(Opacity);
  257. boxmodel->Render(rinfo);
  258. boxmodel->Release_Ref();
  259. // restore the old mask
  260. WW3D::Set_Collision_Box_Display_Mask(oldmask);
  261. #endif
  262. }
  263. void WidgetRenderOpClass::render_axes(RenderInfoClass & rinfo)
  264. {
  265. #ifdef WWDEBUG
  266. RenderObjClass * model = WidgetSystem::Get_Debug_Widget(WidgetSystem::WIDGET_AXES);
  267. if (model == NULL) return;
  268. if (model->Class_ID() != RenderObjClass::CLASSID_MESH) {
  269. model->Release_Ref();
  270. return;
  271. }
  272. model->Set_Transform(Transform);
  273. model->Render(rinfo);
  274. model->Release_Ref();
  275. #endif
  276. }
  277. /*******************************************
  278. **
  279. ** WidgetUserClass Implementation
  280. **
  281. *******************************************/
  282. WidgetUserClass::WidgetUserClass(void)
  283. {
  284. #ifdef WWDEBUG
  285. WidgetRenderOpList = NULL;
  286. #endif
  287. }
  288. WidgetUserClass::~WidgetUserClass(void)
  289. {
  290. Reset_Debug_Widget_List();
  291. }
  292. #ifdef WWDEBUG
  293. void WidgetUserClass::Reset_Debug_Widget_List(void)
  294. {
  295. WidgetRenderOpClass * op = WidgetRenderOpList;
  296. while (op) {
  297. WidgetRenderOpClass * nextop = op->Get_Next();
  298. delete op;
  299. op = nextop;
  300. }
  301. WidgetRenderOpList = NULL;
  302. }
  303. #endif
  304. #ifdef WWDEBUG
  305. void WidgetUserClass::Add_Debug_Widget(WidgetRenderOpClass * op)
  306. {
  307. WWASSERT(op->Get_Next() == NULL);
  308. op->Set_Next(WidgetRenderOpList);
  309. WidgetRenderOpList = op;
  310. }
  311. #endif
  312. #ifdef WWDEBUG
  313. void WidgetUserClass::Add_Debug_Point(const Vector3 & p,const Vector3 & color)
  314. {
  315. WidgetRenderOpClass * op = new WidgetRenderOpClass;
  316. op->Set_Color(color);
  317. op->Init_Point(p);
  318. Add_Debug_Widget(op);
  319. }
  320. #endif
  321. #ifdef WWDEBUG
  322. void WidgetUserClass::Add_Debug_Vector(const Vector3 & p,const Vector3 & v,const Vector3 & color)
  323. {
  324. if (v.Length2() > 0.0f) {
  325. WidgetRenderOpClass * op = new WidgetRenderOpClass;
  326. op->Set_Color(color);
  327. op->Init_Vector(p,v);
  328. Add_Debug_Widget(op);
  329. }
  330. }
  331. #endif
  332. #ifdef WWDEBUG
  333. void WidgetUserClass::Add_Debug_AABox(const AABoxClass & box,const Vector3 & color,float opacity)
  334. {
  335. WidgetRenderOpClass * op = new WidgetRenderOpClass;
  336. op->Set_Color(color);
  337. op->Set_Opacity(opacity);
  338. op->Init_AABox(box);
  339. Add_Debug_Widget(op);
  340. }
  341. #endif
  342. #ifdef WWDEBUG
  343. void WidgetUserClass::Add_Debug_OBBox(const OBBoxClass & box,const Vector3 & color,float opacity)
  344. {
  345. WidgetRenderOpClass * op = new WidgetRenderOpClass;
  346. op->Set_Color(color);
  347. op->Set_Opacity(opacity);
  348. op->Init_OBBox(box);
  349. Add_Debug_Widget(op);
  350. }
  351. #endif
  352. #ifdef WWDEBUG
  353. void WidgetUserClass::Add_Debug_Axes(const Matrix3D & transform,const Vector3 & color)
  354. {
  355. WidgetRenderOpClass * op = new WidgetRenderOpClass;
  356. op->Set_Color(color);
  357. op->Init_Coord_Axes(transform);
  358. Add_Debug_Widget(op);
  359. }
  360. #endif
  361. #ifdef WWDEBUG
  362. void WidgetUserClass::Render_Debug_Widgets(RenderInfoClass & rinfo)
  363. {
  364. WW3D::Flush(rinfo);
  365. WidgetRenderOpClass * op = WidgetRenderOpList;
  366. while (op) {
  367. op->Render(rinfo);
  368. op = op->Get_Next();
  369. WW3D::Flush(rinfo);
  370. }
  371. }
  372. #endif