abstractPolyList.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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 _ABSTRACTPOLYLIST_H_
  23. #define _ABSTRACTPOLYLIST_H_
  24. #ifndef _MMATH_H_
  25. #include "math/mMath.h"
  26. #endif
  27. #ifndef _MPLANETRANSFORMER_H_
  28. #include "math/mPlaneTransformer.h"
  29. #endif
  30. #ifndef _TVECTOR_H_
  31. #include "core/util/tVector.h"
  32. #endif
  33. class SceneObject;
  34. class BaseMatInstance;
  35. /// A polygon filtering interface.
  36. ///
  37. /// The various AbstractPolyList subclasses are used in Torque as an interface to
  38. /// handle spatial queries. SceneObject::buildPolyList() takes an implementor of
  39. /// AbstractPolyList (such as ConcretePolyList, ClippedPolyList, etc.) and a
  40. /// bounding volume. The function runs geometry data from all the objects in the
  41. /// bounding volume through the passed PolyList.
  42. ///
  43. /// This interface only provides a method to get data INTO your implementation. Different
  44. /// subclasses provide different interfaces to get data back out, depending on their
  45. /// specific quirks.
  46. ///
  47. /// The physics engine now uses convex hulls for collision detection.
  48. ///
  49. /// @see Convex
  50. class AbstractPolyList
  51. {
  52. protected:
  53. // User set state
  54. SceneObject* mCurrObject;
  55. MatrixF mBaseMatrix; // Base transform
  56. MatrixF mTransformMatrix; // Current object transform
  57. MatrixF mMatrix; // Base * current transform
  58. Point3F mScale;
  59. PlaneTransformer mPlaneTransformer;
  60. bool mInterestNormalRegistered;
  61. Point3F mInterestNormal;
  62. public:
  63. AbstractPolyList();
  64. virtual ~AbstractPolyList();
  65. /// @name Common Interface
  66. /// @{
  67. void setBaseTransform(const MatrixF& mat);
  68. /// Sets the transform applying to the current stream of
  69. /// vertices.
  70. ///
  71. /// @param mat Transformation of the object. (in)
  72. /// @param scale Scaling of the object. (in)
  73. void setTransform(const MatrixF* mat, const Point3F& scale);
  74. /// Gets the transform applying to the current stream of
  75. /// vertices.
  76. ///
  77. /// @param mat Transformation of the object. (out)
  78. /// @param scale Scaling of the object. (out)
  79. void getTransform(MatrixF* mat, Point3F * scale);
  80. /// This is called by the object which is currently feeding us
  81. /// vertices, to tell us who it is.
  82. void setObject(SceneObject*);
  83. /// Add a box via the query interface (below). This wraps some calls
  84. /// to addPoint and addPlane.
  85. void addBox(const Box3F &box, BaseMatInstance* material = NULL);
  86. void doConstruct();
  87. /// @}
  88. /// @name Query Interface
  89. ///
  90. /// It is through this interface that geometry data is fed to the
  91. /// PolyList. The order of calls are:
  92. /// - begin()
  93. /// - One or more calls to vertex() and one call to plane(), in any order.
  94. /// - end()
  95. ///
  96. /// @code
  97. /// // Example code that adds data to a PolyList.
  98. /// // See AbstractPolyList::addBox() for the function this was taken from.
  99. ///
  100. /// // First, we add points... (note that we use base to track the start of adding.)
  101. /// U32 base = addPoint(pos);
  102. /// pos.y += dy; addPoint(pos);
  103. /// pos.x += dx; addPoint(pos);
  104. /// pos.y -= dy; addPoint(pos);
  105. /// pos.z += dz; addPoint(pos);
  106. /// pos.x -= dx; addPoint(pos);
  107. /// pos.y += dy; addPoint(pos);
  108. /// pos.x += dx; addPoint(pos);
  109. ///
  110. /// // Now we add our surfaces. (there are six, as we are adding a cube here)
  111. /// for (S32 i = 0; i < 6; i++) {
  112. /// // Begin a surface
  113. /// begin(0,i);
  114. ///
  115. /// // Calculate the vertex ids; we have a lookup table to tell us offset from base.
  116. /// // In your own code, you might use a different method.
  117. /// S32 v1 = base + PolyFace[i][0];
  118. /// S32 v2 = base + PolyFace[i][1];
  119. /// S32 v3 = base + PolyFace[i][2];
  120. /// S32 v4 = base + PolyFace[i][3];
  121. ///
  122. /// // Reference the four vertices that make up this surface.
  123. /// vertex(v1);
  124. /// vertex(v2);
  125. /// vertex(v3);
  126. /// vertex(v4);
  127. ///
  128. /// // Indicate the plane of this surface.
  129. /// plane(v1,v2,v3);
  130. ///
  131. /// // End the surface.
  132. /// end();
  133. /// }
  134. /// @endcode
  135. /// @{
  136. /// Are we empty of data?
  137. virtual bool isEmpty() const = 0;
  138. /// Adds a point to the poly list, and returns
  139. /// an ID number for that point.
  140. virtual U32 addPoint(const Point3F& p) = 0;
  141. /// Adds a point and normal to the poly list, and returns
  142. /// an ID number for them. Normals are ignored for polylists
  143. /// that do not support them.
  144. virtual U32 addPointAndNormal(const Point3F& p, const Point3F& normal) { return addPoint( p ); }
  145. /// Adds a plane to the poly list, and returns
  146. /// an ID number for that point.
  147. virtual U32 addPlane(const PlaneF& plane) = 0;
  148. /// Start a surface.
  149. ///
  150. /// @param material A material ID for this surface.
  151. /// @param surfaceKey A key value to associate with this surface.
  152. virtual void begin(BaseMatInstance* material,U32 surfaceKey) = 0;
  153. /// Indicate the plane of the surface.
  154. virtual void plane(U32 v1,U32 v2,U32 v3) = 0;
  155. /// Indicate the plane of the surface.
  156. virtual void plane(const PlaneF& p) = 0;
  157. /// Indicate the plane of the surface.
  158. virtual void plane(const U32 index) = 0;
  159. /// Reference a vertex which is in this surface.
  160. virtual void vertex(U32 vi) = 0;
  161. /// Mark the end of a surface.
  162. virtual void end() = 0;
  163. /// Return list transform and bounds in list space.
  164. ///
  165. /// @returns False if no data is available.
  166. virtual bool getMapping(MatrixF *, Box3F *);
  167. /// @}
  168. /// @name Interest
  169. ///
  170. /// This is a mechanism to let you specify interest in a specific normal.
  171. /// If you set a normal you're interested in, then any planes facing "away"
  172. /// from that normal are culled from the results.
  173. ///
  174. /// This is handy if you're using this to do a physics check, as you're not
  175. /// interested in polygons facing away from you (since you don't collide with
  176. /// the backsides/insides of things).
  177. /// @{
  178. void setInterestNormal(const Point3F& normal);
  179. void clearInterestNormal() { mInterestNormalRegistered = false; }
  180. virtual bool isInterestedInPlane(const PlaneF& plane);
  181. virtual bool isInterestedInPlane(const U32 index);
  182. /// @}
  183. protected:
  184. /// A helper function to convert a plane index to a PlaneF structure.
  185. virtual const PlaneF& getIndexedPlane(const U32 index) = 0;
  186. };
  187. inline AbstractPolyList::AbstractPolyList()
  188. {
  189. doConstruct();
  190. }
  191. inline void AbstractPolyList::doConstruct()
  192. {
  193. mCurrObject = NULL;
  194. mBaseMatrix.identity();
  195. mMatrix.identity();
  196. mScale.set(1, 1, 1);
  197. mPlaneTransformer.setIdentity();
  198. mInterestNormalRegistered = false;
  199. }
  200. inline void AbstractPolyList::setBaseTransform(const MatrixF& mat)
  201. {
  202. mBaseMatrix = mat;
  203. }
  204. inline void AbstractPolyList::setTransform(const MatrixF* mat, const Point3F& scale)
  205. {
  206. mMatrix = mBaseMatrix;
  207. mTransformMatrix = *mat;
  208. mMatrix.mul(*mat);
  209. mScale = scale;
  210. mPlaneTransformer.set(mMatrix, mScale);
  211. }
  212. inline void AbstractPolyList::getTransform(MatrixF* mat, Point3F * scale)
  213. {
  214. *mat = mTransformMatrix;
  215. *scale = mScale;
  216. }
  217. inline void AbstractPolyList::setObject(SceneObject* obj)
  218. {
  219. mCurrObject = obj;
  220. }
  221. #endif // _ABSTRACTPOLYLIST_H_