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