physicalZone.cpp
Engine/source/T3D/physicalZone.cpp
Public Variables
Public Functions
ConsoleDocClass(PhysicalZone , "@brief Physical Zones are areas that modify the player's gravity and/or velocity and/or applied <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">force.\n\n</a>" "The datablock properties determine how the physics, velocity and applied forces affect <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> player who enters this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">zone.\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classphysicalzone/">PhysicalZone</a>(Team1JumpPad) {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "velocityMod=\"1\";" "gravityMod = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "appliedForce = \"0 0 20000\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "polyhedron = \"0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 1.0000000\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "position = \"273.559 -166.371 249.856\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "rotation = \"0 0 1 13.0216\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "scale = \"8 4.95 28.31\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "isRenderEnabled = \"true\";\n" "canSaveDynamicFields = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "enabled = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enviroMisc\n</a>" )
DefineEngineMethod(PhysicalZone , activate , void , () , "Activate the physical zone's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">effects.\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Activate effects <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specific physical <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">zone.\n</a>" "%thisPhysicalZone.activate();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )
DefineEngineMethod(PhysicalZone , deactivate , void , () , "Deactivate the physical zone's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">effects.\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Deactivate effects <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specific physical <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">zone.\n</a>" "%thisPhysicalZone.deactivate();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )
ImplementEnumType(PhysicalZone_ForceType , "Possible physical zone force <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">types.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PhysicalZone\n\n</a>" )
Detailed Description
Public Variables
EndImplementEnumType
Public Functions
ConsoleDocClass(PhysicalZone , "@brief Physical Zones are areas that modify the player's gravity and/or velocity and/or applied <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">force.\n\n</a>" "The datablock properties determine how the physics, velocity and applied forces affect <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> player who enters this <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">zone.\n</a>" " @<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "<a href="/coding/file/tmm__on_8h/#tmm__on_8h_1a1ac41480eb2e4aadd52252ee550b630a">new</a> <a href="/coding/class/classphysicalzone/">PhysicalZone</a>(Team1JumpPad) {\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "velocityMod=\"1\";" "gravityMod = \"0\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "appliedForce = \"0 0 20000\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "polyhedron = \"0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 1.0000000\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "position = \"273.559 -166.371 249.856\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "rotation = \"0 0 1 13.0216\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "scale = \"8 4.95 28.31\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "isRenderEnabled = \"true\";\n" "canSaveDynamicFields = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "enabled = \"1\";\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "};\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">enviroMisc\n</a>" )
DefineEngineMethod(PhysicalZone , activate , void , () , "Activate the physical zone's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">effects.\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Activate effects <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specific physical <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">zone.\n</a>" "%thisPhysicalZone.activate();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )
DefineEngineMethod(PhysicalZone , deactivate , void , () , "Deactivate the physical zone's <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">effects.\n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">tsexample\n</a>" "// Deactivate effects <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1a2732ab74fa0237854c2ba0f75f88a624">for</a> <a href="/coding/file/pointer_8h/#pointer_8h_1aeeddce917cf130d62c370b8f216026dd">a</a> specific physical <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">zone.\n</a>" "%thisPhysicalZone.deactivate();\<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">n</a>" "@<a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">endtsexample\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">Datablocks\n</a>" )
IMPLEMENT_CO_NETOBJECT_V1(PhysicalZone )
ImplementEnumType(PhysicalZone_ForceType , "Possible physical zone force <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">types.\n</a>" "@ingroup <a href="/coding/file/cmdscan_8cpp/#cmdscan_8cpp_1aeab71244afb687f16d8c4f5ee9d6ef0e">PhysicalZone\n\n</a>" )
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 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//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 25// Arcane-FX for MIT Licensed Open Source version of Torque 3D from GarageGames 26// Copyright (C) 2015 Faust Logic, Inc. 27//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~//~~~~~~~~~~~~~~~~~~~~~// 28 29#include "T3D/physicalZone.h" 30#include "core/stream/bitStream.h" 31#include "collision/boxConvex.h" 32#include "collision/clippedPolyList.h" 33#include "console/consoleTypes.h" 34#include "math/mathIO.h" 35#include "scene/sceneRenderState.h" 36#include "T3D/trigger.h" 37#include "gfx/gfxTransformSaver.h" 38#include "renderInstance/renderPassManager.h" 39#include "gfx/gfxDrawUtil.h" 40#include "console/engineAPI.h" 41 42//#include "console/engineTypes.h" 43#include "sim/netConnection.h" 44IMPLEMENT_CO_NETOBJECT_V1(PhysicalZone); 45 46ConsoleDocClass( PhysicalZone, 47 "@brief Physical Zones are areas that modify the player's gravity and/or velocity and/or applied force.\n\n" 48 49 "The datablock properties determine how the physics, velocity and applied forces affect a player who enters this zone.\n" 50 51 "@tsexample\n" 52 "new PhysicalZone(Team1JumpPad) {\n" 53 "velocityMod = \"1\";" 54 "gravityMod = \"0\";\n" 55 "appliedForce = \"0 0 20000\";\n" 56 "polyhedron = \"0.0000000 0.0000000 0.0000000 1.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 1.0000000\";\n" 57 "position = \"273.559 -166.371 249.856\";\n" 58 "rotation = \"0 0 1 13.0216\";\n" 59 "scale = \"8 4.95 28.31\";\n" 60 "isRenderEnabled = \"true\";\n" 61 "canSaveDynamicFields = \"1\";\n" 62 "enabled = \"1\";\n" 63 "};\n" 64 "@endtsexample\n\n" 65 "@ingroup enviroMisc\n" 66); 67 68bool PhysicalZone::smRenderPZones = false; 69 70DefineEngineMethod(PhysicalZone, activate, void, (),, "Activate the physical zone's effects.\n" 71 "@tsexample\n" 72 "// Activate effects for a specific physical zone.\n" 73 "%thisPhysicalZone.activate();\n" 74 "@endtsexample\n" 75 "@ingroup Datablocks\n" 76 ) 77{ 78 if (object->isClientObject()) 79 return; 80 81 object->activate(); 82} 83 84DefineEngineMethod(PhysicalZone, deactivate, void, (),, "Deactivate the physical zone's effects.\n" 85 "@tsexample\n" 86 "// Deactivate effects for a specific physical zone.\n" 87 "%thisPhysicalZone.deactivate();\n" 88 "@endtsexample\n" 89 "@ingroup Datablocks\n" 90 ) 91{ 92 if (object->isClientObject()) 93 return; 94 95 object->deactivate(); 96} 97 98 99//-------------------------------------------------------------------------- 100//-------------------------------------- 101// 102PhysicalZone::PhysicalZone() 103{ 104 mNetFlags.set(Ghostable | ScopeAlways); 105 106 mTypeMask |= PhysicalZoneObjectType; 107 108 mVelocityMod = 1.0f; 109 mGravityMod = 1.0f; 110 mAppliedForce.set(0, 0, 0); 111 112 mConvexList = new Convex; 113 mActive = true; 114 force_type = VECTOR; 115 force_mag = 0.0f; 116 orient_force = false; 117 fade_amt = 1.0f; 118} 119 120PhysicalZone::~PhysicalZone() 121{ 122 delete mConvexList; 123 mConvexList = NULL; 124} 125 126 127ImplementEnumType( PhysicalZone_ForceType, "Possible physical zone force types.\n" "@ingroup PhysicalZone\n\n" ) 128 { PhysicalZone::VECTOR, "vector", "..." }, 129 { PhysicalZone::SPHERICAL, "spherical", "..." }, 130 { PhysicalZone::CYLINDRICAL, "cylindrical", "..." }, 131 // aliases 132 { PhysicalZone::SPHERICAL, "sphere", "..." }, 133 { PhysicalZone::CYLINDRICAL, "cylinder", "..." }, 134EndImplementEnumType; 135 136//-------------------------------------------------------------------------- 137void PhysicalZone::consoleInit() 138{ 139 Con::addVariable( "$PhysicalZone::renderZones", TypeBool, &smRenderPZones, "If true, a box will render around the location of all PhysicalZones.\n" 140 "@ingroup EnviroMisc\n"); 141} 142 143void PhysicalZone::initPersistFields() 144{ 145 addGroup("Misc"); 146 addField("velocityMod", TypeF32, Offset(mVelocityMod, PhysicalZone), "Multiply velocity of objects entering zone by this value every tick."); 147 addField("gravityMod", TypeF32, Offset(mGravityMod, PhysicalZone), "Gravity in PhysicalZone. Multiplies against standard gravity."); 148 addField("appliedForce", TypePoint3F, Offset(mAppliedForce, PhysicalZone), "Three-element floating point value representing forces in three axes to apply to objects entering PhysicalZone."); 149 addField("polyhedron", TypeTriggerPolyhedron, Offset(mPolyhedron, PhysicalZone), 150 "The polyhedron type is really a quadrilateral and consists of a corner" 151 "point followed by three vectors representing the edges extending from the corner." ); 152 endGroup("Misc"); 153 154 addGroup("AFX"); 155 addField("forceType", TYPEID<PhysicalZone::ForceType>(), Offset(force_type, PhysicalZone)); 156 addField("orientForce", TypeBool, Offset(orient_force, PhysicalZone)); 157 endGroup("AFX"); 158 Parent::initPersistFields(); 159} 160 161//-------------------------------------------------------------------------- 162bool PhysicalZone::onAdd() 163{ 164 if(!Parent::onAdd()) 165 return false; 166 167 if (mVelocityMod < -40.0f || mVelocityMod > 40.0f) { 168 Con::errorf("PhysicalZone: velocity mod out of range. [-40, 40]"); 169 mVelocityMod = mVelocityMod < -40.0f ? -40.0f : 40.0f; 170 } 171 if (mGravityMod < -40.0f || mGravityMod > 40.0f) { 172 Con::errorf("PhysicalZone: GravityMod out of range. [-40, 40]"); 173 mGravityMod = mGravityMod < -40.0f ? -40.0f : 40.0f; 174 } 175 static const char* coordString[] = { "x", "y", "z" }; 176 F32* p = mAppliedForce; 177 for (U32 i = 0; i < 3; i++) { 178 if (p[i] < -40000.0f || p[i] > 40000.0f) { 179 Con::errorf("PhysicalZone: applied force: %s out of range. [-40000, 40000]", coordString[i]); 180 p[i] = p[i] < -40000.0f ? -40000.0f : 40000.0f; 181 } 182 } 183 184 Polyhedron temp = mPolyhedron; 185 setPolyhedron(temp); 186 187 switch (force_type) 188 { 189 case SPHERICAL: 190 force_mag = mAppliedForce.magnitudeSafe(); 191 break; 192 case CYLINDRICAL: 193 { 194 Point3F force_vec = mAppliedForce; 195 force_vec.z = 0.0; 196 force_mag = force_vec.magnitudeSafe(); 197 } 198 break; 199 } 200 addToScene(); 201 202 return true; 203} 204 205 206void PhysicalZone::onRemove() 207{ 208 mConvexList->nukeList(); 209 210 removeFromScene(); 211 Parent::onRemove(); 212} 213 214void PhysicalZone::inspectPostApply() 215{ 216 Parent::inspectPostApply(); 217 218 setPolyhedron(mPolyhedron); 219 setMaskBits(PolyhedronMask | MoveMask | SettingsMask | FadeMask); 220} 221 222//------------------------------------------------------------------------------ 223void PhysicalZone::setTransform(const MatrixF & mat) 224{ 225 Parent::setTransform(mat); 226 227 MatrixF base(true); 228 base.scale(Point3F(1.0/<a href="/coding/class/classsceneobject/#classsceneobject_1abf78914dea349b0201b66591567c6d91">mObjScale</a>.x, 229 1.0/<a href="/coding/class/classsceneobject/#classsceneobject_1abf78914dea349b0201b66591567c6d91">mObjScale</a>.y, 230 1.0/<a href="/coding/class/classsceneobject/#classsceneobject_1abf78914dea349b0201b66591567c6d91">mObjScale</a>.z)); 231 base.mul(mWorldToObj); 232 mClippedList.setBaseTransform(base); 233 234 if (isServerObject()) 235 setMaskBits(MoveMask); 236} 237 238 239void PhysicalZone::prepRenderImage( SceneRenderState *state ) 240{ 241 // only render if selected or render flag is set 242 if ( !smRenderPZones && !isSelected() ) 243 return; 244 245 ObjectRenderInst *ri = state->getRenderPass()->allocInst<ObjectRenderInst>(); 246 ri->renderDelegate.bind( this, &PhysicalZone::renderObject ); 247 ri->type = RenderPassManager::RIT_Editor; 248 ri->defaultKey = 0; 249 ri->defaultKey2 = 0; 250 state->getRenderPass()->addInst( ri ); 251} 252 253 254void PhysicalZone::renderObject(ObjectRenderInst *ri, 255 SceneRenderState *state, 256 BaseMatInstance *overrideMat) 257{ 258 if (overrideMat) 259 return; 260 261 GFXStateBlockDesc desc; 262 desc.setZReadWrite(true, false); 263 desc.setBlend(true); 264 desc.setCullMode(GFXCullNone); 265 266 GFXTransformSaver saver; 267 268 GFXDrawUtil *drawer = GFX->getDrawUtil(); 269 270 Point3F start = getBoxCenter(); 271 Box3F obb = mObjBox; //object bounding box 272 273 F32 baseForce = 10000; //roughly the ammount of force needed to push a player back as it walks into a zone. (used for visual scaling) 274 275 Point3F forceDir = getForce(&start); 276 F32 forceLen = forceDir.len()/ baseForce; 277 forceDir.normalizeSafe(); 278 ColorI guideCol = LinearColorF(mFabs(forceDir.x), mFabs(forceDir.y), mFabs(forceDir.z), 0.125).toColorI(); 279 280 if (force_type == VECTOR) 281 { 282 Point3F endPos = start + (forceDir * mMax(forceLen,0.75f)); 283 drawer->drawArrow(desc, start, endPos, guideCol, 0.05f); 284 } 285 286 MatrixF mat = getRenderTransform(); 287 mat.scale(getScale()); 288 289 GFX->multWorld(mat); 290 start = obb.getCenter(); 291 292 if (force_type == VECTOR) 293 { 294 drawer->drawPolyhedron(desc, mPolyhedron, ColorI(0, 255, 0, 45)); 295 } 296 else if (force_type == SPHERICAL) 297 { 298 F32 rad = obb.getBoundingSphere().radius/ 2; 299 drawer->drawSphere(desc, rad, start, ColorI(0, 255, 0, 45)); 300 301 rad = (rad + (mAppliedForce.most() / baseForce))/2; 302 desc.setFillModeWireframe(); 303 drawer->drawSphere(desc, rad, start, ColorI(0, 0, 255, 255)); 304 } 305 else 306 { 307 Point3F bottomPos = start; 308 bottomPos.z -= obb.len_z() / 2; 309 310 Point3F topPos = start; 311 topPos.z += obb.len_z() / 2; 312 F32 rad = obb.len_x() / 2; 313 drawer->drawCylinder(desc, bottomPos, topPos, rad, ColorI(0, 255, 0, 45)); 314 315 Point3F force_vec = mAppliedForce; //raw relative-applied force here as oposed to derived 316 F32 hieght = (force_vec.z / baseForce); 317 318 if (force_vec.z<0) 319 bottomPos.z = (bottomPos.z + hieght)/2; 320 else 321 topPos.z = (topPos.z + hieght) / 2; 322 323 if (force_vec.x > force_vec.y) 324 rad = (rad + (force_vec.x / baseForce)) / 2; 325 else 326 rad = (rad + (force_vec.y / baseForce)) / 2; 327 328 329 desc.setFillModeWireframe(); 330 drawer->drawCylinder(desc, bottomPos, topPos, rad, guideCol); 331 } 332 333 desc.setFillModeWireframe(); 334 drawer->drawPolyhedron(desc, mPolyhedron, ColorI::BLACK); 335} 336 337//-------------------------------------------------------------------------- 338U32 PhysicalZone::packUpdate(NetConnection* con, U32 mask, BitStream* stream) 339{ 340 U32 i; 341 U32 retMask = Parent::packUpdate(con, mask, stream); 342 343 if (stream->writeFlag(mask & PolyhedronMask)) 344 { 345 // Write the polyhedron 346 stream->write(mPolyhedron.mPointList.size()); 347 for (i = 0; i < mPolyhedron.mPointList.size(); i++) 348 mathWrite(*stream, mPolyhedron.mPointList[i]); 349 350 stream->write(mPolyhedron.mPlaneList.size()); 351 for (i = 0; i < mPolyhedron.mPlaneList.size(); i++) 352 mathWrite(*stream, mPolyhedron.mPlaneList[i]); 353 354 stream->write(mPolyhedron.mEdgeList.size()); 355 for (i = 0; i < mPolyhedron.mEdgeList.size(); i++) { 356 const Polyhedron::Edge& rEdge = mPolyhedron.mEdgeList[i]; 357 358 stream->write(rEdge.face[0]); 359 stream->write(rEdge.face[1]); 360 stream->write(rEdge.vertex[0]); 361 stream->write(rEdge.vertex[1]); 362 } 363 } 364 365 if (stream->writeFlag(mask & MoveMask)) 366 { 367 stream->writeAffineTransform(mObjToWorld); 368 mathWrite(*stream, mObjScale); 369 } 370 371 if (stream->writeFlag(mask & SettingsMask)) 372 { 373 stream->write(mVelocityMod); 374 stream->write(mGravityMod); 375 mathWrite(*stream, mAppliedForce); 376 stream->writeInt(force_type, FORCE_TYPE_BITS); 377 stream->writeFlag(orient_force); 378 } 379 380 if (stream->writeFlag(mask & FadeMask)) 381 { 382 U8 fade_byte = (U8)(fade_amt*255.0f); 383 stream->write(fade_byte); 384 } 385 386 stream->writeFlag(mActive); 387 388 return retMask; 389} 390 391void PhysicalZone::unpackUpdate(NetConnection* con, BitStream* stream) 392{ 393 Parent::unpackUpdate(con, stream); 394 395 bool new_ph = false; 396 if (stream->readFlag()) // PolyhedronMask 397 { 398 U32 i, size; 399 Polyhedron tempPH; 400 401 // Read the polyhedron 402 stream->read(&size); 403 tempPH.mPointList.setSize(size); 404 for (i = 0; i < tempPH.mPointList.size(); i++) 405 mathRead(*stream, &tempPH.mPointList[i]); 406 407 stream->read(&size); 408 tempPH.mPlaneList.setSize(size); 409 for (i = 0; i < tempPH.mPlaneList.size(); i++) 410 mathRead(*stream, &tempPH.mPlaneList[i]); 411 412 stream->read(&size); 413 tempPH.mEdgeList.setSize(size); 414 for (i = 0; i < tempPH.mEdgeList.size(); i++) { 415 Polyhedron::Edge& rEdge = tempPH.mEdgeList[i]; 416 417 stream->read(&rEdge.face[0]); 418 stream->read(&rEdge.face[1]); 419 stream->read(&rEdge.vertex[0]); 420 stream->read(&rEdge.vertex[1]); 421 } 422 423 setPolyhedron(tempPH); 424 new_ph = true; 425 } 426 427 if (stream->readFlag()) // MoveMask 428 { 429 MatrixF temp; 430 stream->readAffineTransform(&temp); 431 432 Point3F tempScale; 433 mathRead(*stream, &tempScale); 434 435 //if (!new_ph) 436 //{ 437 // Polyhedron rPolyhedron = mPolyhedron; 438 // setPolyhedron(rPolyhedron); 439 //} 440 setScale(tempScale); 441 setTransform(temp); 442 } 443 444 if (stream->readFlag()) //SettingsMask 445 { 446 stream->read(&mVelocityMod); 447 stream->read(&mGravityMod); 448 mathRead(*stream, &mAppliedForce); 449 force_type = stream->readInt(FORCE_TYPE_BITS); // AFX 450 orient_force = stream->readFlag(); // AFX 451 } 452 453 if (stream->readFlag()) //FadeMask 454 { 455 U8 fade_byte; 456 stream->read(&fade_byte); 457 fade_amt = ((F32)fade_byte)/255.0f; 458 } 459 else 460 fade_amt = 1.0f; 461 462 mActive = stream->readFlag(); 463} 464 465 466//-------------------------------------------------------------------------- 467void PhysicalZone::setPolyhedron(const Polyhedron& rPolyhedron) 468{ 469 mPolyhedron = rPolyhedron; 470 471 if (mPolyhedron.mPointList.size() != 0) { 472 mObjBox.minExtents.set(1e10, 1e10, 1e10); 473 mObjBox.maxExtents.set(-1e10, -1e10, -1e10); 474 for (U32 i = 0; i < mPolyhedron.mPointList.size(); i++) { 475 mObjBox.minExtents.setMin(mPolyhedron.mPointList[i]); 476 mObjBox.maxExtents.setMax(mPolyhedron.mPointList[i]); 477 } 478 } else { 479 mObjBox.minExtents.set(-0.5, -0.5, -0.5); 480 mObjBox.maxExtents.set( 0.5, 0.5, 0.5); 481 } 482 483 MatrixF xform = getTransform(); 484 setTransform(xform); 485 486 mClippedList.clear(); 487 mClippedList.mPlaneList = mPolyhedron.mPlaneList; 488 489 MatrixF base(true); 490 base.scale(Point3F(1.0/<a href="/coding/class/classsceneobject/#classsceneobject_1abf78914dea349b0201b66591567c6d91">mObjScale</a>.x, 491 1.0/<a href="/coding/class/classsceneobject/#classsceneobject_1abf78914dea349b0201b66591567c6d91">mObjScale</a>.y, 492 1.0/<a href="/coding/class/classsceneobject/#classsceneobject_1abf78914dea349b0201b66591567c6d91">mObjScale</a>.z)); 493 base.mul(mWorldToObj); 494 495 mClippedList.setBaseTransform(base); 496} 497 498 499//-------------------------------------------------------------------------- 500void PhysicalZone::buildConvex(const Box3F& box, Convex* convex) 501{ 502 // These should really come out of a pool 503 mConvexList->collectGarbage(); 504 505 Box3F realBox = box; 506 mWorldToObj.mul(realBox); 507 realBox.minExtents.convolveInverse(mObjScale); 508 realBox.maxExtents.convolveInverse(mObjScale); 509 510 if (realBox.isOverlapped(getObjBox()) == false) 511 return; 512 513 // Just return a box convex for the entire shape... 514 Convex* cc = 0; 515 CollisionWorkingList& wl = convex->getWorkingList(); 516 for (CollisionWorkingList* itr = wl.wLink.mNext; itr != &wl; itr = itr->wLink.mNext) { 517 if (itr->mConvex->getType() == BoxConvexType && 518 itr->mConvex->getObject() == this) { 519 cc = itr->mConvex; 520 break; 521 } 522 } 523 if (cc) 524 return; 525 526 // Create a new convex. 527 BoxConvex* cp = new BoxConvex; 528 mConvexList->registerObject(cp); 529 convex->addToWorkingList(cp); 530 cp->init(this); 531 532 mObjBox.getCenter(&cp->mCenter); 533 cp->mSize.x = mObjBox.len_x() / 2.0f; 534 cp->mSize.y = mObjBox.len_y() / 2.0f; 535 cp->mSize.z = mObjBox.len_z() / 2.0f; 536} 537 538bool PhysicalZone::testObject(SceneObject* enter) 539{ 540 // TODO: This doesn't look like it's testing against the polyhedron at 541 // all. And whats the point of building a convex if no collision methods 542 // are implemented? 543 544 if (mPolyhedron.mPointList.size() == 0) 545 return false; 546 547 mClippedList.clear(); 548 549 SphereF sphere; 550 sphere.center = (mWorldBox.minExtents + mWorldBox.maxExtents) * 0.5; 551 VectorF bv = mWorldBox.maxExtents - sphere.center; 552 sphere.radius = bv.len(); 553 554 enter->buildPolyList(PLC_Collision, &mClippedList, mWorldBox, sphere); 555 return mClippedList.isEmpty() == false; 556} 557 558bool PhysicalZone::testBox( const Box3F &box ) const 559{ 560 return mWorldBox.isOverlapped( box ); 561} 562 563void PhysicalZone::activate() 564{ 565 AssertFatal(isServerObject(), "Client objects not allowed in ForceFieldInstance::open()"); 566 567 if (mActive != true) 568 setMaskBits(ActiveMask); 569 mActive = true; 570} 571 572void PhysicalZone::deactivate() 573{ 574 AssertFatal(isServerObject(), "Client objects not allowed in ForceFieldInstance::close()"); 575 576 if (mActive != false) 577 setMaskBits(ActiveMask); 578 mActive = false; 579} 580 581void PhysicalZone::onStaticModified(const char* slotName, const char*newValue) 582{ 583 if (dStricmp(slotName, "appliedForce") == 0 || dStricmp(slotName, "forceType") == 0) 584 { 585 switch (force_type) 586 { 587 case SPHERICAL: 588 force_mag = mAppliedForce.magnitudeSafe(); 589 break; 590 case CYLINDRICAL: 591 { 592 Point3F force_vec = mAppliedForce; 593 force_vec.z = 0.0; 594 force_mag = force_vec.magnitudeSafe(); 595 } 596 break; 597 } 598 } 599} 600 601const Point3F& PhysicalZone::getForce(const Point3F* center) const 602{ 603 static Point3F force_vec; 604 605 if (force_type == VECTOR) 606 { 607 if (orient_force) 608 { 609 getTransform().mulV(mAppliedForce, &force_vec); 610 force_vec *= fade_amt; 611 return force_vec; 612 } 613 force_vec = mAppliedForce; 614 force_vec *= fade_amt; 615 return force_vec; 616 } 617 618 if (!center) 619 { 620 force_vec.zero(); 621 return force_vec; 622 } 623 624 if (force_type == SPHERICAL) 625 { 626 force_vec = *center - getPosition(); 627 force_vec.normalizeSafe(); 628 force_vec *= force_mag*fade_amt; 629 return force_vec; 630 } 631 632 if (orient_force) 633 { 634 force_vec = *center - getPosition(); 635 getWorldTransform().mulV(force_vec); 636 force_vec.z = 0.0f; 637 force_vec.normalizeSafe(); 638 force_vec *= force_mag; 639 force_vec.z = mAppliedForce.z; 640 getTransform().mulV(force_vec); 641 force_vec *= fade_amt; 642 return force_vec; 643 } 644 645 force_vec = *center - getPosition(); 646 force_vec.z = 0.0f; 647 force_vec.normalizeSafe(); 648 force_vec *= force_mag; 649 force_vec *= fade_amt; 650 return force_vec; 651} 652 653bool PhysicalZone::isExcludedObject(SceneObject* obj) const 654{ 655 for (S32 i = 0; i < excluded_objects.size(); i++) 656 if (excluded_objects[i] == obj) 657 return true; 658 659 return false; 660} 661 662void PhysicalZone::registerExcludedObject(SceneObject* obj) 663{ 664 if (isExcludedObject(obj)) 665 return; 666 667 excluded_objects.push_back(obj); 668 setMaskBits(FadeMask); 669} 670 671void PhysicalZone::unregisterExcludedObject(SceneObject* obj) 672{ 673 for (S32 i = 0; i < excluded_objects.size(); i++) 674 if (excluded_objects[i] == obj) 675 { 676 excluded_objects.erase(i); 677 setMaskBits(FadeMask); 678 return; 679 } 680} 681 682