portal.h
Classes:
class
A transitioning zone that connects other zones.
Detailed Description
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#ifndef _PORTAL_H_ 25#define _PORTAL_H_ 26 27#ifndef _ZONE_H_ 28#include "T3D/zone.h" 29#endif 30 31#ifndef _TVECTOR_H_ 32#include "core/util/tVector.h" 33#endif 34 35 36class SceneCullingState; 37class SceneCullingVolume; 38 39 40/// A transitioning zone that connects other zones. 41/// 42/// Basically a portal is two things: 43/// 44/// 1) A zone that overlaps multiple other zones and thus connects them. 45/// 2) A polygon standing upright in the middle of the portal zone's world box. 46/// 47/// When traversing from zone to zone, portals serve as both zones in their own 48/// right (i.e. objects may be located in a portal zone) as well as a peek hole 49/// that determines what area of a target zone is visible through a portal. 50/// 51/// Torque's portals are special in that they are two-way by default. This greatly 52/// simplifies zone setups but it also complicates handling in the engine somewhat. 53/// Also, these portals here are nothing but peek holes--they do not define transform 54/// portals that could be looking at a different location in space altogether. 55/// 56/// Portals can be marked explicitly as being one-sided by flagging either of the portal's 57/// sides as impassable. This flagging can also be used dynamically to, for example, block 58/// a portal while a door is still down and then unblock the portal when the door is 59/// opened. 60/// 61/// Portals are classified as either interior or exterior portals. An exterior portal is 62/// a portal that has only non-SceneRootZone zones on side of the portal plane and only the 63/// SceneRootZone on the other side of it. An interior portal is a portal that has only 64/// non-SceneRootZone zones on both sides of the portal plane. A mixture of the two is not 65/// allowed – when adding SceneRootZone to a portal, it must exist alone on its portal 66/// side. 67class Portal : public Zone 68{ 69 public: 70 71 typedef Zone Parent; 72 73 /// Identifies the subspaces defined by the portal plane. 74 enum Side 75 { 76 FrontSide, ///< Subspace on front side of portal plane. 77 BackSide ///< Subspace on back side of portal plane. 78 }; 79 80 /// Identifies the type of portal. 81 enum Classification 82 { 83 InvalidPortal, ///< Portal does not connect anything. 84 InteriorPortal, ///< Portal between interior zones. 85 ExteriorPortal ///< Portal between interior zones on one and side and SceneRootZone on the other. 86 }; 87 88 protected: 89 90 enum 91 { 92 PassableMask = Parent::NextFreeMask << 0, ///< #mPassableSides has changed. 93 NextFreeMask = Parent::NextFreeMask << 1, 94 }; 95 96 /// Flags that allow preventing traversal through specific 97 /// sides of the portal. By default, both sides are passable. 98 bool mPassableSides[ 2 ]; 99 100 /// @name Derived Portal Data 101 /// @{ 102 103 /// Classification of this portal as interior or exterior portal. 104 Classification mClassification; 105 106 /// For exterior portals, this is the side of the portal on which 107 /// the connected interior zones lie. 108 Side mInteriorSide; 109 110 /// Whether the portal plane and polygon need to be updated. 111 bool mIsGeometryDirty; 112 113 /// Portal polygon in world space. 114 Vector< Point3F> mPortalPolygonWS; 115 116 /// The plane defined by the portal's rectangle. 117 PlaneF mPortalPlane; 118 119 /// Update derived data, if necessary. 120 void _update(); 121 122 /// Update the world space portal geometry. 123 void _updateGeometry(); 124 125 /// Detect whether this is an exterior, interior, or invalid portal. 126 void _updateConnectivity(); 127 128 /// @} 129 130 /// Compute a clipped culling volume from the portal geometry and current 131 /// traversal state. If successful, store the resulting culling volume in 132 /// @a outVolume and return true. 133 bool _generateCullingVolume( SceneTraversalState* state, SceneCullingVolume& outVolume ) const; 134 135 // SceneSpace. 136 virtual void _renderObject( ObjectRenderInst* ri, SceneRenderState* state, BaseMatInstance* overrideMat ); 137 virtual ColorI _getDefaultEditorSolidColor() const { return ColorI( 0, 255, 0, 45 ); } 138 virtual ColorI _getDefaultEditorWireframeColor() const 139 { 140 switch( mClassification ) 141 { 142 case ExteriorPortal: return ColorI( 0, 128, 128, 255 ); break; 143 case InteriorPortal: return ColorI( 128, 128, 0, 255 ); 144 default: return ColorI( 255, 255, 255, 255 ); break; 145 } 146 } 147 148 // SceneObject. 149 virtual void onSceneRemove(); 150 151 // SceneZoneSpace. 152 virtual void _traverseConnectedZoneSpaces( SceneTraversalState* state ); 153 virtual void _disconnectAllZoneSpaces(); 154 155 public: 156 157 Portal(); 158 159 /// Return what kind of portal this is (interior or exterior). 160 Classification getClassification() const { return mClassification; } 161 162 /// Return the plane that is defined by the portal's rectangle. 163 const PlaneF& getPortalPlane() const { return mPortalPlane; } 164 165 /// Return the side that the given point is in relative to the portal plane. 166 Side getSideRelativeToPortalPlane( const Point3F& point ) const; 167 168 /// Test whether the given side of the portal is open for traversal. 169 bool isSidePassable( Side side ) const { return mPassableSides[ side ]; } 170 171 /// Set whether the given portal side is passable. 172 void setSidePassable( Side side, bool value ); 173 174 /// Return true if the portal leads to the outdoor zone. 175 bool isExteriorPortal() const { return ( getClassification() == ExteriorPortal ); } 176 177 /// Return true if the portal connects interior zones only. 178 bool isInteriorPortal() const { return ( getClassification() == InteriorPortal ); } 179 180 /// For exterior portals, get the side on which the interior zones of the portal lie. 181 Side getInteriorSideOfExteriorPortal() const 182 { 183 AssertFatal( isExteriorPortal(), "Portal::getInteriorSideOfExteriorPortal - Not an exterior portal!" ); 184 return mInteriorSide; 185 } 186 187 // SimObject. 188 DECLARE_CONOBJECT( Portal ); 189 190 static void initPersistFields(); 191 static void consoleInit(); 192 193 virtual bool writeField( StringTableEntry fieldName, const char* value ); 194 virtual String describeSelf() const; 195 196 // NetObject. 197 virtual U32 packUpdate( NetConnection* conn, U32 mask, BitStream* stream ); 198 virtual void unpackUpdate( NetConnection* conn, BitStream* stream ); 199 200 // SceneObject. 201 virtual void setTransform( const MatrixF &mat ); 202 203 // SceneZoneSpace. 204 virtual void traverseZones( SceneTraversalState* state, U32 startZoneId ); 205 virtual void connectZoneSpace( SceneZoneSpace* zoneSpace ); 206 virtual void disconnectZoneSpace( SceneZoneSpace* zoneSpace ); 207 208 private: 209 210 static bool _setFrontSidePassable( void* object, const char* index, const char* data ); 211 static bool _setBackSidePassable( void* object, const char* index, const char* data ); 212}; 213 214#endif // _PORTAL_H_ 215