llvolume.h
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:31k
源码类别:

游戏引擎

开发平台:

C++ Builder

  1. /** 
  2.  * @file llvolume.h
  3.  * @brief LLVolume base class.
  4.  *
  5.  * $LicenseInfo:firstyear=2002&license=viewergpl$
  6.  * 
  7.  * Copyright (c) 2002-2010, 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. class LLProfileParams;
  36. class LLPathParams;
  37. class LLVolumeParams;
  38. class LLProfile;
  39. class LLPath;
  40. class LLVolumeFace;
  41. class LLVolume;
  42. #include "lldarray.h"
  43. #include "lluuid.h"
  44. #include "v4color.h"
  45. //#include "vmath.h"
  46. #include "v2math.h"
  47. #include "v3math.h"
  48. #include "llquaternion.h"
  49. #include "llstrider.h"
  50. #include "v4coloru.h"
  51. #include "llrefcount.h"
  52. #include "llfile.h"
  53. //============================================================================
  54. const S32 MIN_DETAIL_FACES = 6;
  55. const S32 MIN_LOD = 0;
  56. const S32 MAX_LOD = 3;
  57. // These are defined here but are not enforced at this level,
  58. // rather they are here for the convenience of code that uses
  59. // the LLVolume class.
  60. const F32 MIN_VOLUME_PROFILE_WIDTH  = 0.05f;
  61. const F32 MIN_VOLUME_PATH_WIDTH  = 0.05f;
  62. const F32 CUT_QUANTA    = 0.00002f;
  63. const F32 SCALE_QUANTA  = 0.01f;
  64. const F32 SHEAR_QUANTA  = 0.01f;
  65. const F32 TAPER_QUANTA  = 0.01f;
  66. const F32 REV_QUANTA    = 0.015f;
  67. const F32 HOLLOW_QUANTA = 0.00002f;
  68. const S32 MAX_VOLUME_TRIANGLE_INDICES = 10000;
  69. //============================================================================
  70. // useful masks
  71. const LLPCode LL_PCODE_HOLLOW_MASK  = 0x80; // has a thickness
  72. const LLPCode LL_PCODE_SEGMENT_MASK = 0x40; // segments (1 angle)
  73. const LLPCode LL_PCODE_PATCH_MASK  = 0x20; // segmented segments (2 angles)
  74. const LLPCode LL_PCODE_HEMI_MASK  = 0x10; // half-primitives get their own type per PR's dictum
  75. const LLPCode LL_PCODE_BASE_MASK  = 0x0F;
  76. // primitive shapes
  77. const LLPCode LL_PCODE_CUBE  = 1;
  78. const LLPCode LL_PCODE_PRISM  = 2;
  79. const LLPCode LL_PCODE_TETRAHEDRON  = 3;
  80. const LLPCode LL_PCODE_PYRAMID  = 4;
  81. const LLPCode LL_PCODE_CYLINDER  = 5;
  82. const LLPCode LL_PCODE_CONE  = 6;
  83. const LLPCode LL_PCODE_SPHERE  = 7;
  84. const LLPCode LL_PCODE_TORUS  = 8;
  85. const LLPCode LL_PCODE_VOLUME = 9;
  86. // surfaces
  87. //const LLPCode LL_PCODE_SURFACE_TRIANGLE  = 10;
  88. //const LLPCode LL_PCODE_SURFACE_SQUARE  = 11;
  89. //const LLPCode LL_PCODE_SURFACE_DISC  = 12;
  90. const LLPCode LL_PCODE_APP = 14; // App specific pcode (for viewer/sim side only objects)
  91. const LLPCode LL_PCODE_LEGACY = 15;
  92. // Pcodes for legacy objects
  93. //const LLPCode LL_PCODE_LEGACY_ATOR = 0x10 | LL_PCODE_LEGACY; // ATOR
  94. const LLPCode LL_PCODE_LEGACY_AVATAR = 0x20 | LL_PCODE_LEGACY; // PLAYER
  95. //const LLPCode LL_PCODE_LEGACY_BIRD = 0x30 | LL_PCODE_LEGACY; // BIRD
  96. //const LLPCode LL_PCODE_LEGACY_DEMON = 0x40 | LL_PCODE_LEGACY; // DEMON
  97. const LLPCode LL_PCODE_LEGACY_GRASS = 0x50 | LL_PCODE_LEGACY; // GRASS
  98. const LLPCode LL_PCODE_TREE_NEW = 0x60 | LL_PCODE_LEGACY; // new trees
  99. //const LLPCode LL_PCODE_LEGACY_ORACLE = 0x70 | LL_PCODE_LEGACY; // ORACLE
  100. const LLPCode LL_PCODE_LEGACY_PART_SYS = 0x80 | LL_PCODE_LEGACY; // PART_SYS
  101. const LLPCode LL_PCODE_LEGACY_ROCK = 0x90 | LL_PCODE_LEGACY; // ROCK
  102. //const LLPCode LL_PCODE_LEGACY_SHOT = 0xA0 | LL_PCODE_LEGACY; // BASIC_SHOT
  103. //const LLPCode LL_PCODE_LEGACY_SHOT_BIG = 0xB0 | LL_PCODE_LEGACY;
  104. //const LLPCode LL_PCODE_LEGACY_SMOKE = 0xC0 | LL_PCODE_LEGACY; // SMOKE
  105. //const LLPCode LL_PCODE_LEGACY_SPARK = 0xD0 | LL_PCODE_LEGACY;// SPARK
  106. const LLPCode LL_PCODE_LEGACY_TEXT_BUBBLE = 0xE0 | LL_PCODE_LEGACY; // TEXTBUBBLE
  107. const LLPCode LL_PCODE_LEGACY_TREE = 0xF0 | LL_PCODE_LEGACY; // TREE
  108. // hemis
  109. const LLPCode LL_PCODE_CYLINDER_HEMI = LL_PCODE_CYLINDER | LL_PCODE_HEMI_MASK;
  110. const LLPCode LL_PCODE_CONE_HEMI = LL_PCODE_CONE | LL_PCODE_HEMI_MASK;
  111. const LLPCode LL_PCODE_SPHERE_HEMI = LL_PCODE_SPHERE | LL_PCODE_HEMI_MASK;
  112. const LLPCode LL_PCODE_TORUS_HEMI = LL_PCODE_TORUS | LL_PCODE_HEMI_MASK;
  113. // Volumes consist of a profile at the base that is swept around
  114. // a path to make a volume.
  115. // The profile code
  116. const U8 LL_PCODE_PROFILE_MASK = 0x0f;
  117. const U8 LL_PCODE_PROFILE_MIN = 0x00;
  118. const U8    LL_PCODE_PROFILE_CIRCLE = 0x00;
  119. const U8    LL_PCODE_PROFILE_SQUARE = 0x01;
  120. const U8 LL_PCODE_PROFILE_ISOTRI = 0x02;
  121. const U8    LL_PCODE_PROFILE_EQUALTRI = 0x03;
  122. const U8    LL_PCODE_PROFILE_RIGHTTRI = 0x04;
  123. const U8 LL_PCODE_PROFILE_CIRCLE_HALF = 0x05;
  124. const U8 LL_PCODE_PROFILE_MAX = 0x05;
  125. // Stored in the profile byte
  126. const U8 LL_PCODE_HOLE_MASK = 0xf0;
  127. const U8 LL_PCODE_HOLE_MIN = 0x00;   
  128. const U8 LL_PCODE_HOLE_SAME = 0x00; // same as outside profile
  129. const U8 LL_PCODE_HOLE_CIRCLE = 0x10;
  130. const U8 LL_PCODE_HOLE_SQUARE = 0x20;
  131. const U8 LL_PCODE_HOLE_TRIANGLE = 0x30;
  132. const U8 LL_PCODE_HOLE_MAX = 0x03; // min/max needs to be >> 4 of real min/max
  133. const U8    LL_PCODE_PATH_IGNORE    = 0x00;
  134. const U8 LL_PCODE_PATH_MIN = 0x01; // min/max needs to be >> 4 of real min/max
  135. const U8    LL_PCODE_PATH_LINE      = 0x10;
  136. const U8    LL_PCODE_PATH_CIRCLE    = 0x20;
  137. const U8    LL_PCODE_PATH_CIRCLE2   = 0x30;
  138. const U8    LL_PCODE_PATH_TEST      = 0x40;
  139. const U8    LL_PCODE_PATH_FLEXIBLE  = 0x80;
  140. const U8 LL_PCODE_PATH_MAX = 0x08;
  141. //============================================================================
  142. // face identifiers
  143. typedef U16 LLFaceID;
  144. const LLFaceID LL_FACE_PATH_BEGIN = 0x1 << 0;
  145. const LLFaceID LL_FACE_PATH_END = 0x1 << 1;
  146. const LLFaceID LL_FACE_INNER_SIDE = 0x1 << 2;
  147. const LLFaceID LL_FACE_PROFILE_BEGIN = 0x1 << 3;
  148. const LLFaceID LL_FACE_PROFILE_END = 0x1 << 4;
  149. const LLFaceID LL_FACE_OUTER_SIDE_0 = 0x1 << 5;
  150. const LLFaceID LL_FACE_OUTER_SIDE_1 = 0x1 << 6;
  151. const LLFaceID LL_FACE_OUTER_SIDE_2 = 0x1 << 7;
  152. const LLFaceID LL_FACE_OUTER_SIDE_3 = 0x1 << 8;
  153. //============================================================================
  154. // sculpt types + flags
  155. const U8 LL_SCULPT_TYPE_NONE      = 0;
  156. const U8 LL_SCULPT_TYPE_SPHERE    = 1;
  157. const U8 LL_SCULPT_TYPE_TORUS     = 2;
  158. const U8 LL_SCULPT_TYPE_PLANE     = 3;
  159. const U8 LL_SCULPT_TYPE_CYLINDER  = 4;
  160. const U8 LL_SCULPT_TYPE_MASK      = LL_SCULPT_TYPE_SPHERE | LL_SCULPT_TYPE_TORUS | LL_SCULPT_TYPE_PLANE | LL_SCULPT_TYPE_CYLINDER;
  161. const U8 LL_SCULPT_FLAG_INVERT    = 64;
  162. const U8 LL_SCULPT_FLAG_MIRROR    = 128;
  163. class LLProfileParams
  164. {
  165. public:
  166. LLProfileParams()
  167. : mCurveType(LL_PCODE_PROFILE_SQUARE),
  168.   mBegin(0.f),
  169.   mEnd(1.f),
  170.   mHollow(0.f),
  171.   mCRC(0)
  172. {
  173. }
  174. LLProfileParams(U8 curve, F32 begin, F32 end, F32 hollow)
  175. : mCurveType(curve),
  176.   mBegin(begin),
  177.   mEnd(end),
  178.   mHollow(hollow),
  179.   mCRC(0)
  180. {
  181. }
  182. LLProfileParams(U8 curve, U16 begin, U16 end, U16 hollow)
  183. {
  184. mCurveType = curve;
  185. F32 temp_f32 = begin * CUT_QUANTA;
  186. if (temp_f32 > 1.f)
  187. {
  188. temp_f32 = 1.f;
  189. }
  190. mBegin = temp_f32;
  191. temp_f32 = end * CUT_QUANTA;
  192. if (temp_f32 > 1.f)
  193. {
  194. temp_f32 = 1.f;
  195. }
  196. mEnd = 1.f - temp_f32;
  197. temp_f32 = hollow * HOLLOW_QUANTA;
  198. if (temp_f32 > 1.f)
  199. {
  200. temp_f32 = 1.f;
  201. }
  202. mHollow = temp_f32;
  203. mCRC = 0;
  204. }
  205. bool operator==(const LLProfileParams &params) const;
  206. bool operator!=(const LLProfileParams &params) const;
  207. bool operator<(const LLProfileParams &params) const;
  208. void copyParams(const LLProfileParams &params);
  209. BOOL importFile(LLFILE *fp);
  210. BOOL exportFile(LLFILE *fp) const;
  211. BOOL importLegacyStream(std::istream& input_stream);
  212. BOOL exportLegacyStream(std::ostream& output_stream) const;
  213. LLSD asLLSD() const;
  214. operator LLSD() const { return asLLSD(); }
  215. bool fromLLSD(LLSD& sd);
  216. const F32&  getBegin () const { return mBegin; }
  217. const F32&  getEnd   () const { return mEnd;   }
  218. const F32&  getHollow() const { return mHollow; }
  219. const U8&   getCurveType () const { return mCurveType; }
  220. void setCurveType(const U32 type) { mCurveType = type;}
  221. void setBegin(const F32 begin) { mBegin = (begin >= 1.0f) ? 0.0f : ((int) (begin * 100000))/100000.0f;}
  222. void setEnd(const F32 end) { mEnd   = (end   <= 0.0f) ? 1.0f : ((int) (end * 100000))/100000.0f;}
  223. void setHollow(const F32 hollow) { mHollow = ((int) (hollow * 100000))/100000.0f;}
  224. friend std::ostream& operator<<(std::ostream &s, const LLProfileParams &profile_params);
  225. protected:
  226. // Profile params
  227. U8   mCurveType;
  228. F32           mBegin;
  229. F32           mEnd;
  230. F32   mHollow;
  231. U32           mCRC;
  232. };
  233. inline bool LLProfileParams::operator==(const LLProfileParams &params) const
  234. {
  235. return 
  236. (getCurveType() == params.getCurveType()) &&
  237. (getBegin() == params.getBegin()) &&
  238. (getEnd() == params.getEnd()) &&
  239. (getHollow() == params.getHollow());
  240. }
  241. inline bool LLProfileParams::operator!=(const LLProfileParams &params) const
  242. {
  243. return 
  244. (getCurveType() != params.getCurveType()) ||
  245. (getBegin() != params.getBegin()) ||
  246. (getEnd() != params.getEnd()) ||
  247. (getHollow() != params.getHollow());
  248. }
  249. inline bool LLProfileParams::operator<(const LLProfileParams &params) const
  250. {
  251. if (getCurveType() != params.getCurveType())
  252. {
  253. return getCurveType() < params.getCurveType();
  254. }
  255. else
  256. if (getBegin() != params.getBegin())
  257. {
  258. return getBegin() < params.getBegin();
  259. }
  260. else
  261. if (getEnd() != params.getEnd())
  262. {
  263. return getEnd() < params.getEnd();
  264. }
  265. else
  266. {
  267. return getHollow() < params.getHollow();
  268. }
  269. }
  270. #define U8_TO_F32(x) (F32)(*((S8 *)&x))
  271. class LLPathParams
  272. {
  273. public:
  274. LLPathParams()
  275. :
  276. mCurveType(LL_PCODE_PATH_LINE),
  277. mBegin(0.f),
  278. mEnd(1.f),
  279. mScale(1.f,1.f),
  280. mShear(0.f,0.f),
  281. mTwistBegin(0.f),
  282. mTwistEnd(0.f),
  283. mRadiusOffset(0.f),
  284. mTaper(0.f,0.f),
  285. mRevolutions(1.f),
  286. mSkew(0.f),
  287. mCRC(0)
  288. {
  289. }
  290. LLPathParams(U8 curve, F32 begin, F32 end, F32 scx, F32 scy, F32 shx, F32 shy, F32 twistend, F32 twistbegin, F32 radiusoffset, F32 tx, F32 ty, F32 revolutions, F32 skew)
  291. : mCurveType(curve),
  292.   mBegin(begin),
  293.   mEnd(end),
  294.   mScale(scx,scy),
  295.   mShear(shx,shy),
  296.   mTwistBegin(twistbegin),
  297.   mTwistEnd(twistend), 
  298.   mRadiusOffset(radiusoffset),
  299.   mTaper(tx,ty),
  300.   mRevolutions(revolutions),
  301.   mSkew(skew),
  302.   mCRC(0)
  303. {
  304. }
  305. LLPathParams(U8 curve, U16 begin, U16 end, U8 scx, U8 scy, U8 shx, U8 shy, U8 twistend, U8 twistbegin, U8 radiusoffset, U8 tx, U8 ty, U8 revolutions, U8 skew)
  306. {
  307. mCurveType = curve;
  308. mBegin = (F32)(begin * CUT_QUANTA);
  309. mEnd = (F32)(100.f - end) * CUT_QUANTA;
  310. if (mEnd > 1.f)
  311. mEnd = 1.f;
  312. mScale.setVec((F32) (200 - scx) * SCALE_QUANTA,(F32) (200 - scy) * SCALE_QUANTA);
  313. mShear.setVec(U8_TO_F32(shx) * SHEAR_QUANTA,U8_TO_F32(shy) * SHEAR_QUANTA);
  314. mTwistBegin = U8_TO_F32(twistbegin) * SCALE_QUANTA;
  315. mTwistEnd = U8_TO_F32(twistend) * SCALE_QUANTA;
  316. mRadiusOffset = U8_TO_F32(radiusoffset) * SCALE_QUANTA;
  317. mTaper.setVec(U8_TO_F32(tx) * TAPER_QUANTA,U8_TO_F32(ty) * TAPER_QUANTA);
  318. mRevolutions = ((F32)revolutions) * REV_QUANTA + 1.0f;
  319. mSkew = U8_TO_F32(skew) * SCALE_QUANTA;
  320. mCRC = 0;
  321. }
  322. bool operator==(const LLPathParams &params) const;
  323. bool operator!=(const LLPathParams &params) const;
  324. bool operator<(const LLPathParams &params) const;
  325. void copyParams(const LLPathParams &params);
  326. BOOL importFile(LLFILE *fp);
  327. BOOL exportFile(LLFILE *fp) const;
  328. BOOL importLegacyStream(std::istream& input_stream);
  329. BOOL exportLegacyStream(std::ostream& output_stream) const;
  330. LLSD asLLSD() const;
  331. operator LLSD() const { return asLLSD(); }
  332. bool fromLLSD(LLSD& sd);
  333. const F32& getBegin() const { return mBegin; }
  334. const F32& getEnd() const { return mEnd; }
  335. const LLVector2 &getScale() const { return mScale; }
  336. const F32& getScaleX() const { return mScale.mV[0]; }
  337. const F32& getScaleY() const { return mScale.mV[1]; }
  338. const LLVector2 getBeginScale() const;
  339. const LLVector2 getEndScale() const;
  340. const LLVector2 &getShear() const { return mShear; }
  341. const F32& getShearX() const { return mShear.mV[0]; }
  342. const F32& getShearY() const { return mShear.mV[1]; }
  343. const U8& getCurveType () const { return mCurveType; }
  344. const F32& getTwistBegin() const { return mTwistBegin; }
  345. const F32& getTwistEnd() const { return mTwistEnd; }
  346. const F32& getTwist() const { return mTwistEnd; } // deprecated
  347. const F32& getRadiusOffset() const { return mRadiusOffset; }
  348. const LLVector2 &getTaper() const { return mTaper; }
  349. const F32& getTaperX() const { return mTaper.mV[0]; }
  350. const F32& getTaperY() const { return mTaper.mV[1]; }
  351. const F32& getRevolutions() const { return mRevolutions; }
  352. const F32& getSkew() const { return mSkew; }
  353. void setCurveType(const U8 type) { mCurveType = type; }
  354. void setBegin(const F32 begin) { mBegin     = begin; }
  355. void setEnd(const F32 end) { mEnd       = end; }
  356. void setScale(const F32 x, const F32 y) { mScale.setVec(x,y); }
  357. void setScaleX(const F32 v) { mScale.mV[VX] = v; }
  358. void setScaleY(const F32 v) { mScale.mV[VY] = v; }
  359. void setShear(const F32 x, const F32 y) { mShear.setVec(x,y); }
  360. void setShearX(const F32 v) { mShear.mV[VX] = v; }
  361. void setShearY(const F32 v) { mShear.mV[VY] = v; }
  362. void setTwistBegin(const F32 twist_begin) { mTwistBegin = twist_begin; }
  363. void setTwistEnd(const F32 twist_end) { mTwistEnd = twist_end; }
  364. void setTwist(const F32 twist) { setTwistEnd(twist); } // deprecated
  365. void setRadiusOffset(const F32 radius_offset){ mRadiusOffset = radius_offset; }
  366. void setTaper(const F32 x, const F32 y) { mTaper.setVec(x,y); }
  367. void setTaperX(const F32 v) { mTaper.mV[VX] = v; }
  368. void setTaperY(const F32 v) { mTaper.mV[VY] = v; }
  369. void setRevolutions(const F32 revolutions) { mRevolutions = revolutions; }
  370. void setSkew(const F32 skew) { mSkew = skew; }
  371. friend std::ostream& operator<<(std::ostream &s, const LLPathParams &path_params);
  372. protected:
  373. // Path params
  374. U8   mCurveType;
  375. F32           mBegin;
  376. F32           mEnd;
  377. LLVector2   mScale;
  378. LLVector2     mShear;
  379. F32   mTwistBegin;
  380. F32   mTwistEnd;
  381. F32   mRadiusOffset;
  382. LLVector2   mTaper;
  383. F32   mRevolutions;
  384. F32   mSkew;
  385. U32           mCRC;
  386. };
  387. inline bool LLPathParams::operator==(const LLPathParams &params) const
  388. {
  389. return
  390. (getCurveType() == params.getCurveType()) && 
  391. (getScale() == params.getScale()) &&
  392. (getBegin() == params.getBegin()) && 
  393. (getEnd() == params.getEnd()) && 
  394. (getShear() == params.getShear()) &&
  395. (getTwist() == params.getTwist()) &&
  396. (getTwistBegin() == params.getTwistBegin()) &&
  397. (getRadiusOffset() == params.getRadiusOffset()) &&
  398. (getTaper() == params.getTaper()) &&
  399. (getRevolutions() == params.getRevolutions()) &&
  400. (getSkew() == params.getSkew());
  401. }
  402. inline bool LLPathParams::operator!=(const LLPathParams &params) const
  403. {
  404. return
  405. (getCurveType() != params.getCurveType()) ||
  406. (getScale() != params.getScale()) ||
  407. (getBegin() != params.getBegin()) || 
  408. (getEnd() != params.getEnd()) || 
  409. (getShear() != params.getShear()) ||
  410. (getTwist() != params.getTwist()) ||
  411. (getTwistBegin() !=params.getTwistBegin()) ||
  412. (getRadiusOffset() != params.getRadiusOffset()) ||
  413. (getTaper() != params.getTaper()) ||
  414. (getRevolutions() != params.getRevolutions()) ||
  415. (getSkew() != params.getSkew());
  416. }
  417. inline bool LLPathParams::operator<(const LLPathParams &params) const
  418. {
  419. if( getCurveType() != params.getCurveType()) 
  420. {
  421. return getCurveType() < params.getCurveType();
  422. }
  423. else
  424. if( getScale() != params.getScale()) 
  425. {
  426. return getScale() < params.getScale();
  427. }
  428. else
  429. if( getBegin() != params.getBegin()) 
  430. {
  431. return getBegin() < params.getBegin();
  432. }
  433. else
  434. if( getEnd() != params.getEnd()) 
  435. {
  436. return getEnd() < params.getEnd();
  437. }
  438. else
  439. if( getShear() != params.getShear()) 
  440. {
  441. return getShear() < params.getShear();
  442. }
  443. else
  444. if( getTwist() != params.getTwist())
  445. {
  446. return getTwist() < params.getTwist();
  447. }
  448. else
  449. if( getTwistBegin() != params.getTwistBegin())
  450. {
  451. return getTwistBegin() < params.getTwistBegin();
  452. }
  453. else
  454. if( getRadiusOffset() != params.getRadiusOffset())
  455. {
  456. return getRadiusOffset() < params.getRadiusOffset();
  457. }
  458. else
  459. if( getTaper() != params.getTaper())
  460. {
  461. return getTaper() < params.getTaper();
  462. }
  463. else
  464. if( getRevolutions() != params.getRevolutions())
  465. {
  466. return getRevolutions() < params.getRevolutions();
  467. }
  468. else
  469. {
  470. return getSkew() < params.getSkew();
  471. }
  472. }
  473. typedef LLVolumeParams* LLVolumeParamsPtr;
  474. typedef const LLVolumeParams* const_LLVolumeParamsPtr;
  475. class LLVolumeParams
  476. {
  477. public:
  478. LLVolumeParams()
  479. : mSculptType(LL_SCULPT_TYPE_NONE)
  480. {
  481. }
  482. LLVolumeParams(LLProfileParams &profile, LLPathParams &path,
  483.    LLUUID sculpt_id = LLUUID::null, U8 sculpt_type = LL_SCULPT_TYPE_NONE)
  484. : mProfileParams(profile), mPathParams(path), mSculptID(sculpt_id), mSculptType(sculpt_type)
  485. {
  486. }
  487. bool operator==(const LLVolumeParams &params) const;
  488. bool operator!=(const LLVolumeParams &params) const;
  489. bool operator<(const LLVolumeParams &params) const;
  490. void copyParams(const LLVolumeParams &params);
  491. const LLProfileParams &getProfileParams() const {return mProfileParams;}
  492. LLProfileParams &getProfileParams() {return mProfileParams;}
  493. const LLPathParams &getPathParams() const {return mPathParams;}
  494. LLPathParams &getPathParams() {return mPathParams;}
  495. BOOL importFile(LLFILE *fp);
  496. BOOL exportFile(LLFILE *fp) const;
  497. BOOL importLegacyStream(std::istream& input_stream);
  498. BOOL exportLegacyStream(std::ostream& output_stream) const;
  499. LLSD asLLSD() const;
  500. operator LLSD() const { return asLLSD(); }
  501. bool fromLLSD(LLSD& sd);
  502. bool setType(U8 profile, U8 path);
  503. //void setBeginS(const F32 beginS) { mProfileParams.setBegin(beginS); } // range 0 to 1
  504. //void setBeginT(const F32 beginT) { mPathParams.setBegin(beginT); } // range 0 to 1
  505. //void setEndS(const F32 endS) { mProfileParams.setEnd(endS); } // range 0 to 1, must be greater than begin
  506. //void setEndT(const F32 endT) { mPathParams.setEnd(endT); } // range 0 to 1, must be greater than begin
  507. bool setBeginAndEndS(const F32 begin, const F32 end); // both range from 0 to 1, begin must be less than end
  508. bool setBeginAndEndT(const F32 begin, const F32 end); // both range from 0 to 1, begin must be less than end
  509. bool setHollow(const F32 hollow); // range 0 to 1
  510. bool setRatio(const F32 x) { return setRatio(x,x); } // 0 = point, 1 = same as base
  511. bool setShear(const F32 x) { return setShear(x,x); } // 0 = no movement, 
  512. bool setRatio(const F32 x, const F32 y); // 0 = point, 1 = same as base
  513. bool setShear(const F32 x, const F32 y); // 0 = no movement
  514. bool setTwistBegin(const F32 twist_begin); // range -1 to 1
  515. bool setTwistEnd(const F32 twist_end); // range -1 to 1
  516. bool setTwist(const F32 twist) { return setTwistEnd(twist); } // deprecated
  517. bool setTaper(const F32 x, const F32 y) { bool pass_x = setTaperX(x); bool pass_y = setTaperY(y); return pass_x && pass_y; }
  518. bool setTaperX(const F32 v); // -1 to 1
  519. bool setTaperY(const F32 v); // -1 to 1
  520. bool setRevolutions(const F32 revolutions); // 1 to 4
  521. bool setRadiusOffset(const F32 radius_offset);
  522. bool setSkew(const F32 skew);
  523. bool setSculptID(const LLUUID sculpt_id, U8 sculpt_type);
  524. static bool validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow,
  525. U8 path_curve, F32 path_begin, F32 path_end,
  526. F32 scx, F32 scy, F32 shx, F32 shy,
  527. F32 twistend, F32 twistbegin, F32 radiusoffset,
  528. F32 tx, F32 ty, F32 revolutions, F32 skew);
  529. const F32&  getBeginS()  const { return mProfileParams.getBegin(); }
  530.   const F32&  getBeginT()  const { return mPathParams.getBegin(); }
  531.   const F32&  getEndS()  const { return mProfileParams.getEnd(); }
  532.   const F32&  getEndT()  const { return mPathParams.getEnd(); }
  533.  
  534.   const F32&  getHollow()  const   { return mProfileParams.getHollow(); }
  535.   const F32&  getTwist()  const    { return mPathParams.getTwist(); }
  536.   const F32&  getRatio()  const { return mPathParams.getScaleX(); }
  537.   const F32&  getRatioX()  const   { return mPathParams.getScaleX(); }
  538.   const F32&  getRatioY()  const   { return mPathParams.getScaleY(); }
  539.   const F32&  getShearX()  const   { return mPathParams.getShearX(); }
  540.   const F32&  getShearY()  const   { return mPathParams.getShearY(); }
  541. const F32& getTwistBegin()const { return mPathParams.getTwistBegin(); }
  542. const F32&  getRadiusOffset() const { return mPathParams.getRadiusOffset(); }
  543. const F32&  getTaper() const { return mPathParams.getTaperX(); }
  544. const F32& getTaperX() const { return mPathParams.getTaperX(); }
  545. const F32&  getTaperY() const { return mPathParams.getTaperY(); }
  546. const F32&  getRevolutions() const { return mPathParams.getRevolutions(); }
  547. const F32&  getSkew() const { return mPathParams.getSkew(); }
  548. const LLUUID& getSculptID() const { return mSculptID; }
  549. const U8& getSculptType() const     { return mSculptType;                   }
  550. BOOL isConvex() const;
  551. // 'begin' and 'end' should be in range [0, 1] (they will be clamped)
  552. // (begin, end) = (0, 1) will not change the volume
  553. // (begin, end) = (0, 0.5) will reduce the volume to the first half of its profile/path (S/T)
  554. void reduceS(F32 begin, F32 end);
  555. void reduceT(F32 begin, F32 end);
  556. struct compare
  557. {
  558. bool operator()( const const_LLVolumeParamsPtr& first, const const_LLVolumeParamsPtr& second) const
  559. {
  560. return (*first < *second);
  561. }
  562. };
  563. friend std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
  564. // debug helper functions
  565. void setCube();
  566. protected:
  567. LLProfileParams mProfileParams;
  568. LLPathParams mPathParams;
  569. LLUUID mSculptID;
  570. U8 mSculptType;
  571. };
  572. class LLProfile
  573. {
  574. public:
  575. LLProfile()
  576. : mOpen(FALSE),
  577.   mConcave(FALSE),
  578.   mDirty(TRUE),
  579.   mTotalOut(0),
  580.   mTotal(2)
  581. {
  582. }
  583. ~LLProfile();
  584. S32  getTotal() const { return mTotal; }
  585. S32  getTotalOut() const { return mTotalOut; } // Total number of outside points
  586. BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); }
  587. BOOL isOpen() const { return mOpen; }
  588. void setDirty() { mDirty     = TRUE; }
  589. BOOL generate(const LLProfileParams& params, BOOL path_open, F32 detail = 1.0f, S32 split = 0,
  590.   BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
  591. BOOL isConcave() const { return mConcave; }
  592. public:
  593. struct Face
  594. {
  595. S32       mIndex;
  596. S32       mCount;
  597. F32       mScaleU;
  598. BOOL      mCap;
  599. BOOL      mFlat;
  600. LLFaceID  mFaceID;
  601. };
  602. std::vector<LLVector3> mProfile;
  603. std::vector<LLVector2> mNormals;
  604. std::vector<Face>      mFaces;
  605. std::vector<LLVector3> mEdgeNormals;
  606. std::vector<LLVector3> mEdgeCenters;
  607. friend std::ostream& operator<<(std::ostream &s, const LLProfile &profile);
  608. protected:
  609. void genNormals(const LLProfileParams& params);
  610. void genNGon(const LLProfileParams& params, S32 sides, F32 offset=0.0f, F32 bevel = 0.0f, F32 ang_scale = 1.f, S32 split = 0);
  611. Face* addHole(const LLProfileParams& params, BOOL flat, F32 sides, F32 offset, F32 box_hollow, F32 ang_scale, S32 split = 0);
  612. Face* addCap (S16 faceID);
  613. Face* addFace(S32 index, S32 count, F32 scaleU, S16 faceID, BOOL flat);
  614. protected:
  615. BOOL   mOpen;
  616. BOOL   mConcave;
  617. BOOL          mDirty;
  618. S32   mTotalOut;
  619. S32   mTotal;
  620. };
  621. //-------------------------------------------------------------------
  622. // SWEEP/EXTRUDE PATHS
  623. //-------------------------------------------------------------------
  624. class LLPath
  625. {
  626. public:
  627. struct PathPt
  628. {
  629. LLVector3  mPos;
  630. LLVector2    mScale;
  631. LLQuaternion mRot;
  632. F32  mTexT;
  633. PathPt() { mPos.setVec(0,0,0); mTexT = 0; mScale.setVec(0,0); mRot.loadIdentity(); }
  634. };
  635. public:
  636. LLPath()
  637. : mOpen(FALSE),
  638.   mTotal(0),
  639.   mDirty(TRUE),
  640.   mStep(1)
  641. {
  642. }
  643. virtual ~LLPath();
  644. void genNGon(const LLPathParams& params, S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
  645. virtual BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0,
  646.   BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
  647. BOOL isOpen() const { return mOpen; }
  648. F32 getStep() const { return mStep; }
  649. void setDirty() { mDirty     = TRUE; }
  650. S32 getPathLength() const { return (S32)mPath.size(); }
  651. void resizePath(S32 length) { mPath.resize(length); }
  652. friend std::ostream& operator<<(std::ostream &s, const LLPath &path);
  653. public:
  654. std::vector<PathPt> mPath;
  655. protected:
  656. BOOL   mOpen;
  657. S32   mTotal;
  658. BOOL          mDirty;
  659. F32           mStep;
  660. };
  661. class LLDynamicPath : public LLPath
  662. {
  663. public:
  664. LLDynamicPath() : LLPath() { }
  665. /*virtual*/ BOOL generate(const LLPathParams& params, F32 detail=1.0f, S32 split = 0,
  666.   BOOL is_sculpted = FALSE, S32 sculpt_size = 0);
  667. };
  668. // Yet another "face" class - caches volume-specific, but not instance-specific data for faces)
  669. class LLVolumeFace
  670. {
  671. public:
  672. LLVolumeFace() : 
  673. mID(0),
  674. mTypeMask(0),
  675. mHasBinormals(FALSE),
  676. mBeginS(0),
  677. mBeginT(0),
  678. mNumS(0),
  679. mNumT(0)
  680. {
  681. }
  682. BOOL create(LLVolume* volume, BOOL partial_build = FALSE);
  683. void createBinormals();
  684. class VertexData
  685. {
  686. public:
  687. LLVector3 mPosition;
  688. LLVector3 mNormal;
  689. LLVector3 mBinormal;
  690. LLVector2 mTexCoord;
  691. };
  692. enum
  693. {
  694. SINGLE_MASK = 0x0001,
  695. CAP_MASK = 0x0002,
  696. END_MASK = 0x0004,
  697. SIDE_MASK = 0x0008,
  698. INNER_MASK = 0x0010,
  699. OUTER_MASK = 0x0020,
  700. HOLLOW_MASK = 0x0040,
  701. OPEN_MASK = 0x0080,
  702. FLAT_MASK = 0x0100,
  703. TOP_MASK = 0x0200,
  704. BOTTOM_MASK = 0x0400
  705. };
  706. public:
  707. S32 mID;
  708. U32 mTypeMask;
  709. LLVector3 mCenter;
  710. BOOL mHasBinormals;
  711. // Only used for INNER/OUTER faces
  712. S32 mBeginS;
  713. S32 mBeginT;
  714. S32 mNumS;
  715. S32 mNumT;
  716. LLVector3 mExtents[2]; //minimum and maximum point of face
  717. std::vector<VertexData> mVertices;
  718. std::vector<U16> mIndices;
  719. std::vector<S32> mEdge;
  720. private:
  721. BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE);
  722. BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE);
  723. BOOL createSide(LLVolume* volume, BOOL partial_build = FALSE);
  724. };
  725. class LLVolume : public LLRefCount
  726. {
  727. friend class LLVolumeLODGroup;
  728. private:
  729. LLVolume(const LLVolume&);  // Don't implement
  730. ~LLVolume(); // use unref
  731. public:
  732. struct Point
  733. {
  734. LLVector3 mPos;
  735. };
  736. struct FaceParams
  737. {
  738. LLFaceID mFaceID;
  739. S32 mBeginS;
  740. S32 mCountS;
  741. S32 mBeginT;
  742. S32 mCountT;
  743. };
  744. LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL generate_single_face = FALSE, const BOOL is_unique = FALSE);
  745. U8 getProfileType() const { return mParams.getProfileParams().getCurveType(); }
  746. U8 getPathType() const { return mParams.getPathParams().getCurveType(); }
  747. S32 getNumFaces() const { return (S32)mProfilep->mFaces.size(); }
  748. S32 getNumVolumeFaces() const { return mVolumeFaces.size(); }
  749. F32 getDetail() const { return mDetail; }
  750. const LLVolumeParams& getParams() const { return mParams; }
  751. LLVolumeParams getCopyOfParams() const { return mParams; }
  752. const LLProfile& getProfile() const { return *mProfilep; }
  753. LLPath& getPath() const { return *mPathp; }
  754. void resizePath(S32 length);
  755. const std::vector<Point>& getMesh() const { return mMesh; }
  756. const LLVector3& getMeshPt(const U32 i) const { return mMesh[i].mPos; }
  757. void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); }
  758. void regen();
  759. void genBinormals(S32 face);
  760. BOOL isConvex() const;
  761. BOOL isCap(S32 face);
  762. BOOL isFlat(S32 face);
  763. BOOL isUnique() const { return mUnique; }
  764. S32 getSculptLevel() const                              { return mSculptLevel; }
  765. S32 *getTriangleIndices(U32 &num_indices) const;
  766. // returns number of triangle indeces required for path/profile mesh
  767. S32 getNumTriangleIndices() const;
  768. void generateSilhouetteVertices(std::vector<LLVector3> &vertices, 
  769. std::vector<LLVector3> &normals, 
  770. std::vector<S32> &segments, 
  771. const LLVector3& view_vec,
  772. const LLMatrix4& mat,
  773. const LLMatrix3& norm_mat,
  774. S32 face_index);
  775. //get the face index of the face that intersects with the given line segment at the point 
  776. //closest to start.  Moves end to the point of intersection.  Returns -1 if no intersection.
  777. //Line segment must be in volume space.
  778. S32 lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
  779.  S32 face = -1,                          // which face to check, -1 = ALL_SIDES
  780.  LLVector3* intersection = NULL,         // return the intersection point
  781.  LLVector2* tex_coord = NULL,            // return the texture coordinates of the intersection point
  782.  LLVector3* normal = NULL,               // return the surface normal at the intersection point
  783.  LLVector3* bi_normal = NULL             // return the surface bi-normal at the intersection point
  784. );
  785. // The following cleans up vertices and triangles,
  786. // getting rid of degenerate triangles and duplicate vertices,
  787. // and allocates new arrays with the clean data.
  788. static BOOL cleanupTriangleData( const S32 num_input_vertices,
  789. const std::vector<Point> &input_vertices,
  790. const S32 num_input_triangles,
  791. S32 *input_triangles,
  792. S32 &num_output_vertices,
  793. LLVector3 **output_vertices,
  794. S32 &num_output_triangles,
  795. S32 **output_triangles);
  796. LLFaceID generateFaceMask();
  797. BOOL isFaceMaskValid(LLFaceID face_mask);
  798. static S32 sNumMeshPoints;
  799. friend std::ostream& operator<<(std::ostream &s, const LLVolume &volume);
  800. friend std::ostream& operator<<(std::ostream &s, const LLVolume *volumep); // HACK to bypass Windoze confusion over 
  801. // conversion if *(LLVolume*) to LLVolume&
  802. const LLVolumeFace &getVolumeFace(const S32 f) const {return mVolumeFaces[f];} // DO NOT DELETE VOLUME WHILE USING THIS REFERENCE, OR HOLD A POINTER TO THIS VOLUMEFACE
  803. U32 mFaceMask; // bit array of which faces exist in this volume
  804. LLVector3 mLODScaleBias; // vector for biasing LOD based on scale
  805. void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level);
  806. private:
  807. void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type);
  808. F32 sculptGetSurfaceArea();
  809. void sculptGeneratePlaceholder();
  810. void sculptCalcMeshResolution(U16 width, U16 height, U8 type, S32& s, S32& t);
  811. protected:
  812. BOOL generate();
  813. void createVolumeFaces();
  814.  protected:
  815. BOOL mUnique;
  816. F32 mDetail;
  817. S32 mSculptLevel;
  818. LLVolumeParams mParams;
  819. LLPath *mPathp;
  820. LLProfile *mProfilep;
  821. std::vector<Point> mMesh;
  822. BOOL mGenerateSingleFace;
  823. typedef std::vector<LLVolumeFace> face_list_t;
  824. face_list_t mVolumeFaces;
  825. };
  826. std::ostream& operator<<(std::ostream &s, const LLVolumeParams &volume_params);
  827. LLVector3 calc_binormal_from_triangle(
  828. const LLVector3& pos0,
  829. const LLVector2& tex0,
  830. const LLVector3& pos1,
  831. const LLVector2& tex1,
  832. const LLVector3& pos2,
  833. const LLVector2& tex2);
  834. BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size);
  835. BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
  836. F32* intersection_a, F32* intersection_b, F32* intersection_t, BOOL two_sided);
  837. #endif