123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- // Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames
- // Copyright (C) 2015 Faust Logic, Inc.
- //
- // Permission is hereby granted, free of charge, to any person obtaining a copy
- // of this software and associated documentation files (the "Software"), to
- // deal in the Software without restriction, including without limitation the
- // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- // sell copies of the Software, and to permit persons to whom the Software is
- // furnished to do so, subject to the following conditions:
- //
- // The above copyright notice and this permission notice shall be included in
- // all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- // IN THE SOFTWARE.
- //
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- #include "afx/arcaneFX.h"
- #include "console/consoleTypes.h"
- #include "core/stream/bitStream.h"
- #include "scene/sceneRenderState.h"
- #include "materials/shaderData.h"
- #include "core/frameAllocator.h"
- #include "terrain/terrRender.h"
- #include "T3D/tsStatic.h"
- #include "T3D/groundPlane.h"
- #include "environment/meshRoad.h"
- #include "collision/concretePolyList.h"
- #include "gfx/primBuilder.h"
- #include "terrain/terrCell.h"
- #include "afx/ce/afxZodiac.h"
- #include "afx/ce/afxZodiacMgr.h"
- #include "afx/afxZodiacTerrainRenderer_T3D.h"
- #include "afx/afxZodiacGroundPlaneRenderer_T3D.h"
- #include "afx/afxZodiacMeshRoadRenderer_T3D.h"
- #include "afx/afxZodiacPolysoupRenderer_T3D.h"
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- // POLYSOUP INTERIOR ZODIACS //
- void afxZodiacMgr::renderPolysoupZodiacs(SceneRenderState* state, TSStatic* tss)
- {
- // check for active interior zodiacs
- S32 n_zodes = inter_zodes.size();
- if (n_zodes <= 0)
- return;
-
- static SphereF dummy_sphere;
- const Box3F& mWorldBox = tss->getWorldBox();
- const Point3F& cam_pos = state->getCameraPosition();
- // loop through the interior zodiacs
- for (U32 i = 0; i < n_zodes; i++)
- {
- // calculate zodiac extents
- F32 radius = inter_zodes[i].radius_xy;
- Box3F box_w; box_w.minExtents = box_w.maxExtents = inter_zodes[i].pos;
- box_w.minExtents -= Point3F(radius, radius, inter_zodes[i].vert_range.x);
- box_w.maxExtents += Point3F(radius, radius, inter_zodes[i].vert_range.y);
- // skip zodiacs not overlapping this object
- if (mWorldBox.isOverlapped(box_w) == false)
- continue;
- // collect list of zodiac-intersecting polygons
- ConcretePolyList* poly_list = new ConcretePolyList();
- ((SceneObject*)tss)->buildPolyList(PLC_Decal, poly_list, box_w, dummy_sphere);
- // render the polys if we get any
- if (!poly_list->mPolyList.empty())
- {
- // calculate zodiac distance from camera
- Point3F cam_vec = cam_pos - inter_zodes[i].pos;
- F32 cam_dist = cam_vec.lenSquared();
- // render zodiacs
- afxZodiacPolysoupRenderer::getMaster()->addZodiac(i, poly_list, inter_zodes[i].pos, inter_zodes[i].angle, tss, cam_dist);
- // note: poly_list will be deleted by render-manager after rendering is done.
- }
- else
- {
- delete poly_list; // avoids crash when overlapping box but not polygons
- }
- }
- }
- ShaderData* afxZodiacMgr::getPolysoupZodiacShader()
- {
- if (!polysoup_zode_shader)
- {
- if( !Sim::findObject("afxZodiacPolysoupShader", polysoup_zode_shader))
- {
- Con::errorf("afxZodiacMgr::getPolysoupZodiacShader() - failed to find shader 'afxZodiacPolysoupShader'.");
- return 0;
- }
- }
- return polysoup_zode_shader;
- }
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
-
- bool afxZodiacMgr::doesBoxOverlapZodiac(const Box3F& box, const afxZodiacMgr::ZodiacSpec& zode)
- {
- if ((zode.pos.x - zode.radius_xy) > box.maxExtents.x ||
- (zode.pos.y - zode.radius_xy) > box.maxExtents.y)
- return false;
- if ((zode.pos.x + zode.radius_xy) < box.minExtents.x ||
- ( zode.pos.y + zode.radius_xy) < box.minExtents.y)
- return false;
- return true;
- }
- static U32 last_terr_zode_idx = 0;
- bool afxZodiacMgr::doesBlockContainZodiacs(SceneRenderState* state, TerrainBlock* block)
- {
- // for now, only look at diffuse-passes
- if (!state->isDiffusePass())
- return false;
- // check for active terrain zodiacs
- S32 n_zodes = terr_zodes.size();
- if (n_zodes <= 0)
- return false;
- const Box3F& block_box = block->getWorldBox();
- last_terr_zode_idx = 0;
- for (U32 i = 0; i < n_zodes; i++)
- {
- if (doesBoxOverlapZodiac(block_box, terr_zodes[i]))
- {
- last_terr_zode_idx = i;
- return true;
- }
- }
- return false;
- }
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- bool afxZodiacMgr::renderTerrainZodiacs(SceneRenderState* state, TerrainBlock* block, TerrCell* cell)
- {
- // we assume here that afxZodiacMgr::doesBlockContainZodiacs() was recently called to
- // determine that at least one zodiac intersects the block and its index is last_terr_zode_idx.
- bool cell_has_zodiacs = false;
- const Point3F& cam_pos = state->getCameraPosition();
- const Box3F& block_box = block->getWorldBox();
- S32 n_zodes = terr_zodes.size();
- for (U32 i = last_terr_zode_idx; i < n_zodes; i++)
- {
- // first test against block's box
- if (!doesBoxOverlapZodiac(block_box, terr_zodes[i]))
- continue;
- const MatrixF& mRenderObjToWorld = block->getRenderTransform();
- Box3F cell_box = cell->getBounds();
- mRenderObjToWorld.mul(cell_box);
- if (!doesBoxOverlapZodiac(cell_box, terr_zodes[i]))
- continue;
- // at this point we know the zodiac overlaps AABB of cell...
- // calculate zodiac distance from camera
- Point3F cam_vec = cam_pos - terr_zodes[i].pos;
- F32 cam_dist = cam_vec.lenSquared();
- //if (cam_dist > 2500)
- // continue;
- // render zodiacs
- afxZodiacTerrainRenderer::getMaster()->addZodiac(i, terr_zodes[i].pos, terr_zodes[i].angle, block, cell, mRenderObjToWorld, cam_dist);
- cell_has_zodiacs = true;
- }
- last_terr_zode_idx = 0;
- return cell_has_zodiacs;
- }
- ShaderData* afxZodiacMgr::getTerrainZodiacShader()
- {
- if (!terrain_zode_shader)
- {
- if (!Sim::findObject("afxZodiacTerrainShader", terrain_zode_shader))
- {
- Con::errorf("afxZodiacMgr::getTerrainZodiacShader() - failed to find shader 'afxZodiacTerrainShader'.");
- return 0;
- }
- }
- return terrain_zode_shader;
- }
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- void afxZodiacMgr::renderGroundPlaneZodiacs(SceneRenderState* state, GroundPlane* ground_plane)
- {
- // check for active terrain zodiacs
- S32 n_zodes = terr_zodes.size();
- if (n_zodes <= 0)
- return;
- // we currently expect gound-plane to be infinite
- if (!ground_plane->isGlobalBounds())
- {
- return;
- }
- static SphereF dummy_sphere;
- static Box3F dummy_box;
- const Point3F& cam_pos = state->getCameraPosition();
- // loop through the terrain zodiacs
- for (U32 i = 0; i < n_zodes; i++)
- {
- // calculate zodiac distance from camera
- Point3F cam_vec = cam_pos - terr_zodes[i].pos;
- F32 cam_dist = cam_vec.lenSquared();
- // render zodiacs
- afxZodiacGroundPlaneRenderer::getMaster()->addZodiac(i, terr_zodes[i].pos, terr_zodes[i].angle, ground_plane, cam_dist);
- }
- }
- ShaderData* afxZodiacMgr::getGroundPlaneZodiacShader()
- {
- if (!terrain_zode_shader)
- {
- if (!Sim::findObject("afxZodiacTerrainShader", terrain_zode_shader))
- {
- Con::errorf("afxZodiacMgr::getTerrainZodiacShader() - failed to find shader 'afxZodiacTerrainShader'.");
- return 0;
- }
- }
- return terrain_zode_shader;
- }
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
- void afxZodiacMgr::renderMeshRoadZodiacs(SceneRenderState* state, MeshRoad* mesh_road)
- {
- // check for active terrain zodiacs
- S32 n_zodes = terr_zodes.size();
- if (n_zodes <= 0)
- return;
- const Box3F& mWorldBox = mesh_road->getWorldBox();
- const Point3F& cam_pos = state->getCameraPosition();
- // loop through the terrain zodiacs
- for (U32 i = 0; i < n_zodes; i++)
- {
- // calculate zodiac extents
- F32 radius = terr_zodes[i].radius_xy;
- Box3F box_w; box_w.minExtents = box_w.maxExtents = terr_zodes[i].pos;
- box_w.minExtents -= Point3F(radius, radius, terr_zodes[i].vert_range.x);
- box_w.maxExtents += Point3F(radius, radius, terr_zodes[i].vert_range.y);
- // skip zodiacs not overlapping this object
- if (mWorldBox.isOverlapped(box_w) == false)
- continue;
- // collect list of zodiac-intersecting polygons
- ConcretePolyList* poly_list = new ConcretePolyList();
- mesh_road->buildTopPolyList(PLC_Decal, poly_list);
- // render the polys if we get any
- if (!poly_list->mPolyList.empty())
- {
- // calculate zodiac distance from camera
- Point3F cam_vec = cam_pos - terr_zodes[i].pos;
- F32 cam_dist = cam_vec.lenSquared();
- // render zodiacs
- afxZodiacMeshRoadRenderer::getMaster()->addZodiac(i, poly_list, terr_zodes[i].pos, terr_zodes[i].angle, mesh_road, cam_dist);
- // note: poly_list will be deleted by render-manager after rendering is done.
- }
- else
- {
- delete poly_list; // avoids crash when overlapping box but not polygons
- }
- }
- }
- ShaderData* afxZodiacMgr::getMeshRoadZodiacShader()
- {
- if (!terrain_zode_shader)
- {
- if (!Sim::findObject("afxZodiacTerrainShader", terrain_zode_shader))
- {
- Con::errorf("afxZodiacMgr::getTerrainZodiacShader() - failed to find shader 'afxZodiacTerrainShader'.");
- return 0;
- }
- }
- return terrain_zode_shader;
- }
- //~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~//
|