llvolume.h 45 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562
  1. /**
  2. * @file llvolume.h
  3. * @brief LLVolume base class.
  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. #ifndef LL_LLVOLUME_H
  33. #define LL_LLVOLUME_H
  34. #include <iostream>
  35. #include <vector>
  36. #if LL_JEMALLOC
  37. # include "jemalloc/jemalloc.h"
  38. # include "hbtracy.h"
  39. #endif
  40. #include "llalignedarray.h"
  41. #include "llcolor4.h"
  42. #include "llcolor4u.h"
  43. #include "llfile.h"
  44. #include "llmath.h"
  45. #include "llmatrix4a.h"
  46. #include "llmutex.h"
  47. #include "llpointer.h"
  48. #include "llrefcount.h"
  49. #include "llstrider.h"
  50. #include "lluuid.h"
  51. #include "llvector2.h"
  52. #include "llvector3.h"
  53. #include "llvector3d.h"
  54. #include "llvector4.h"
  55. class LLPath;
  56. class LLPathParams;
  57. class LLProfile;
  58. class LLProfileParams;
  59. class LLVolume;
  60. class LLVolumeFace;
  61. class LLVolumeOctree;
  62. class LLVolumeParams;
  63. class LLVolumeTriangle;
  64. // Define to 1 in case we add support for on-the-wire tangents
  65. #define LL_USE_TANGENTS 0
  66. // To reduce the sources verbosity and typing, you may use this macro in the
  67. // public methods declaration block for classes dealing with volumes. HB
  68. #define LL_VOLUME_AREANA_NEW_DELETE \
  69. LL_INLINE void* operator new(size_t size) \
  70. { return allocate_volume_mem(size); } \
  71. LL_INLINE void* operator new[](size_t size) \
  72. { return allocate_volume_mem(size); } \
  73. LL_INLINE void operator delete(void* ptr) noexcept \
  74. { free_volume_mem(ptr); } \
  75. LL_INLINE void operator delete[](void* ptr) noexcept \
  76. { free_volume_mem(ptr); }
  77. // Forward declarations
  78. LL_INLINE void* allocate_volume_mem(size_t size);
  79. LL_INLINE void free_volume_mem(void* addr) noexcept;
  80. constexpr S32 MIN_DETAIL_FACES = 6;
  81. // These are defined here but are not enforced at this level, rather they are
  82. // here for the convenience of code that uses the LLVolume class.
  83. constexpr F32 MIN_VOLUME_PROFILE_WIDTH = 0.05f;
  84. constexpr F32 MIN_VOLUME_PATH_WIDTH = 0.05f;
  85. constexpr F32 CUT_QUANTA = 0.00002f;
  86. constexpr F32 SCALE_QUANTA = 0.01f;
  87. constexpr F32 SHEAR_QUANTA = 0.01f;
  88. constexpr F32 TAPER_QUANTA = 0.01f;
  89. constexpr F32 REV_QUANTA = 0.015f;
  90. constexpr F32 HOLLOW_QUANTA = 0.00002f;
  91. constexpr S32 MAX_VOLUME_TRIANGLE_INDICES = 10000;
  92. // Useful masks
  93. constexpr LLPCode LL_PCODE_HOLLOW_MASK = 0x80; // Has a thickness
  94. constexpr LLPCode LL_PCODE_SEGMENT_MASK = 0x40; // Segments (1 angle)
  95. constexpr LLPCode LL_PCODE_PATCH_MASK = 0x20; // Segmented segments (2 angles)
  96. constexpr LLPCode LL_PCODE_HEMI_MASK = 0x10; // Half-prims get their own type
  97. constexpr LLPCode LL_PCODE_BASE_MASK = 0x0F;
  98. // Primitive shapes
  99. constexpr LLPCode LL_PCODE_CUBE = 1;
  100. constexpr LLPCode LL_PCODE_PRISM = 2;
  101. constexpr LLPCode LL_PCODE_TETRAHEDRON = 3;
  102. constexpr LLPCode LL_PCODE_PYRAMID = 4;
  103. constexpr LLPCode LL_PCODE_CYLINDER = 5;
  104. constexpr LLPCode LL_PCODE_CONE = 6;
  105. constexpr LLPCode LL_PCODE_SPHERE = 7;
  106. constexpr LLPCode LL_PCODE_TORUS = 8;
  107. constexpr LLPCode LL_PCODE_VOLUME = 9;
  108. // Surfaces (deprecated)
  109. //constexpr LLPCode LL_PCODE_SURFACE_TRIANGLE = 10;
  110. //constexpr LLPCode LL_PCODE_SURFACE_SQUARE = 11;
  111. //constexpr LLPCode LL_PCODE_SURFACE_DISC = 12;
  112. // App specific pcode (for viewer/sim side only objects)
  113. constexpr LLPCode LL_PCODE_APP = 14;
  114. constexpr LLPCode LL_PCODE_LEGACY = 15;
  115. // Pcodes for legacy objects
  116. constexpr LLPCode LL_PCODE_LEGACY_AVATAR = 0x20 | LL_PCODE_LEGACY;
  117. constexpr LLPCode LL_PCODE_LEGACY_GRASS = 0x50 | LL_PCODE_LEGACY;
  118. constexpr LLPCode LL_PCODE_LEGACY_PART_SYS = 0x80 | LL_PCODE_LEGACY;
  119. constexpr LLPCode LL_PCODE_LEGACY_ROCK = 0x90 | LL_PCODE_LEGACY;
  120. constexpr LLPCode LL_PCODE_LEGACY_TREE = 0xF0 | LL_PCODE_LEGACY;
  121. // Deprecated
  122. //constexpr LLPCode LL_PCODE_LEGACY_ATOR = 0x10 | LL_PCODE_LEGACY;
  123. //constexpr LLPCode LL_PCODE_LEGACY_BIRD = 0x30 | LL_PCODE_LEGACY;
  124. //constexpr LLPCode LL_PCODE_LEGACY_DEMON = 0x40 | LL_PCODE_LEGACY;
  125. //constexpr LLPCode LL_PCODE_TREE_NEW = 0x60 | LL_PCODE_LEGACY;
  126. //constexpr LLPCode LL_PCODE_LEGACY_ORACLE = 0x70 | LL_PCODE_LEGACY;
  127. //constexpr LLPCode LL_PCODE_LEGACY_SHOT = 0xA0 | LL_PCODE_LEGACY;
  128. //constexpr LLPCode LL_PCODE_LEGACY_SHOT_BIG= 0xB0 | LL_PCODE_LEGACY;
  129. //constexpr LLPCode LL_PCODE_LEGACY_SMOKE = 0xC0 | LL_PCODE_LEGACY;
  130. //constexpr LLPCode LL_PCODE_LEGACY_SPARK = 0xD0 | LL_PCODE_LEGACY;
  131. //constexpr LLPCode LL_PCODE_LEGACY_TEXT_BUBBLE= 0xE0 | LL_PCODE_LEGACY;
  132. // Hemis
  133. constexpr LLPCode LL_PCODE_CYLINDER_HEMI = LL_PCODE_HEMI_MASK | LL_PCODE_CYLINDER;
  134. constexpr LLPCode LL_PCODE_CONE_HEMI = LL_PCODE_HEMI_MASK | LL_PCODE_CONE;
  135. constexpr LLPCode LL_PCODE_SPHERE_HEMI = LL_PCODE_HEMI_MASK | LL_PCODE_SPHERE;
  136. constexpr LLPCode LL_PCODE_TORUS_HEMI = LL_PCODE_HEMI_MASK | LL_PCODE_TORUS;
  137. // Volumes consist of a profile at the base that is swept around a path to make
  138. // a volume.
  139. // The profile code
  140. constexpr U8 LL_PCODE_PROFILE_MASK = 0x0f;
  141. constexpr U8 LL_PCODE_PROFILE_MIN = 0x00;
  142. constexpr U8 LL_PCODE_PROFILE_CIRCLE = 0x00;
  143. constexpr U8 LL_PCODE_PROFILE_SQUARE = 0x01;
  144. constexpr U8 LL_PCODE_PROFILE_ISOTRI = 0x02;
  145. constexpr U8 LL_PCODE_PROFILE_EQUALTRI = 0x03;
  146. constexpr U8 LL_PCODE_PROFILE_RIGHTTRI = 0x04;
  147. constexpr U8 LL_PCODE_PROFILE_CIRCLE_HALF = 0x05;
  148. constexpr U8 LL_PCODE_PROFILE_MAX = 0x05;
  149. // Stored in the profile byte
  150. constexpr U8 LL_PCODE_HOLE_MASK = 0xf0;
  151. constexpr U8 LL_PCODE_HOLE_MIN = 0x00;
  152. constexpr U8 LL_PCODE_HOLE_SAME = 0x00; // Same as outside profile
  153. constexpr U8 LL_PCODE_HOLE_CIRCLE = 0x10;
  154. constexpr U8 LL_PCODE_HOLE_SQUARE = 0x20;
  155. constexpr U8 LL_PCODE_HOLE_TRIANGLE = 0x30;
  156. constexpr U8 LL_PCODE_HOLE_MAX = 0x03; // Min/max needs to be >> 4 of real min/max
  157. constexpr U8 LL_PCODE_PATH_IGNORE = 0x00;
  158. constexpr U8 LL_PCODE_PATH_MIN = 0x01; // Min/max needs to be >> 4 of real min/max
  159. constexpr U8 LL_PCODE_PATH_LINE = 0x10;
  160. constexpr U8 LL_PCODE_PATH_CIRCLE = 0x20;
  161. constexpr U8 LL_PCODE_PATH_CIRCLE2 = 0x30;
  162. constexpr U8 LL_PCODE_PATH_TEST = 0x40;
  163. constexpr U8 LL_PCODE_PATH_FLEXIBLE = 0x80;
  164. constexpr U8 LL_PCODE_PATH_MAX = 0x08;
  165. // Face identifiers
  166. typedef U16 LLFaceID;
  167. constexpr LLFaceID LL_FACE_PATH_BEGIN = 0x1 << 0;
  168. constexpr LLFaceID LL_FACE_PATH_END = 0x1 << 1;
  169. constexpr LLFaceID LL_FACE_INNER_SIDE = 0x1 << 2;
  170. constexpr LLFaceID LL_FACE_PROFILE_BEGIN = 0x1 << 3;
  171. constexpr LLFaceID LL_FACE_PROFILE_END = 0x1 << 4;
  172. constexpr LLFaceID LL_FACE_OUTER_SIDE_0 = 0x1 << 5;
  173. constexpr LLFaceID LL_FACE_OUTER_SIDE_1 = 0x1 << 6;
  174. constexpr LLFaceID LL_FACE_OUTER_SIDE_2 = 0x1 << 7;
  175. constexpr LLFaceID LL_FACE_OUTER_SIDE_3 = 0x1 << 8;
  176. // Sculpt types + flags
  177. constexpr U8 LL_SCULPT_TYPE_NONE = 0;
  178. constexpr U8 LL_SCULPT_TYPE_SPHERE = 1;
  179. constexpr U8 LL_SCULPT_TYPE_TORUS = 2;
  180. constexpr U8 LL_SCULPT_TYPE_PLANE = 3;
  181. constexpr U8 LL_SCULPT_TYPE_CYLINDER = 4;
  182. constexpr U8 LL_SCULPT_TYPE_MESH = 5;
  183. constexpr U8 LL_SCULPT_TYPE_GLTF = 6;
  184. constexpr U8 LL_SCULPT_TYPE_MASK = LL_SCULPT_TYPE_SPHERE |
  185. LL_SCULPT_TYPE_TORUS |
  186. LL_SCULPT_TYPE_PLANE |
  187. LL_SCULPT_TYPE_CYLINDER |
  188. LL_SCULPT_TYPE_MESH |
  189. LL_SCULPT_TYPE_GLTF;
  190. // For value checks, assign new value after adding new types
  191. constexpr U8 LL_SCULPT_TYPE_MAX = LL_SCULPT_TYPE_GLTF;
  192. constexpr U8 LL_SCULPT_FLAG_INVERT = 64;
  193. constexpr U8 LL_SCULPT_FLAG_MIRROR = 128;
  194. constexpr U8 LL_SCULPT_FLAG_MASK = LL_SCULPT_FLAG_INVERT | LL_SCULPT_FLAG_MIRROR;
  195. constexpr S32 LL_SCULPT_MESH_MAX_FACES = 8;
  196. class LLProfileParams
  197. {
  198. protected:
  199. LOG_CLASS(LLProfileParams);
  200. public:
  201. LLProfileParams()
  202. : mCurveType(LL_PCODE_PROFILE_SQUARE),
  203. mBegin(0.f),
  204. mEnd(1.f),
  205. mHollow(0.f),
  206. mCRC(0)
  207. {
  208. }
  209. LLProfileParams(U8 curve, F32 begin, F32 end, F32 hollow)
  210. : mCurveType(curve),
  211. mBegin(begin),
  212. mEnd(end),
  213. mHollow(hollow),
  214. mCRC(0)
  215. {
  216. }
  217. LLProfileParams(U8 curve, U16 begin, U16 end, U16 hollow)
  218. {
  219. mCurveType = curve;
  220. F32 temp_f32 = begin * CUT_QUANTA;
  221. if (temp_f32 > 1.f)
  222. {
  223. temp_f32 = 1.f;
  224. }
  225. mBegin = temp_f32;
  226. temp_f32 = end * CUT_QUANTA;
  227. if (temp_f32 > 1.f)
  228. {
  229. temp_f32 = 1.f;
  230. }
  231. mEnd = 1.f - temp_f32;
  232. temp_f32 = hollow * HOLLOW_QUANTA;
  233. if (temp_f32 > 1.f)
  234. {
  235. temp_f32 = 1.f;
  236. }
  237. mHollow = temp_f32;
  238. mCRC = 0;
  239. }
  240. bool operator==(const LLProfileParams& params) const;
  241. bool operator!=(const LLProfileParams& params) const;
  242. bool operator<(const LLProfileParams& params) const;
  243. void copyParams(const LLProfileParams& params);
  244. bool importFile(LLFILE* fp);
  245. bool exportFile(LLFILE* fp) const;
  246. bool importLegacyStream(std::istream& input_stream);
  247. bool exportLegacyStream(std::ostream& output_stream) const;
  248. LLSD asLLSD() const;
  249. LL_INLINE operator LLSD() const { return asLLSD(); }
  250. bool fromLLSD(LLSD& sd);
  251. LL_INLINE F32 getBegin() const { return mBegin; }
  252. LL_INLINE F32 getEnd() const { return mEnd; }
  253. LL_INLINE F32 getHollow() const { return mHollow; }
  254. LL_INLINE U8 getCurveType() const { return mCurveType; }
  255. LL_INLINE void setCurveType(U32 type) { mCurveType = type; }
  256. LL_INLINE void setBegin(F32 begin)
  257. {
  258. mBegin = begin >= 1.f ? 0.f : ((S32)(begin * 100000.f)) / 100000.f;
  259. }
  260. LL_INLINE void setEnd(F32 end)
  261. {
  262. mEnd = end <= 0.f ? 1.f : ((S32)(end * 100000.f)) / 100000.f;
  263. }
  264. LL_INLINE void setHollow(F32 hollow)
  265. {
  266. mHollow = ((S32)(hollow * 100000.f)) / 100000.f;
  267. }
  268. friend std::ostream& operator<<(std::ostream& s,
  269. const LLProfileParams& profile_params);
  270. protected:
  271. // Profile params
  272. F32 mBegin;
  273. F32 mEnd;
  274. F32 mHollow;
  275. U32 mCRC;
  276. U8 mCurveType;
  277. };
  278. LL_INLINE bool LLProfileParams::operator==(const LLProfileParams& params) const
  279. {
  280. return getCurveType() == params.getCurveType() &&
  281. getBegin() == params.getBegin() &&
  282. getEnd() == params.getEnd() &&
  283. getHollow() == params.getHollow();
  284. }
  285. LL_INLINE bool LLProfileParams::operator!=(const LLProfileParams& params) const
  286. {
  287. return getCurveType() != params.getCurveType() ||
  288. getBegin() != params.getBegin() ||
  289. getEnd() != params.getEnd() ||
  290. getHollow() != params.getHollow();
  291. }
  292. LL_INLINE bool LLProfileParams::operator<(const LLProfileParams& params) const
  293. {
  294. if (getCurveType() != params.getCurveType())
  295. {
  296. return getCurveType() < params.getCurveType();
  297. }
  298. if (getBegin() != params.getBegin())
  299. {
  300. return getBegin() < params.getBegin();
  301. }
  302. if (getEnd() != params.getEnd())
  303. {
  304. return getEnd() < params.getEnd();
  305. }
  306. return getHollow() < params.getHollow();
  307. }
  308. #define U8_TO_F32(x) (F32)(*((S8*)&x))
  309. class LLPathParams
  310. {
  311. protected:
  312. LOG_CLASS(LLPathParams);
  313. public:
  314. LLPathParams()
  315. : mCurveType(LL_PCODE_PATH_LINE),
  316. mBegin(0.f),
  317. mEnd(1.f),
  318. mScale(1.f, 1.f),
  319. mShear(0.f, 0.f),
  320. mTwistBegin(0.f),
  321. mTwistEnd(0.f),
  322. mRadiusOffset(0.f),
  323. mTaper(0.f, 0.f),
  324. mRevolutions(1.f),
  325. mSkew(0.f),
  326. mCRC(0)
  327. {
  328. }
  329. LLPathParams(U8 curve, F32 begin, F32 end, F32 scx, F32 scy,
  330. F32 shx, F32 shy, F32 twistend, F32 twistbegin,
  331. F32 radiusoffset, F32 tx, F32 ty, F32 revolutions, F32 skew)
  332. : mCurveType(curve),
  333. mBegin(begin),
  334. mEnd(end),
  335. mScale(scx, scy),
  336. mShear(shx, shy),
  337. mTwistBegin(twistbegin),
  338. mTwistEnd(twistend),
  339. mRadiusOffset(radiusoffset),
  340. mTaper(tx, ty),
  341. mRevolutions(revolutions),
  342. mSkew(skew),
  343. mCRC(0)
  344. {
  345. }
  346. LLPathParams(U8 curve, U16 begin, U16 end, U8 scx, U8 scy, U8 shx, U8 shy,
  347. U8 twistend, U8 twistbegin, U8 radiusoffset, U8 tx, U8 ty,
  348. U8 revolutions, U8 skew)
  349. {
  350. mCurveType = curve;
  351. mBegin = (F32)(begin * CUT_QUANTA);
  352. mEnd = (F32)(100.f - end) * CUT_QUANTA;
  353. if (mEnd > 1.f)
  354. {
  355. mEnd = 1.f;
  356. }
  357. mScale.set((F32)(200 - scx) * SCALE_QUANTA,
  358. (F32)(200 - scy) * SCALE_QUANTA);
  359. mShear.set(U8_TO_F32(shx) * SHEAR_QUANTA,
  360. U8_TO_F32(shy) * SHEAR_QUANTA);
  361. mTwistBegin = U8_TO_F32(twistbegin) * SCALE_QUANTA;
  362. mTwistEnd = U8_TO_F32(twistend) * SCALE_QUANTA;
  363. mRadiusOffset = U8_TO_F32(radiusoffset) * SCALE_QUANTA;
  364. mTaper.set(U8_TO_F32(tx) * TAPER_QUANTA,
  365. U8_TO_F32(ty) * TAPER_QUANTA);
  366. mRevolutions = (F32)revolutions * REV_QUANTA + 1.f;
  367. mSkew = U8_TO_F32(skew) * SCALE_QUANTA;
  368. mCRC = 0;
  369. }
  370. bool operator==(const LLPathParams& params) const;
  371. bool operator!=(const LLPathParams& params) const;
  372. bool operator<(const LLPathParams& params) const;
  373. void copyParams(const LLPathParams& params);
  374. bool importFile(LLFILE* fp);
  375. bool exportFile(LLFILE* fp) const;
  376. bool importLegacyStream(std::istream& input_stream);
  377. bool exportLegacyStream(std::ostream& output_stream) const;
  378. LLSD asLLSD() const;
  379. LL_INLINE operator LLSD() const { return asLLSD(); }
  380. bool fromLLSD(LLSD& sd);
  381. LL_INLINE F32 getBegin() const { return mBegin; }
  382. LL_INLINE F32 getEnd() const { return mEnd; }
  383. LL_INLINE const LLVector2& getScale() const { return mScale; }
  384. LL_INLINE F32 getScaleX() const { return mScale.mV[0]; }
  385. LL_INLINE F32 getScaleY() const { return mScale.mV[1]; }
  386. LLVector2 getBeginScale() const;
  387. LLVector2 getEndScale() const;
  388. LL_INLINE const LLVector2& getShear() const { return mShear; }
  389. LL_INLINE F32 getShearX() const { return mShear.mV[0]; }
  390. LL_INLINE F32 getShearY() const { return mShear.mV[1]; }
  391. LL_INLINE U8 getCurveType () const { return mCurveType; }
  392. LL_INLINE F32 getTwistBegin() const { return mTwistBegin; }
  393. // Note: getTwist() has been deprecated in favour of getTwistEnd(()
  394. LL_INLINE F32 getTwistEnd() const { return mTwistEnd; }
  395. LL_INLINE F32 getRadiusOffset() const { return mRadiusOffset; }
  396. LL_INLINE const LLVector2& getTaper() const { return mTaper; }
  397. LL_INLINE F32 getTaperX() const { return mTaper.mV[0]; }
  398. LL_INLINE F32 getTaperY() const { return mTaper.mV[1]; }
  399. LL_INLINE F32 getRevolutions() const { return mRevolutions; }
  400. LL_INLINE F32 getSkew() const { return mSkew; }
  401. LL_INLINE void setCurveType(U8 type) { mCurveType = type; }
  402. LL_INLINE void setBegin(F32 begin) { mBegin = begin; }
  403. LL_INLINE void setEnd(F32 end) { mEnd = end; }
  404. LL_INLINE void setScale(F32 x, F32 y) { mScale.set(x, y); }
  405. LL_INLINE void setScaleX(F32 v) { mScale.mV[VX] = v; }
  406. LL_INLINE void setScaleY(F32 v) { mScale.mV[VY] = v; }
  407. LL_INLINE void setShear(F32 x, F32 y) { mShear.set(x, y); }
  408. LL_INLINE void setShearX(F32 v) { mShear.mV[VX] = v; }
  409. LL_INLINE void setShearY(F32 v) { mShear.mV[VY] = v; }
  410. LL_INLINE void setTwistBegin(F32 tbegin) { mTwistBegin = tbegin; }
  411. // Note: setTwist() has been deprecated in favour of setTwistEnd(()
  412. LL_INLINE void setTwistEnd(F32 tend) { mTwistEnd = tend; }
  413. LL_INLINE void setRadiusOffset(F32 roff) { mRadiusOffset = roff; }
  414. LL_INLINE void setTaper(F32 x, F32 y) { mTaper.set(x, y); }
  415. LL_INLINE void setTaperX(F32 v) { mTaper.mV[VX] = v; }
  416. LL_INLINE void setTaperY(F32 v) { mTaper.mV[VY] = v; }
  417. LL_INLINE void setRevolutions(F32 revol) { mRevolutions = revol; }
  418. LL_INLINE void setSkew(F32 skew) { mSkew = skew; }
  419. friend std::ostream& operator<<(std::ostream& s,
  420. const LLPathParams& path_params);
  421. protected:
  422. // Path params
  423. LLVector2 mScale;
  424. LLVector2 mShear;
  425. F32 mBegin;
  426. F32 mEnd;
  427. LLVector2 mTaper;
  428. F32 mRevolutions;
  429. F32 mSkew;
  430. F32 mTwistBegin;
  431. F32 mTwistEnd;
  432. F32 mRadiusOffset;
  433. U32 mCRC;
  434. U8 mCurveType;
  435. };
  436. LL_INLINE bool LLPathParams::operator==(const LLPathParams& params) const
  437. {
  438. return getCurveType() == params.getCurveType() &&
  439. getScale() == params.getScale() &&
  440. getBegin() == params.getBegin() &&
  441. getEnd() == params.getEnd() &&
  442. getShear() == params.getShear() &&
  443. getTwistEnd() == params.getTwistEnd() &&
  444. getTwistBegin() == params.getTwistBegin() &&
  445. getRadiusOffset() == params.getRadiusOffset() &&
  446. getTaper() == params.getTaper() &&
  447. getRevolutions() == params.getRevolutions() &&
  448. getSkew() == params.getSkew();
  449. }
  450. LL_INLINE bool LLPathParams::operator!=(const LLPathParams& params) const
  451. {
  452. return getCurveType() != params.getCurveType() ||
  453. getScale() != params.getScale() ||
  454. getBegin() != params.getBegin() ||
  455. getEnd() != params.getEnd() ||
  456. getShear() != params.getShear() ||
  457. getTwistEnd() != params.getTwistEnd() ||
  458. getTwistBegin() !=params.getTwistBegin() ||
  459. getRadiusOffset() != params.getRadiusOffset() ||
  460. getTaper() != params.getTaper() ||
  461. getRevolutions() != params.getRevolutions() ||
  462. getSkew() != params.getSkew();
  463. }
  464. LL_INLINE bool LLPathParams::operator<(const LLPathParams& params) const
  465. {
  466. if (getCurveType() != params.getCurveType())
  467. {
  468. return getCurveType() < params.getCurveType();
  469. }
  470. if (getScale() != params.getScale())
  471. {
  472. return getScale() < params.getScale();
  473. }
  474. if (getBegin() != params.getBegin())
  475. {
  476. return getBegin() < params.getBegin();
  477. }
  478. if (getEnd() != params.getEnd())
  479. {
  480. return getEnd() < params.getEnd();
  481. }
  482. if (getShear() != params.getShear())
  483. {
  484. return getShear() < params.getShear();
  485. }
  486. if (getTwistEnd() != params.getTwistEnd())
  487. {
  488. return getTwistEnd() < params.getTwistEnd();
  489. }
  490. if (getTwistBegin() != params.getTwistBegin())
  491. {
  492. return getTwistBegin() < params.getTwistBegin();
  493. }
  494. if (getRadiusOffset() != params.getRadiusOffset())
  495. {
  496. return getRadiusOffset() < params.getRadiusOffset();
  497. }
  498. if (getTaper() != params.getTaper())
  499. {
  500. return getTaper() < params.getTaper();
  501. }
  502. if (getRevolutions() != params.getRevolutions())
  503. {
  504. return getRevolutions() < params.getRevolutions();
  505. }
  506. return getSkew() < params.getSkew();
  507. }
  508. typedef LLVolumeParams* LLVolumeParamsPtr;
  509. typedef const LLVolumeParams* const_LLVolumeParamsPtr;
  510. class LLVolumeParams
  511. {
  512. protected:
  513. LOG_CLASS(LLVolumeParams);
  514. public:
  515. LLVolumeParams()
  516. : mSculptType(LL_SCULPT_TYPE_NONE)
  517. {
  518. }
  519. LLVolumeParams(LLProfileParams& profile, LLPathParams& path,
  520. LLUUID sculpt_id = LLUUID::null,
  521. U8 sculpt_type = LL_SCULPT_TYPE_NONE)
  522. : mProfileParams(profile),
  523. mPathParams(path),
  524. mSculptID(sculpt_id),
  525. mSculptType(sculpt_type)
  526. {
  527. }
  528. bool operator==(const LLVolumeParams& params) const;
  529. bool operator!=(const LLVolumeParams& params) const;
  530. bool operator<(const LLVolumeParams& params) const;
  531. void copyParams(const LLVolumeParams& params);
  532. LL_INLINE const LLProfileParams& getProfileParams() const
  533. {
  534. return mProfileParams;
  535. }
  536. LL_INLINE LLProfileParams& getProfileParams() { return mProfileParams; }
  537. LL_INLINE const LLPathParams& getPathParams() const { return mPathParams; }
  538. LL_INLINE LLPathParams& getPathParams() { return mPathParams; }
  539. bool importFile(LLFILE* fp);
  540. bool exportFile(LLFILE* fp) const;
  541. bool importLegacyStream(std::istream& input_stream);
  542. bool exportLegacyStream(std::ostream& output_stream) const;
  543. LLSD sculptAsLLSD() const;
  544. bool sculptFromLLSD(LLSD& sd);
  545. LLSD asLLSD() const;
  546. LL_INLINE operator LLSD() const { return asLLSD(); }
  547. bool fromLLSD(LLSD& sd);
  548. bool setType(U8 profile, U8 path);
  549. // Both range from 0 to 1, begin must be less than end
  550. bool setBeginAndEndS(F32 begin, F32 end);
  551. bool setBeginAndEndT(F32 begin, F32 end);
  552. bool setHollow(F32 hollow); // Range 0 to 1
  553. // 0 = point, 1 = same as base
  554. LL_INLINE bool setRatio(F32 x) { return setRatio(x, x); }
  555. // 0 = no movement,
  556. LL_INLINE bool setShear(F32 x) { return setShear(x, x); }
  557. bool setRatio(F32 x, F32 y); // 0 = point, 1 = same as base
  558. bool setShear(F32 x, F32 y); // 0 = no movement
  559. bool setTwistBegin(F32 twist_begin); // Range -1 to 1
  560. bool setTwistEnd(F32 twist_end); // Range -1 to 1
  561. LL_INLINE bool setTaper(F32 x, F32 y)
  562. {
  563. bool pass_x = setTaperX(x);
  564. bool pass_y = setTaperY(y);
  565. return pass_x && pass_y;
  566. }
  567. bool setTaperX(F32 v); // -1 to 1
  568. bool setTaperY(F32 v); // -1 to 1
  569. bool setRevolutions(F32 revolutions); // 1 to 4
  570. bool setRadiusOffset(F32 radius_offset);
  571. bool setSkew(F32 skew);
  572. bool setSculptID(const LLUUID& sculpt_id, U8 sculpt_type);
  573. static bool validate(U8 prof_curve, F32 prof_begin, F32 prof_end,
  574. F32 hollow,
  575. U8 path_curve, F32 path_begin, F32 path_end,
  576. F32 scx, F32 scy, F32 shx, F32 shy,
  577. F32 twistend, F32 twistbegin, F32 radiusoffset,
  578. F32 tx, F32 ty, F32 revolutions, F32 skew);
  579. LL_INLINE F32 getBeginS() const { return mProfileParams.getBegin(); }
  580. LL_INLINE F32 getBeginT() const { return mPathParams.getBegin(); }
  581. LL_INLINE F32 getEndS() const { return mProfileParams.getEnd(); }
  582. LL_INLINE F32 getEndT() const { return mPathParams.getEnd(); }
  583. LL_INLINE F32 getHollow() const { return mProfileParams.getHollow(); }
  584. LL_INLINE F32 getRatio() const { return mPathParams.getScaleX(); }
  585. LL_INLINE F32 getRatioX() const { return mPathParams.getScaleX(); }
  586. LL_INLINE F32 getRatioY() const { return mPathParams.getScaleY(); }
  587. LL_INLINE F32 getShearX() const { return mPathParams.getShearX(); }
  588. LL_INLINE F32 getShearY() const { return mPathParams.getShearY(); }
  589. LL_INLINE F32 getTwistBegin()const { return mPathParams.getTwistBegin(); }
  590. // Note: getTwist() has been deprecated in favour of getTwistEnd(()
  591. LL_INLINE F32 getTwistEnd() const { return mPathParams.getTwistEnd(); }
  592. LL_INLINE F32 getRadiusOffset() const { return mPathParams.getRadiusOffset(); }
  593. LL_INLINE F32 getTaper() const { return mPathParams.getTaperX(); }
  594. LL_INLINE F32 getTaperX() const { return mPathParams.getTaperX(); }
  595. LL_INLINE F32 getTaperY() const { return mPathParams.getTaperY(); }
  596. LL_INLINE F32 getRevolutions() const { return mPathParams.getRevolutions(); }
  597. LL_INLINE F32 getSkew() const { return mPathParams.getSkew(); }
  598. LL_INLINE const LLUUID& getSculptID() const { return mSculptID; }
  599. LL_INLINE U8 getSculptType() const { return mSculptType; }
  600. LL_INLINE bool isSculpt() const
  601. {
  602. return (mSculptType & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_NONE;
  603. }
  604. LL_INLINE bool isMeshSculpt() const
  605. {
  606. return (mSculptType & LL_SCULPT_TYPE_MASK) == LL_SCULPT_TYPE_MESH;
  607. }
  608. bool isConvex() const;
  609. // 'begin' and 'end' should be in range [0, 1] (they will be clamped)
  610. // (begin, end) = (0, 1) will not change the volume
  611. // (begin, end) = (0, 0.5) will reduce the volume to the first half of its
  612. // profile/path (S/T)
  613. void reduceS(F32 begin, F32 end);
  614. void reduceT(F32 begin, F32 end);
  615. struct compare
  616. {
  617. LL_INLINE bool operator()(const const_LLVolumeParamsPtr& first,
  618. const const_LLVolumeParamsPtr& second) const
  619. {
  620. return *first < *second;
  621. }
  622. };
  623. friend std::ostream& operator<<(std::ostream& s,
  624. const LLVolumeParams& volume_params);
  625. // debug helper functions
  626. void setCube();
  627. protected:
  628. LLUUID mSculptID;
  629. LLProfileParams mProfileParams;
  630. // Note: LLProfileParams ends with an U8, so let's use the aligmenent gap with
  631. // another U8, at least... HB
  632. U8 mSculptType;
  633. LLPathParams mPathParams;
  634. };
  635. class LLProfile
  636. {
  637. protected:
  638. LOG_CLASS(LLProfile);
  639. public:
  640. LLProfile()
  641. : mOpen(false),
  642. mConcave(false),
  643. mDirty(true),
  644. mTotalOut(0),
  645. mTotal(2)
  646. {
  647. }
  648. LL_INLINE S32 getTotal() const { return mTotal; }
  649. // Total number of outside points:
  650. LL_INLINE S32 getTotalOut() const { return mTotalOut; }
  651. LL_INLINE bool isFlat(S32 face) const { return mFaces[face].mCount == 2; }
  652. LL_INLINE bool isOpen() const { return mOpen; }
  653. LL_INLINE bool isConcave() const { return mConcave; }
  654. LL_INLINE void setDirty() { mDirty = true; }
  655. static S32 getNumPoints(const LLProfileParams& params, bool path_open,
  656. F32 detail = 1.f, S32 split = 0,
  657. bool is_sculpted = false, S32 sculpt_size = 0);
  658. bool generate(const LLProfileParams& params, bool path_open,
  659. F32 detail = 1.f, S32 split = 0,
  660. bool is_sculpted = false, S32 sculpt_size = 0);
  661. friend std::ostream& operator<<(std::ostream& s, const LLProfile& profile);
  662. struct Face
  663. {
  664. LLFaceID mFaceID;
  665. S32 mIndex;
  666. S32 mCount;
  667. F32 mScaleU;
  668. bool mCap;
  669. bool mFlat;
  670. };
  671. protected:
  672. static S32 getNumNGonPoints(const LLProfileParams& params, S32 sides,
  673. F32 ang_scale = 1.f, S32 split = 0);
  674. void genNGon(const LLProfileParams& params, S32 sides, F32 offset = 0.f,
  675. F32 ang_scale = 1.f, S32 split = 0);
  676. Face* addHole(const LLProfileParams& params, bool flat, F32 sides,
  677. F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0);
  678. Face* addCap(S16 face_id);
  679. Face* addFace(S32 index, S32 count, F32 u_scale, S16 face_id, bool flat);
  680. public:
  681. LLAlignedArray<LLVector4a, 64> mVertices;
  682. std::vector<Face> mFaces;
  683. protected:
  684. LLMutex mMutex;
  685. S32 mTotalOut;
  686. S32 mTotal;
  687. bool mOpen;
  688. bool mConcave;
  689. bool mDirty;
  690. };
  691. //-------------------------------------------------------------------
  692. // SWEEP/EXTRUDE PATHS
  693. //-------------------------------------------------------------------
  694. class LLPath
  695. {
  696. protected:
  697. LOG_CLASS(LLPath);
  698. public:
  699. #if LL_JEMALLOC
  700. // LLPath does not need to be 16-byte aligned but benefits from arenas
  701. LL_VOLUME_AREANA_NEW_DELETE
  702. #endif
  703. class alignas(16) PathPt
  704. {
  705. public:
  706. LLMatrix4a mRot;
  707. LLVector4a mPos;
  708. LLVector4a mScale;
  709. F32 mTexT;
  710. F32 pad[3]; // For alignment
  711. PathPt()
  712. {
  713. mPos.clear();
  714. mTexT = 0;
  715. mScale.clear();
  716. mRot.setRows(LLVector4a(1, 0, 0, 0), LLVector4a(0, 1, 0, 0),
  717. LLVector4a(0, 0, 1, 0));
  718. // Distinguished data in the pad for debugging
  719. pad[0] = F_PI;
  720. pad[1] = -F_PI;
  721. pad[2] = 0.585f;
  722. }
  723. };
  724. public:
  725. LLPath()
  726. : mOpen(false),
  727. mTotal(0),
  728. mDirty(true),
  729. mStep(1.f)
  730. {
  731. }
  732. virtual ~LLPath() = default;
  733. static S32 getNumPoints(const LLPathParams& params, F32 detail);
  734. static S32 getNumNGonPoints(const LLPathParams& params, S32 sides);
  735. void genNGon(const LLPathParams& params, S32 sides, F32 end_scale = 1.f,
  736. F32 twist_scale = 1.f);
  737. virtual bool generate(const LLPathParams& params, F32 detail = 1.f,
  738. S32 split = 0,
  739. bool is_sculpted = false, S32 sculpt_size = 0);
  740. LL_INLINE bool isOpen() const { return mOpen; }
  741. LL_INLINE F32 getStep() const { return mStep; }
  742. LL_INLINE void setDirty() { mDirty = true; }
  743. LL_INLINE S32 getPathLength() const { return (S32)mPath.size(); }
  744. LL_INLINE void resizePath(S32 length) { mPath.resize(length); }
  745. friend std::ostream& operator<<(std::ostream& s, const LLPath& path);
  746. protected:
  747. S32 mTotal;
  748. F32 mStep;
  749. bool mOpen;
  750. bool mDirty;
  751. public:
  752. LLAlignedArray<PathPt, 64> mPath;
  753. };
  754. class LLDynamicPath : public LLPath
  755. {
  756. protected:
  757. LOG_CLASS(LLDynamicPath);
  758. public:
  759. bool generate(const LLPathParams& params, F32 detail = 1.f, S32 split = 0,
  760. bool is_sculpted = false, S32 sculpt_size = 0) override;
  761. };
  762. // ----------------------------------------------------------------------------
  763. // LLJointRiggingInfo class.
  764. // Stores information related to associated rigged mesh vertices.
  765. // ----------------------------------------------------------------------------
  766. class alignas(16) LLJointRiggingInfo
  767. {
  768. public:
  769. LL_VOLUME_AREANA_NEW_DELETE
  770. LLJointRiggingInfo();
  771. LL_INLINE LLVector4a* getRiggedExtents() { return mRiggedExtents; }
  772. LL_INLINE const LLVector4a* getRiggedExtents() const
  773. {
  774. return mRiggedExtents;
  775. }
  776. LL_INLINE void setIsRiggedTo(bool val = true) { mIsRiggedTo = val; }
  777. LL_INLINE bool isRiggedTo() const { return mIsRiggedTo; }
  778. void merge(const LLJointRiggingInfo& other);
  779. private:
  780. alignas(16) LLVector4a mRiggedExtents[2];
  781. bool mIsRiggedTo;
  782. };
  783. // ----------------------------------------------------------------------------
  784. // LLJointRiggingInfoTab class.
  785. // For storing all the rigging info associated with a given avatar or object,
  786. // keyed by joint_key.
  787. // ----------------------------------------------------------------------------
  788. class LLJointRiggingInfoTab
  789. {
  790. public:
  791. #if LL_JEMALLOC
  792. // LLJointRiggingInfoTab does not need to be 16-byte aligned but benefits
  793. // from arenas
  794. LL_VOLUME_AREANA_NEW_DELETE
  795. #endif
  796. LLJointRiggingInfoTab();
  797. ~LLJointRiggingInfoTab();
  798. void clear();
  799. void resize(U32 size);
  800. LL_INLINE U32 size() const { return mSize; }
  801. void merge(const LLJointRiggingInfoTab& src);
  802. LL_INLINE LLJointRiggingInfo& operator[](S32 i) { return mRigInfoPtr[i]; }
  803. LL_INLINE const LLJointRiggingInfo& operator[](S32 i) const
  804. {
  805. return mRigInfoPtr[i];
  806. }
  807. LL_INLINE bool needsUpdate() { return mNeedsUpdate; }
  808. LL_INLINE void setNeedsUpdate(bool val = true) { mNeedsUpdate = val; }
  809. private:
  810. // Not implemented, on purpose.
  811. LLJointRiggingInfoTab& operator=(const LLJointRiggingInfoTab& src);
  812. LLJointRiggingInfoTab(const LLJointRiggingInfoTab& src);
  813. private:
  814. LLJointRiggingInfo* mRigInfoPtr;
  815. U32 mSize;
  816. bool mNeedsUpdate;
  817. };
  818. // ----------------------------------------------------------------------------
  819. // LLVolumeFace class.
  820. // Yet another "face" class - caches volume-specific, but not instance-specific
  821. // data for faces)
  822. // ----------------------------------------------------------------------------
  823. class LLVolumeFace
  824. {
  825. protected:
  826. LOG_CLASS(LLVolumeFace);
  827. public:
  828. #if LL_JEMALLOC
  829. // LLVolumeFace does not need to be 16-byte aligned but benefits from
  830. // arenas
  831. LL_VOLUME_AREANA_NEW_DELETE
  832. #endif
  833. class VertexData
  834. {
  835. private:
  836. enum
  837. {
  838. POSITION = 0,
  839. NORMAL = 1
  840. };
  841. void init();
  842. public:
  843. LL_INLINE VertexData() { mData = NULL; init(); }
  844. LL_INLINE VertexData(const VertexData& rhs) { mData = NULL; *this = rhs; }
  845. const VertexData& operator=(const VertexData& rhs);
  846. ~VertexData();
  847. LL_INLINE LLVector4a& getPosition() { return mData[POSITION]; }
  848. LL_INLINE LLVector4a& getNormal() { return mData[NORMAL]; }
  849. LL_INLINE const LLVector4a& getPosition() const { return mData[POSITION]; }
  850. LL_INLINE const LLVector4a& getNormal() const { return mData[NORMAL]; }
  851. LL_INLINE void setPosition(const LLVector4a& p) { mData[POSITION] = p; }
  852. LL_INLINE void setNormal(const LLVector4a& n) { mData[NORMAL] = n; }
  853. LLVector2 mTexCoord;
  854. bool operator<(const VertexData& rhs) const;
  855. LL_INLINE bool operator==(const VertexData& rhs) const;
  856. bool compareNormal(const VertexData& rhs, F32 angle_cutoff) const;
  857. private:
  858. LLVector4a* mData;
  859. };
  860. LLVolumeFace();
  861. LLVolumeFace(const LLVolumeFace& src);
  862. LLVolumeFace& operator=(const LLVolumeFace& rhs);
  863. ~LLVolumeFace();
  864. static void initClass();
  865. bool create(LLVolume* volume, bool partial_build = false);
  866. void createTangents();
  867. bool resizeVertices(S32 num_verts);
  868. bool allocateTangents(S32 num_verts);
  869. bool allocateWeights(S32 num_verts);
  870. bool resizeIndices(S32 num_indices);
  871. void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v,
  872. std::vector<U16>& idx);
  873. // Note: max_indice is the number of indices in the unoptimized face
  874. void pushVertex(const VertexData& cv, S32 max_indice);
  875. void pushVertex(const LLVector4a& pos, const LLVector4a& norm,
  876. const LLVector2& tc, S32 max_indice);
  877. void pushIndex(const U16& idx);
  878. void swapData(LLVolumeFace& rhs);
  879. void getVertexData(U16 indx, LLVolumeFace::VertexData& cv);
  880. class VertexMapData : public LLVolumeFace::VertexData
  881. {
  882. public:
  883. bool operator==(const LLVolumeFace::VertexData& rhs) const;
  884. struct ComparePosition
  885. {
  886. bool operator()(const LLVector3& a, const LLVector3& b) const;
  887. };
  888. typedef std::map<LLVector3, std::vector<VertexMapData>,
  889. VertexMapData::ComparePosition> PointMap;
  890. public:
  891. U16 mIndex;
  892. };
  893. // Used to be a validate_face(const LLVolumeFace& face) global function in
  894. // llmodel.h. HB
  895. bool validate(bool check_nans = false) const;
  896. // Used to be a ll_is_degenerate() global function in llmodel.h. HB
  897. static bool isDegenerate(const LLVector4a& a, const LLVector4a& b,
  898. const LLVector4a& c);
  899. // Eliminates non unique triangles, taking positions, normals and texture
  900. // coordinates into account.
  901. void remap();
  902. void optimize(F32 angle_cutoff = 2.f);
  903. bool cacheOptimize(bool gen_tangents = false);
  904. void createOctree(F32 scaler = 0.25f,
  905. const LLVector4a& center = LLVector4a(0.f, 0.f, 0.f),
  906. const LLVector4a& size = LLVector4a(0.5f, 0.5f, 0.5f));
  907. enum
  908. {
  909. SINGLE_MASK = 0x0001,
  910. CAP_MASK = 0x0002,
  911. END_MASK = 0x0004,
  912. SIDE_MASK = 0x0008,
  913. INNER_MASK = 0x0010,
  914. OUTER_MASK = 0x0020,
  915. HOLLOW_MASK = 0x0040,
  916. OPEN_MASK = 0x0080,
  917. FLAT_MASK = 0x0100,
  918. TOP_MASK = 0x0200,
  919. BOTTOM_MASK = 0x0400
  920. };
  921. void destroyOctree();
  922. #if LL_JEMALLOC
  923. LL_INLINE static U32 getMallocxFlags16() { return sMallocxFlags16; }
  924. LL_INLINE static U32 getMallocxFlags64() { return sMallocxFlags64; }
  925. #endif
  926. private:
  927. void freeData();
  928. bool createUnCutCubeCap(LLVolume* volume, bool partial_build = false);
  929. bool createCap(LLVolume* volume, bool partial_build = false);
  930. bool createSide(LLVolume* volume, bool partial_build = false);
  931. private:
  932. #if LL_JEMALLOC
  933. static U32 sMallocxFlags16;
  934. static U32 sMallocxFlags64;
  935. #endif
  936. // NOTE: some of the member variables below would better be private, but
  937. // this would forbid using the offsetof() macro on LLVolumeFace (gcc error
  938. // "'offsetof' within non-standard-layout type 'LLVolumeFace' is
  939. // conditionally-supported"), and we do need the latter... HB
  940. public:
  941. // This octree stores raw pointer references to triangles in
  942. // mOctreeTriangles
  943. LLVolumeOctree* mOctree;
  944. LLVolumeTriangle* mOctreeTriangles;
  945. // List of skin weights for rigged volumes. Format is:
  946. // mWeights[vertex_index].mV[influence] = <joint_index>.<weight>
  947. // mWeights.size() should be empty or match mVertices.size()
  948. LLVector4a* mWeights;
  949. std::vector<S32> mEdge;
  950. LLJointRiggingInfoTab mJointRiggingInfoTab;
  951. // If this is a mesh asset, scale and translation that were applied when
  952. // encoding the source mesh into a unit cube used for regenerating tangents
  953. LLVector3 mNormalizedScale;
  954. // Minimum and maximum of texture coordinates of the face:
  955. LLVector2 mTexCoordExtents[2];
  956. // Minimum and maximum point of face:
  957. LLVector4a* mExtents;
  958. LLVector4a* mCenter;
  959. // mPositions contains vertices, normals and texcoords
  960. LLVector4a* mPositions;
  961. LLVector4a* mNormals;
  962. LLVector4a* mTangents;
  963. // Pointer into mPositions
  964. LLVector2* mTexCoords;
  965. // mIndices contains mNumIndices amount of elements. It contains triangles,
  966. // each 3 indices describe one triangle.
  967. // If mIndices contains {0, 2, 3, 1, 2, 4}, it means there are 2 triangles
  968. // {0, 2, 3} and {1, 2, 4} with values being indexes for mPositions,
  969. // mNormals, mTexCoords.
  970. U16* mIndices;
  971. S32 mID;
  972. U32 mTypeMask;
  973. // Only used for INNER/OUTER faces
  974. S32 mBeginS;
  975. S32 mBeginT;
  976. S32 mNumS;
  977. S32 mNumT;
  978. // mNumVertices == num vertices == num normals == num texcoords
  979. S32 mNumVertices;
  980. S32 mNumAllocatedVertices;
  981. S32 mNumIndices;
  982. mutable bool mWeightsScrubbed;
  983. // Whether or not face has been cache optimized
  984. bool mOptimized;
  985. };
  986. LL_INLINE bool LLVolumeFace::VertexData::operator==(const LLVolumeFace::VertexData& rhs) const
  987. {
  988. return mData[POSITION].equals3(rhs.getPosition()) &&
  989. mData[NORMAL].equals3(rhs.getNormal()) &&
  990. mTexCoord == rhs.mTexCoord;
  991. }
  992. class LLVolume : public LLRefCount
  993. {
  994. friend class LLVolumeLODGroup;
  995. protected:
  996. LOG_CLASS(LLVolume);
  997. ~LLVolume() override; // Uses unref
  998. public:
  999. #if LL_JEMALLOC
  1000. // LLVolume does not need to be 16-byte aligned but benefits from arenas
  1001. LL_VOLUME_AREANA_NEW_DELETE
  1002. #endif
  1003. typedef std::vector<LLVolumeFace> face_list_t;
  1004. struct FaceParams
  1005. {
  1006. LLFaceID mFaceID;
  1007. S32 mBeginS;
  1008. S32 mCountS;
  1009. S32 mBeginT;
  1010. S32 mCountT;
  1011. };
  1012. LLVolume(const LLVolumeParams& params, F32 detail,
  1013. bool generate_single_face = false, bool is_unique = false);
  1014. LL_INLINE U8 getProfileType() const { return mParams.getProfileParams().getCurveType(); }
  1015. LL_INLINE U8 getPathType() const { return mParams.getPathParams().getCurveType(); }
  1016. LL_INLINE S32 getNumFaces() const
  1017. {
  1018. return mIsMeshAssetLoaded ? getNumVolumeFaces()
  1019. : (S32)mProfile.mFaces.size();
  1020. }
  1021. LL_INLINE S32 getNumVolumeFaces() const { return mVolumeFaces.size(); }
  1022. LL_INLINE F32 getDetail() const { return mDetail; }
  1023. LL_INLINE F32 getSurfaceArea() const { return mSurfaceArea; }
  1024. LL_INLINE const LLVolumeParams& getParams() const { return mParams; }
  1025. LL_INLINE LLVolumeParams getCopyOfParams() const { return mParams; }
  1026. LL_INLINE const LLProfile& getProfile() const { return mProfile; }
  1027. LL_INLINE LLPath& getPath() const { return *mPathp; }
  1028. void resizePath(S32 length);
  1029. LL_INLINE const LLAlignedArray<LLVector4a, 64>& getMesh() const
  1030. {
  1031. return mMesh;
  1032. }
  1033. LL_INLINE const LLVector4a& getMeshPt(U32 i) const
  1034. {
  1035. return mMesh[i];
  1036. }
  1037. LL_INLINE void setDirty()
  1038. {
  1039. mPathp->setDirty();
  1040. mProfile.setDirty();
  1041. }
  1042. void regen();
  1043. void genTangents(S32 face);
  1044. // mParams.isConvex() may return false even though the final geometry is
  1045. // actually convex due to LOD approximations.
  1046. // *TODO: provide LLPath and LLProfile with isConvex() methods that
  1047. // correctly determine convexity. -- Leviathan
  1048. LL_INLINE bool isConvex() const { return mParams.isConvex(); }
  1049. LL_INLINE bool isCap(S32 face) { return mProfile.mFaces[face].mCap; }
  1050. LL_INLINE bool isFlat(S32 face) { return mProfile.mFaces[face].mFlat; }
  1051. LL_INLINE bool isUnique() const { return mUnique; }
  1052. LL_INLINE S32 getSculptLevel() const { return mSculptLevel; }
  1053. LL_INLINE void setSculptLevel(S32 level) { mSculptLevel = level; }
  1054. void getLoDTriangleCounts(S32* counts);
  1055. S32 getNumTriangles(S32* vcount = NULL) const;
  1056. void generateSilhouetteVertices(std::vector<LLVector3>& vertices,
  1057. std::vector<LLVector3>& normals,
  1058. const LLVector3& view_vec,
  1059. const LLMatrix4& mat,
  1060. const LLMatrix3& norm_mat,
  1061. S32 face_index);
  1062. // Gets the face index of the face that intersects with the given line
  1063. // segment at the point closest to start. Moves end to the point of
  1064. // intersection. Returns -1 if no intersection. Line segment must be in
  1065. // volume space.
  1066. S32 lineSegmentIntersect(const LLVector4a& start,
  1067. const LLVector4a& end,
  1068. // Which face to check, -1 = ALL_SIDES
  1069. S32 face = -1,
  1070. // Returns the intersection point
  1071. LLVector4a* intersection = NULL,
  1072. // Returns the texture coordinates at intersection
  1073. LLVector2* tex_coord = NULL,
  1074. // Returns the surface normal at intersection
  1075. LLVector4a* normal = NULL,
  1076. // Returns the surface tangent at intersection
  1077. LLVector4a* tangent = NULL);
  1078. LLFaceID generateFaceMask();
  1079. bool isFaceMaskValid(LLFaceID face_mask);
  1080. friend std::ostream& operator<<(std::ostream& s, const LLVolume& volume);
  1081. // *HACK to bypass Windoze confusion over conversion if *(LLVolume*) to
  1082. // LLVolume&
  1083. friend std::ostream& operator<<(std::ostream& s, const LLVolume* volumep);
  1084. // ------------------------------------------------------------------------
  1085. // DO NOT DELETE VOLUME WHILE USING THESE REFERENCES, OR HOLD A POINTER TO
  1086. // THESE VOLUMEFACES
  1087. LL_INLINE const LLVolumeFace& getVolumeFace(S32 f) const
  1088. {
  1089. return mVolumeFaces[f];
  1090. }
  1091. LL_INLINE LLVolumeFace& getVolumeFace(S32 f)
  1092. {
  1093. return mVolumeFaces[f];
  1094. }
  1095. LL_INLINE face_list_t& getVolumeFaces() { return mVolumeFaces; }
  1096. // ------------------------------------------------------------------------
  1097. void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components,
  1098. const U8* sculpt_data, S32 sculpt_level,
  1099. bool visible_placeholder = false);
  1100. LL_INLINE void copyFacesTo(std::vector<LLVolumeFace>& faces) const
  1101. {
  1102. faces = mVolumeFaces;
  1103. }
  1104. LL_INLINE void copyFacesFrom(const std::vector<LLVolumeFace>& faces)
  1105. {
  1106. mVolumeFaces = faces;
  1107. mSculptLevel = 0;
  1108. }
  1109. LL_INLINE void copyVolumeFaces(const LLVolume* volume)
  1110. {
  1111. if (volume)
  1112. {
  1113. mVolumeFaces = volume->mVolumeFaces;
  1114. mSculptLevel = 0;
  1115. }
  1116. }
  1117. bool cacheOptimize(bool gen_tangents = false);
  1118. bool unpackVolumeFaces(std::istream& is, S32 size);
  1119. bool unpackVolumeFaces(const U8* in, S32 size);
  1120. LL_INLINE void setMeshAssetLoaded(bool b) { mIsMeshAssetLoaded = b; }
  1121. LL_INLINE bool isMeshAssetLoaded() { return mIsMeshAssetLoaded; }
  1122. protected:
  1123. bool generate();
  1124. void createVolumeFaces();
  1125. private:
  1126. bool unpackVolumeFaces(const LLSD& mdl);
  1127. void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height,
  1128. S8 sculpt_components, const U8* sculpt_data,
  1129. U8 sculpt_type);
  1130. F32 sculptGetSurfaceArea();
  1131. void sculptGenerateEmptyPlaceholder();
  1132. void sculptGenerateSpherePlaceholder();
  1133. void sculptCalcMeshResolution(U16 width, U16 height, U8 type,
  1134. S32& s, S32& t);
  1135. protected:
  1136. // Note: before these variables, we find the 32 bits counter from
  1137. // LLRefCount... HB
  1138. F32 mDetail;
  1139. S32 mSculptLevel;
  1140. F32 mSurfaceArea; // Unscaled surface area
  1141. LLPath* mPathp;
  1142. const LLVolumeParams mParams;
  1143. LLProfile mProfile;
  1144. LLAlignedArray<LLVector4a, 64> mMesh;
  1145. face_list_t mVolumeFaces;
  1146. struct TrianglesPerLODCache
  1147. {
  1148. LLProfileParams mProfileParams;
  1149. LLPathParams mPathParams;
  1150. S32 mTriangles[4];
  1151. };
  1152. TrianglesPerLODCache* mTrianglesCache;
  1153. bool mUnique;
  1154. bool mGenerateSingleFace;
  1155. bool mIsMeshAssetLoaded;
  1156. public:
  1157. // Bit array of which faces exist in this volume
  1158. U32 mFaceMask;
  1159. // Vector for biasing LOD based on scale
  1160. LLVector3 mLODScaleBias;
  1161. LLVector4a* mHullPoints;
  1162. U16* mHullIndices;
  1163. S32 mNumHullPoints;
  1164. S32 mNumHullIndices;
  1165. static U32 sLODCacheHit;
  1166. static U32 sLODCacheMiss;
  1167. static S32 sNumMeshPoints;
  1168. static bool sOptimizeCache;
  1169. };
  1170. std::ostream& operator<<(std::ostream& s, const LLVolumeParams& volume_params);
  1171. bool calculate_tangent_array(const U32 vertex_count, const LLVector4a* vertp,
  1172. const LLVector4a* normp, const LLVector2* tcoordp,
  1173. U32 triangle_count, const U16* indexp,
  1174. LLVector4a* tangentp);
  1175. bool LLLineSegmentBoxIntersect(const F32* start, const F32* end,
  1176. const F32* center, const F32* size);
  1177. bool LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end,
  1178. const LLVector3& center, const LLVector3& size);
  1179. bool LLLineSegmentBoxIntersect(const LLVector4a& start, const LLVector4a& end,
  1180. const LLVector4a& center, const LLVector4a& size);
  1181. #if 0
  1182. bool LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1,
  1183. const LLVector3& vert2, const LLVector3& orig,
  1184. const LLVector3& dir,
  1185. F32& intersection_a, F32& intersection_b,
  1186. F32& intersection_t, bool two_sided);
  1187. #endif
  1188. bool LLTriangleRayIntersect(const LLVector4a& vert0, const LLVector4a& vert1,
  1189. const LLVector4a& vert2, const LLVector4a& orig,
  1190. const LLVector4a& dir,
  1191. F32& intersection_a, F32& intersection_b,
  1192. F32& intersection_t);
  1193. bool LLTriangleRayIntersectTwoSided(const LLVector4a& vert0,
  1194. const LLVector4a& vert1,
  1195. const LLVector4a& vert2,
  1196. const LLVector4a& orig,
  1197. const LLVector4a& dir,
  1198. F32& intersection_a,
  1199. F32& intersection_b,
  1200. F32& intersection_t);
  1201. F32 LLTriangleClosestPoint(const LLVector3& vert0, const LLVector3& vert1,
  1202. const LLVector3& vert2, const LLVector3& target,
  1203. F32& closest_a, F32& closest_b);
  1204. // NOTE: since the memory functions below use void* pointers instead of char*
  1205. // (because void* is the type used by malloc and jemalloc), strict aliasing is
  1206. // not possible on structures allocated with them. Make sure you forbid your
  1207. // compiler to optimize with strict aliasing assumption (i.e. for gcc, DO use
  1208. // the -fno-strict-aliasing option) !
  1209. LL_INLINE void* allocate_volume_mem(size_t size)
  1210. {
  1211. if (LL_UNLIKELY(size <= 0)) return NULL;
  1212. void* addr;
  1213. #if LL_JEMALLOC
  1214. addr = mallocx(size, LLVolumeFace::getMallocxFlags16());
  1215. LL_TRACY_ALLOC(addr, size, trc_mem_volume);
  1216. #else
  1217. addr = ll_aligned_malloc_16(size);
  1218. #endif
  1219. if (LL_UNLIKELY(addr == NULL))
  1220. {
  1221. LLMemory::allocationFailed(size);
  1222. }
  1223. return addr;
  1224. }
  1225. LL_INLINE void free_volume_mem(void* addr) noexcept
  1226. {
  1227. if (LL_UNLIKELY(addr == NULL)) return;
  1228. #if LL_JEMALLOC
  1229. LL_TRACY_FREE(addr, trc_mem_volume);
  1230. dallocx(addr, 0);
  1231. #else
  1232. ll_aligned_free_16(addr);
  1233. #endif
  1234. }
  1235. LL_INLINE void* realloc_volume_mem(void* ptr, size_t size, size_t old_size)
  1236. {
  1237. if (LL_UNLIKELY(size <= 0))
  1238. {
  1239. free_volume_mem(ptr);
  1240. return NULL;
  1241. }
  1242. if (LL_UNLIKELY(ptr == NULL))
  1243. {
  1244. return allocate_volume_mem(size);
  1245. }
  1246. #if LL_JEMALLOC
  1247. LL_TRACY_FREE(ptr, trc_mem_volume);
  1248. void* addr = rallocx(ptr, size, LLVolumeFace::getMallocxFlags16());
  1249. if (LL_UNLIKELY(addr == NULL))
  1250. {
  1251. LLMemory::allocationFailed(size);
  1252. }
  1253. LL_TRACY_ALLOC(addr, size, trc_mem_volume);
  1254. return addr;
  1255. #else
  1256. return ll_aligned_realloc_16(ptr, size, old_size);
  1257. #endif
  1258. }
  1259. LL_INLINE void* allocate_volume_mem_64(size_t size)
  1260. {
  1261. if (LL_UNLIKELY(size <= 0)) return NULL;
  1262. void* addr;
  1263. #if LL_JEMALLOC
  1264. addr = mallocx(size, LLVolumeFace::getMallocxFlags64());
  1265. LL_TRACY_ALLOC(addr, size, trc_mem_volume64);
  1266. #else
  1267. addr = ll_aligned_malloc(size, 64);
  1268. #endif
  1269. if (LL_UNLIKELY(addr == NULL))
  1270. {
  1271. LLMemory::allocationFailed(size);
  1272. }
  1273. return addr;
  1274. }
  1275. LL_INLINE void free_volume_mem_64(void* addr) noexcept
  1276. {
  1277. if (LL_LIKELY(addr))
  1278. {
  1279. #if LL_JEMALLOC
  1280. LL_TRACY_FREE(addr, trc_mem_volume64);
  1281. dallocx(addr, 0);
  1282. #else
  1283. ll_aligned_free(addr);
  1284. #endif
  1285. }
  1286. }
  1287. #endif