llvograss.cpp 27 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076
  1. /**
  2. * @file llvograss.cpp
  3. * @brief Not a blade, but a clump of grass
  4. *
  5. * $LicenseInfo:firstyear=2001&license=viewergpl$
  6. *
  7. * Copyright (c) 2001-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 "llvograss.h"
  34. #include "imageids.h"
  35. #include "lldir.h"
  36. #include "llfasttimer.h"
  37. #include "llnotifications.h"
  38. #include "llxmltree.h"
  39. #include "llagent.h"
  40. #include "lldrawable.h"
  41. #include "lldrawpoolalpha.h"
  42. #include "llface.h"
  43. #include "llpipeline.h"
  44. #include "llselectmgr.h"
  45. #include "llsky.h"
  46. #include "llspatialpartition.h"
  47. #include "llsurface.h"
  48. #include "llsurfacepatch.h"
  49. #include "llviewercamera.h"
  50. #include "llviewercontrol.h"
  51. #include "llviewerregion.h"
  52. #include "llviewertexturelist.h"
  53. #include "llvotree.h"
  54. #include "llvosky.h"
  55. #include "llworld.h"
  56. constexpr S32 GRASS_MAX_BLADES = 32;
  57. constexpr F32 GRASS_BLADE_BASE = 0.25f; // Width of grass at base
  58. constexpr F32 GRASS_BLADE_HEIGHT = 0.5f; // In meters
  59. constexpr F32 GRASS_DISTRIBUTION_SD = 0.15f; // Empirically defined
  60. F32 exp_x[GRASS_MAX_BLADES];
  61. F32 exp_y[GRASS_MAX_BLADES];
  62. F32 rot_x[GRASS_MAX_BLADES];
  63. F32 rot_y[GRASS_MAX_BLADES];
  64. F32 dz_x [GRASS_MAX_BLADES];
  65. F32 dz_y [GRASS_MAX_BLADES];
  66. // Factor to modulate wind movement by to randomize appearance
  67. F32 w_mod[GRASS_MAX_BLADES];
  68. LLVOGrass::data_map_t LLVOGrass::sSpeciesTable;
  69. LLVOGrass::species_list_t LLVOGrass::sSpeciesNames;
  70. S32 LLVOGrass::sMaxGrassSpecies = 0;
  71. ///////////////////////////////////////////////////////////////////////////////
  72. // LLVOGrass class
  73. ///////////////////////////////////////////////////////////////////////////////
  74. LLVOGrass::LLVOGrass(const LLUUID& id, LLViewerRegion* regionp)
  75. : LLAlphaObject(id, LL_PCODE_LEGACY_GRASS, regionp),
  76. mPatch(NULL),
  77. mLastPatchUpdateTime(0),
  78. mNumBlades(GRASS_MAX_BLADES)
  79. {
  80. mCanSelect = true;
  81. setNumTEs(1);
  82. setTEColor(0, LLColor4(1.f, 1.f, 1.f, 1.f));
  83. }
  84. void LLVOGrass::updateSpecies()
  85. {
  86. mSpecies = mAttachmentState;
  87. if (!sSpeciesTable.count(mSpecies))
  88. {
  89. llinfos << "Unknown grass type, substituting grass type." << llendl;
  90. data_map_t::const_iterator it = sSpeciesTable.begin();
  91. mSpecies = it->first;
  92. }
  93. setTEImage(0,
  94. LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID,
  95. FTT_DEFAULT,
  96. true,
  97. LLGLTexture::BOOST_NONE,
  98. LLViewerTexture::LOD_TEXTURE));
  99. }
  100. void LLVOGrass::initClass()
  101. {
  102. std::string xml_filename = gDirUtil.getFullPath(LL_PATH_APP_SETTINGS,
  103. "grass.xml");
  104. LLXmlTree grass_def_grass;
  105. if (!grass_def_grass.parseFile(xml_filename))
  106. {
  107. llerrs << "Failed to parse grass file." << llendl;
  108. return;
  109. }
  110. LLXmlTreeNode* rootp = grass_def_grass.getRoot();
  111. if (!rootp)
  112. {
  113. llerrs << "Failed to parse grass file." << llendl;
  114. return;
  115. }
  116. LLUUID id;
  117. F32 f32_val;
  118. for (LLXmlTreeNode* grass_def = rootp->getFirstChild(); grass_def;
  119. grass_def = rootp->getNextChild())
  120. {
  121. if (!grass_def->hasName("grass"))
  122. {
  123. llwarns << "Invalid grass definition node " << grass_def->getName()
  124. << llendl;
  125. continue;
  126. }
  127. bool success = true;
  128. S32 species;
  129. static LLStdStringHandle species_id_string =
  130. LLXmlTree::addAttributeString("species_id");
  131. if (!grass_def->getFastAttributeS32(species_id_string, species))
  132. {
  133. llwarns << "No species id defined" << llendl;
  134. continue;
  135. }
  136. if (species < 0)
  137. {
  138. llwarns << "Invalid species id " << species << llendl;
  139. continue;
  140. }
  141. GrassSpeciesData* new_grass = new GrassSpeciesData();
  142. static LLStdStringHandle texture_id_string =
  143. LLXmlTree::addAttributeString("texture_id");
  144. grass_def->getFastAttributeUUID(texture_id_string, id);
  145. new_grass->mTextureID = id;
  146. if (new_grass->mTextureID.isNull())
  147. {
  148. static LLStdStringHandle texture_name_string =
  149. LLXmlTree::addAttributeString("texture_name");
  150. std::string tex_name;
  151. success &= grass_def->getFastAttributeString(texture_name_string,
  152. tex_name);
  153. LLViewerTexture* grass_image =
  154. LLViewerTextureManager::getFetchedTextureFromFile(tex_name);
  155. new_grass->mTextureID = grass_image->getID();
  156. }
  157. static LLStdStringHandle blade_sizex_string =
  158. LLXmlTree::addAttributeString("blade_size_x");
  159. success &= grass_def->getFastAttributeF32(blade_sizex_string, f32_val);
  160. new_grass->mBladeSizeX = f32_val;
  161. static LLStdStringHandle blade_sizey_string =
  162. LLXmlTree::addAttributeString("blade_size_y");
  163. success &= grass_def->getFastAttributeF32(blade_sizey_string, f32_val);
  164. new_grass->mBladeSizeY = f32_val;
  165. if (sSpeciesTable.count(species))
  166. {
  167. llinfos << "Grass species " << species
  168. << " already defined ! Duplicate discarded." << llendl;
  169. delete new_grass;
  170. continue;
  171. }
  172. else
  173. {
  174. sSpeciesTable[species] = new_grass;
  175. }
  176. if (species >= sMaxGrassSpecies)
  177. {
  178. sMaxGrassSpecies = species + 1;
  179. }
  180. std::string name;
  181. static LLStdStringHandle name_string =
  182. LLXmlTree::addAttributeString("name");
  183. success &= grass_def->getFastAttributeString(name_string, name);
  184. sSpeciesNames[name] = species;
  185. if (!success)
  186. {
  187. llwarns << "Incomplete definition of grass " << name << llendl;
  188. }
  189. }
  190. bool have_all_grass = true;
  191. std::string err;
  192. for (S32 i = 0; i < sMaxGrassSpecies; ++i)
  193. {
  194. if (!sSpeciesTable.count(i))
  195. {
  196. err.append(llformat(" %d", i));
  197. have_all_grass = false;
  198. }
  199. }
  200. if (!have_all_grass)
  201. {
  202. LLSD args;
  203. args["SPECIES"] = err;
  204. gNotifications.add("ErrorUndefinedGrasses", args);
  205. }
  206. // Create nifty list of exponential distribution 0-1
  207. F32 x = 0.f;
  208. F32 y = 0.f;
  209. F32 rot;
  210. for (S32 i = 0; i < GRASS_MAX_BLADES; ++i)
  211. {
  212. #if 0 // Set to 1 for X blading
  213. if (i % 2 == 0)
  214. {
  215. F32 u = sqrtf(-2.f * logf(ll_frand()));
  216. F32 v = 2.f * F_PI * ll_frand();
  217. x = u * sinf(v) * GRASS_DISTRIBUTION_SD;
  218. y = u * cosf(v) * GRASS_DISTRIBUTION_SD;
  219. rot = ll_frand(F_PI);
  220. }
  221. else
  222. {
  223. rot += (F_PI * 0.4f + ll_frand(0.2f * F_PI));
  224. }
  225. #else
  226. F32 u = sqrtf(-2.f * logf(ll_frand()));
  227. F32 v = 2.f * F_PI * ll_frand();
  228. x = u * sinf(v) * GRASS_DISTRIBUTION_SD;
  229. y = u * cosf(v) * GRASS_DISTRIBUTION_SD;
  230. rot = ll_frand(F_PI);
  231. #endif
  232. exp_x[i] = x;
  233. exp_y[i] = y;
  234. rot_x[i] = sinf(rot);
  235. rot_y[i] = cosf(rot);
  236. dz_x[i] = ll_frand(GRASS_BLADE_BASE * 0.25f);
  237. dz_y[i] = ll_frand(GRASS_BLADE_BASE * 0.25f);
  238. // Degree to which blade is moved by wind
  239. w_mod[i] = 0.5f + ll_frand();
  240. }
  241. }
  242. void LLVOGrass::cleanupClass()
  243. {
  244. for_each(sSpeciesTable.begin(), sSpeciesTable.end(),
  245. DeletePairedPointer());
  246. sSpeciesTable.clear();
  247. }
  248. U32 LLVOGrass::processUpdateMessage(LLMessageSystem* mesgsys,
  249. void** user_data, U32 block_num,
  250. EObjectUpdateType update_type,
  251. LLDataPacker* dp)
  252. {
  253. // Do base class updates...
  254. U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data,
  255. block_num, update_type,
  256. dp);
  257. updateSpecies();
  258. if (getVelocity().lengthSquared() > 0.f ||
  259. getAcceleration().lengthSquared() > 0.f ||
  260. getAngularVelocity().lengthSquared() > 0.f)
  261. {
  262. llinfos << "ACK ! Moving grass !" << llendl;
  263. setVelocity(LLVector3::zero);
  264. setAcceleration(LLVector3::zero);
  265. setAngularVelocity(LLVector3::zero);
  266. }
  267. if (mDrawable)
  268. {
  269. gPipeline.markRebuild(mDrawable);
  270. }
  271. return retval;
  272. }
  273. void LLVOGrass::idleUpdate(F64 time)
  274. {
  275. if (mDead || !gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_GRASS) ||
  276. !mDrawable) // So that drones work.
  277. {
  278. return;
  279. }
  280. if (LLVOTree::isTreeRenderingStopped()) // Stop rendering grass
  281. {
  282. if (mNumBlades)
  283. {
  284. mNumBlades = 0;
  285. gPipeline.markRebuild(mDrawable);
  286. }
  287. return;
  288. }
  289. if (!mNumBlades) // Restart grass rendering
  290. {
  291. mNumBlades = GRASS_MAX_BLADES;
  292. gPipeline.markRebuild(mDrawable);
  293. return;
  294. }
  295. if (mPatch && mLastPatchUpdateTime != mPatch->getLastUpdateTime())
  296. {
  297. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME);
  298. }
  299. }
  300. void LLVOGrass::setPixelAreaAndAngle()
  301. {
  302. // This should be the camera's center, as soon as we move to all
  303. // region-local.
  304. LLVector3 relative_position = getPositionAgent() -
  305. gAgent.getCameraPositionAgent();
  306. F32 range = relative_position.length();
  307. F32 max_scale = getMaxScale();
  308. mAppAngle = atan2f(max_scale, range) * RAD_TO_DEG;
  309. // Compute pixels per meter at the given range
  310. F32 pixels_per_meter = gViewerCamera.getViewHeightInPixels() /
  311. (tanf(gViewerCamera.getView()) * range);
  312. // Assume grass texture is a 5 meter by 5 meter sprite at the grass
  313. // object's center
  314. mPixelArea = pixels_per_meter * pixels_per_meter * 25.f;
  315. }
  316. // *TODO: could speed this up by caching the relative_position and range
  317. // calculations
  318. void LLVOGrass::updateTextures()
  319. {
  320. if (getTEImage(0))
  321. {
  322. if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
  323. {
  324. setDebugText(llformat("%4.0f", sqrtf(mPixelArea)));
  325. }
  326. getTEImage(0)->addTextureStats(mPixelArea);
  327. }
  328. }
  329. bool LLVOGrass::updateLOD()
  330. {
  331. if (mDrawable->getNumFaces() <= 0)
  332. {
  333. return false;
  334. }
  335. if (LLVOTree::isTreeRenderingStopped())
  336. {
  337. if (mNumBlades)
  338. {
  339. mNumBlades = 0;
  340. gPipeline.markRebuild(mDrawable);
  341. }
  342. return true;
  343. }
  344. if (!mNumBlades)
  345. {
  346. mNumBlades = GRASS_MAX_BLADES;
  347. }
  348. LLFace* face = mDrawable->getFace(0);
  349. if (!face)
  350. {
  351. return false;
  352. }
  353. F32 tan_angle = mScale.mV[0] * mScale.mV[1] /
  354. mDrawable->mDistanceWRTCamera;
  355. S32 num_blades = llmin(GRASS_MAX_BLADES, lltrunc(tan_angle * 5.f));
  356. num_blades = llmax(1, num_blades);
  357. if (num_blades >= (mNumBlades << 1))
  358. {
  359. while (mNumBlades < num_blades)
  360. {
  361. mNumBlades <<= 1;
  362. }
  363. face->setSize(mNumBlades * 8, mNumBlades * 12);
  364. gPipeline.markRebuild(mDrawable);
  365. }
  366. else if (num_blades <= (mNumBlades >> 1))
  367. {
  368. while (mNumBlades > num_blades)
  369. {
  370. mNumBlades >>= 1;
  371. }
  372. face->setSize(mNumBlades * 8, mNumBlades * 12);
  373. gPipeline.markRebuild(mDrawable);
  374. return true;
  375. }
  376. return false;
  377. }
  378. LLDrawable* LLVOGrass::createDrawable()
  379. {
  380. gPipeline.allocDrawable(this);
  381. mDrawable->setRenderType(LLPipeline::RENDER_TYPE_GRASS);
  382. return mDrawable;
  383. }
  384. bool LLVOGrass::updateGeometry(LLDrawable* drawable)
  385. {
  386. LL_FAST_TIMER(FTM_UPDATE_GRASS);
  387. dirtySpatialGroup();
  388. if (!mNumBlades) // Stop rendering grass
  389. {
  390. if (mDrawable->getNumFaces() > 0)
  391. {
  392. LLFace* facep = mDrawable->getFace(0);
  393. if (facep)
  394. {
  395. facep->setSize(0, 0);
  396. }
  397. }
  398. }
  399. else
  400. {
  401. plantBlades();
  402. }
  403. return true;
  404. }
  405. void LLVOGrass::plantBlades()
  406. {
  407. // It is possible that the species of a grass is not defined. This is bad,
  408. // but not the end of the world.
  409. if (!sSpeciesTable.count(mSpecies))
  410. {
  411. llinfos << "Unknown grass species " << mSpecies << llendl;
  412. return;
  413. }
  414. if (mDrawable->getNumFaces() < 1)
  415. {
  416. mDrawable->setNumFaces(1, NULL, getTEImage(0));
  417. }
  418. LLFace* face = mDrawable->getFace(0);
  419. if (!face)
  420. {
  421. return;
  422. }
  423. face->setDiffuseMap(getTEImage(0));
  424. face->setState(LLFace::GLOBAL);
  425. face->setSize(mNumBlades * 8, mNumBlades * 12);
  426. face->setVertexBuffer(NULL);
  427. face->setTEOffset(0);
  428. face->mCenterLocal = mPosition + mRegionp->getOriginAgent();
  429. mDepth = (face->mCenterLocal - gViewerCamera.getOrigin()) *
  430. gViewerCamera.getAtAxis();
  431. mDrawable->setPosition(face->mCenterLocal);
  432. mDrawable->movePartition();
  433. }
  434. void LLVOGrass::getGeometry(S32 idx,
  435. LLStrider<LLVector4a>& verticesp,
  436. LLStrider<LLVector3>& normalsp,
  437. LLStrider<LLVector2>& texcoordsp,
  438. LLStrider<LLColor4U>& colorsp,
  439. LLStrider<LLColor4U>& emissivep,
  440. LLStrider<U16>& indicesp)
  441. {
  442. if (!mNumBlades) // stop rendering grass
  443. {
  444. return;
  445. }
  446. mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion());
  447. if (mPatch)
  448. {
  449. mLastPatchUpdateTime = mPatch->getLastUpdateTime();
  450. }
  451. LLVector3 position;
  452. // Create random blades of grass with gaussian distribution
  453. F32 x, y, xf, yf, dzx, dzy;
  454. LLColor4U color(255, 255, 255, 255);
  455. LLFace* face = mDrawable->getFace(idx);
  456. if (!face)
  457. {
  458. return;
  459. }
  460. F32 width = sSpeciesTable[mSpecies]->mBladeSizeX;
  461. F32 height = sSpeciesTable[mSpecies]->mBladeSizeY;
  462. U32 index_offset = face->getGeomIndex();
  463. LLVector3 origin_agent = mRegionp->getOriginAgent();
  464. for (S32 i = 0; i < mNumBlades; ++i)
  465. {
  466. x = exp_x[i] * mScale.mV[VX];
  467. y = exp_y[i] * mScale.mV[VY];
  468. xf = rot_x[i] * GRASS_BLADE_BASE * width * w_mod[i];
  469. yf = rot_y[i] * GRASS_BLADE_BASE * width * w_mod[i];
  470. dzx = dz_x [i];
  471. dzy = dz_y [i];
  472. LLVector3 v1, v2, v3;
  473. F32 blade_height = GRASS_BLADE_HEIGHT * height * w_mod[i];
  474. *texcoordsp++ = LLVector2(0, 0);
  475. *texcoordsp++ = LLVector2(0, 0);
  476. *texcoordsp++ = LLVector2(0, 0.98f);
  477. *texcoordsp++ = LLVector2(0, 0.98f);
  478. *texcoordsp++ = LLVector2(1, 0);
  479. *texcoordsp++ = LLVector2(1, 0);
  480. *texcoordsp++ = LLVector2(1, 0.98f);
  481. *texcoordsp++ = LLVector2(1, 0.98f);
  482. position.mV[0] = mPosition.mV[VX] + x + xf;
  483. position.mV[1] = mPosition.mV[VY] + y + yf;
  484. position.mV[2] = mRegionp->getLand().resolveHeightRegion(position);
  485. v1 = position + origin_agent;
  486. (*verticesp++).load3(v1.mV);
  487. (*verticesp++).load3(v1.mV);
  488. position.mV[0] += dzx;
  489. position.mV[1] += dzy;
  490. position.mV[2] += blade_height;
  491. v2 = position + origin_agent;
  492. (*verticesp++).load3(v2.mV);
  493. (*verticesp++).load3(v2.mV);
  494. position.mV[0] = mPosition.mV[VX] + x - xf;
  495. position.mV[1] = mPosition.mV[VY] + y - xf;
  496. position.mV[2] = mRegionp->getLand().resolveHeightRegion(position);
  497. v3 = position + origin_agent;
  498. (*verticesp++).load3(v3.mV);
  499. (*verticesp++).load3(v3.mV);
  500. LLVector3 normal1 = (v1 - v2) % (v2 - v3);
  501. normal1.mV[VZ] = 0.75f;
  502. normal1.normalize();
  503. LLVector3 normal2 = -normal1;
  504. normal2.mV[VZ] = -normal2.mV[VZ];
  505. position.mV[0] += dzx;
  506. position.mV[1] += dzy;
  507. position.mV[2] += blade_height;
  508. v1 = position + origin_agent;
  509. (*verticesp++).load3(v1.mV);
  510. (*verticesp++).load3(v1.mV);
  511. *(normalsp++) = normal1;
  512. *(normalsp++) = normal2;
  513. *(normalsp++) = normal1;
  514. *(normalsp++) = normal2;
  515. *(normalsp++) = normal1;
  516. *(normalsp++) = normal2;
  517. *(normalsp++) = normal1;
  518. *(normalsp++) = normal2;
  519. *(colorsp++) = color;
  520. *(colorsp++) = color;
  521. *(colorsp++) = color;
  522. *(colorsp++) = color;
  523. *(colorsp++) = color;
  524. *(colorsp++) = color;
  525. *(colorsp++) = color;
  526. *(colorsp++) = color;
  527. *indicesp++ = index_offset;
  528. *indicesp++ = index_offset + 2;
  529. *indicesp++ = index_offset + 4;
  530. *indicesp++ = index_offset + 2;
  531. *indicesp++ = index_offset + 6;
  532. *indicesp++ = index_offset + 4;
  533. *indicesp++ = index_offset + 1;
  534. *indicesp++ = index_offset + 5;
  535. *indicesp++ = index_offset + 3;
  536. *indicesp++ = index_offset + 3;
  537. *indicesp++ = index_offset + 5;
  538. *indicesp++ = index_offset + 7;
  539. index_offset += 8;
  540. }
  541. }
  542. U32 LLVOGrass::getPartitionType() const
  543. {
  544. return LLViewerRegion::PARTITION_GRASS;
  545. }
  546. ///////////////////////////////////////////////////////////////////////////////
  547. // LLGrassPartition class (declared in llspatialpartition.h)
  548. ///////////////////////////////////////////////////////////////////////////////
  549. LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp)
  550. : LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK |
  551. LLVertexBuffer::MAP_TEXTURE_INDEX,
  552. true, regionp)
  553. {
  554. mDrawableType = LLPipeline::RENDER_TYPE_GRASS;
  555. mPartitionType = LLViewerRegion::PARTITION_GRASS;
  556. mLODPeriod = 16;
  557. mDepthMask = true;
  558. mSlopRatio = 0.1f;
  559. mRenderPass = LLRenderPass::PASS_GRASS;
  560. }
  561. //virtual
  562. void LLGrassPartition::addGeometryCount(LLSpatialGroup* group,
  563. U32& vertex_count,
  564. U32& index_count)
  565. {
  566. mFaceList.clear();
  567. for (LLSpatialGroup::element_iter i = group->getDataBegin();
  568. i != group->getDataEnd(); ++i)
  569. {
  570. LLDrawable* drawablep = (LLDrawable*)(*i)->getDrawable();
  571. if (!drawablep || drawablep->isDead())
  572. {
  573. continue;
  574. }
  575. LLViewerObject* vobj = drawablep->getVObj().get();
  576. if (!vobj) // Paranoia
  577. {
  578. llwarns_once << "NULL viewer object for drawable " << std::hex
  579. << drawablep << std::dec << llendl;
  580. continue;
  581. }
  582. LLAlphaObject* obj = vobj->asAlphaObject();
  583. if (!obj)
  584. {
  585. llwarns_once << "Not an alpha object for drawable " << std::hex
  586. << drawablep << std::dec << llendl;
  587. continue;
  588. }
  589. obj->mDepth = 0.f;
  590. U32 count = 0;
  591. for (S32 j = 0; j < drawablep->getNumFaces(); ++j)
  592. {
  593. drawablep->updateFaceSize(j);
  594. LLFace* facep = drawablep->getFace(j);
  595. if (!facep || !facep->hasGeometry())
  596. {
  597. continue;
  598. }
  599. if (facep->getGeomCount() + vertex_count <= 65536)
  600. {
  601. ++count;
  602. facep->mDistance = (facep->mCenterLocal -
  603. gViewerCamera.getOrigin()) *
  604. gViewerCamera.getAtAxis();
  605. obj->mDepth += facep->mDistance;
  606. mFaceList.push_back(facep);
  607. vertex_count += facep->getGeomCount();
  608. index_count += facep->getIndicesCount();
  609. llassert(facep->getIndicesCount() < 65536);
  610. }
  611. else
  612. {
  613. facep->clearVertexBuffer();
  614. }
  615. }
  616. obj->mDepth /= count;
  617. }
  618. }
  619. //virtual
  620. void LLGrassPartition::getGeometry(LLSpatialGroup* group)
  621. {
  622. LL_FAST_TIMER(FTM_REBUILD_GRASS_VB);
  623. std::sort(mFaceList.begin(), mFaceList.end(),
  624. LLFace::CompareDistanceGreater());
  625. U32 index_count = 0;
  626. U32 vertex_count = 0;
  627. group->clearDrawMap();
  628. LLVertexBuffer* buffer = group->mVertexBuffer;
  629. if (!buffer) return; // Paranoia
  630. LLStrider<U16> indicesp;
  631. LLStrider<LLVector4a> verticesp;
  632. LLStrider<LLVector3> normalsp;
  633. LLStrider<LLVector2> texcoordsp;
  634. LLStrider<LLColor4U> colorsp;
  635. if (!buffer->getVertexStrider(verticesp) ||
  636. !buffer->getNormalStrider(normalsp) ||
  637. !buffer->getColorStrider(colorsp) ||
  638. !buffer->getTexCoord0Strider(texcoordsp) ||
  639. !buffer->getIndexStrider(indicesp))
  640. {
  641. return;
  642. }
  643. LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass];
  644. for (U32 i = 0, count = mFaceList.size(); i < count; ++i)
  645. {
  646. LLFace* facep = mFaceList[i];
  647. LLViewerObject* vobj = facep->getViewerObject();
  648. if (!vobj) // Paranoia
  649. {
  650. llwarns_once << "NULL viewer object for face " << std::hex << facep
  651. << std::dec << llendl;
  652. continue;
  653. }
  654. LLAlphaObject* object = vobj->asAlphaObject();
  655. if (!object)
  656. {
  657. llwarns_once << "Not an alpha object for face " << std::hex
  658. << facep << std::dec << llendl;
  659. continue;
  660. }
  661. facep->setGeomIndex(vertex_count);
  662. facep->setIndicesIndex(index_count);
  663. facep->setVertexBuffer(buffer);
  664. facep->setPoolType(LLDrawPool::POOL_ALPHA);
  665. // Dummy parameter (unused by this implementation)
  666. LLStrider<LLColor4U> emissivep;
  667. object->getGeometry(facep->getTEOffset(), verticesp, normalsp,
  668. texcoordsp, colorsp, emissivep, indicesp);
  669. vertex_count += facep->getGeomCount();
  670. index_count += facep->getIndicesCount();
  671. S32 idx = draw_vec.size() - 1;
  672. bool fullbright = facep->isState(LLFace::FULLBRIGHT);
  673. F32 vsize = facep->getVirtualSize();
  674. U16 geomcount = facep->getGeomCount();
  675. U32 indicescount = facep->getIndicesCount();
  676. if (idx >= 0 &&
  677. draw_vec[idx]->mEnd == facep->getGeomIndex() - 1 &&
  678. draw_vec[idx]->mTexture == facep->getTexture() &&
  679. (U32)(draw_vec[idx]->mEnd - draw_vec[idx]->mStart + geomcount) <=
  680. (U32)gGLManager.mGLMaxVertexRange &&
  681. #if 0
  682. draw_vec[idx]->mCount + indicescount <=
  683. (U32)gGLManager.mGLMaxIndexRange &&
  684. #endif
  685. draw_vec[idx]->mEnd - draw_vec[idx]->mStart + geomcount < 4096 &&
  686. draw_vec[idx]->mFullbright == fullbright)
  687. {
  688. draw_vec[idx]->mCount += indicescount;
  689. draw_vec[idx]->mEnd += geomcount;
  690. draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize);
  691. }
  692. else
  693. {
  694. U32 start = facep->getGeomIndex();
  695. U32 end = start + geomcount - 1;
  696. U32 offset = facep->getIndicesStart();
  697. LLDrawInfo* info = new LLDrawInfo(start, end, indicescount, offset,
  698. facep->getTexture(), buffer,
  699. fullbright);
  700. const LLVector4a* exts = group->getObjectExtents();
  701. info->mExtents[0] = exts[0];
  702. info->mExtents[1] = exts[1];
  703. info->mVSize = vsize;
  704. draw_vec.push_back(info);
  705. // For alpha sorting
  706. facep->setDrawInfo(info);
  707. }
  708. }
  709. buffer->unmapBuffer();
  710. mFaceList.clear();
  711. }
  712. //virtual
  713. void LLVOGrass::updateDrawable(bool force_damped)
  714. {
  715. // Force an immediate rebuild on any update
  716. if (mDrawable.notNull())
  717. {
  718. mDrawable->updateXform(true);
  719. gPipeline.markRebuild(mDrawable);
  720. }
  721. clearChanged(SHIFTED);
  722. }
  723. //virtual
  724. bool LLVOGrass::lineSegmentIntersect(const LLVector4a& start,
  725. const LLVector4a& end,
  726. S32 face,
  727. bool pick_transparent,
  728. bool pick_rigged,
  729. S32* face_hitp,
  730. LLVector4a* intersection,
  731. LLVector2* tex_coord,
  732. LLVector4a* normal,
  733. LLVector4a* tangent)
  734. {
  735. bool ret = false;
  736. if (!mCanSelect || mDrawable.isNull() || mDrawable->isDead() ||
  737. !gPipeline.hasRenderType(mDrawable->getRenderType()))
  738. {
  739. return false;
  740. }
  741. LLVector4a dir;
  742. dir.setSub(end, start);
  743. mPatch = mRegionp->getLand().resolvePatchRegion(getPositionRegion());
  744. LLVector3 position;
  745. // Create random blades of grass with gaussian distribution
  746. F32 x,y,xf,yf,dzx,dzy;
  747. LLColor4U color(255, 255, 255, 255);
  748. F32 width = sSpeciesTable[mSpecies]->mBladeSizeX;
  749. F32 height = sSpeciesTable[mSpecies]->mBladeSizeY;
  750. LLVector2 tc[4];
  751. LLVector3 v[4];
  752. F32 closest_t = 1.f;
  753. LLVector3 origin_agent = mRegionp->getOriginAgent();
  754. for (S32 i = 0; i < mNumBlades; ++i)
  755. {
  756. x = exp_x[i] * mScale.mV[VX];
  757. y = exp_y[i] * mScale.mV[VY];
  758. xf = rot_x[i] * GRASS_BLADE_BASE * width * w_mod[i];
  759. yf = rot_y[i] * GRASS_BLADE_BASE * width * w_mod[i];
  760. dzx = dz_x [i];
  761. dzy = dz_y [i];
  762. LLVector3 v1, v2, v3;
  763. F32 blade_height = GRASS_BLADE_HEIGHT * height * w_mod[i];
  764. tc[0] = LLVector2(0, 0);
  765. tc[1] = LLVector2(0, 0.98f);
  766. tc[2] = LLVector2(1, 0);
  767. tc[3] = LLVector2(1, 0.98f);
  768. position.mV[0] = mPosition.mV[VX] + x + xf;
  769. position.mV[1] = mPosition.mV[VY] + y + yf;
  770. position.mV[2] = mRegionp->getLand().resolveHeightRegion(position);
  771. v[0] = v1 = position + origin_agent;
  772. position.mV[0] += dzx;
  773. position.mV[1] += dzy;
  774. position.mV[2] += blade_height;
  775. v[1] = v2 = position + origin_agent;
  776. position.mV[0] = mPosition.mV[VX] + x - xf;
  777. position.mV[1] = mPosition.mV[VY] + y - xf;
  778. position.mV[2] = mRegionp->getLand().resolveHeightRegion(position);
  779. v[2] = v3 = position + origin_agent;
  780. LLVector3 normal1 = (v1 - v2) % (v2 - v3);
  781. normal1.normalize();
  782. position.mV[0] += dzx;
  783. position.mV[1] += dzy;
  784. position.mV[2] += blade_height;
  785. v[3] = v1 = position + origin_agent;
  786. F32 a, b, t;
  787. bool hit = false;
  788. U32 idx0 = 0, idx1 = 0, idx2 = 0;
  789. LLVector4a v0a, v1a, v2a, v3a;
  790. v0a.load3(v[0].mV);
  791. v1a.load3(v[1].mV);
  792. v2a.load3(v[2].mV);
  793. v3a.load3(v[3].mV);
  794. if (LLTriangleRayIntersect(v0a, v1a, v2a, start, dir, a, b, t))
  795. {
  796. hit = true;
  797. idx0 = 0; idx1 = 1; idx2 = 2;
  798. }
  799. else if (LLTriangleRayIntersect(v1a, v3a, v2a, start, dir, a, b, t))
  800. {
  801. hit = true;
  802. idx0 = 1; idx1 = 3; idx2 = 2;
  803. }
  804. else if (LLTriangleRayIntersect(v2a, v1a, v0a, start, dir, a, b, t))
  805. {
  806. normal1 = -normal1;
  807. hit = true;
  808. idx0 = 2; idx1 = 1; idx2 = 0;
  809. }
  810. else if (LLTriangleRayIntersect(v2a, v3a, v1a, start, dir, a, b, t))
  811. {
  812. normal1 = -normal1;
  813. hit = true;
  814. idx0 = 2; idx1 = 3; idx2 = 1;
  815. }
  816. if (hit)
  817. {
  818. if (t >= 0.f && t <= 1.f && t < closest_t)
  819. {
  820. LLVector2 hit_tc = ((1.f - a - b) * tc[idx0] + a * tc[idx1] +
  821. b * tc[idx2]);
  822. if (pick_transparent || getTEImage(0)->getMask(hit_tc))
  823. {
  824. closest_t = t;
  825. if (intersection != NULL)
  826. {
  827. dir.mul(closest_t);
  828. intersection->setAdd(start, dir);
  829. }
  830. if (tex_coord != NULL)
  831. {
  832. *tex_coord = hit_tc;
  833. }
  834. if (normal != NULL)
  835. {
  836. normal->load3(normal1.mV);
  837. }
  838. ret = true;
  839. }
  840. }
  841. }
  842. }
  843. return ret;
  844. }
  845. void LLVOGrass::generateSilhouetteVertices(std::vector<LLVector3>& vertices,
  846. std::vector<LLVector3>& normals,
  847. const LLVector3& obj_cam_vec,
  848. const LLMatrix4& mat,
  849. const LLMatrix3& norm_mat)
  850. {
  851. vertices.clear();
  852. normals.clear();
  853. F32 width = sSpeciesTable[mSpecies]->mBladeSizeX;
  854. F32 height = sSpeciesTable[mSpecies]->mBladeSizeY;
  855. LLVector3 origin_agent = mRegionp->getOriginAgent();
  856. for (S32 i = 0; i < mNumBlades; ++i)
  857. {
  858. F32 x = exp_x[i] * mScale.mV[VX];
  859. F32 y = exp_y[i] * mScale.mV[VY];
  860. F32 xf = rot_x[i] * GRASS_BLADE_BASE * width * w_mod[i];
  861. F32 yf = rot_y[i] * GRASS_BLADE_BASE * width * w_mod[i];
  862. F32 dzx = dz_x [i];
  863. F32 dzy = dz_y [i];
  864. F32 blade_height = GRASS_BLADE_HEIGHT * height * w_mod[i];
  865. LLVector3 position1;
  866. position1.mV[0] = mPosition.mV[VX] + x + xf;
  867. position1.mV[1] = mPosition.mV[VY] + y + yf;
  868. position1.mV[2] = mRegionp->getLand().resolveHeightRegion(position1);
  869. LLVector3 position2 = position1;
  870. position2.mV[0] += dzx;
  871. position2.mV[1] += dzy;
  872. position2.mV[2] += blade_height;
  873. LLVector3 position3;
  874. position3.mV[0] = mPosition.mV[VX] + x - xf;
  875. position3.mV[1] = mPosition.mV[VY] + y - xf;
  876. position3.mV[2] = mRegionp->getLand().resolveHeightRegion(position3);
  877. LLVector3 position4 = position3;
  878. position4.mV[0] += dzx;
  879. position4.mV[1] += dzy;
  880. position4.mV[2] += blade_height;
  881. LLVector3 normal = (position1 - position2) % (position2 - position3);
  882. normal.normalize();
  883. vertices.emplace_back(position1 + origin_agent);
  884. normals.emplace_back(normal);
  885. vertices.emplace_back(position2 + origin_agent);
  886. normals.emplace_back(normal);
  887. vertices.emplace_back(position2 + origin_agent);
  888. normals.emplace_back(normal);
  889. vertices.emplace_back(position4 + origin_agent);
  890. normals.emplace_back(normal);
  891. vertices.emplace_back(position4 + origin_agent);
  892. normals.emplace_back(normal);
  893. vertices.emplace_back(position3 + origin_agent);
  894. normals.emplace_back(normal);
  895. vertices.emplace_back(position3 + origin_agent);
  896. normals.emplace_back(normal);
  897. vertices.emplace_back(position1 + origin_agent);
  898. normals.emplace_back(normal);
  899. }
  900. }
  901. void LLVOGrass::generateSilhouette(LLSelectNode* nodep)
  902. {
  903. generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals,
  904. LLVector3::zero, LLMatrix4(), LLMatrix3());
  905. nodep->mSilhouetteGenerated = true;
  906. }