llvowater.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. /**
  2. * @file llvowater.cpp
  3. * @brief LLVOWater class implementation
  4. *
  5. * $LicenseInfo:firstyear=2005&license=viewergpl$
  6. *
  7. * Copyright (c) 2005-2009, Linden Research, Inc.
  8. *
  9. * Second Life Viewer Source Code
  10. * The source code in this file ("Source Code") is provided by Linden Lab
  11. * to you under the terms of the GNU General Public License, version 2.0
  12. * ("GPL"), unless you have obtained a separate licensing agreement
  13. * ("Other License"), formally executed by you and Linden Lab. Terms of
  14. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  15. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  16. *
  17. * There are special exceptions to the terms and conditions of the GPL as
  18. * it is applied to this Source Code. View the full text of the exception
  19. * in the file doc/FLOSS-exception.txt in this software distribution, or
  20. * online at
  21. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  22. *
  23. * By copying, modifying or distributing this software, you acknowledge
  24. * that you have read and understood your obligations described above,
  25. * and agree to abide by those obligations.
  26. *
  27. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  28. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  29. * COMPLETENESS OR PERFORMANCE.
  30. * $/LicenseInfo$
  31. */
  32. #include "llviewerprecompiledheaders.h"
  33. #include "llvowater.h"
  34. #include "imageids.h"
  35. #include "llfasttimer.h"
  36. #include "llagent.h"
  37. #include "lldrawable.h"
  38. #include "lldrawpoolwater.h"
  39. #include "llface.h"
  40. #include "llsky.h"
  41. #include "llspatialpartition.h"
  42. #include "llsurface.h"
  43. #include "llviewercamera.h"
  44. #include "llviewercontrol.h"
  45. #include "llviewertexturelist.h"
  46. #include "llvosky.h"
  47. #include "llworld.h"
  48. ///////////////////////////////////
  49. template<class T> LL_INLINE T LERP(T a, T b, F32 factor)
  50. {
  51. return a + (b - a) * factor;
  52. }
  53. LLVOWater::LLVOWater(const LLUUID& id, LLViewerRegion* regionp, LLPCode pcode)
  54. : LLStaticViewerObject(id, pcode, regionp),
  55. mRenderType(LLPipeline::RENDER_TYPE_WATER),
  56. mUseTexture(true),
  57. mIsEdgePatch(false)
  58. {
  59. // Terrain must draw during selection passes so it can block objects behind
  60. // it.
  61. mCanSelect = false;
  62. // Hack for setting scale for bounding boxes/visibility.
  63. // Variable region size support
  64. setScale(LLVector3(regionp->getWidth(), regionp->getWidth(), 0.f));
  65. }
  66. void LLVOWater::setPixelAreaAndAngle()
  67. {
  68. mAppAngle = 50;
  69. mPixelArea = 500 * 500;
  70. }
  71. LLDrawable* LLVOWater::createDrawable()
  72. {
  73. gPipeline.allocDrawable(this);
  74. mDrawable->setLit(false);
  75. mDrawable->setRenderType(mRenderType);
  76. LLDrawPoolWater* pool = (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER);
  77. if (mUseTexture)
  78. {
  79. mDrawable->setNumFaces(1, pool, mRegionp->getLand().getWaterTexture());
  80. }
  81. else
  82. {
  83. mDrawable->setNumFaces(1, pool, gWorld.getDefaultWaterTexture());
  84. }
  85. return mDrawable;
  86. }
  87. bool LLVOWater::updateGeometry(LLDrawable* drawable)
  88. {
  89. LL_FAST_TIMER(FTM_UPDATE_WATER);
  90. if (drawable->getNumFaces() < 1)
  91. {
  92. LLDrawPoolWater* poolp =
  93. (LLDrawPoolWater*)gPipeline.getPool(LLDrawPool::POOL_WATER);
  94. drawable->addFace(poolp, NULL);
  95. }
  96. LLFace* face = drawable->getFace(0);
  97. if (!face)
  98. {
  99. llerrs << "Could not add a new face !" << llendl;
  100. }
  101. S32 size = 1;
  102. if (LLPipeline::waterReflectionType())
  103. {
  104. size = 16;
  105. }
  106. const U32 num_quads = size * size;
  107. // A quad is 4 vertices and 6 indices (making 2 triangles)
  108. constexpr U32 vertices_per_quad = 4;
  109. constexpr U32 indices_per_quad = 6;
  110. face->setSize(vertices_per_quad * num_quads,
  111. indices_per_quad * num_quads);
  112. LLVertexBuffer* buffp = face->getVertexBuffer();
  113. if (!buffp || buffp->getNumIndices() != face->getIndicesCount() ||
  114. buffp->getNumVerts() != face->getGeomCount())
  115. {
  116. buffp = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK);
  117. #if LL_DEBUG_VB_ALLOC
  118. buffp->setOwner("LLVOWater");
  119. #endif
  120. if (!buffp->allocateBuffer(face->getGeomCount(),
  121. face->getIndicesCount()))
  122. {
  123. llwarns << "Failure to allocate a vertex buffer with "
  124. << face->getGeomCount() << " vertices and "
  125. << face->getIndicesCount() << " indices" << llendl;
  126. return false;
  127. }
  128. face->setIndicesIndex(0);
  129. face->setGeomIndex(0);
  130. face->setVertexBuffer(buffp);
  131. }
  132. LLStrider<LLVector3> verticesp, normalsp;
  133. LLStrider<LLVector2> texcoordsp;
  134. LLStrider<U16> indicesp;
  135. U16 index_offset = face->getGeometry(verticesp, normalsp, texcoordsp,
  136. indicesp);
  137. LLVector3 position_agent = getPositionAgent();
  138. face->mCenterAgent = position_agent;
  139. face->mCenterLocal = position_agent;
  140. F32 step_x = getScale().mV[0] / (F32)size;
  141. F32 step_y = getScale().mV[1] / (F32)size;
  142. const LLVector3 up(0.f, step_y * 0.5f, 0.f);
  143. const LLVector3 right(step_x * 0.5f, 0.f, 0.f);
  144. const LLVector3 normal(0.f, 0.f, 1.f);
  145. F32 size_inv = 1.f / (F32)size;
  146. for (S32 y = 0; y < size; ++y)
  147. {
  148. for (S32 x = 0; x < size; ++x)
  149. {
  150. S32 toffset = index_offset + 4 * (y * size + x);
  151. LLVector3 pos = position_agent - getScale() * 0.5f;
  152. pos.mV[VX] += (x + 0.5f) * step_x;
  153. pos.mV[VY] += (y + 0.5f) * step_y;
  154. *verticesp++ = pos - right + up;
  155. *verticesp++ = pos - right - up;
  156. *verticesp++ = pos + right + up;
  157. *verticesp++ = pos + right - up;
  158. *texcoordsp++ = LLVector2(x * size_inv, (y + 1) * size_inv);
  159. *texcoordsp++ = LLVector2(x * size_inv, y * size_inv);
  160. *texcoordsp++ = LLVector2((x + 1) * size_inv, (y + 1) * size_inv);
  161. *texcoordsp++ = LLVector2((x + 1) * size_inv, y * size_inv);
  162. *normalsp++ = normal;
  163. *normalsp++ = normal;
  164. *normalsp++ = normal;
  165. *normalsp++ = normal;
  166. *indicesp++ = toffset + 0;
  167. *indicesp++ = toffset + 1;
  168. *indicesp++ = toffset + 2;
  169. *indicesp++ = toffset + 1;
  170. *indicesp++ = toffset + 3;
  171. *indicesp++ = toffset + 2;
  172. }
  173. }
  174. buffp->unmapBuffer();
  175. mDrawable->movePartition();
  176. return true;
  177. }
  178. void setVecZ(LLVector3& v)
  179. {
  180. v.mV[VX] = v.mV[VY] = 0;
  181. v.mV[VZ] = 1;
  182. }
  183. void LLVOWater::updateSpatialExtents(LLVector4a& new_min, LLVector4a& new_max)
  184. {
  185. LLVector4a pos;
  186. pos.load3(getPositionAgent().mV);
  187. LLVector4a scale;
  188. scale.load3(getScale().mV);
  189. scale.mul(0.5f);
  190. new_min.setSub(pos, scale);
  191. new_max.setAdd(pos, scale);
  192. pos.setAdd(new_min, new_max);
  193. pos.mul(0.5f);
  194. mDrawable->setPositionGroup(pos);
  195. }
  196. LLWaterPartition::LLWaterPartition(LLViewerRegion* regionp)
  197. : LLSpatialPartition(0, false, regionp)
  198. {
  199. mInfiniteFarClip = true;
  200. mDrawableType = LLPipeline::RENDER_TYPE_WATER;
  201. mPartitionType = LLViewerRegion::PARTITION_WATER;
  202. }
  203. LLVoidWaterPartition::LLVoidWaterPartition(LLViewerRegion* regionp)
  204. : LLWaterPartition(regionp)
  205. {
  206. mDrawableType = LLPipeline::RENDER_TYPE_VOIDWATER;
  207. mPartitionType = LLViewerRegion::PARTITION_VOIDWATER;
  208. }