mirrorSubObject.cpp 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  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. #include "interior/mirrorSubObject.h"
  23. #include "interior/interiorInstance.h"
  24. #include "interior/interior.h"
  25. #include "materials/materialList.h"
  26. #include "core/stream/stream.h"
  27. #include "scene/sgUtil.h"
  28. IMPLEMENT_CONOBJECT(MirrorSubObject);
  29. ConsoleDocClass( MirrorSubObject,
  30. "@deprecated Dysfunctional"
  31. "@internal"
  32. );
  33. //--------------------------------------------------------------------------
  34. MirrorSubObject::MirrorSubObject()
  35. {
  36. mTypeMask = StaticObjectType;
  37. mInitialized = false;
  38. mWhite = NULL;
  39. }
  40. MirrorSubObject::~MirrorSubObject()
  41. {
  42. delete mWhite;
  43. mWhite = NULL;
  44. }
  45. //--------------------------------------------------------------------------
  46. void MirrorSubObject::initPersistFields()
  47. {
  48. Parent::initPersistFields();
  49. //
  50. }
  51. //--------------------------------------------------------------------------
  52. /*
  53. void MirrorSubObject::renderObject(SceneRenderState* state, SceneRenderImage* image)
  54. {
  55. }
  56. */
  57. //--------------------------------------------------------------------------
  58. void MirrorSubObject::transformModelview(const U32 portalIndex, const MatrixF& oldMV, MatrixF* pNewMV)
  59. {
  60. AssertFatal(isInitialized() == true, "Error, we should have been initialized by this point!");
  61. AssertFatal(portalIndex == 0, "Error, we only have one portal!");
  62. *pNewMV = oldMV;
  63. pNewMV->mul(mReflectionMatrix);
  64. }
  65. //--------------------------------------------------------------------------
  66. void MirrorSubObject::transformPosition(const U32 portalIndex, Point3F& ioPosition)
  67. {
  68. AssertFatal(isInitialized() == true, "Error, we should have been initialized by this point!");
  69. AssertFatal(portalIndex == 0, "Error, we only have one portal!");
  70. mReflectionMatrix.mulP(ioPosition);
  71. }
  72. //--------------------------------------------------------------------------
  73. bool MirrorSubObject::computeNewFrustum(const U32 portalIndex,
  74. const Frustum &oldFrustum,
  75. const F64 nearPlane,
  76. const F64 farPlane,
  77. const RectI& oldViewport,
  78. F64 *newFrustum,
  79. RectI& newViewport,
  80. const bool flippedMatrix)
  81. {
  82. AssertFatal(isInitialized() == true, "Error, we should have been initialized by this point!");
  83. AssertFatal(portalIndex == 0, "Error, mirrortests only have one portal!");
  84. Interior* interior = getInstance()->getDetailLevel(mDetailLevel);
  85. static Vector<SGWinding> mirrorWindings;
  86. mirrorWindings.setSize(surfaceCount);
  87. for (U32 i = 0; i < surfaceCount; i++) {
  88. SGWinding& rSGWinding = mirrorWindings[i];
  89. const Interior::Surface& rSurface = interior->mSurfaces[surfaceStart + i];
  90. U32 fanIndices[32];
  91. U32 numFanIndices = 0;
  92. interior->collisionFanFromSurface(rSurface, fanIndices, &numFanIndices);
  93. for (U32 j = 0; j < numFanIndices; j++)
  94. rSGWinding.points[j] = interior->mPoints[fanIndices[j]].point;
  95. rSGWinding.numPoints = numFanIndices;
  96. }
  97. MatrixF finalModelView;
  98. finalModelView.mul(getSOTransform());
  99. finalModelView.scale(getSOScale());
  100. return sgComputeNewFrustum(oldFrustum, nearPlane, farPlane,
  101. oldViewport,
  102. mirrorWindings.address(), mirrorWindings.size(),
  103. finalModelView,
  104. newFrustum, newViewport,
  105. flippedMatrix);
  106. }
  107. //--------------------------------------------------------------------------
  108. void MirrorSubObject::openPortal(const U32 portalIndex,
  109. SceneRenderState* pCurrState,
  110. SceneRenderState* pParentState)
  111. {
  112. }
  113. //--------------------------------------------------------------------------
  114. void MirrorSubObject::closePortal(const U32 portalIndex,
  115. SceneRenderState* pCurrState,
  116. SceneRenderState* pParentState)
  117. {
  118. }
  119. //--------------------------------------------------------------------------
  120. void MirrorSubObject::getWSPortalPlane(const U32 portalIndex, PlaneF* pPlane)
  121. {
  122. AssertFatal(portalIndex == 0, "Error, mirrortests only have one portal!");
  123. Interior* interior = getInstance()->getDetailLevel(mDetailLevel);
  124. const Interior::Surface& rSurface = interior->mSurfaces[surfaceStart];
  125. PlaneF temp = interior->getPlane(rSurface.planeIndex);
  126. if (Interior::planeIsFlipped(rSurface.planeIndex))
  127. temp.neg();
  128. mTransformPlane(getSOTransform(), getSOScale(), temp, pPlane);
  129. }
  130. //--------------------------------------------------------------------------
  131. U32 MirrorSubObject::getSubObjectKey() const
  132. {
  133. return InteriorSubObject::MirrorSubObjectKey;
  134. }
  135. bool MirrorSubObject::_readISO(Stream& stream)
  136. {
  137. AssertFatal(isInitialized() == false, "Error, should not be initialized here!");
  138. if (Parent::_readISO(stream) == false)
  139. return false;
  140. stream.read(&mDetailLevel);
  141. stream.read(&mZone);
  142. stream.read(&mAlphaLevel);
  143. stream.read(&surfaceCount);
  144. stream.read(&surfaceStart);
  145. stream.read(&mCentroid.x);
  146. stream.read(&mCentroid.y);
  147. stream.read(&mCentroid.z);
  148. return true;
  149. }
  150. bool MirrorSubObject::_writeISO(Stream& stream) const
  151. {
  152. if (Parent::_writeISO(stream) == false)
  153. return false;
  154. stream.write(mDetailLevel);
  155. stream.write(mZone);
  156. stream.write(mAlphaLevel);
  157. stream.write(surfaceCount);
  158. stream.write(surfaceStart);
  159. stream.write(mCentroid.x);
  160. stream.write(mCentroid.y);
  161. stream.write(mCentroid.z);
  162. return true;
  163. }
  164. bool MirrorSubObject::renderDetailDependant() const
  165. {
  166. return true;
  167. }
  168. U32 MirrorSubObject::getZone() const
  169. {
  170. return mZone;
  171. }
  172. void MirrorSubObject::setupTransforms()
  173. {
  174. mInitialized = true;
  175. // This is really bad, but it's just about the only good place for this...
  176. if (getInstance()->isClientObject() && mWhite == NULL)
  177. mWhite = new GFXTexHandle("special/whiteAlpha0", &GFXDefaultStaticDiffuseProfile, avar("%s() - mWhite (line %d)", __FUNCTION__, __LINE__));
  178. Interior* interior = getInstance()->getDetailLevel(mDetailLevel);
  179. const Interior::Surface& rSurface = interior->mSurfaces[surfaceStart];
  180. PlaneF plane = interior->getPlane(rSurface.planeIndex);
  181. if (Interior::planeIsFlipped(rSurface.planeIndex))
  182. plane.neg();
  183. Point3F n(plane.x, plane.y, plane.z);
  184. Point3F q = n;
  185. q *= -plane.d;
  186. MatrixF t(true);
  187. t.scale(getSOScale());
  188. t.mul(getSOTransform());
  189. t.mulV(n);
  190. t.mulP(q);
  191. F32* ra = mReflectionMatrix;
  192. ra[0] = 1.0f - 2.0f*(n.x*n.x); ra[1] = 0.0f - 2.0f*(n.x*n.y); ra[2] = 0.0f - 2.0f*(n.x*n.z); ra[3] = 0.0f;
  193. ra[4] = 0.0f - 2.0f*(n.y*n.x); ra[5] = 1.0f - 2.0f*(n.y*n.y); ra[6] = 0.0f - 2.0f*(n.y*n.z); ra[7] = 0.0f;
  194. ra[8] = 0.0f - 2.0f*(n.z*n.x); ra[9] = 0.0f - 2.0f*(n.z*n.y); ra[10] = 1.0f - 2.0f*(n.z*n.z); ra[11] = 0.0f;
  195. Point3F qnn = n * mDot(n, q);
  196. ra[12] = qnn.x * 2.0f;
  197. ra[13] = qnn.y * 2.0f;
  198. ra[14] = qnn.z * 2.0f;
  199. ra[15] = 1.0f;
  200. // Now, the GGems series (as of v1) uses row vectors (arg)
  201. mReflectionMatrix.transpose();
  202. }
  203. void MirrorSubObject::noteTransformChange()
  204. {
  205. setupTransforms();
  206. Parent::noteTransformChange();
  207. }
  208. InteriorSubObject* MirrorSubObject::clone(InteriorInstance* instance) const
  209. {
  210. MirrorSubObject* pClone = new MirrorSubObject;
  211. pClone->mDetailLevel = mDetailLevel;
  212. pClone->mZone = mZone;
  213. pClone->mAlphaLevel = mAlphaLevel;
  214. pClone->mCentroid = mCentroid;
  215. pClone->surfaceCount = surfaceCount;
  216. pClone->surfaceStart = surfaceStart;
  217. pClone->mInteriorInstance = instance;
  218. return pClone;
  219. }