afxXM_AltitudeConform.cpp
Engine/source/afx/xm/afxXM_AltitudeConform.cpp
Classes:
Public Functions
ConsoleDocClass(afxXM_AltitudeConformData , "@brief An xmod <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxXMods\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )
Detailed Description
Public Functions
ConsoleDocClass(afxXM_AltitudeConformData , "@brief An xmod <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">datablock.\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">afxXMods\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">AFX\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )
IMPLEMENT_CO_DATABLOCK_V1(afxXM_AltitudeConformData )
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 "afx/afxEffectWrapper.h" 30#include "afx/xm/afxXfmMod.h" 31 32//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 33 34class afxXM_AltitudeConformData : public afxXM_WeightedBaseData 35{ 36 typedef afxXM_WeightedBaseData Parent; 37 38public: 39 F32 height; 40 bool do_terrain; 41 bool do_interiors; 42 U32 interior_types; 43 U32 terrain_types; 44 bool do_freeze; 45 46public: 47 /*C*/ afxXM_AltitudeConformData(); 48 /*C*/ afxXM_AltitudeConformData(const afxXM_AltitudeConformData&, bool = false); 49 50 void packData(BitStream* stream); 51 void unpackData(BitStream* stream); 52 static void initPersistFields(); 53 54 afxXM_Base* create(afxEffectWrapper* fx, bool on_server); 55 56 DECLARE_CONOBJECT(afxXM_AltitudeConformData); 57 DECLARE_CATEGORY("AFX"); 58}; 59 60class afxXM_AltitudeConform : public afxXM_WeightedBase 61{ 62 typedef afxXM_WeightedBase Parent; 63 64 afxXM_AltitudeConformData* mConformData; 65 SceneContainer* mContainer; 66 bool mDo_freeze; 67 bool mIs_frozen; 68 F32 mTerrain_alt; 69 F32 mInterior_alt; 70 Point3F mConformed_pos; 71 72public: 73 /*C*/ afxXM_AltitudeConform(afxXM_AltitudeConformData*, afxEffectWrapper*, bool on_server); 74 75 virtual void updateParams(F32 dt, F32 elapsed, afxXM_Params& params); 76}; 77 78//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 79 80IMPLEMENT_CO_DATABLOCK_V1(afxXM_AltitudeConformData); 81 82ConsoleDocClass( afxXM_AltitudeConformData, 83 "@brief An xmod datablock.\n\n" 84 85 "@ingroup afxXMods\n" 86 "@ingroup AFX\n" 87 "@ingroup Datablocks\n" 88); 89 90afxXM_AltitudeConformData::afxXM_AltitudeConformData() 91{ 92 height = 0.0f; 93 do_terrain = false; 94 do_interiors = true; 95 do_freeze = false; 96 interior_types = InteriorLikeObjectType; 97 terrain_types = TerrainObjectType | TerrainLikeObjectType; 98} 99 100afxXM_AltitudeConformData::afxXM_AltitudeConformData(const afxXM_AltitudeConformData& other, bool temp_clone) 101 : afxXM_WeightedBaseData(other, temp_clone) 102{ 103 height = other.height; 104 do_terrain = other.do_terrain; 105 do_interiors = other.do_interiors; 106 do_freeze = other.do_freeze; 107 interior_types = other.interior_types; 108 terrain_types = other.terrain_types; 109} 110 111void afxXM_AltitudeConformData::initPersistFields() 112{ 113 addField("height", TypeF32, Offset(height, afxXM_AltitudeConformData), 114 "..."); 115 addField("conformToTerrain", TypeBool, Offset(do_terrain, afxXM_AltitudeConformData), 116 "..."); 117 addField("conformToInteriors", TypeBool, Offset(do_interiors, afxXM_AltitudeConformData), 118 "..."); 119 addField("freeze", TypeBool, Offset(do_freeze, afxXM_AltitudeConformData), 120 "..."); 121 addField("interiorTypes", TypeS32, Offset(interior_types, afxXM_AltitudeConformData), 122 "..."); 123 addField("terrainTypes", TypeS32, Offset(terrain_types, afxXM_AltitudeConformData), 124 "..."); 125 126 Parent::initPersistFields(); 127} 128 129void afxXM_AltitudeConformData::packData(BitStream* stream) 130{ 131 Parent::packData(stream); 132 stream->write(height); 133 stream->writeFlag(do_terrain); 134 stream->writeFlag(do_interiors); 135 stream->writeFlag(do_freeze); 136 stream->write(interior_types); 137 stream->write(terrain_types); 138} 139 140void afxXM_AltitudeConformData::unpackData(BitStream* stream) 141{ 142 Parent::unpackData(stream); 143 stream->read(&height); 144 do_terrain = stream->readFlag(); 145 do_interiors = stream->readFlag(); 146 do_freeze = stream->readFlag(); 147 stream->read(&interior_types); 148 stream->read(&terrain_types); 149} 150 151afxXM_Base* afxXM_AltitudeConformData::create(afxEffectWrapper* fx, bool on_server) 152{ 153 return new afxXM_AltitudeConform(this, fx, on_server); 154} 155 156//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~// 157 158afxXM_AltitudeConform::afxXM_AltitudeConform(afxXM_AltitudeConformData* db, afxEffectWrapper* fxw, bool on_server) 159: afxXM_WeightedBase(db, fxw) 160{ 161 mConformData = db; 162 mContainer = (on_server) ? &gServerContainer : &gClientContainer; 163 mDo_freeze = db->do_freeze; 164 mIs_frozen = false; 165 mTerrain_alt = -1.0f; 166 mInterior_alt = -1.0f; 167 mConformed_pos.zero(); 168} 169 170void afxXM_AltitudeConform::updateParams(F32 dt, F32 elapsed, afxXM_Params& params) 171{ 172 if (mIs_frozen) 173 { 174 if (mTerrain_alt >= 0.0f) 175 fx_wrapper->setTerrainAltitude(mTerrain_alt); 176 if (mInterior_alt >= 0.0f) 177 fx_wrapper->setInteriorAltitude(mInterior_alt); 178 params.pos = mConformed_pos; 179 return; 180 } 181 182 RayInfo rInfo1, rInfo2; 183 bool hit1 = false, hit2 = false; 184 bool hit1_is_interior = false; 185 186 // find primary ground 187 Point3F above_pos(params.pos); above_pos.z += 0.1f; 188 Point3F below_pos(params.pos); below_pos.z -= 10000; 189 hit1 = mContainer->castRay(above_pos, below_pos, mConformData->interior_types | mConformData->terrain_types, &rInfo1); 190 191 // find secondary ground 192 if (hit1 && rInfo1.object) 193 { 194 hit1_is_interior = ((rInfo1.object->getTypeMask() & mConformData->interior_types) != 0); 195 U32 mask = (hit1_is_interior) ? mConformData->terrain_types : mConformData->interior_types; 196 hit2 = mContainer->castRay(above_pos, below_pos, mask, &rInfo2); 197 } 198 199 if (hit1) 200 { 201 F32 wt_factor = calc_weight_factor(elapsed); 202 F32 incoming_z = params.pos.z; 203 F32 ground1_z = rInfo1.point.z + mConformData->height; 204 F32 pos_z = ground1_z + (1.0f - wt_factor)*(incoming_z - ground1_z); 205 206 if (hit1_is_interior) 207 { 208 mInterior_alt = incoming_z - pos_z; 209 fx_wrapper->setInteriorAltitude(mInterior_alt); 210 if (mConformData->do_interiors) 211 params.pos.z = pos_z; 212 } 213 else 214 { 215 mTerrain_alt = incoming_z - pos_z; 216 fx_wrapper->setTerrainAltitude(mTerrain_alt); 217 if (mConformData->do_terrain) 218 params.pos.z = pos_z; 219 } 220 221 if (hit2) 222 { 223 F32 ground2_z = rInfo2.point.z + mConformData->height; 224 F32 z2 = ground2_z + (1.0f - wt_factor)*(incoming_z - ground2_z); 225 if (hit1_is_interior) 226 { 227 mTerrain_alt = incoming_z - z2; 228 fx_wrapper->setTerrainAltitude(mTerrain_alt); 229 } 230 else 231 { 232 mInterior_alt = incoming_z - z2; 233 fx_wrapper->setInteriorAltitude(mInterior_alt); 234 } 235 } 236 237 // check for case where interior is underground 238 else if (hit1_is_interior) 239 { 240 RayInfo rInfo0; 241 Point3F lookup_from_pos(params.pos); lookup_from_pos.z -= 0.1f; 242 Point3F lookup_to_pos(params.pos); lookup_to_pos.z += 10000; 243 if (mContainer->castRay(lookup_from_pos, lookup_to_pos, TerrainObjectType, &rInfo0)) 244 { 245 F32 ground2_z = rInfo0.point.z + mConformData->height; 246 F32 z2 = ground2_z + (1.0f - wt_factor)*(incoming_z - ground2_z); 247 mTerrain_alt = z2 - incoming_z; 248 fx_wrapper->setTerrainAltitude(mTerrain_alt); 249 } 250 } 251 252 if (mDo_freeze) 253 { 254 mConformed_pos = params.pos; 255 mIs_frozen = true; 256 } 257 } 258} 259 260//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 261 262