forceField.h 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2012 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #ifndef _FORCEFIELD_H_
  23. #define _FORCEFIELD_H_
  24. #ifndef _PLATFORM_H_
  25. #include "platform/platform.h"
  26. #endif
  27. #ifndef _TVECTOR_H_
  28. #include "core/util/tVector.h"
  29. #endif
  30. #ifndef _MBOX_H_
  31. #include "math/mBox.h"
  32. #endif
  33. #ifndef _MSPHERE_H_
  34. #include "math/mSphere.h"
  35. #endif
  36. #ifndef _MPLANE_H_
  37. #include "math/mPlane.h"
  38. #endif
  39. #ifndef _MPOINT3_H_
  40. #include "math/mPoint3.h"
  41. #endif
  42. #ifndef _COLOR_H_
  43. #include "core/color.h"
  44. #endif
  45. //-------------------------------------- forward decls.
  46. class EditGeometry;
  47. class InteriorInstance;
  48. class Stream;
  49. class AbstractPolyList;
  50. struct RayInfo;
  51. //--------------------------------------------------------------------------
  52. class ForceField
  53. {
  54. static const U32 smFileVersion;
  55. friend class EditGeometry;
  56. friend class InteriorInstance;
  57. //-------------------------------------- Public interfaces
  58. public:
  59. ForceField();
  60. ~ForceField();
  61. bool prepForRendering();
  62. void render(const ColorF& color, const F32 fadeLevel);
  63. const Box3F& getBoundingBox() const;
  64. bool castRay(const Point3F&, const Point3F&, RayInfo*);
  65. bool buildPolyList(AbstractPolyList*, SphereF&);
  66. //-------------------------------------- Persistence interface
  67. public:
  68. bool read(Stream& stream);
  69. bool write(Stream& stream) const;
  70. public:
  71. static U16 getPlaneIndex(U16 index);
  72. static bool planeIsFlipped(U16 index);
  73. //-------------------------------------- BSP Structures
  74. private:
  75. struct IBSPNode {
  76. U16 planeIndex;
  77. U16 frontIndex;
  78. U16 backIndex;
  79. U16 __padding__;
  80. };
  81. struct IBSPLeafSolid {
  82. U32 surfaceIndex;
  83. U16 surfaceCount;
  84. U16 __padding__;
  85. };
  86. bool isBSPLeafIndex(U16 index) const;
  87. bool isBSPSolidLeaf(U16 index) const;
  88. bool isBSPEmptyLeaf(U16 index) const;
  89. U16 getBSPSolidLeafIndex(U16 index) const;
  90. bool writePlaneVector(Stream&) const;
  91. bool readPlaneVector(Stream&);
  92. private:
  93. const PlaneF& getPlane(U16 index) const;
  94. bool areEqualPlanes(U16, U16) const;
  95. struct Surface {
  96. U32 windingStart;
  97. U32 fanMask;
  98. U16 planeIndex;
  99. U8 windingCount;
  100. U8 surfaceFlags;
  101. };
  102. protected:
  103. StringTableEntry mName;
  104. ColorF mColor;
  105. Vector<StringTableEntry> mTriggers;
  106. Box3F mBoundingBox;
  107. SphereF mBoundingSphere;
  108. Vector<PlaneF> mPlanes;
  109. Vector<Point3F> mPoints;
  110. Vector<IBSPNode> mBSPNodes;
  111. Vector<IBSPLeafSolid> mBSPSolidLeaves;
  112. Vector<U32> mSolidLeafSurfaces;
  113. bool mPreppedForRender;
  114. Vector<U32> mWindings;
  115. Vector<Surface> mSurfaces;
  116. protected:
  117. bool castRay_r(const U16, const Point3F&, const Point3F&, RayInfo*);
  118. void buildPolyList_r(const U16, Vector<U16>&, AbstractPolyList*, SphereF&);
  119. void collisionFanFromSurface(const Surface&, U32* fan, U32* numIndices) const;
  120. };
  121. //------------------------------------------------------------------------------
  122. inline bool ForceField::isBSPLeafIndex(U16 index) const
  123. {
  124. return (index & 0x8000) != 0;
  125. }
  126. inline bool ForceField::isBSPSolidLeaf(U16 index) const
  127. {
  128. AssertFatal(isBSPLeafIndex(index) == true, "Error, only call for leaves!");
  129. return (index & 0x4000) != 0;
  130. }
  131. inline bool ForceField::isBSPEmptyLeaf(U16 index) const
  132. {
  133. AssertFatal(isBSPLeafIndex(index) == true, "Error, only call for leaves!");
  134. return (index & 0x4000) == 0;
  135. }
  136. inline U16 ForceField::getBSPSolidLeafIndex(U16 index) const
  137. {
  138. AssertFatal(isBSPSolidLeaf(index) == true, "Error, only call for leaves!");
  139. return (index & ~0xC000);
  140. }
  141. inline const PlaneF& ForceField::getPlane(U16 index) const
  142. {
  143. AssertFatal(U32(index & ~0x8000) < mPlanes.size(),
  144. "ForceField::getPlane: planeIndex out of range");
  145. return mPlanes[index & ~0x8000];
  146. }
  147. inline U16 ForceField::getPlaneIndex(U16 index)
  148. {
  149. return index & ~0x8000;
  150. }
  151. inline bool ForceField::planeIsFlipped(U16 index)
  152. {
  153. return (index & 0x8000) != 0;
  154. }
  155. inline bool ForceField::areEqualPlanes(U16 o, U16 t) const
  156. {
  157. return (o & ~0x8000) == (t & ~0x8000);
  158. }
  159. inline const Box3F& ForceField::getBoundingBox() const
  160. {
  161. return mBoundingBox;
  162. }
  163. #endif // _H_FORCEFIELD_