afxZodiacMgr_T3D.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  2. // Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
  3. // Copyright (C) 2015 Faust Logic, Inc.
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to
  7. // deal in the Software without restriction, including without limitation the
  8. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  9. // sell copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. // IN THE SOFTWARE.
  22. //
  23. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  24. #include "afx/arcaneFX.h"
  25. #include "console/consoleTypes.h"
  26. #include "core/stream/bitStream.h"
  27. #include "scene/sceneRenderState.h"
  28. #include "materials/shaderData.h"
  29. #include "core/frameAllocator.h"
  30. #include "terrain/terrRender.h"
  31. #include "T3D/tsStatic.h"
  32. #include "T3D/groundPlane.h"
  33. #include "environment/meshRoad.h"
  34. #include "collision/concretePolyList.h"
  35. #include "gfx/primBuilder.h"
  36. #include "terrain/terrCell.h"
  37. #include "afx/ce/afxZodiac.h"
  38. #include "afx/ce/afxZodiacMgr.h"
  39. #include "afx/afxZodiacTerrainRenderer_T3D.h"
  40. #include "afx/afxZodiacGroundPlaneRenderer_T3D.h"
  41. #include "afx/afxZodiacMeshRoadRenderer_T3D.h"
  42. #include "afx/afxZodiacPolysoupRenderer_T3D.h"
  43. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  44. // POLYSOUP INTERIOR ZODIACS //
  45. void afxZodiacMgr::renderPolysoupZodiacs(SceneRenderState* state, TSStatic* tss)
  46. {
  47. // check for active interior zodiacs
  48. S32 n_zodes = inter_zodes.size();
  49. if (n_zodes <= 0)
  50. return;
  51. static SphereF dummy_sphere;
  52. const Box3F& mWorldBox = tss->getWorldBox();
  53. const Point3F& cam_pos = state->getCameraPosition();
  54. // loop through the interior zodiacs
  55. for (U32 i = 0; i < n_zodes; i++)
  56. {
  57. // calculate zodiac extents
  58. F32 radius = inter_zodes[i].radius_xy;
  59. Box3F box_w; box_w.minExtents = box_w.maxExtents = inter_zodes[i].pos;
  60. box_w.minExtents -= Point3F(radius, radius, inter_zodes[i].vert_range.x);
  61. box_w.maxExtents += Point3F(radius, radius, inter_zodes[i].vert_range.y);
  62. // skip zodiacs not overlapping this object
  63. if (mWorldBox.isOverlapped(box_w) == false)
  64. continue;
  65. // collect list of zodiac-intersecting polygons
  66. ConcretePolyList* poly_list = new ConcretePolyList();
  67. ((SceneObject*)tss)->buildPolyList(PLC_Decal, poly_list, box_w, dummy_sphere);
  68. // render the polys if we get any
  69. if (!poly_list->mPolyList.empty())
  70. {
  71. // calculate zodiac distance from camera
  72. Point3F cam_vec = cam_pos - inter_zodes[i].pos;
  73. F32 cam_dist = cam_vec.lenSquared();
  74. // render zodiacs
  75. afxZodiacPolysoupRenderer::getMaster()->addZodiac(i, poly_list, inter_zodes[i].pos, inter_zodes[i].angle, tss, cam_dist);
  76. // note: poly_list will be deleted by render-manager after rendering is done.
  77. }
  78. else
  79. {
  80. delete poly_list; // avoids crash when overlapping box but not polygons
  81. }
  82. }
  83. }
  84. ShaderData* afxZodiacMgr::getPolysoupZodiacShader()
  85. {
  86. if (!polysoup_zode_shader)
  87. {
  88. if( !Sim::findObject("afxZodiacPolysoupShader", polysoup_zode_shader))
  89. {
  90. Con::errorf("afxZodiacMgr::getPolysoupZodiacShader() - failed to find shader 'afxZodiacPolysoupShader'.");
  91. return 0;
  92. }
  93. }
  94. return polysoup_zode_shader;
  95. }
  96. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  97. bool afxZodiacMgr::doesBoxOverlapZodiac(const Box3F& box, const afxZodiacMgr::ZodiacSpec& zode)
  98. {
  99. if ((zode.pos.x - zode.radius_xy) > box.maxExtents.x ||
  100. (zode.pos.y - zode.radius_xy) > box.maxExtents.y)
  101. return false;
  102. if ((zode.pos.x + zode.radius_xy) < box.minExtents.x ||
  103. ( zode.pos.y + zode.radius_xy) < box.minExtents.y)
  104. return false;
  105. return true;
  106. }
  107. static U32 last_terr_zode_idx = 0;
  108. bool afxZodiacMgr::doesBlockContainZodiacs(SceneRenderState* state, TerrainBlock* block)
  109. {
  110. // for now, only look at diffuse-passes
  111. if (!state->isDiffusePass())
  112. return false;
  113. // check for active terrain zodiacs
  114. S32 n_zodes = terr_zodes.size();
  115. if (n_zodes <= 0)
  116. return false;
  117. const Box3F& block_box = block->getWorldBox();
  118. last_terr_zode_idx = 0;
  119. for (U32 i = 0; i < n_zodes; i++)
  120. {
  121. if (doesBoxOverlapZodiac(block_box, terr_zodes[i]))
  122. {
  123. last_terr_zode_idx = i;
  124. return true;
  125. }
  126. }
  127. return false;
  128. }
  129. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  130. bool afxZodiacMgr::renderTerrainZodiacs(SceneRenderState* state, TerrainBlock* block, TerrCell* cell)
  131. {
  132. // we assume here that afxZodiacMgr::doesBlockContainZodiacs() was recently called to
  133. // determine that at least one zodiac intersects the block and its index is last_terr_zode_idx.
  134. bool cell_has_zodiacs = false;
  135. const Point3F& cam_pos = state->getCameraPosition();
  136. const Box3F& block_box = block->getWorldBox();
  137. S32 n_zodes = terr_zodes.size();
  138. for (U32 i = last_terr_zode_idx; i < n_zodes; i++)
  139. {
  140. // first test against block's box
  141. if (!doesBoxOverlapZodiac(block_box, terr_zodes[i]))
  142. continue;
  143. const MatrixF& mRenderObjToWorld = block->getRenderTransform();
  144. Box3F cell_box = cell->getBounds();
  145. mRenderObjToWorld.mul(cell_box);
  146. if (!doesBoxOverlapZodiac(cell_box, terr_zodes[i]))
  147. continue;
  148. // at this point we know the zodiac overlaps AABB of cell...
  149. // calculate zodiac distance from camera
  150. Point3F cam_vec = cam_pos - terr_zodes[i].pos;
  151. F32 cam_dist = cam_vec.lenSquared();
  152. //if (cam_dist > 2500)
  153. // continue;
  154. // render zodiacs
  155. afxZodiacTerrainRenderer::getMaster()->addZodiac(i, terr_zodes[i].pos, terr_zodes[i].angle, block, cell, mRenderObjToWorld, cam_dist);
  156. cell_has_zodiacs = true;
  157. }
  158. last_terr_zode_idx = 0;
  159. return cell_has_zodiacs;
  160. }
  161. ShaderData* afxZodiacMgr::getTerrainZodiacShader()
  162. {
  163. if (!terrain_zode_shader)
  164. {
  165. if (!Sim::findObject("afxZodiacTerrainShader", terrain_zode_shader))
  166. {
  167. Con::errorf("afxZodiacMgr::getTerrainZodiacShader() - failed to find shader 'afxZodiacTerrainShader'.");
  168. return 0;
  169. }
  170. }
  171. return terrain_zode_shader;
  172. }
  173. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  174. void afxZodiacMgr::renderGroundPlaneZodiacs(SceneRenderState* state, GroundPlane* ground_plane)
  175. {
  176. // check for active terrain zodiacs
  177. S32 n_zodes = terr_zodes.size();
  178. if (n_zodes <= 0)
  179. return;
  180. // we currently expect gound-plane to be infinite
  181. if (!ground_plane->isGlobalBounds())
  182. {
  183. return;
  184. }
  185. static SphereF dummy_sphere;
  186. static Box3F dummy_box;
  187. const Point3F& cam_pos = state->getCameraPosition();
  188. // loop through the terrain zodiacs
  189. for (U32 i = 0; i < n_zodes; i++)
  190. {
  191. // calculate zodiac distance from camera
  192. Point3F cam_vec = cam_pos - terr_zodes[i].pos;
  193. F32 cam_dist = cam_vec.lenSquared();
  194. // render zodiacs
  195. afxZodiacGroundPlaneRenderer::getMaster()->addZodiac(i, terr_zodes[i].pos, terr_zodes[i].angle, ground_plane, cam_dist);
  196. }
  197. }
  198. ShaderData* afxZodiacMgr::getGroundPlaneZodiacShader()
  199. {
  200. if (!terrain_zode_shader)
  201. {
  202. if (!Sim::findObject("afxZodiacTerrainShader", terrain_zode_shader))
  203. {
  204. Con::errorf("afxZodiacMgr::getTerrainZodiacShader() - failed to find shader 'afxZodiacTerrainShader'.");
  205. return 0;
  206. }
  207. }
  208. return terrain_zode_shader;
  209. }
  210. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
  211. void afxZodiacMgr::renderMeshRoadZodiacs(SceneRenderState* state, MeshRoad* mesh_road)
  212. {
  213. // check for active terrain zodiacs
  214. S32 n_zodes = terr_zodes.size();
  215. if (n_zodes <= 0)
  216. return;
  217. const Box3F& mWorldBox = mesh_road->getWorldBox();
  218. const Point3F& cam_pos = state->getCameraPosition();
  219. // loop through the terrain zodiacs
  220. for (U32 i = 0; i < n_zodes; i++)
  221. {
  222. // calculate zodiac extents
  223. F32 radius = terr_zodes[i].radius_xy;
  224. Box3F box_w; box_w.minExtents = box_w.maxExtents = terr_zodes[i].pos;
  225. box_w.minExtents -= Point3F(radius, radius, terr_zodes[i].vert_range.x);
  226. box_w.maxExtents += Point3F(radius, radius, terr_zodes[i].vert_range.y);
  227. // skip zodiacs not overlapping this object
  228. if (mWorldBox.isOverlapped(box_w) == false)
  229. continue;
  230. // collect list of zodiac-intersecting polygons
  231. ConcretePolyList* poly_list = new ConcretePolyList();
  232. mesh_road->buildTopPolyList(PLC_Decal, poly_list);
  233. // render the polys if we get any
  234. if (!poly_list->mPolyList.empty())
  235. {
  236. // calculate zodiac distance from camera
  237. Point3F cam_vec = cam_pos - terr_zodes[i].pos;
  238. F32 cam_dist = cam_vec.lenSquared();
  239. // render zodiacs
  240. afxZodiacMeshRoadRenderer::getMaster()->addZodiac(i, poly_list, terr_zodes[i].pos, terr_zodes[i].angle, mesh_road, cam_dist);
  241. // note: poly_list will be deleted by render-manager after rendering is done.
  242. }
  243. else
  244. {
  245. delete poly_list; // avoids crash when overlapping box but not polygons
  246. }
  247. }
  248. }
  249. ShaderData* afxZodiacMgr::getMeshRoadZodiacShader()
  250. {
  251. if (!terrain_zode_shader)
  252. {
  253. if (!Sim::findObject("afxZodiacTerrainShader", terrain_zode_shader))
  254. {
  255. Con::errorf("afxZodiacMgr::getTerrainZodiacShader() - failed to find shader 'afxZodiacTerrainShader'.");
  256. return 0;
  257. }
  258. }
  259. return terrain_zode_shader;
  260. }
  261. //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//