llvotree.cpp 42 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517
  1. /**
  2. * @file llvotree.cpp
  3. * @brief LLVOTree class implementation
  4. *
  5. * $LicenseInfo:firstyear=2002&license=viewergpl$
  6. *
  7. * Copyright (c) 2002-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 "llvotree.h"
  34. #include "imageids.h"
  35. #include "lldir.h"
  36. #include "llfasttimer.h"
  37. #include "llnoise.h"
  38. #include "llnotifications.h"
  39. #include "llprimitive.h"
  40. #include "lltree_common.h"
  41. #include "llxmltree.h"
  42. #include "object_flags.h"
  43. #include "llraytrace.h"
  44. #include "llagent.h"
  45. #include "lldrawable.h"
  46. #include "llface.h"
  47. #include "llpipeline.h"
  48. #include "llselectmgr.h"
  49. #include "llspatialpartition.h"
  50. #include "llviewercamera.h"
  51. #include "llviewercontrol.h"
  52. #include "llviewerobjectlist.h"
  53. #include "llviewerregion.h"
  54. #include "llviewertexturelist.h"
  55. #include "llworld.h"
  56. constexpr S32 MAX_SLICES = 32;
  57. constexpr F32 LEAF_LEFT = 0.52f;
  58. constexpr F32 LEAF_RIGHT = 0.98f;
  59. constexpr F32 LEAF_TOP = 1.0f;
  60. constexpr F32 LEAF_BOTTOM = 0.52f;
  61. constexpr F32 LEAF_WIDTH = 1.f;
  62. // How many frames between wind update per tree:
  63. constexpr U32 FRAMES_PER_WIND_UPDATE = 20U;
  64. S32 LLVOTree::sLODVertexOffset[MAX_NUM_TREE_LOD_LEVELS];
  65. S32 LLVOTree::sLODVertexCount[MAX_NUM_TREE_LOD_LEVELS];
  66. S32 LLVOTree::sLODIndexOffset[MAX_NUM_TREE_LOD_LEVELS];
  67. S32 LLVOTree::sLODIndexCount[MAX_NUM_TREE_LOD_LEVELS];
  68. S32 LLVOTree::sLODSlices[MAX_NUM_TREE_LOD_LEVELS] = { 10, 5, 4, 3 };
  69. F32 LLVOTree::sLODAngles[MAX_NUM_TREE_LOD_LEVELS] = { 30.f, 20.f, 15.f, F_ALMOST_ZERO };
  70. F32 LLVOTree::sTreeAnimationDamping = 0.99f;
  71. F32 LLVOTree::sTreeTrunkStiffness = 0.1f;
  72. F32 LLVOTree::sTreeWindSensitivity = 0.005f;
  73. bool LLVOTree::sRenderAnimateTrees = false;
  74. F32 LLVOTree::sTreeFactor = 1.f;
  75. LLVOTree::data_map_t LLVOTree::sSpeciesTable;
  76. LLVOTree::species_list_t LLVOTree::sSpeciesNames;
  77. S32 LLVOTree::sMaxTreeSpecies = 0;
  78. ///////////////////////////////////////////////////////////////////////////////
  79. // LLTreePartition class (declared in llspatialpartition.h)
  80. ///////////////////////////////////////////////////////////////////////////////
  81. LLTreePartition::LLTreePartition(LLViewerRegion* regionp)
  82. : LLSpatialPartition(0, false, regionp)
  83. {
  84. mDrawableType = LLPipeline::RENDER_TYPE_TREE;
  85. mPartitionType = LLViewerRegion::PARTITION_TREE;
  86. mSlopRatio = 0.f;
  87. mLODPeriod = 1;
  88. }
  89. ///////////////////////////////////////////////////////////////////////////////
  90. // LLVOTree class
  91. ///////////////////////////////////////////////////////////////////////////////
  92. LLVOTree::LLVOTree(const LLUUID& id, LLViewerRegion* regionp)
  93. : LLViewerObject(id, LL_PCODE_LEGACY_TREE, regionp),
  94. mTrunkLOD(0),
  95. mFrameCount(0),
  96. mWind(mRegionp->mWind.getVelocity(getPositionRegion()))
  97. {
  98. data_map_t::const_iterator it = sSpeciesTable.begin();
  99. mSpecies = it->first;
  100. mSpeciesData = it->second;
  101. }
  102. LLVOTree::~LLVOTree()
  103. {
  104. if (mData)
  105. {
  106. delete[] mData;
  107. mData = NULL;
  108. }
  109. mReferenceBuffer = NULL;
  110. mUpdateMeshBuffer = NULL;
  111. }
  112. //static
  113. bool LLVOTree::isTreeRenderingStopped()
  114. {
  115. return sTreeFactor < sLODAngles[MAX_NUM_TREE_LOD_LEVELS - 1];
  116. }
  117. // static
  118. void LLVOTree::initClass()
  119. {
  120. updateSettings();
  121. std::string xml_filename = gDirUtil.getFullPath(LL_PATH_APP_SETTINGS,
  122. "trees.xml");
  123. LLXmlTree tree_def_tree;
  124. if (!tree_def_tree.parseFile(xml_filename))
  125. {
  126. llerrs << "Failed to parse tree file." << llendl;
  127. }
  128. LLXmlTreeNode* rootp = tree_def_tree.getRoot();
  129. if (!rootp)
  130. {
  131. llerrs << "Failed to parse tree file." << llendl;
  132. return;
  133. }
  134. LLUUID id;
  135. S32 s32_val, species;
  136. F32 f32_val;
  137. for (LLXmlTreeNode* tree_def = rootp->getFirstChild(); tree_def;
  138. tree_def = rootp->getNextChild())
  139. {
  140. if (!tree_def->hasName("tree"))
  141. {
  142. llwarns << "Invalid tree definition node \"" << tree_def->getName()
  143. << "\"" << llendl;
  144. continue;
  145. }
  146. bool success = true;
  147. static LLStdStringHandle species_id_string = LLXmlTree::addAttributeString("species_id");
  148. if (!tree_def->getFastAttributeS32(species_id_string, species))
  149. {
  150. llwarns << "No species id defined" << llendl;
  151. continue;
  152. }
  153. if (species < 0)
  154. {
  155. llwarns << "Invalid species id " << species << llendl;
  156. continue;
  157. }
  158. if (sSpeciesTable.count(species))
  159. {
  160. llwarns << "Tree species \"" << species
  161. << "\" already defined ! Duplicate discarded." << llendl;
  162. continue;
  163. }
  164. TreeSpeciesData* new_tree = new TreeSpeciesData();
  165. static LLStdStringHandle texture_id_string =
  166. LLXmlTree::addAttributeString("texture_id");
  167. success &= tree_def->getFastAttributeUUID(texture_id_string, id);
  168. new_tree->mTextureID = id;
  169. static LLStdStringHandle droop_string =
  170. LLXmlTree::addAttributeString("droop");
  171. success &= tree_def->getFastAttributeF32(droop_string, f32_val);
  172. new_tree->mDroop = f32_val;
  173. static LLStdStringHandle twist_string =
  174. LLXmlTree::addAttributeString("twist");
  175. success &= tree_def->getFastAttributeF32(twist_string, f32_val);
  176. new_tree->mTwist = f32_val;
  177. static LLStdStringHandle branches_string =
  178. LLXmlTree::addAttributeString("branches");
  179. success &= tree_def->getFastAttributeF32(branches_string, f32_val);
  180. new_tree->mBranches = f32_val;
  181. static LLStdStringHandle depth_string =
  182. LLXmlTree::addAttributeString("depth");
  183. success &= tree_def->getFastAttributeS32(depth_string, s32_val);
  184. new_tree->mDepth = s32_val;
  185. static LLStdStringHandle scale_step_string =
  186. LLXmlTree::addAttributeString("scale_step");
  187. success &= tree_def->getFastAttributeF32(scale_step_string, f32_val);
  188. new_tree->mScaleStep = f32_val;
  189. static LLStdStringHandle trunk_depth_string =
  190. LLXmlTree::addAttributeString("trunk_depth");
  191. success &= tree_def->getFastAttributeS32(trunk_depth_string, s32_val);
  192. new_tree->mTrunkDepth = s32_val;
  193. static LLStdStringHandle branch_length_string =
  194. LLXmlTree::addAttributeString("branch_length");
  195. success &= tree_def->getFastAttributeF32(branch_length_string,
  196. f32_val);
  197. new_tree->mBranchLength = f32_val;
  198. static LLStdStringHandle trunk_length_string =
  199. LLXmlTree::addAttributeString("trunk_length");
  200. success &= tree_def->getFastAttributeF32(trunk_length_string, f32_val);
  201. new_tree->mTrunkLength = f32_val;
  202. static LLStdStringHandle leaf_scale_string =
  203. LLXmlTree::addAttributeString("leaf_scale");
  204. success &= tree_def->getFastAttributeF32(leaf_scale_string, f32_val);
  205. new_tree->mLeafScale = f32_val;
  206. static LLStdStringHandle billboard_scale_string =
  207. LLXmlTree::addAttributeString("billboard_scale");
  208. success &= tree_def->getFastAttributeF32(billboard_scale_string,
  209. f32_val);
  210. new_tree->mBillboardScale = f32_val;
  211. static LLStdStringHandle billboard_ratio_string =
  212. LLXmlTree::addAttributeString("billboard_ratio");
  213. success &= tree_def->getFastAttributeF32(billboard_ratio_string,
  214. f32_val);
  215. new_tree->mBillboardRatio = f32_val;
  216. static LLStdStringHandle trunk_aspect_string =
  217. LLXmlTree::addAttributeString("trunk_aspect");
  218. success &= tree_def->getFastAttributeF32(trunk_aspect_string, f32_val);
  219. new_tree->mTrunkAspect = f32_val;
  220. static LLStdStringHandle branch_aspect_string =
  221. LLXmlTree::addAttributeString("branch_aspect");
  222. success &= tree_def->getFastAttributeF32(branch_aspect_string,
  223. f32_val);
  224. new_tree->mBranchAspect = f32_val;
  225. static LLStdStringHandle leaf_rotate_string =
  226. LLXmlTree::addAttributeString("leaf_rotate");
  227. success &= tree_def->getFastAttributeF32(leaf_rotate_string, f32_val);
  228. new_tree->mRandomLeafRotate = f32_val;
  229. static LLStdStringHandle noise_mag_string =
  230. LLXmlTree::addAttributeString("noise_mag");
  231. success &= tree_def->getFastAttributeF32(noise_mag_string, f32_val);
  232. new_tree->mNoiseMag = f32_val;
  233. static LLStdStringHandle noise_scale_string =
  234. LLXmlTree::addAttributeString("noise_scale");
  235. success &= tree_def->getFastAttributeF32(noise_scale_string, f32_val);
  236. new_tree->mNoiseScale = f32_val;
  237. static LLStdStringHandle taper_string =
  238. LLXmlTree::addAttributeString("taper");
  239. success &= tree_def->getFastAttributeF32(taper_string, f32_val);
  240. new_tree->mTaper = f32_val;
  241. static LLStdStringHandle repeat_z_string =
  242. LLXmlTree::addAttributeString("repeat_z");
  243. success &= tree_def->getFastAttributeF32(repeat_z_string, f32_val);
  244. new_tree->mRepeatTrunkZ = f32_val;
  245. sSpeciesTable[species] = new_tree;
  246. if (species >= sMaxTreeSpecies)
  247. {
  248. sMaxTreeSpecies = species + 1;
  249. }
  250. std::string name;
  251. static LLStdStringHandle name_string =
  252. LLXmlTree::addAttributeString("name");
  253. success &= tree_def->getFastAttributeString(name_string, name);
  254. sSpeciesNames[name] = species;
  255. if (!success)
  256. {
  257. llwarns << "Incomplete definition of tree " << name << llendl;
  258. }
  259. }
  260. if (sSpeciesTable.empty())
  261. {
  262. llerrs << "Could not load any tree species !" << llendl;
  263. }
  264. bool have_all_trees = true;
  265. std::string err;
  266. for (S32 i = 0; i < sMaxTreeSpecies; ++i)
  267. {
  268. if (!sSpeciesTable.count(i))
  269. {
  270. err.append(llformat(" %d", i));
  271. have_all_trees = false;
  272. }
  273. }
  274. if (!have_all_trees)
  275. {
  276. LLSD args;
  277. args["SPECIES"] = err;
  278. gNotifications.add("ErrorUndefinedTrees", args);
  279. }
  280. }
  281. //static
  282. void LLVOTree::cleanupClass()
  283. {
  284. std::for_each(sSpeciesTable.begin(), sSpeciesTable.end(),
  285. DeletePairedPointer());
  286. sSpeciesTable.clear();
  287. }
  288. //static
  289. void LLVOTree::updateSettings()
  290. {
  291. sTreeFactor = llmax(gSavedSettings.getF32("RenderTreeLODFactor"), 0.1f);
  292. sRenderAnimateTrees = gSavedSettings.getBool("RenderAnimateTrees");
  293. sTreeAnimationDamping =
  294. llclamp(gSavedSettings.getF32("RenderTreeAnimationDamping"), 0.1f,
  295. 1.f);
  296. sTreeTrunkStiffness =
  297. llclamp(gSavedSettings.getF32("RenderTreeTrunkStiffness"), 0.01f, 1.f);
  298. sTreeWindSensitivity =
  299. llclamp(gSavedSettings.getF32("RenderTreeWindSensitivity"), 0.00005f,
  300. 0.05f);
  301. }
  302. U32 LLVOTree::processUpdateMessage(LLMessageSystem* mesgsys,
  303. void** user_data, U32 block_num,
  304. EObjectUpdateType update_type,
  305. LLDataPacker* dp)
  306. {
  307. // Do base class updates...
  308. U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data,
  309. block_num, update_type,
  310. dp);
  311. if (getVelocity().lengthSquared() > 0.f ||
  312. getAcceleration().lengthSquared() > 0.f ||
  313. getAngularVelocity().lengthSquared() > 0.f)
  314. {
  315. llwarns << "ACK ! Moving tree !" << llendl;
  316. setVelocity(LLVector3::zero);
  317. setAcceleration(LLVector3::zero);
  318. setAngularVelocity(LLVector3::zero);
  319. }
  320. if (update_type == OUT_TERSE_IMPROVED)
  321. {
  322. // Nothing else needs to be done for the terse message.
  323. return retval;
  324. }
  325. //
  326. // Load Instance-Specific data
  327. //
  328. if (mData)
  329. {
  330. mSpecies = ((U8*)mData)[0];
  331. }
  332. data_map_t::const_iterator it = sSpeciesTable.find(mSpecies);
  333. if (it == sSpeciesTable.end())
  334. {
  335. llwarns_once << "Unknown tree species: " << mSpecies
  336. << ". Using default species." << llendl;
  337. it = sSpeciesTable.begin();
  338. mSpecies = it->first;
  339. }
  340. mSpeciesData = it->second;
  341. // Load Species-Specific data
  342. constexpr S32 MAX_TREE_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL = 32; // Frames.
  343. mTreeImagep =
  344. LLViewerTextureManager::getFetchedTexture(mSpeciesData->mTextureID,
  345. FTT_DEFAULT, true,
  346. LLGLTexture::BOOST_TERRAIN,
  347. LLViewerTexture::LOD_TEXTURE);
  348. // Allow to wait for at most 16 frames to reset virtual size.
  349. mTreeImagep->setMaxVirtualSizeResetInterval(MAX_TREE_TEXTURE_VIRTUAL_SIZE_RESET_INTERVAL);
  350. mBranchLength = mSpeciesData->mBranchLength;
  351. mTrunkLength = mSpeciesData->mTrunkLength;
  352. mLeafScale = mSpeciesData->mLeafScale;
  353. mDroop = mSpeciesData->mDroop;
  354. mTwist = mSpeciesData->mTwist;
  355. mBranches = mSpeciesData->mBranches;
  356. mDepth = mSpeciesData->mDepth;
  357. mScaleStep = mSpeciesData->mScaleStep;
  358. mTrunkDepth = mSpeciesData->mTrunkDepth;
  359. mBillboardScale = mSpeciesData->mBillboardScale;
  360. mBillboardRatio = mSpeciesData->mBillboardRatio;
  361. mTrunkAspect = mSpeciesData->mTrunkAspect;
  362. mBranchAspect = mSpeciesData->mBranchAspect;
  363. // Position change not caused by us, etc. make sure to rebuild.
  364. gPipeline.markRebuild(mDrawable);
  365. return retval;
  366. }
  367. void LLVOTree::idleUpdate(F64 time)
  368. {
  369. if (mDead || !gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_TREE))
  370. {
  371. return;
  372. }
  373. if (sRenderAnimateTrees)
  374. {
  375. // For all tree objects, update the trunk bending with the current
  376. // wind. Walk sprite list in order away from viewer.
  377. if (!(mFrameCount % FRAMES_PER_WIND_UPDATE))
  378. {
  379. // If needed, Get latest wind for this tree
  380. mWind = mRegionp->mWind.getVelocity(getPositionRegion());
  381. }
  382. ++mFrameCount;
  383. F32 mass_inv = 1.f / (5.f + mDepth * mBranches * 0.2f);
  384. // Pull in direction of wind
  385. mTrunkVel += mWind * mass_inv * sTreeWindSensitivity;
  386. // Restoring force in direction of trunk
  387. mTrunkVel -= mTrunkBend * mass_inv * sTreeTrunkStiffness;
  388. mTrunkBend += mTrunkVel;
  389. // Add damping
  390. mTrunkVel *= sTreeAnimationDamping;
  391. if (mTrunkBend.lengthSquared() > 1.f)
  392. {
  393. mTrunkBend.normalize();
  394. }
  395. if (mTrunkVel.lengthSquared() > 1.f)
  396. {
  397. mTrunkVel.normalize();
  398. }
  399. }
  400. U32 trunk_lod = MAX_NUM_TREE_LOD_LEVELS;
  401. F32 app_angle = getAppAngle() * sTreeFactor;
  402. for (U32 j = 0; j < MAX_NUM_TREE_LOD_LEVELS; ++j)
  403. {
  404. if (app_angle > sLODAngles[j])
  405. {
  406. trunk_lod = j;
  407. break;
  408. }
  409. }
  410. if (!sRenderAnimateTrees)
  411. {
  412. if (mReferenceBuffer.isNull() || trunk_lod != mTrunkLOD)
  413. {
  414. gPipeline.markRebuild(mDrawable);
  415. }
  416. else
  417. {
  418. // We are not animating but we may *still* need to regenerate the
  419. // mesh if we moved, since position and rotation are baked into the
  420. // mesh.
  421. // *TODO: I do not know what is so special about trees that they
  422. // do not get REBUILD_POSITION automatically at a higher level.
  423. const LLVector3& this_position = getPositionRegion();
  424. if (this_position != mLastPosition)
  425. {
  426. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION);
  427. mLastPosition = this_position;
  428. }
  429. else
  430. {
  431. const LLQuaternion& this_rotation = getRotation();
  432. if (this_rotation != mLastRotation)
  433. {
  434. gPipeline.markRebuild(mDrawable,
  435. LLDrawable::REBUILD_POSITION);
  436. mLastRotation = this_rotation;
  437. }
  438. }
  439. }
  440. }
  441. mTrunkLOD = trunk_lod;
  442. }
  443. void LLVOTree::setPixelAreaAndAngle()
  444. {
  445. LLVector3 center = getPositionAgent(); // Center of tree.
  446. LLVector3 viewer_pos_agent = gAgent.getCameraPositionAgent();
  447. LLVector3 lookAt = center - viewer_pos_agent;
  448. F32 dist = lookAt.normalize();
  449. F32 cos_angle_to_view_dir = lookAt * gViewerCamera.getXAxis();
  450. F32 range = dist - getMinScale() * 0.5f;
  451. if (range < F_ALMOST_ZERO || isHUDAttachment()) // range == zero
  452. {
  453. range = 0.f;
  454. mAppAngle = 180.f;
  455. }
  456. else
  457. {
  458. mAppAngle = atan2f(getMaxScale(), range) * RAD_TO_DEG;
  459. }
  460. F32 max_scale = mBillboardScale * getMaxScale();
  461. F32 area = mBillboardRatio * max_scale * max_scale;
  462. // Compute pixels per meter at the given range
  463. F32 pixels_per_meter = gViewerCamera.getViewHeightInPixels() /
  464. (tanf(gViewerCamera.getView()) * dist);
  465. mPixelArea = pixels_per_meter * pixels_per_meter * area;
  466. F32 importance = LLFace::calcImportanceToCamera(cos_angle_to_view_dir,
  467. dist);
  468. mPixelArea = LLFace::adjustPixelArea(importance, mPixelArea);
  469. if (mPixelArea > gViewerCamera.getScreenPixelArea())
  470. {
  471. mAppAngle = 180.f;
  472. }
  473. #if 0
  474. // mAppAngle is a bit of voodoo; use the one calculated with
  475. // LLViewerObject::setPixelAreaAndAngle above to avoid LOD
  476. // miscalculations
  477. mAppAngle = atan2f(max_scale, range) * RAD_TO_DEG;
  478. #endif
  479. }
  480. void LLVOTree::updateTextures()
  481. {
  482. if (mTreeImagep)
  483. {
  484. if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
  485. {
  486. setDebugText(llformat("%4.0f", sqrtf(mPixelArea)));
  487. }
  488. mTreeImagep->addTextureStats(mPixelArea);
  489. }
  490. }
  491. LLDrawable* LLVOTree::createDrawable()
  492. {
  493. gPipeline.allocDrawable(this);
  494. mDrawable->setLit(false);
  495. mDrawable->setRenderType(LLPipeline::RENDER_TYPE_TREE);
  496. LLDrawPoolTree* poolp =
  497. (LLDrawPoolTree*)gPipeline.getPool(LLDrawPool::POOL_TREE, mTreeImagep);
  498. // Just a placeholder for an actual object...
  499. LLFace* facep = mDrawable->addFace(poolp, mTreeImagep);
  500. facep->setSize(1, 3);
  501. updateRadius();
  502. return mDrawable;
  503. }
  504. constexpr S32 LEAF_INDICES = 24;
  505. constexpr S32 LEAF_VERTICES = 16;
  506. bool LLVOTree::updateGeometry(LLDrawable* drawable)
  507. {
  508. LL_FAST_TIMER(FTM_UPDATE_TREE);
  509. LLFace* face = drawable->getFace(0);
  510. if (mTrunkLOD >= MAX_NUM_TREE_LOD_LEVELS) // Do not display the tree.
  511. {
  512. mReferenceBuffer = NULL;
  513. if (face)
  514. {
  515. face->setVertexBuffer(NULL);
  516. }
  517. return true;
  518. }
  519. if (mDrawable->getFace(0) &&
  520. (mReferenceBuffer.isNull() ||
  521. !mDrawable->getFace(0)->getVertexBuffer()))
  522. {
  523. if (!face) return true; // Abort
  524. constexpr F32 SRR3 = 0.577350269f; // sqrtf(1/3)
  525. constexpr F32 SRR2 = 0.707106781f; // sqrtf(1/2)
  526. U32 i, j;
  527. U32 slices = MAX_SLICES;
  528. S32 max_indices = LEAF_INDICES;
  529. S32 max_vertices = LEAF_VERTICES;
  530. U32 lod;
  531. face->mCenterAgent = getPositionAgent();
  532. face->mCenterLocal = face->mCenterAgent;
  533. for (lod = 0; lod < MAX_NUM_TREE_LOD_LEVELS; ++lod)
  534. {
  535. slices = sLODSlices[lod];
  536. sLODVertexOffset[lod] = max_vertices;
  537. sLODVertexCount[lod] = slices * slices;
  538. sLODIndexOffset[lod] = max_indices;
  539. sLODIndexCount[lod] = (slices - 1) * (slices - 1) * 6;
  540. max_indices += sLODIndexCount[lod];
  541. max_vertices += sLODVertexCount[lod];
  542. }
  543. mReferenceBuffer =
  544. new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
  545. #if LL_DEBUG_VB_ALLOC
  546. mReferenceBuffer->setOwner("LLVOTree reference");
  547. #endif
  548. if (!mReferenceBuffer->allocateBuffer(max_vertices, max_indices))
  549. {
  550. llwarns << "Failure to allocate a vertex buffer with "
  551. << max_vertices << " vertices and "
  552. << max_indices << " indices" << llendl;
  553. mReferenceBuffer = NULL;
  554. return true; // Abort
  555. }
  556. LLStrider<LLVector3> vertices, normals;
  557. LLStrider<LLVector2> tex_coords;
  558. LLStrider<LLColor4U> colors;
  559. LLStrider<U16> indicesp;
  560. if (!mReferenceBuffer->getVertexStrider(vertices) ||
  561. !mReferenceBuffer->getNormalStrider(normals) ||
  562. !mReferenceBuffer->getTexCoord0Strider(tex_coords) ||
  563. !mReferenceBuffer->getColorStrider(colors) ||
  564. !mReferenceBuffer->getIndexStrider(indicesp))
  565. {
  566. return false;
  567. }
  568. // First leaf
  569. *(normals++) = LLVector3(-SRR2, -SRR2, 0.f);
  570. *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM);
  571. *(vertices++) = LLVector3(-0.5f * LEAF_WIDTH, 0.f, 0.f);
  572. *(colors++) = LLColor4U::white;
  573. *(normals++) = LLVector3(SRR3, -SRR3, SRR3);
  574. *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP);
  575. *(vertices++) = LLVector3(0.5f * LEAF_WIDTH, 0.f, 1.f);
  576. *(colors++) = LLColor4U::white;
  577. *(normals++) = LLVector3(-SRR3, -SRR3, SRR3);
  578. *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP);
  579. *(vertices++) = LLVector3(-0.5f * LEAF_WIDTH, 0.f, 1.f);
  580. *(colors++) = LLColor4U::white;
  581. *(normals++) = LLVector3(SRR2, -SRR2, 0.f);
  582. *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM);
  583. *(vertices++) = LLVector3(0.5f * LEAF_WIDTH, 0.f, 0.f);
  584. *(colors++) = LLColor4U::white;
  585. *(indicesp++) = 0;
  586. *(indicesp++) = 1;
  587. *(indicesp++) = 2;
  588. *(indicesp++) = 0;
  589. *(indicesp++) = 3;
  590. *(indicesp++) = 1;
  591. // Same leaf, inverse winding/normals
  592. *(normals++) = LLVector3(-SRR2, SRR2, 0.f);
  593. *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM);
  594. *(vertices++) = LLVector3(-0.5f * LEAF_WIDTH, 0.f, 0.f);
  595. *(colors++) = LLColor4U::white;
  596. *(normals++) = LLVector3(SRR3, SRR3, SRR3);
  597. *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP);
  598. *(vertices++) = LLVector3(0.5f * LEAF_WIDTH, 0.f, 1.f);
  599. *(colors++) = LLColor4U::white;
  600. *(normals++) = LLVector3(-SRR3, SRR3, SRR3);
  601. *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP);
  602. *(vertices++) = LLVector3(-0.5f * LEAF_WIDTH, 0.f, 1.f);
  603. *(colors++) = LLColor4U::white;
  604. *(normals++) = LLVector3(SRR2, SRR2, 0.f);
  605. *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM);
  606. *(vertices++) = LLVector3(0.5f * LEAF_WIDTH, 0.f, 0.f);
  607. *(colors++) = LLColor4U::white;
  608. *(indicesp++) = 4;
  609. *(indicesp++) = 6;
  610. *(indicesp++) = 5;
  611. *(indicesp++) = 4;
  612. *(indicesp++) = 5;
  613. *(indicesp++) = 7;
  614. // next leaf
  615. *(normals++) = LLVector3(SRR2, -SRR2, 0.f);
  616. *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM);
  617. *(vertices++) = LLVector3(0.f, -0.5f * LEAF_WIDTH, 0.f);
  618. *(colors++) = LLColor4U::white;
  619. *(normals++) = LLVector3(SRR3, SRR3, SRR3);
  620. *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP);
  621. *(vertices++) = LLVector3(0.f, 0.5f * LEAF_WIDTH, 1.f);
  622. *(colors++) = LLColor4U::white;
  623. *(normals++) = LLVector3(SRR3, -SRR3, SRR3);
  624. *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP);
  625. *(vertices++) = LLVector3(0.f, -0.5f * LEAF_WIDTH, 1.f);
  626. *(colors++) = LLColor4U::white;
  627. *(normals++) = LLVector3(SRR2, SRR2, 0.f);
  628. *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM);
  629. *(vertices++) = LLVector3(0.f, 0.5f * LEAF_WIDTH, 0.f);
  630. *(colors++) = LLColor4U::white;
  631. *(indicesp++) = 8;
  632. *(indicesp++) = 9;
  633. *(indicesp++) = 10;
  634. *(indicesp++) = 8;
  635. *(indicesp++) = 11;
  636. *(indicesp++) = 9;
  637. // Other side of same leaf
  638. *(normals++) = LLVector3(-SRR2, -SRR2, 0.f);
  639. *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_BOTTOM);
  640. *(vertices++) = LLVector3(0.f, -0.5f * LEAF_WIDTH, 0.f);
  641. *(colors++) = LLColor4U::white;
  642. *(normals++) = LLVector3(-SRR3, SRR3, SRR3);
  643. *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_TOP);
  644. *(vertices++) = LLVector3(0.f, 0.5f * LEAF_WIDTH, 1.f);
  645. *(colors++) = LLColor4U::white;
  646. *(normals++) = LLVector3(-SRR3, -SRR3, SRR3);
  647. *(tex_coords++) = LLVector2(LEAF_LEFT, LEAF_TOP);
  648. *(vertices++) = LLVector3(0.f, -0.5f * LEAF_WIDTH, 1.f);
  649. *(colors++) = LLColor4U::white;
  650. *(normals++) = LLVector3(-SRR2, SRR2, 0.f);
  651. *(tex_coords++) = LLVector2(LEAF_RIGHT, LEAF_BOTTOM);
  652. *(vertices++) = LLVector3(0.f, 0.5f * LEAF_WIDTH, 0.f);
  653. *(colors++) = LLColor4U::white;
  654. *(indicesp++) = 12;
  655. *(indicesp++) = 14;
  656. *(indicesp++) = 13;
  657. *(indicesp++) = 12;
  658. *(indicesp++) = 13;
  659. *(indicesp++) = 15;
  660. // Generate geometry (vertices and indices) for the cylinders for each
  661. // LOD.
  662. for (lod = 0; lod < MAX_NUM_TREE_LOD_LEVELS; ++lod)
  663. {
  664. slices = sLODSlices[lod];
  665. S32 offset_vertex = sLODVertexOffset[lod];
  666. F32 base_radius = 0.65f;
  667. F32 top_radius = base_radius * mSpeciesData->mTaper;
  668. F32 angle = 0;
  669. F32 angle_inc = 360.f / (F32)(slices - 1);
  670. F32 z = 0.f;
  671. F32 z_inc = 1.f;
  672. if (slices > 3)
  673. {
  674. z_inc = 1.f / (F32)(slices - 3);
  675. }
  676. F32 radius = base_radius;
  677. F32 x1, y1;
  678. F32 noise_scale = mSpeciesData->mNoiseMag;
  679. LLVector3 nvec;
  680. // Height to 'peak' the caps on top/bottom of branch
  681. constexpr F32 cap_nudge = 0.1f;
  682. constexpr S32 fractal_depth = 5;
  683. F32 nvec_scale = 1.f * mSpeciesData->mNoiseScale;
  684. F32 nvec_scalez = 4.f * mSpeciesData->mNoiseScale;
  685. F32 tex_z_repeat = mSpeciesData->mRepeatTrunkZ;
  686. F32 start_radius;
  687. F32 nangle = 0;
  688. F32 height = 1.f;
  689. F32 r0;
  690. for (i = 0; i < slices; ++i)
  691. {
  692. if (i == 0)
  693. {
  694. z = - cap_nudge;
  695. r0 = 0.f;
  696. }
  697. else if (i == slices - 1)
  698. {
  699. z = 1.f + cap_nudge; //((i - 2) * z_inc) + cap_nudge;
  700. r0 = 0.f;
  701. }
  702. else
  703. {
  704. z = (F32)(i - 1) * z_inc;
  705. r0 = base_radius + (top_radius - base_radius) * z;
  706. }
  707. for (j = 0; j < slices; ++j)
  708. {
  709. if (slices - 1 == j)
  710. {
  711. angle = 0.f;
  712. }
  713. else
  714. {
  715. angle = j * angle_inc;
  716. }
  717. nangle = angle;
  718. x1 = cosf(angle * DEG_TO_RAD);
  719. y1 = sinf(angle * DEG_TO_RAD);
  720. LLVector2 tc;
  721. // This is not totally accurate. Should compute based on
  722. // slope as well.
  723. start_radius =
  724. r0 * (1.f + 1.2f * fabsf(z - 0.66f * height) / height);
  725. nvec.set(cosf(nangle * DEG_TO_RAD) * start_radius *
  726. nvec_scale,
  727. sinf(nangle * DEG_TO_RAD) * start_radius *
  728. nvec_scale,
  729. z * nvec_scalez);
  730. // First and last slice at 0 radius (to bring in top/bottom
  731. // of structure)
  732. radius = start_radius +
  733. turbulence3((F32*)&nvec.mV, (F32)fractal_depth) *
  734. noise_scale;
  735. if (slices - 1 == j)
  736. {
  737. // Not 0.5 for slight slop factor to avoid edges on
  738. // leaves
  739. tc = LLVector2(0.49f, (1.f - z * 0.5f) * tex_z_repeat);
  740. }
  741. else
  742. {
  743. tc = LLVector2(angle / 720.f,
  744. (1.f - z * 0.5f) * tex_z_repeat);
  745. }
  746. *vertices++ = LLVector3(x1 * radius, y1 * radius, z);
  747. *normals++ = LLVector3(x1, y1, 0.f);
  748. *tex_coords++ = tc;
  749. *(colors++) = LLColor4U::white;
  750. }
  751. }
  752. for (i = 0; i < slices - 1; ++i)
  753. {
  754. for (j = 0; j < slices - 1; ++j)
  755. {
  756. S32 x1_offset = j + 1;
  757. if (j + 1 == slices)
  758. {
  759. x1_offset = 0;
  760. }
  761. // Generate the matching quads
  762. *indicesp++ = j + i * slices + offset_vertex;
  763. *indicesp++ = x1_offset + (i + 1) * slices + offset_vertex;
  764. *indicesp++ = j + (i + 1) * slices + offset_vertex;
  765. *indicesp++ = j + i * slices + offset_vertex;
  766. *indicesp++ = x1_offset + i * slices + offset_vertex;
  767. *indicesp++ = x1_offset + (i + 1) * slices + offset_vertex;
  768. }
  769. }
  770. slices /= 2;
  771. }
  772. mReferenceBuffer->unmapBuffer();
  773. }
  774. if (sRenderAnimateTrees && mDrawable->getFace(0))
  775. {
  776. mDrawable->getFace(0)->setVertexBuffer(mReferenceBuffer);
  777. }
  778. else
  779. {
  780. // Generate tree mesh
  781. updateMesh();
  782. }
  783. return true;
  784. }
  785. void LLVOTree::updateMesh()
  786. {
  787. LLMatrix4 matrix;
  788. // Translate to tree base HACK - adjustment in Z plants tree underground
  789. const LLVector3& pos_region = getPositionRegion();
  790. if (pos_region.isExactlyZero())
  791. {
  792. llwarns << "Wrong region position for tree, aborting." << llendl;
  793. }
  794. LLMatrix4 trans_mat;
  795. trans_mat.setTranslation(pos_region.mV[VX], pos_region.mV[VY],
  796. pos_region.mV[VZ] - 0.1f);
  797. trans_mat *= matrix;
  798. // Rotate to tree position and bend for current trunk/wind. Note that trunk
  799. // stiffness controls the amount of bend at the trunk as opposed to the
  800. // crown of the tree
  801. static const LLQuaternion qz(90.f * DEG_TO_RAD, LLVector4(0.f, 0.f, 1.f));
  802. F32 trunc_bend_length = mTrunkBend.length();
  803. LLQuaternion rot = LLQuaternion(trunc_bend_length * TRUNK_STIFF,
  804. LLVector4(mTrunkBend.mV[VX],
  805. mTrunkBend.mV[VY], 0.f)) *
  806. qz * getRotation();
  807. LLMatrix4 rot_mat(rot);
  808. rot_mat *= trans_mat;
  809. F32 radius = getScale().length() * 0.05f;
  810. LLMatrix4 scale_mat;
  811. scale_mat.mMatrix[0][0] = scale_mat.mMatrix[1][1] =
  812. scale_mat.mMatrix[2][2] = radius;
  813. scale_mat *= rot_mat;
  814. F32 droop = mDroop + 25.f * (1.f - trunc_bend_length);
  815. S32 stop_depth = 0;
  816. F32 alpha = 1.f;
  817. U32 vert_count = 0;
  818. U32 index_count = 0;
  819. calcNumVerts(vert_count, index_count, mTrunkLOD, stop_depth, mDepth,
  820. mTrunkDepth, mBranches);
  821. LLFace* facep = mDrawable->getFace(0);
  822. if (!facep) return; // Abort
  823. if (mUpdateMeshBuffer.isNull())
  824. {
  825. mUpdateMeshBuffer =
  826. new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK);
  827. #if LL_DEBUG_VB_ALLOC
  828. mUpdateMeshBuffer->setOwner("LLVOTree mesh");
  829. #endif
  830. }
  831. if (!mUpdateMeshBuffer->allocateBuffer(vert_count, index_count))
  832. {
  833. llwarns << "Failure to resize a vertex buffer with " << vert_count
  834. << " vertices and " << index_count << " indices" << llendl;
  835. mUpdateMeshBuffer->allocateBuffer(1, 3);
  836. mUpdateMeshBuffer->resetVertexData();
  837. mUpdateMeshBuffer->resetIndexData();
  838. facep->setSize(1, 3);
  839. facep->setVertexBuffer(mUpdateMeshBuffer);
  840. mReferenceBuffer->unmapBuffer();
  841. mUpdateMeshBuffer->unmapBuffer();
  842. return;
  843. }
  844. facep->setVertexBuffer(mUpdateMeshBuffer);
  845. LLStrider<LLVector3> vertices, normals;
  846. LLStrider<LLVector2> tex_coords;
  847. LLStrider<LLColor4U> colors;
  848. LLStrider<U16> indices;
  849. U16 idx_offset = 0;
  850. if (!mUpdateMeshBuffer->getVertexStrider(vertices) ||
  851. !mUpdateMeshBuffer->getNormalStrider(normals) ||
  852. !mUpdateMeshBuffer->getTexCoord0Strider(tex_coords) ||
  853. !mUpdateMeshBuffer->getColorStrider(colors) ||
  854. !mUpdateMeshBuffer->getIndexStrider(indices))
  855. {
  856. return;
  857. }
  858. genBranchPipeline(vertices, normals, tex_coords, colors, indices,
  859. idx_offset, scale_mat, mTrunkLOD, stop_depth, mDepth,
  860. mTrunkDepth, 1.f, mTwist, droop, mBranches, alpha);
  861. mReferenceBuffer->unmapBuffer();
  862. mUpdateMeshBuffer->unmapBuffer();
  863. }
  864. void LLVOTree::appendMesh(LLStrider<LLVector3>& vertices,
  865. LLStrider<LLVector3>& normals,
  866. LLStrider<LLVector2>& tex_coords,
  867. LLStrider<LLColor4U>& colors,
  868. LLStrider<U16>& indices, U16& cur_idx,
  869. const LLMatrix4& matrix, const LLMatrix4& norm_mat,
  870. S32 vert_start, S32 vert_count,
  871. S32 index_count, S32 index_offset)
  872. {
  873. LLStrider<LLVector3> v, n;
  874. LLStrider<LLVector2> t;
  875. LLStrider<LLColor4U> c;
  876. LLStrider<U16> idx;
  877. if (!mReferenceBuffer->getVertexStrider(v) ||
  878. !mReferenceBuffer->getNormalStrider(n) ||
  879. !mReferenceBuffer->getTexCoord0Strider(t) ||
  880. !mReferenceBuffer->getColorStrider(c) ||
  881. !mReferenceBuffer->getIndexStrider(idx))
  882. {
  883. return;
  884. }
  885. // Copy/transform vertices into mesh - check
  886. for (S32 i = 0; i < vert_count; ++i)
  887. {
  888. U16 index = vert_start + i;
  889. *vertices++ = v[index] * matrix;
  890. LLVector3 norm = n[index] * norm_mat;
  891. norm.normalize();
  892. *normals++ = norm;
  893. *tex_coords++ = t[index];
  894. *colors++ = c[index];
  895. }
  896. // Copy offset indices into mesh - check
  897. for (S32 i = 0; i < index_count; ++i)
  898. {
  899. U16 index = index_offset + i;
  900. *indices++ = idx[index] - vert_start + cur_idx;
  901. }
  902. // Increment index offset - check
  903. cur_idx += vert_count;
  904. }
  905. void LLVOTree::genBranchPipeline(LLStrider<LLVector3>& vertices,
  906. LLStrider<LLVector3>& normals,
  907. LLStrider<LLVector2>& tex_coords,
  908. LLStrider<LLColor4U>& colors,
  909. LLStrider<U16>& indices, U16& index_offset,
  910. const LLMatrix4& matrix,
  911. S32 trunk_lod, S32 stop_level,
  912. U16 depth, U16 trunk_depth,
  913. F32 scale, F32 twist, F32 droop,
  914. F32 branches, F32 alpha)
  915. {
  916. if (stop_level < 0)
  917. {
  918. return;
  919. }
  920. // Generates a tree mesh by recursing, generating branches and then a
  921. // 'leaf' texture.
  922. if (depth > stop_level)
  923. {
  924. llassert(sLODIndexCount[trunk_lod] > 0);
  925. F32 length = trunk_depth || scale == 1.f ? mTrunkLength
  926. : mBranchLength;
  927. F32 aspect = trunk_depth || scale == 1.f ? mTrunkAspect
  928. : mBranchAspect;
  929. F32 width = scale * length * aspect;
  930. LLMatrix4 scale_mat;
  931. scale_mat.mMatrix[0][0] = scale_mat.mMatrix[1][1] = width;
  932. scale_mat.mMatrix[2][2] = scale * length;
  933. scale_mat *= matrix;
  934. LLMatrix4a m(scale_mat);
  935. m.invert();
  936. m.transpose();
  937. #if 0 // Do not do that: it breaks lighting of trees (can easily be seen when
  938. // toggling "Animate trees" on/off).
  939. m.invert();
  940. #endif
  941. LLMatrix4 norm_mat(m.getF32ptr());
  942. appendMesh(vertices, normals, tex_coords, colors, indices,
  943. index_offset, scale_mat, norm_mat,
  944. sLODVertexOffset[trunk_lod], sLODVertexCount[trunk_lod],
  945. sLODIndexCount[trunk_lod], sLODIndexOffset[trunk_lod]);
  946. LLMatrix4 trans_mat;
  947. trans_mat.setTranslation(0.f, 0.f, scale * length);
  948. trans_mat *= matrix;
  949. // Recurse to create more branches
  950. static const LLVector4 vec4z(0.f, 0.f, 1.f);
  951. static const LLQuaternion qz(20.f * DEG_TO_RAD, vec4z);
  952. const LLQuaternion qy(droop * DEG_TO_RAD, LLVector4(0.f, 1.f, 0.f));
  953. const LLQuaternion qzy(qz * qy);
  954. const F32 constant_twist = 360.f / branches;
  955. for (S32 i = 0; i < (S32)branches; ++i)
  956. {
  957. F32 angle = (constant_twist +
  958. (i % 2 == 0 ? twist : -twist)) * i * DEG_TO_RAD;
  959. LLQuaternion qt(angle, vec4z);
  960. LLMatrix4 rot_mat(qzy * qt);
  961. rot_mat *= trans_mat;
  962. genBranchPipeline(vertices, normals, tex_coords, colors, indices,
  963. index_offset, rot_mat, trunk_lod, stop_level,
  964. depth - 1, 0, scale * mScaleStep, twist, droop,
  965. branches, alpha);
  966. }
  967. // Recurse to continue trunk
  968. if (trunk_depth)
  969. {
  970. LLMatrix4 rot_mat(70.5f * DEG_TO_RAD, vec4z);
  971. rot_mat *= trans_mat; // Rotate a bit around Z when ascending
  972. genBranchPipeline(vertices, normals, tex_coords, colors, indices,
  973. index_offset, rot_mat, trunk_lod, stop_level,
  974. depth, trunk_depth - 1, scale * mScaleStep,
  975. twist, droop, branches, alpha);
  976. }
  977. }
  978. else
  979. {
  980. // Append leaves as two 90 deg crossed quads with leaf textures
  981. LLMatrix4 scale_mat;
  982. scale_mat.mMatrix[0][0] = scale_mat.mMatrix[1][1] =
  983. scale_mat.mMatrix[2][2] = scale * mLeafScale;
  984. scale_mat *= matrix;
  985. LLMatrix4a m(scale_mat);
  986. m.invert();
  987. m.transpose();
  988. LLMatrix4 norm_mat(m.getF32ptr());
  989. appendMesh(vertices, normals, tex_coords, colors, indices,
  990. index_offset, scale_mat, norm_mat, 0,
  991. LEAF_VERTICES, LEAF_INDICES, 0);
  992. }
  993. }
  994. void LLVOTree::calcNumVerts(U32& vert_count, U32& index_count, S32 trunk_lod,
  995. S32 stop_level, U16 depth, U16 trunk_depth,
  996. F32 branches)
  997. {
  998. if (stop_level >= 0)
  999. {
  1000. if (depth > stop_level)
  1001. {
  1002. index_count += sLODIndexCount[trunk_lod];
  1003. vert_count += sLODVertexCount[trunk_lod];
  1004. // Recurse to create more branches
  1005. for (S32 i = 0; i < (S32)branches; ++i)
  1006. {
  1007. calcNumVerts(vert_count, index_count, trunk_lod, stop_level,
  1008. depth - 1, 0, branches);
  1009. }
  1010. // Recurse to continue trunk
  1011. if (trunk_depth)
  1012. {
  1013. calcNumVerts(vert_count, index_count, trunk_lod, stop_level,
  1014. depth, trunk_depth - 1, branches);
  1015. }
  1016. }
  1017. else
  1018. {
  1019. index_count += LEAF_INDICES;
  1020. vert_count += LEAF_VERTICES;
  1021. }
  1022. }
  1023. else
  1024. {
  1025. index_count += LEAF_INDICES;
  1026. vert_count += LEAF_VERTICES;
  1027. }
  1028. }
  1029. U32 LLVOTree::drawBranchPipeline(LLMatrix4& matrix, U16* indicesp,
  1030. S32 trunk_lod, S32 stop_level, U16 depth,
  1031. U16 trunk_depth, F32 scale, F32 twist,
  1032. F32 droop, F32 branches, F32 alpha)
  1033. {
  1034. U32 ret = 0;
  1035. //
  1036. // Draws a tree by recursing, drawing branches and then a 'leaf' texture.
  1037. // If stop_level = -1, simply draws the whole tree as a billboarded
  1038. // texture.
  1039. //
  1040. if (!LLPipeline::sReflectionRender && stop_level >= 0)
  1041. {
  1042. //
  1043. // Draw the tree using recursion
  1044. //
  1045. if (depth > stop_level)
  1046. {
  1047. F32 length = trunk_depth || scale == 1.f ? mTrunkLength
  1048. : mBranchLength;
  1049. F32 aspect = trunk_depth || scale == 1.f ? mTrunkAspect
  1050. : mBranchAspect;
  1051. {
  1052. llassert(sLODIndexCount[trunk_lod] > 0);
  1053. F32 width = scale * length * aspect;
  1054. LLMatrix4 scale_mat;
  1055. scale_mat.mMatrix[0][0] = width;
  1056. scale_mat.mMatrix[1][1] = width;
  1057. scale_mat.mMatrix[2][2] = scale * length;
  1058. scale_mat *= matrix;
  1059. gGL.loadMatrix(scale_mat.getF32ptr());
  1060. gGL.syncMatrices();
  1061. glDrawElements(GL_TRIANGLES, sLODIndexCount[trunk_lod],
  1062. GL_UNSIGNED_SHORT,
  1063. indicesp + sLODIndexOffset[trunk_lod]);
  1064. gPipeline.addTrianglesDrawn(LEAF_INDICES);
  1065. ret += sLODIndexCount[trunk_lod];
  1066. }
  1067. LLMatrix4 trans_mat;
  1068. trans_mat.setTranslation(0.f, 0.f, scale * length);
  1069. trans_mat *= matrix;
  1070. // Recurse to create more branches
  1071. static const LLVector4 vec4z(0.f, 0.f, 1.f);
  1072. static const LLQuaternion qz(20.f * DEG_TO_RAD, vec4z);
  1073. const LLQuaternion qy(droop * DEG_TO_RAD, LLVector4(0.f, 1.f, 0.f));
  1074. const LLQuaternion qzy(qz * qy);
  1075. const F32 constant_twist = 360.f / branches;
  1076. for (S32 i = 0; i < (S32)branches; ++i)
  1077. {
  1078. F32 angle = (constant_twist +
  1079. (i % 2 == 0 ? twist : -twist)) * i * DEG_TO_RAD;
  1080. LLQuaternion qt(angle, vec4z);
  1081. LLMatrix4 rot_mat(qzy * qt);
  1082. rot_mat *= trans_mat;
  1083. ret += drawBranchPipeline(rot_mat, indicesp, trunk_lod,
  1084. stop_level, depth - 1, 0,
  1085. scale * mScaleStep, twist, droop,
  1086. branches, alpha);
  1087. }
  1088. // Recurse to continue trunk
  1089. if (trunk_depth)
  1090. {
  1091. LLMatrix4 rot_mat(70.5f * DEG_TO_RAD, vec4z);
  1092. rot_mat *= trans_mat; // Rotate a bit around Z when ascending
  1093. ret += drawBranchPipeline(rot_mat, indicesp, trunk_lod,
  1094. stop_level, depth, trunk_depth - 1,
  1095. scale * mScaleStep, twist, droop,
  1096. branches, alpha);
  1097. }
  1098. }
  1099. else
  1100. {
  1101. //
  1102. // Draw leaves as two 90 deg crossed quads with leaf textures
  1103. //
  1104. LLMatrix4 scale_mat;
  1105. scale_mat.mMatrix[0][0] =
  1106. scale_mat.mMatrix[1][1] =
  1107. scale_mat.mMatrix[2][2] = scale * mLeafScale;
  1108. scale_mat *= matrix;
  1109. gGL.loadMatrix(scale_mat.getF32ptr());
  1110. gGL.syncMatrices();
  1111. glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT,
  1112. indicesp);
  1113. gPipeline.addTrianglesDrawn(LEAF_INDICES);
  1114. ret += LEAF_INDICES;
  1115. }
  1116. }
  1117. else
  1118. {
  1119. //
  1120. // Draw the tree as a single billboard texture
  1121. //
  1122. LLMatrix4 scale_mat;
  1123. scale_mat.mMatrix[0][0] =
  1124. scale_mat.mMatrix[1][1] =
  1125. scale_mat.mMatrix[2][2] = mBillboardScale * mBillboardRatio;
  1126. scale_mat *= matrix;
  1127. gGL.matrixMode(LLRender::MM_TEXTURE);
  1128. gGL.translatef(0.f, -0.5f, 0.f);
  1129. gGL.matrixMode(LLRender::MM_MODELVIEW);
  1130. gGL.loadMatrix(scale_mat.getF32ptr());
  1131. gGL.syncMatrices();
  1132. glDrawElements(GL_TRIANGLES, LEAF_INDICES, GL_UNSIGNED_SHORT,
  1133. indicesp);
  1134. gPipeline.addTrianglesDrawn(LEAF_INDICES);
  1135. ret += LEAF_INDICES;
  1136. gGL.matrixMode(LLRender::MM_TEXTURE);
  1137. gGL.loadIdentity();
  1138. gGL.matrixMode(LLRender::MM_MODELVIEW);
  1139. }
  1140. stop_glerror();
  1141. return ret;
  1142. }
  1143. void LLVOTree::updateRadius()
  1144. {
  1145. if (mDrawable.notNull())
  1146. {
  1147. mDrawable->setRadius(32.0f);
  1148. }
  1149. }
  1150. void LLVOTree::updateSpatialExtents(LLVector4a& new_min, LLVector4a& new_max)
  1151. {
  1152. F32 radius = getScale().length() * 0.05f;
  1153. LLVector3 center = getRenderPosition();
  1154. F32 sz = mBillboardScale * mBillboardRatio * radius * 0.5f;
  1155. LLVector3 size(sz, sz, sz);
  1156. center += LLVector3(0.f, 0.f, size.mV[2]) * getRotation();
  1157. new_min.load3((center - size).mV);
  1158. new_max.load3((center + size).mV);
  1159. LLVector4a pos;
  1160. pos.load3(center.mV);
  1161. mDrawable->setPositionGroup(pos);
  1162. }
  1163. bool LLVOTree::lineSegmentIntersect(const LLVector4a& start,
  1164. const LLVector4a& end,
  1165. S32 face,
  1166. bool pick_transparent,
  1167. bool pick_rigged,
  1168. S32* face_hitp,
  1169. LLVector4a* intersection,
  1170. LLVector2* tex_coord,
  1171. LLVector4a* normal,
  1172. LLVector4a* tangent)
  1173. {
  1174. if (!lineSegmentBoundingBox(start, end))
  1175. {
  1176. return false;
  1177. }
  1178. const LLVector4a* exta = mDrawable->getSpatialExtents();
  1179. // VECTORIZE THIS
  1180. LLVector3 ext[2];
  1181. ext[0].set(exta[0].getF32ptr());
  1182. ext[1].set(exta[1].getF32ptr());
  1183. LLVector3 center = (ext[1] + ext[0]) * 0.5f;
  1184. LLVector3 size = ext[1] - ext[0];
  1185. LLQuaternion quat = getRotation();
  1186. center -= LLVector3(0.f, 0.f, size.length() * 0.25f) * quat;
  1187. size.scaleVec(LLVector3(0.25f, 0.25f, 1.f));
  1188. size.mV[0] = llmin(size.mV[0], 1.f);
  1189. size.mV[1] = llmin(size.mV[1], 1.f);
  1190. LLVector3 pos, norm;
  1191. LLVector3 start3(start.getF32ptr());
  1192. LLVector3 end3(end.getF32ptr());
  1193. if (linesegment_tetrahedron(start3, end3, center, size, quat, pos, norm))
  1194. {
  1195. if (intersection)
  1196. {
  1197. intersection->load3(pos.mV);
  1198. }
  1199. if (normal)
  1200. {
  1201. normal->load3(norm.mV);
  1202. }
  1203. return true;
  1204. }
  1205. return false;
  1206. }
  1207. U32 LLVOTree::getPartitionType() const
  1208. {
  1209. return LLViewerRegion::PARTITION_TREE;
  1210. }
  1211. void LLVOTree::generateSilhouetteVertices(std::vector<LLVector3>& vertices,
  1212. std::vector<LLVector3>& normals,
  1213. const LLVector3& obj_cam_vec,
  1214. const LLMatrix4& local_matrix,
  1215. const LLMatrix3& normal_matrix)
  1216. {
  1217. vertices.clear();
  1218. normals.clear();
  1219. F32 height = mBillboardScale; // *mBillboardRatio * 0.5;
  1220. F32 width = height * mTrunkAspect;
  1221. LLVector3 position1 = LLVector3(-width * 0.5f, 0.f, 0.f) * local_matrix;
  1222. LLVector3 position2 = LLVector3(-width * 0.5f, 0.f, height) * local_matrix;
  1223. LLVector3 position3 = LLVector3(width * 0.5f, 0.f, height) * local_matrix;
  1224. LLVector3 position4 = LLVector3(width * 0.5f, 0.f, 0.f) * local_matrix;
  1225. LLVector3 position5 = LLVector3(0.f, -width * 0.5f, 0.f) * local_matrix;
  1226. LLVector3 position6 = LLVector3(0.f, -width * 0.5f, height) * local_matrix;
  1227. LLVector3 position7 = LLVector3(0.f, width * 0.5f, height) * local_matrix;
  1228. LLVector3 position8 = LLVector3(0.f, width * 0.5f, 0.f) * local_matrix;
  1229. LLVector3 normal = (position1 - position2) % (position2 - position3);
  1230. normal.normalize();
  1231. vertices.emplace_back(position1);
  1232. normals.emplace_back(normal);
  1233. vertices.emplace_back(position2);
  1234. normals.emplace_back(normal);
  1235. vertices.emplace_back(position2);
  1236. normals.emplace_back(normal);
  1237. vertices.emplace_back(position3);
  1238. normals.emplace_back(normal);
  1239. vertices.emplace_back(position3);
  1240. normals.emplace_back(normal);
  1241. vertices.emplace_back(position4);
  1242. normals.emplace_back(normal);
  1243. vertices.emplace_back(position4);
  1244. normals.emplace_back(normal);
  1245. vertices.emplace_back(position1);
  1246. normals.emplace_back(normal);
  1247. normal = (position5 - position6) % (position6 - position7);
  1248. normal.normalize();
  1249. vertices.emplace_back(position5);
  1250. normals.emplace_back(normal);
  1251. vertices.emplace_back(position6);
  1252. normals.emplace_back(normal);
  1253. vertices.emplace_back(position6);
  1254. normals.emplace_back(normal);
  1255. vertices.emplace_back(position7);
  1256. normals.emplace_back(normal);
  1257. vertices.emplace_back(position7);
  1258. normals.emplace_back(normal);
  1259. vertices.emplace_back(position8);
  1260. normals.emplace_back(normal);
  1261. vertices.emplace_back(position8);
  1262. normals.emplace_back(normal);
  1263. vertices.emplace_back(position5);
  1264. normals.emplace_back(normal);
  1265. }
  1266. void LLVOTree::generateSilhouette(LLSelectNode* nodep)
  1267. {
  1268. LLVector3 position;
  1269. LLQuaternion rotation;
  1270. if (!mDrawable->isActive())
  1271. {
  1272. position = getPosition() + getRegion()->getOriginAgent();
  1273. rotation = getRotation();
  1274. }
  1275. else if (!mDrawable->isSpatialRoot())
  1276. {
  1277. position = mDrawable->getPosition();
  1278. rotation = mDrawable->getRotation();
  1279. }
  1280. // Trees have strange scaling rules...
  1281. F32 radius = getScale().length() * 0.05f;
  1282. // Compose final matrix
  1283. LLMatrix4 local_matrix;
  1284. local_matrix.initAll(LLVector3(radius, radius, radius), rotation,
  1285. position);
  1286. generateSilhouetteVertices(nodep->mSilhouetteVertices,
  1287. nodep->mSilhouetteNormals, LLVector3::zero,
  1288. local_matrix, LLMatrix3());
  1289. nodep->mSilhouetteGenerated = true;
  1290. }