diff options
author | Jacek Antonelli | 2008-08-15 23:45:42 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:42 -0500 |
commit | ce28e056c20bf2723f565bbf464b87781ec248a2 (patch) | |
tree | ef7b0501c4de4b631a916305cbc2a5fdc125e52d /linden/indra/llprimitive | |
parent | Second Life viewer sources 1.19.1.4b (diff) | |
download | meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.zip meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.gz meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.bz2 meta-impy-ce28e056c20bf2723f565bbf464b87781ec248a2.tar.xz |
Second Life viewer sources 1.20.2
Diffstat (limited to 'linden/indra/llprimitive')
-rw-r--r-- | linden/indra/llprimitive/llmaterialtable.cpp | 48 | ||||
-rw-r--r-- | linden/indra/llprimitive/llmaterialtable.h | 57 | ||||
-rw-r--r-- | linden/indra/llprimitive/llprimitive.cpp | 45 | ||||
-rw-r--r-- | linden/indra/llprimitive/llprimitive.h | 54 | ||||
-rw-r--r-- | linden/indra/llprimitive/llprimitive.vcproj | 15 | ||||
-rw-r--r-- | linden/indra/llprimitive/llprimlinkinfo.h | 388 |
6 files changed, 586 insertions, 21 deletions
diff --git a/linden/indra/llprimitive/llmaterialtable.cpp b/linden/indra/llprimitive/llmaterialtable.cpp index 537c968..5e45e44 100644 --- a/linden/indra/llprimitive/llmaterialtable.cpp +++ b/linden/indra/llprimitive/llmaterialtable.cpp | |||
@@ -39,6 +39,54 @@ | |||
39 | 39 | ||
40 | LLMaterialTable LLMaterialTable::basic(1); | 40 | LLMaterialTable LLMaterialTable::basic(1); |
41 | 41 | ||
42 | /* | ||
43 | Old Havok 1 constants | ||
44 | |||
45 | // these are the approximately correct friction values for various materials | ||
46 | // however Havok1's friction dynamics are not very correct, so the effective | ||
47 | // friction coefficients that result from these numbers are approximately | ||
48 | // 25-50% too low, more incorrect for the lower values. | ||
49 | F32 const LLMaterialTable::FRICTION_MIN = 0.2f; | ||
50 | F32 const LLMaterialTable::FRICTION_GLASS = 0.2f; // borosilicate glass | ||
51 | F32 const LLMaterialTable::FRICTION_LIGHT = 0.2f; // | ||
52 | F32 const LLMaterialTable::FRICTION_METAL = 0.3f; // steel | ||
53 | F32 const LLMaterialTable::FRICTION_PLASTIC = 0.4f; // HDPE | ||
54 | F32 const LLMaterialTable::FRICTION_WOOD = 0.6f; // southern pine | ||
55 | F32 const LLMaterialTable::FRICTION_FLESH = 0.60f; // saltwater | ||
56 | F32 const LLMaterialTable::FRICTION_LAND = 0.78f; // dirt | ||
57 | F32 const LLMaterialTable::FRICTION_STONE = 0.8f; // concrete | ||
58 | F32 const LLMaterialTable::FRICTION_RUBBER = 0.9f; // | ||
59 | F32 const LLMaterialTable::FRICTION_MAX = 0.95f; // | ||
60 | */ | ||
61 | |||
62 | // #if LL_CURRENT_HAVOK_VERSION == LL_HAVOK_VERSION_460 | ||
63 | // Havok4 has more correct friction dynamics, however here we have to use | ||
64 | // the "incorrect" equivalents for the legacy Havok1 behavior | ||
65 | F32 const LLMaterialTable::FRICTION_MIN = 0.15f; | ||
66 | F32 const LLMaterialTable::FRICTION_GLASS = 0.13f; // borosilicate glass | ||
67 | F32 const LLMaterialTable::FRICTION_LIGHT = 0.14f; // | ||
68 | F32 const LLMaterialTable::FRICTION_METAL = 0.22f; // steel | ||
69 | F32 const LLMaterialTable::FRICTION_PLASTIC = 0.3f; // HDPE | ||
70 | F32 const LLMaterialTable::FRICTION_WOOD = 0.44f; // southern pine | ||
71 | F32 const LLMaterialTable::FRICTION_FLESH = 0.46f; // saltwater | ||
72 | F32 const LLMaterialTable::FRICTION_LAND = 0.58f; // dirt | ||
73 | F32 const LLMaterialTable::FRICTION_STONE = 0.6f; // concrete | ||
74 | F32 const LLMaterialTable::FRICTION_RUBBER = 0.67f; // | ||
75 | F32 const LLMaterialTable::FRICTION_MAX = 0.71f; // | ||
76 | // #endif | ||
77 | |||
78 | F32 const LLMaterialTable::RESTITUTION_MIN = 0.02f; | ||
79 | F32 const LLMaterialTable::RESTITUTION_LAND = LLMaterialTable::RESTITUTION_MIN; | ||
80 | F32 const LLMaterialTable::RESTITUTION_FLESH = 0.2f; // saltwater | ||
81 | F32 const LLMaterialTable::RESTITUTION_STONE = 0.4f; // concrete | ||
82 | F32 const LLMaterialTable::RESTITUTION_METAL = 0.4f; // steel | ||
83 | F32 const LLMaterialTable::RESTITUTION_WOOD = 0.5f; // southern pine | ||
84 | F32 const LLMaterialTable::RESTITUTION_GLASS = 0.7f; // borosilicate glass | ||
85 | F32 const LLMaterialTable::RESTITUTION_PLASTIC = 0.7f; // HDPE | ||
86 | F32 const LLMaterialTable::RESTITUTION_LIGHT = 0.7f; // | ||
87 | F32 const LLMaterialTable::RESTITUTION_RUBBER = 0.9f; // | ||
88 | F32 const LLMaterialTable::RESTITUTION_MAX = 0.95f; | ||
89 | |||
42 | F32 const LLMaterialTable::DEFAULT_FRICTION = 0.5f; | 90 | F32 const LLMaterialTable::DEFAULT_FRICTION = 0.5f; |
43 | F32 const LLMaterialTable::DEFAULT_RESTITUTION = 0.4f; | 91 | F32 const LLMaterialTable::DEFAULT_RESTITUTION = 0.4f; |
44 | 92 | ||
diff --git a/linden/indra/llprimitive/llmaterialtable.h b/linden/indra/llprimitive/llmaterialtable.h index b48c832..863fb25 100644 --- a/linden/indra/llprimitive/llmaterialtable.h +++ b/linden/indra/llprimitive/llmaterialtable.h | |||
@@ -33,11 +33,36 @@ | |||
33 | #define LL_LLMATERIALTABLE_H | 33 | #define LL_LLMATERIALTABLE_H |
34 | 34 | ||
35 | #include "lluuid.h" | 35 | #include "lluuid.h" |
36 | #include "linked_lists.h" | ||
37 | #include "llstring.h" | 36 | #include "llstring.h" |
38 | 37 | ||
38 | #include <list> | ||
39 | |||
39 | const U32 LLMATERIAL_INFO_NAME_LENGTH = 256; | 40 | const U32 LLMATERIAL_INFO_NAME_LENGTH = 256; |
40 | 41 | ||
42 | // We've moved toward more reasonable mass values for the Havok4 engine. | ||
43 | // The LEGACY_DEFAULT_OBJECT_DENSITY is used to maintain support for | ||
44 | // legacy scripts code (llGetMass()) and script energy consumption. | ||
45 | const F32 DEFAULT_OBJECT_DENSITY = 1000.0f; // per m^3 | ||
46 | const F32 LEGACY_DEFAULT_OBJECT_DENSITY = 10.0f; | ||
47 | |||
48 | // Avatars density depends on the collision shape used. The approximate | ||
49 | // legacy volumes of avatars are: | ||
50 | // Body_Length Body_Width Body_Fat Leg_Length Volume(m^3) | ||
51 | // ------------------------------------------------------- | ||
52 | // min | min | min | min | 0.123 | | ||
53 | // max | max | max | max | 0.208 | | ||
54 | // | ||
55 | // Either the avatar shape must be tweaked to match those volumes | ||
56 | // or the DEFAULT_AVATAR_DENSITY must be adjusted to achieve the | ||
57 | // legacy mass. | ||
58 | // | ||
59 | // The current density appears to be low because the mass and | ||
60 | // inertia are computed as if the avatar were a cylinder which | ||
61 | // has more volume than the actual collision shape of the avatar. | ||
62 | // See the physics engine mass properties code for more info. | ||
63 | const F32 DEFAULT_AVATAR_DENSITY = 445.3f; // was 444.24f; | ||
64 | |||
65 | |||
41 | class LLMaterialInfo | 66 | class LLMaterialInfo |
42 | { | 67 | { |
43 | public: | 68 | public: |
@@ -84,9 +109,33 @@ public: | |||
84 | class LLMaterialTable | 109 | class LLMaterialTable |
85 | { | 110 | { |
86 | public: | 111 | public: |
112 | static const F32 FRICTION_MIN; | ||
113 | static const F32 FRICTION_GLASS; | ||
114 | static const F32 FRICTION_LIGHT; | ||
115 | static const F32 FRICTION_METAL; | ||
116 | static const F32 FRICTION_PLASTIC; | ||
117 | static const F32 FRICTION_WOOD; | ||
118 | static const F32 FRICTION_LAND; | ||
119 | static const F32 FRICTION_STONE; | ||
120 | static const F32 FRICTION_FLESH; | ||
121 | static const F32 FRICTION_RUBBER; | ||
122 | static const F32 FRICTION_MAX; | ||
123 | |||
124 | static const F32 RESTITUTION_MIN; | ||
125 | static const F32 RESTITUTION_LAND; | ||
126 | static const F32 RESTITUTION_FLESH; | ||
127 | static const F32 RESTITUTION_STONE; | ||
128 | static const F32 RESTITUTION_METAL; | ||
129 | static const F32 RESTITUTION_WOOD; | ||
130 | static const F32 RESTITUTION_GLASS; | ||
131 | static const F32 RESTITUTION_PLASTIC; | ||
132 | static const F32 RESTITUTION_LIGHT; | ||
133 | static const F32 RESTITUTION_RUBBER; | ||
134 | static const F32 RESTITUTION_MAX; | ||
135 | |||
87 | typedef std::list<LLMaterialInfo*> info_list_t; | 136 | typedef std::list<LLMaterialInfo*> info_list_t; |
88 | info_list_t mMaterialInfoList; | 137 | info_list_t mMaterialInfoList; |
89 | 138 | ||
90 | LLUUID *mCollisionSoundMatrix; | 139 | LLUUID *mCollisionSoundMatrix; |
91 | LLUUID *mSlidingSoundMatrix; | 140 | LLUUID *mSlidingSoundMatrix; |
92 | LLUUID *mRollingSoundMatrix; | 141 | LLUUID *mRollingSoundMatrix; |
@@ -117,8 +166,8 @@ public: | |||
117 | char* getName(U8 mcode); | 166 | char* getName(U8 mcode); |
118 | 167 | ||
119 | F32 getDensity(U8 mcode); // kg/m^3, 0 if not found | 168 | F32 getDensity(U8 mcode); // kg/m^3, 0 if not found |
120 | F32 getFriction(U8 mcode); // havok values | 169 | F32 getFriction(U8 mcode); // physics values |
121 | F32 getRestitution(U8 mcode); // havok values | 170 | F32 getRestitution(U8 mcode); // physics values |
122 | F32 getHPMod(U8 mcode); | 171 | F32 getHPMod(U8 mcode); |
123 | F32 getDamageMod(U8 mcode); | 172 | F32 getDamageMod(U8 mcode); |
124 | F32 getEPMod(U8 mcode); | 173 | F32 getEPMod(U8 mcode); |
diff --git a/linden/indra/llprimitive/llprimitive.cpp b/linden/indra/llprimitive/llprimitive.cpp index 91d3c4e..a906926 100644 --- a/linden/indra/llprimitive/llprimitive.cpp +++ b/linden/indra/llprimitive/llprimitive.cpp | |||
@@ -113,9 +113,38 @@ const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE; | |||
113 | 113 | ||
114 | const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e"; | 114 | const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e"; |
115 | 115 | ||
116 | //static | ||
117 | // LEGACY: by default we use the LLVolumeMgr::gVolumeMgr global | ||
118 | // TODO -- eliminate this global from the codebase! | ||
119 | LLVolumeMgr* LLPrimitive::sVolumeManager = NULL; | ||
120 | |||
121 | // static | ||
122 | void LLPrimitive::setVolumeManager( LLVolumeMgr* volume_manager ) | ||
123 | { | ||
124 | if ( !volume_manager || sVolumeManager ) | ||
125 | { | ||
126 | llerrs << "Unable to set LLPrimitive::sVolumeManager to NULL" << llendl; | ||
127 | } | ||
128 | sVolumeManager = volume_manager; | ||
129 | } | ||
130 | |||
131 | // static | ||
132 | bool LLPrimitive::cleanupVolumeManager() | ||
133 | { | ||
134 | BOOL res = FALSE; | ||
135 | if (sVolumeManager) | ||
136 | { | ||
137 | res = sVolumeManager->cleanup(); | ||
138 | delete sVolumeManager; | ||
139 | sVolumeManager = NULL; | ||
140 | } | ||
141 | return res; | ||
142 | } | ||
143 | |||
116 | 144 | ||
117 | //=============================================================== | 145 | //=============================================================== |
118 | LLPrimitive::LLPrimitive() | 146 | LLPrimitive::LLPrimitive() |
147 | : mMiscFlags(0) | ||
119 | { | 148 | { |
120 | mPrimitiveCode = 0; | 149 | mPrimitiveCode = 0; |
121 | 150 | ||
@@ -149,7 +178,7 @@ LLPrimitive::~LLPrimitive() | |||
149 | // Cleanup handled by volume manager | 178 | // Cleanup handled by volume manager |
150 | if (mVolumep) | 179 | if (mVolumep) |
151 | { | 180 | { |
152 | gVolumeMgr->cleanupVolume(mVolumep); | 181 | sVolumeManager->cleanupVolume(mVolumep); |
153 | } | 182 | } |
154 | mVolumep = NULL; | 183 | mVolumep = NULL; |
155 | } | 184 | } |
@@ -162,7 +191,7 @@ LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) | |||
162 | 191 | ||
163 | if (retval) | 192 | if (retval) |
164 | { | 193 | { |
165 | retval->init(p_code); | 194 | retval->init_primitive(p_code); |
166 | } | 195 | } |
167 | else | 196 | else |
168 | { | 197 | { |
@@ -173,7 +202,7 @@ LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) | |||
173 | } | 202 | } |
174 | 203 | ||
175 | //=============================================================== | 204 | //=============================================================== |
176 | void LLPrimitive::init(LLPCode p_code) | 205 | void LLPrimitive::init_primitive(LLPCode p_code) |
177 | { | 206 | { |
178 | if (mNumTEs) | 207 | if (mNumTEs) |
179 | { | 208 | { |
@@ -533,6 +562,8 @@ S32 LLPrimitive::setTEGlow(const U8 te, const F32 glow) | |||
533 | 562 | ||
534 | LLPCode LLPrimitive::legacyToPCode(const U8 legacy) | 563 | LLPCode LLPrimitive::legacyToPCode(const U8 legacy) |
535 | { | 564 | { |
565 | // TODO: Should this default to something valid? | ||
566 | // Maybe volume? | ||
536 | LLPCode pcode = 0; | 567 | LLPCode pcode = 0; |
537 | 568 | ||
538 | switch (legacy) | 569 | switch (legacy) |
@@ -621,7 +652,7 @@ LLPCode LLPrimitive::legacyToPCode(const U8 legacy) | |||
621 | pcode = LL_PCODE_TREE_NEW; | 652 | pcode = LL_PCODE_TREE_NEW; |
622 | break; | 653 | break; |
623 | default: | 654 | default: |
624 | llwarns << "Unknown legacy code " << legacy << "!" << llendl; | 655 | llwarns << "Unknown legacy code " << legacy << " [" << (S32)legacy << "]!" << llendl; |
625 | } | 656 | } |
626 | 657 | ||
627 | return pcode; | 658 | return pcode; |
@@ -904,10 +935,10 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai | |||
904 | } | 935 | } |
905 | } | 936 | } |
906 | 937 | ||
907 | volumep = gVolumeMgr->getVolume(volume_params, detail); | 938 | volumep = sVolumeManager->getVolume(volume_params, detail); |
908 | if (volumep == mVolumep) | 939 | if (volumep == mVolumep) |
909 | { | 940 | { |
910 | gVolumeMgr->cleanupVolume( volumep ); // gVolumeMgr->getVolume() creates a reference, but we don't need a second one. | 941 | sVolumeManager->cleanupVolume( volumep ); // LLVolumeMgr::getVolume() creates a reference, but we don't need a second one. |
911 | return TRUE; | 942 | return TRUE; |
912 | } | 943 | } |
913 | } | 944 | } |
@@ -950,7 +981,7 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai | |||
950 | 981 | ||
951 | 982 | ||
952 | // build the new object | 983 | // build the new object |
953 | gVolumeMgr->cleanupVolume(mVolumep); | 984 | sVolumeManager->cleanupVolume(mVolumep); |
954 | mVolumep = volumep; | 985 | mVolumep = volumep; |
955 | 986 | ||
956 | U32 new_face_mask = mVolumep->mFaceMask; | 987 | U32 new_face_mask = mVolumep->mFaceMask; |
diff --git a/linden/indra/llprimitive/llprimitive.h b/linden/indra/llprimitive/llprimitive.h index 3b43e8f..e698a31 100644 --- a/linden/indra/llprimitive/llprimitive.h +++ b/linden/indra/llprimitive/llprimitive.h | |||
@@ -48,6 +48,7 @@ class LLColor4; | |||
48 | class LLColor3; | 48 | class LLColor3; |
49 | class LLTextureEntry; | 49 | class LLTextureEntry; |
50 | class LLDataPacker; | 50 | class LLDataPacker; |
51 | class LLVolumeMgr; | ||
51 | 52 | ||
52 | enum LLGeomType // NOTE: same vals as GL Ids | 53 | enum LLGeomType // NOTE: same vals as GL Ids |
53 | { | 54 | { |
@@ -269,11 +270,32 @@ public: | |||
269 | class LLPrimitive : public LLXform | 270 | class LLPrimitive : public LLXform |
270 | { | 271 | { |
271 | public: | 272 | public: |
273 | |||
274 | // HACK for removing LLPrimitive's dependency on gVolumeMgr global. | ||
275 | // If a different LLVolumeManager is instantiated and set early enough | ||
276 | // then the LLPrimitive class will use it instead of gVolumeMgr. | ||
277 | static LLVolumeMgr* getVolumeManager() { return sVolumeManager; } | ||
278 | static void setVolumeManager( LLVolumeMgr* volume_manager); | ||
279 | static bool cleanupVolumeManager(); | ||
280 | |||
281 | // these flags influence how the RigidBody representation is built | ||
282 | static const U32 PRIM_FLAG_PHANTOM = 0x1 << 0; | ||
283 | static const U32 PRIM_FLAG_VOLUME_DETECT = 0x1 << 1; | ||
284 | static const U32 PRIM_FLAG_DYNAMIC = 0x1 << 2; | ||
285 | static const U32 PRIM_FLAG_AVATAR = 0x1 << 3; | ||
286 | static const U32 PRIM_FLAG_SCULPT = 0x1 << 4; | ||
287 | // not used yet, but soon | ||
288 | static const U32 PRIM_FLAG_COLLISION_CALLBACK = 0x1 << 5; | ||
289 | static const U32 PRIM_FLAG_CONVEX = 0x1 << 6; | ||
290 | static const U32 PRIM_FLAG_DEFAULT_VOLUME = 0x1 << 7; | ||
291 | static const U32 PRIM_FLAG_SITTING = 0x1 << 8; | ||
292 | static const U32 PRIM_FLAG_SITTING_ON_GROUND = 0x1 << 9; // Set along with PRIM_FLAG_SITTING | ||
293 | |||
272 | LLPrimitive(); | 294 | LLPrimitive(); |
273 | virtual ~LLPrimitive(); | 295 | virtual ~LLPrimitive(); |
274 | 296 | ||
275 | static LLPrimitive *createPrimitive(LLPCode p_code); | 297 | static LLPrimitive *createPrimitive(LLPCode p_code); |
276 | void init(LLPCode p_code); | 298 | void init_primitive(LLPCode p_code); |
277 | 299 | ||
278 | void setPCode(const LLPCode pcode); | 300 | void setPCode(const LLPCode pcode); |
279 | const LLVolume *getVolumeConst() const { return mVolumep; } // HACK for Windoze confusion about ostream operator in LLVolume | 301 | const LLVolume *getVolumeConst() const { return mVolumep; } // HACK for Windoze confusion about ostream operator in LLVolume |
@@ -369,8 +391,15 @@ public: | |||
369 | 391 | ||
370 | void setTextureList(LLTextureEntry *listp); | 392 | void setTextureList(LLTextureEntry *listp); |
371 | 393 | ||
372 | inline BOOL isAvatar() const; | 394 | inline BOOL isAvatar() const; |
373 | 395 | inline BOOL isSittingAvatar() const; | |
396 | inline BOOL isSittingAvatarOnGround() const; | ||
397 | |||
398 | void setFlags(U32 flags) { mMiscFlags = flags; } | ||
399 | void addFlags(U32 flags) { mMiscFlags |= flags; } | ||
400 | void removeFlags(U32 flags) { mMiscFlags &= ~flags; } | ||
401 | U32 getFlags() const { return mMiscFlags; } | ||
402 | |||
374 | static const char *pCodeToString(const LLPCode pcode); | 403 | static const char *pCodeToString(const LLPCode pcode); |
375 | static LLPCode legacyToPCode(const U8 legacy); | 404 | static LLPCode legacyToPCode(const U8 legacy); |
376 | static U8 pCodeToLegacy(const LLPCode pcode); | 405 | static U8 pCodeToLegacy(const LLPCode pcode); |
@@ -388,11 +417,28 @@ protected: | |||
388 | LLTextureEntry *mTextureList; // list of texture GUIDs, scales, offsets | 417 | LLTextureEntry *mTextureList; // list of texture GUIDs, scales, offsets |
389 | U8 mMaterial; // Material code | 418 | U8 mMaterial; // Material code |
390 | U8 mNumTEs; // # of faces on the primitve | 419 | U8 mNumTEs; // # of faces on the primitve |
420 | U32 mMiscFlags; // home for misc bools | ||
421 | |||
422 | static LLVolumeMgr* sVolumeManager; | ||
391 | }; | 423 | }; |
392 | 424 | ||
393 | inline BOOL LLPrimitive::isAvatar() const | 425 | inline BOOL LLPrimitive::isAvatar() const |
394 | { | 426 | { |
395 | return mPrimitiveCode == LL_PCODE_LEGACY_AVATAR; | 427 | return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode ) ? TRUE : FALSE; |
428 | } | ||
429 | |||
430 | inline BOOL LLPrimitive::isSittingAvatar() const | ||
431 | { | ||
432 | // this is only used server-side | ||
433 | return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode | ||
434 | && ((getFlags() & (PRIM_FLAG_SITTING | PRIM_FLAG_SITTING_ON_GROUND)) != 0) ) ? TRUE : FALSE; | ||
435 | } | ||
436 | |||
437 | inline BOOL LLPrimitive::isSittingAvatarOnGround() const | ||
438 | { | ||
439 | // this is only used server-side | ||
440 | return ( LL_PCODE_LEGACY_AVATAR == mPrimitiveCode | ||
441 | && ((getFlags() & PRIM_FLAG_SITTING_ON_GROUND) != 0) ) ? TRUE : FALSE; | ||
396 | } | 442 | } |
397 | 443 | ||
398 | // static | 444 | // static |
diff --git a/linden/indra/llprimitive/llprimitive.vcproj b/linden/indra/llprimitive/llprimitive.vcproj index b04d938..620ace4 100644 --- a/linden/indra/llprimitive/llprimitive.vcproj +++ b/linden/indra/llprimitive/llprimitive.vcproj | |||
@@ -19,8 +19,8 @@ | |||
19 | <Tool | 19 | <Tool |
20 | Name="VCCLCompilerTool" | 20 | Name="VCCLCompilerTool" |
21 | Optimization="0" | 21 | Optimization="0" |
22 | AdditionalIncludeDirectories="..\llxml;..\llprimitive;..\llcommon;..\llmath;..\llmessage;..\..\libraries\i686-win32\include;..\..\libraries\include\" | 22 | AdditionalIncludeDirectories="..\;..\llxml;..\llprimitive;..\llcommon;..\llmath;..\llmessage;..\..\libraries\i686-win32\include;..\..\libraries\include" |
23 | PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;LL_DEBUG" | 23 | PreprocessorDefinitions="WIN32;_DEBUG;_LIB;LL_WINDOWS;LL_DEBUG;LL_CURRENT_HAVOK_VERSION=460" |
24 | MinimalRebuild="TRUE" | 24 | MinimalRebuild="TRUE" |
25 | BasicRuntimeChecks="3" | 25 | BasicRuntimeChecks="3" |
26 | RuntimeLibrary="1" | 26 | RuntimeLibrary="1" |
@@ -64,8 +64,8 @@ | |||
64 | <Tool | 64 | <Tool |
65 | Name="VCCLCompilerTool" | 65 | Name="VCCLCompilerTool" |
66 | AdditionalOptions="/Oy-" | 66 | AdditionalOptions="/Oy-" |
67 | AdditionalIncludeDirectories="..\llxml;..\llprimitive;..\llcommon;..\llmath;..\llmessage;..\..\libraries\i686-win32\include;..\..\libraries\include\" | 67 | AdditionalIncludeDirectories="..\;..\llxml;..\llprimitive;..\llcommon;..\llmath;..\llmessage;..\..\libraries\i686-win32\include;..\..\libraries\include\" |
68 | PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE" | 68 | PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE;LL_CURRENT_HAVOK_VERSION=460" |
69 | RuntimeLibrary="0" | 69 | RuntimeLibrary="0" |
70 | StructMemberAlignment="0" | 70 | StructMemberAlignment="0" |
71 | ForceConformanceInForLoopScope="TRUE" | 71 | ForceConformanceInForLoopScope="TRUE" |
@@ -108,8 +108,8 @@ | |||
108 | Name="VCCLCompilerTool" | 108 | Name="VCCLCompilerTool" |
109 | AdditionalOptions="/Oy-" | 109 | AdditionalOptions="/Oy-" |
110 | Optimization="0" | 110 | Optimization="0" |
111 | AdditionalIncludeDirectories="..\llxml;..\llprimitive;..\llcommon;..\llmath;..\llmessage;..\..\libraries\i686-win32\include;..\..\libraries\include\" | 111 | AdditionalIncludeDirectories="..\;..\llxml;..\llprimitive;..\llcommon;..\llmath;..\llmessage;..\..\libraries\i686-win32\include;..\..\libraries\include" |
112 | PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE" | 112 | PreprocessorDefinitions="WIN32;NDEBUG;_LIB;LL_WINDOWS;LL_RELEASE;LL_CURRENT_HAVOK_VERSION=460" |
113 | RuntimeLibrary="0" | 113 | RuntimeLibrary="0" |
114 | StructMemberAlignment="0" | 114 | StructMemberAlignment="0" |
115 | ForceConformanceInForLoopScope="TRUE" | 115 | ForceConformanceInForLoopScope="TRUE" |
@@ -186,6 +186,9 @@ | |||
186 | RelativePath=".\llprimitive.h"> | 186 | RelativePath=".\llprimitive.h"> |
187 | </File> | 187 | </File> |
188 | <File | 188 | <File |
189 | RelativePath=".\llprimlinkinfo.h"> | ||
190 | </File> | ||
191 | <File | ||
189 | RelativePath=".\lltextureanim.h"> | 192 | RelativePath=".\lltextureanim.h"> |
190 | </File> | 193 | </File> |
191 | <File | 194 | <File |
diff --git a/linden/indra/llprimitive/llprimlinkinfo.h b/linden/indra/llprimitive/llprimlinkinfo.h new file mode 100644 index 0000000..8de5ca0 --- /dev/null +++ b/linden/indra/llprimitive/llprimlinkinfo.h | |||
@@ -0,0 +1,388 @@ | |||
1 | /** | ||
2 | * @file llprimlinkinfo.h | ||
3 | * @author andrew@lindenlab.com | ||
4 | * @brief A template for determining which prims in a set are linkable | ||
5 | * | ||
6 | * $LicenseInfo:firstyear=2007&license=internal$ | ||
7 | * | ||
8 | * Copyright (c) 2007-2008, Linden Research, Inc. | ||
9 | * | ||
10 | * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of | ||
11 | * this source code is governed by the Linden Lab Source Code Disclosure | ||
12 | * Agreement ("Agreement") previously entered between you and Linden | ||
13 | * Lab. By accessing, using, copying, modifying or distributing this | ||
14 | * software, you acknowledge that you have been informed of your | ||
15 | * obligations under the Agreement and agree to abide by those obligations. | ||
16 | * | ||
17 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
18 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
19 | * COMPLETENESS OR PERFORMANCE. | ||
20 | * $/LicenseInfo$ | ||
21 | */ | ||
22 | |||
23 | |||
24 | #ifndef LL_PRIM_LINK_INFO_H | ||
25 | #define LL_PRIM_LINK_INFO_H | ||
26 | |||
27 | // system includes | ||
28 | #include <iostream> | ||
29 | #include <map> | ||
30 | #include <list> | ||
31 | #include <vector> | ||
32 | |||
33 | // common includes | ||
34 | #include "stdtypes.h" | ||
35 | #include "v3math.h" | ||
36 | #include "llquaternion.h" | ||
37 | #include "llsphere.h" | ||
38 | |||
39 | |||
40 | const F32 MAX_OBJECT_SPAN = 54.f; // max distance from outside edge of an object to the farthest edge | ||
41 | const F32 OBJECT_SPAN_BONUS = 2.f; // infinitesimally small prims can always link up to this distance | ||
42 | const S32 MAX_PRIMS_PER_OBJECT = 255; | ||
43 | |||
44 | |||
45 | template < typename DATA_TYPE > | ||
46 | class LLPrimLinkInfo | ||
47 | { | ||
48 | public: | ||
49 | LLPrimLinkInfo(); | ||
50 | LLPrimLinkInfo( DATA_TYPE data, const LLSphere& sphere ); | ||
51 | ~LLPrimLinkInfo(); | ||
52 | |||
53 | void set( DATA_TYPE data, const LLSphere& sphere ); | ||
54 | void append( DATA_TYPE data, const LLSphere& sphere ); | ||
55 | void getData( std::list< DATA_TYPE >& data_list ) const; | ||
56 | F32 getDiameter() const; | ||
57 | LLVector3 getCenter() const; | ||
58 | |||
59 | // returns 'true' if this info can link with other_info | ||
60 | bool canLink( const LLPrimLinkInfo< DATA_TYPE >& other_info ); | ||
61 | |||
62 | S32 getPrimCount() const { return mDataMap.size(); } | ||
63 | |||
64 | void mergeLinkableSet( typename std::list< LLPrimLinkInfo < DATA_TYPE > >& unlinked ); | ||
65 | |||
66 | void transform(const LLVector3& position, const LLQuaternion& rotation); | ||
67 | |||
68 | private: | ||
69 | // returns number of merges made | ||
70 | S32 merge(LLPrimLinkInfo< DATA_TYPE >& other_info); | ||
71 | |||
72 | // returns number of collapses made | ||
73 | static S32 collapse(typename std::list< LLPrimLinkInfo < DATA_TYPE > >& unlinked ); | ||
74 | |||
75 | void computeBoundingSphere(); | ||
76 | |||
77 | // Internal utility to encapsulate the link rules | ||
78 | F32 get_max_linkable_span(const LLSphere& first, const LLSphere& second); | ||
79 | F32 get_span(const LLSphere& first, const LLSphere& second); | ||
80 | |||
81 | private: | ||
82 | std::map< DATA_TYPE, LLSphere > mDataMap; | ||
83 | LLSphere mBoundingSphere; | ||
84 | }; | ||
85 | |||
86 | |||
87 | |||
88 | template < typename DATA_TYPE > | ||
89 | LLPrimLinkInfo< DATA_TYPE >::LLPrimLinkInfo() | ||
90 | : mBoundingSphere( LLVector3(0.f, 0.f, 0.f), 0.f ) | ||
91 | { | ||
92 | } | ||
93 | |||
94 | template < typename DATA_TYPE > | ||
95 | LLPrimLinkInfo< DATA_TYPE >::LLPrimLinkInfo( DATA_TYPE data, const LLSphere& sphere) | ||
96 | : mBoundingSphere(sphere) | ||
97 | { | ||
98 | mDataMap[data] = sphere; | ||
99 | } | ||
100 | |||
101 | template < typename DATA_TYPE > | ||
102 | LLPrimLinkInfo< DATA_TYPE >::~LLPrimLinkInfo() | ||
103 | { | ||
104 | mDataMap.clear(); | ||
105 | } | ||
106 | |||
107 | template < typename DATA_TYPE > | ||
108 | void LLPrimLinkInfo< DATA_TYPE>::set( DATA_TYPE data, const LLSphere& sphere ) | ||
109 | { | ||
110 | if (!mDataMap.empty()) | ||
111 | { | ||
112 | mDataMap.clear(); | ||
113 | } | ||
114 | mDataMap[data] = sphere; | ||
115 | mBoundingSphere = sphere; | ||
116 | } | ||
117 | |||
118 | template < typename DATA_TYPE > | ||
119 | void LLPrimLinkInfo< DATA_TYPE>::append( DATA_TYPE data, const LLSphere& sphere ) | ||
120 | { | ||
121 | mDataMap[data] = sphere; | ||
122 | if (!mBoundingSphere.contains(sphere)) | ||
123 | { | ||
124 | computeBoundingSphere(); | ||
125 | } | ||
126 | } | ||
127 | |||
128 | template < typename DATA_TYPE > | ||
129 | void LLPrimLinkInfo< DATA_TYPE >::getData( std::list< DATA_TYPE >& data_list) const | ||
130 | { | ||
131 | typename std::map< DATA_TYPE, LLSphere >::const_iterator map_itr; | ||
132 | for (map_itr = mDataMap.begin(); map_itr != mDataMap.end(); ++map_itr) | ||
133 | { | ||
134 | data_list.push_back(map_itr->first); | ||
135 | } | ||
136 | } | ||
137 | |||
138 | template < typename DATA_TYPE > | ||
139 | F32 LLPrimLinkInfo< DATA_TYPE >::getDiameter() const | ||
140 | { | ||
141 | return 2.f * mBoundingSphere.getRadius(); | ||
142 | } | ||
143 | |||
144 | template < typename DATA_TYPE > | ||
145 | LLVector3 LLPrimLinkInfo< DATA_TYPE >::getCenter() const | ||
146 | { | ||
147 | return mBoundingSphere.getCenter(); | ||
148 | } | ||
149 | |||
150 | template < typename DATA_TYPE > | ||
151 | F32 LLPrimLinkInfo< DATA_TYPE >::get_max_linkable_span(const LLSphere& first, const LLSphere& second) | ||
152 | { | ||
153 | F32 max_span = 3.f * (first.getRadius() + second.getRadius()) + OBJECT_SPAN_BONUS; | ||
154 | if (max_span > MAX_OBJECT_SPAN) | ||
155 | { | ||
156 | max_span = MAX_OBJECT_SPAN; | ||
157 | } | ||
158 | |||
159 | return max_span; | ||
160 | } | ||
161 | |||
162 | template < typename DATA_TYPE > | ||
163 | F32 LLPrimLinkInfo< DATA_TYPE >::get_span(const LLSphere& first, const LLSphere& second) | ||
164 | { | ||
165 | F32 span = (first.getCenter() - second.getCenter()).length() | ||
166 | + first.getRadius() + second.getRadius(); | ||
167 | return span; | ||
168 | } | ||
169 | |||
170 | // static | ||
171 | // returns 'true' if this info can link with any part of other_info | ||
172 | template < typename DATA_TYPE > | ||
173 | bool LLPrimLinkInfo< DATA_TYPE >::canLink(const LLPrimLinkInfo& other_info) | ||
174 | { | ||
175 | F32 max_span = get_max_linkable_span(mBoundingSphere, other_info.mBoundingSphere); | ||
176 | |||
177 | F32 span = get_span(mBoundingSphere, other_info.mBoundingSphere); | ||
178 | |||
179 | if (span <= max_span) | ||
180 | { | ||
181 | // The entire other_info fits inside the max span. | ||
182 | return TRUE; | ||
183 | } | ||
184 | else if (span > max_span + 2.f * other_info.mBoundingSphere.getRadius()) | ||
185 | { | ||
186 | // there is no way any piece of other_info could link with this one | ||
187 | return FALSE; | ||
188 | } | ||
189 | |||
190 | // there may be a piece of other_info that is linkable | ||
191 | typename std::map< DATA_TYPE, LLSphere >::const_iterator map_itr; | ||
192 | for (map_itr = other_info.mDataMap.begin(); map_itr != other_info.mDataMap.end(); ++map_itr) | ||
193 | { | ||
194 | const LLSphere& other_sphere = (*map_itr).second; | ||
195 | max_span = get_max_linkable_span(mBoundingSphere, other_sphere); | ||
196 | |||
197 | span = get_span(mBoundingSphere, other_sphere); | ||
198 | |||
199 | if (span <= max_span) | ||
200 | { | ||
201 | // found one piece that is linkable | ||
202 | return TRUE; | ||
203 | } | ||
204 | } | ||
205 | return FALSE; | ||
206 | } | ||
207 | |||
208 | // merges elements of 'unlinked' | ||
209 | // returns number of links made (NOT final prim count, NOR linked prim count) | ||
210 | // and removes any linkable infos from 'unlinked' | ||
211 | template < typename DATA_TYPE > | ||
212 | void LLPrimLinkInfo< DATA_TYPE >::mergeLinkableSet(std::list< LLPrimLinkInfo< DATA_TYPE > > & unlinked) | ||
213 | { | ||
214 | bool linked_something = true; | ||
215 | while (linked_something) | ||
216 | { | ||
217 | linked_something = false; | ||
218 | |||
219 | typename std::list< LLPrimLinkInfo< DATA_TYPE > >::iterator other_itr = unlinked.begin(); | ||
220 | while ( other_itr != unlinked.end() | ||
221 | && getPrimCount() < MAX_PRIMS_PER_OBJECT ) | ||
222 | { | ||
223 | S32 merge_count = merge(*other_itr); | ||
224 | if (merge_count > 0) | ||
225 | { | ||
226 | linked_something = true; | ||
227 | } | ||
228 | if (0 == (*other_itr).getPrimCount()) | ||
229 | { | ||
230 | unlinked.erase(other_itr++); | ||
231 | } | ||
232 | else | ||
233 | { | ||
234 | ++other_itr; | ||
235 | } | ||
236 | } | ||
237 | if (!linked_something | ||
238 | && unlinked.size() > 1) | ||
239 | { | ||
240 | S32 collapse_count = collapse(unlinked); | ||
241 | if (collapse_count > 0) | ||
242 | { | ||
243 | linked_something = true; | ||
244 | } | ||
245 | } | ||
246 | } | ||
247 | } | ||
248 | |||
249 | // transforms all of the spheres into a new reference frame | ||
250 | template < typename DATA_TYPE > | ||
251 | void LLPrimLinkInfo< DATA_TYPE >::transform(const LLVector3& position, const LLQuaternion& rotation) | ||
252 | { | ||
253 | typename std::map< DATA_TYPE, LLSphere >::iterator map_itr; | ||
254 | for (map_itr = mDataMap.begin(); map_itr != mDataMap.end(); ++map_itr) | ||
255 | { | ||
256 | (*map_itr).second.setCenter((*map_itr).second.getCenter() * rotation + position); | ||
257 | } | ||
258 | mBoundingSphere.setCenter(mBoundingSphere.getCenter() * rotation + position); | ||
259 | } | ||
260 | |||
261 | // private | ||
262 | // returns number of links made | ||
263 | template < typename DATA_TYPE > | ||
264 | S32 LLPrimLinkInfo< DATA_TYPE >::merge(LLPrimLinkInfo& other_info) | ||
265 | { | ||
266 | S32 link_count = 0; | ||
267 | |||
268 | // F32 other_radius = other_info.mBoundingSphere.getRadius(); | ||
269 | // other_info.computeBoundingSphere(); | ||
270 | // if ( other_radius != other_info.mBoundingSphere.getRadius() ) | ||
271 | // { | ||
272 | // llinfos << "Other bounding sphere changed!!" << llendl; | ||
273 | // } | ||
274 | |||
275 | // F32 this_radius = mBoundingSphere.getRadius(); | ||
276 | // computeBoundingSphere(); | ||
277 | // if ( this_radius != mBoundingSphere.getRadius() ) | ||
278 | // { | ||
279 | // llinfos << "This bounding sphere changed!!" << llendl; | ||
280 | // } | ||
281 | |||
282 | |||
283 | F32 max_span = get_max_linkable_span(mBoundingSphere, other_info.mBoundingSphere); | ||
284 | |||
285 | // F32 center_dist = (mBoundingSphere.getCenter() - other_info.mBoundingSphere.getCenter()).length(); | ||
286 | // llinfos << "objects are " << center_dist << "m apart" << llendl; | ||
287 | F32 span = get_span(mBoundingSphere, other_info.mBoundingSphere); | ||
288 | |||
289 | F32 span_limit = max_span + (2.f * other_info.mBoundingSphere.getRadius()); | ||
290 | if (span > span_limit) | ||
291 | { | ||
292 | // there is no way any piece of other_info could link with this one | ||
293 | // llinfos << "span too large: " << span << " vs. " << span_limit << llendl; | ||
294 | return 0; | ||
295 | } | ||
296 | |||
297 | bool completely_linkable = (span <= max_span) ? true : false; | ||
298 | |||
299 | typename std::map< DATA_TYPE, LLSphere >::iterator map_itr = other_info.mDataMap.begin(); | ||
300 | while (map_itr != other_info.mDataMap.end() | ||
301 | && getPrimCount() < MAX_PRIMS_PER_OBJECT ) | ||
302 | { | ||
303 | DATA_TYPE other_data = (*map_itr).first; | ||
304 | LLSphere& other_sphere = (*map_itr).second; | ||
305 | |||
306 | if (!completely_linkable) | ||
307 | { | ||
308 | max_span = get_max_linkable_span(mBoundingSphere, other_sphere); | ||
309 | |||
310 | F32 span = get_span(mBoundingSphere, other_sphere); | ||
311 | |||
312 | if (span > max_span) | ||
313 | { | ||
314 | ++map_itr; | ||
315 | continue; | ||
316 | } | ||
317 | } | ||
318 | |||
319 | mDataMap[other_data] = other_sphere; | ||
320 | ++link_count; | ||
321 | |||
322 | if (!mBoundingSphere.contains(other_sphere) ) | ||
323 | { | ||
324 | computeBoundingSphere(); | ||
325 | } | ||
326 | |||
327 | // remove from the other info | ||
328 | other_info.mDataMap.erase(map_itr++); | ||
329 | } | ||
330 | |||
331 | if (link_count > 0 && other_info.getPrimCount() > 0) | ||
332 | { | ||
333 | other_info.computeBoundingSphere(); | ||
334 | } | ||
335 | return link_count; | ||
336 | } | ||
337 | |||
338 | // links any linkable elements of unlinked | ||
339 | template < typename DATA_TYPE > | ||
340 | S32 LLPrimLinkInfo< DATA_TYPE >::collapse(std::list< LLPrimLinkInfo< DATA_TYPE > > & unlinked) | ||
341 | { | ||
342 | S32 link_count = 0; | ||
343 | bool linked_something = true; | ||
344 | while (linked_something) | ||
345 | { | ||
346 | linked_something = false; | ||
347 | |||
348 | typename std::list< LLPrimLinkInfo< DATA_TYPE > >::iterator this_itr = unlinked.begin(); | ||
349 | typename std::list< LLPrimLinkInfo< DATA_TYPE > >::iterator other_itr = this_itr; | ||
350 | ++other_itr; | ||
351 | while ( other_itr != unlinked.end() ) | ||
352 | |||
353 | { | ||
354 | S32 merge_count = (*this_itr).merge(*other_itr); | ||
355 | if (merge_count > 0) | ||
356 | { | ||
357 | linked_something = true; | ||
358 | link_count += merge_count; | ||
359 | } | ||
360 | if (0 == (*other_itr).getPrimCount()) | ||
361 | { | ||
362 | unlinked.erase(other_itr++); | ||
363 | } | ||
364 | else | ||
365 | { | ||
366 | ++other_itr; | ||
367 | } | ||
368 | } | ||
369 | } | ||
370 | return link_count; | ||
371 | } | ||
372 | |||
373 | |||
374 | template < typename DATA_TYPE > | ||
375 | void LLPrimLinkInfo< DATA_TYPE >::computeBoundingSphere() | ||
376 | { | ||
377 | std::vector< LLSphere > sphere_list; | ||
378 | typename std::map< DATA_TYPE, LLSphere >::const_iterator map_itr; | ||
379 | for (map_itr = mDataMap.begin(); map_itr != mDataMap.end(); ++map_itr) | ||
380 | { | ||
381 | sphere_list.push_back(map_itr->second); | ||
382 | } | ||
383 | mBoundingSphere = LLSphere::getBoundingSphere(sphere_list); | ||
384 | } | ||
385 | |||
386 | |||
387 | #endif | ||
388 | |||