diff options
author | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:44:46 -0500 |
commit | 38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4 (patch) | |
tree | adca584755d22ca041a2dbfc35d4eca01f70b32c /linden/indra/newview/llvoavatar.cpp | |
parent | README.txt (diff) | |
download | meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.zip meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.gz meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.bz2 meta-impy-38d6d37f2d982fa959e9e8a4a3f7e1ccfad7b5d4.tar.xz |
Second Life viewer sources 1.13.2.12
Diffstat (limited to 'linden/indra/newview/llvoavatar.cpp')
-rw-r--r-- | linden/indra/newview/llvoavatar.cpp | 9443 |
1 files changed, 9443 insertions, 0 deletions
diff --git a/linden/indra/newview/llvoavatar.cpp b/linden/indra/newview/llvoavatar.cpp new file mode 100644 index 0000000..3d4f1c0 --- /dev/null +++ b/linden/indra/newview/llvoavatar.cpp | |||
@@ -0,0 +1,9443 @@ | |||
1 | /** | ||
2 | * @file llvoavatar.cpp | ||
3 | * @brief Implementation of LLVOAvatar class which is a derivation fo LLViewerObject | ||
4 | * | ||
5 | * Copyright (c) 2001-2007, Linden Research, Inc. | ||
6 | * | ||
7 | * The source code in this file ("Source Code") is provided by Linden Lab | ||
8 | * to you under the terms of the GNU General Public License, version 2.0 | ||
9 | * ("GPL"), unless you have obtained a separate licensing agreement | ||
10 | * ("Other License"), formally executed by you and Linden Lab. Terms of | ||
11 | * the GPL can be found in doc/GPL-license.txt in this distribution, or | ||
12 | * online at http://secondlife.com/developers/opensource/gplv2 | ||
13 | * | ||
14 | * There are special exceptions to the terms and conditions of the GPL as | ||
15 | * it is applied to this Source Code. View the full text of the exception | ||
16 | * in the file doc/FLOSS-exception.txt in this software distribution, or | ||
17 | * online at http://secondlife.com/developers/opensource/flossexception | ||
18 | * | ||
19 | * By copying, modifying or distributing this software, you acknowledge | ||
20 | * that you have read and understood your obligations described above, | ||
21 | * and agree to abide by those obligations. | ||
22 | * | ||
23 | * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO | ||
24 | * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, | ||
25 | * COMPLETENESS OR PERFORMANCE. | ||
26 | */ | ||
27 | |||
28 | #include "llviewerprecompiledheaders.h" | ||
29 | |||
30 | #include <algorithm> | ||
31 | #include <vector> | ||
32 | #include "llstl.h" | ||
33 | |||
34 | #include "llvoavatar.h" | ||
35 | |||
36 | #include "audioengine.h" | ||
37 | #include "imageids.h" | ||
38 | #include "indra_constants.h" | ||
39 | #include "llchat.h" | ||
40 | #include "llfontgl.h" | ||
41 | #include "llprimitive.h" | ||
42 | #include "lltextureentry.h" | ||
43 | #include "message.h" | ||
44 | #include "noise.h" | ||
45 | #include "sound_ids.h" | ||
46 | #include "lltimer.h" | ||
47 | #include "timing.h" | ||
48 | |||
49 | #include "llagent.h" // Get state values from here | ||
50 | #include "llagparray.h" | ||
51 | #include "llviewercontrol.h" | ||
52 | #include "llcriticaldamp.h" | ||
53 | #include "lldir.h" | ||
54 | #include "lldrawable.h" | ||
55 | #include "lldrawpoolavatar.h" | ||
56 | #include "lldrawpoolalpha.h" | ||
57 | #include "lldrawpoolbump.h" | ||
58 | #include "lldriverparam.h" | ||
59 | #include "lleditingmotion.h" | ||
60 | #include "llemote.h" | ||
61 | #include "llface.h" | ||
62 | #include "llfasttimer.h" | ||
63 | #include "llfirstuse.h" | ||
64 | #include "llfloatercustomize.h" | ||
65 | #include "llfloatertools.h" | ||
66 | #include "llgldbg.h" | ||
67 | #include "llhandmotion.h" | ||
68 | #include "llheadrotmotion.h" | ||
69 | #include "llhudeffectbeam.h" | ||
70 | #include "llhudeffectlookat.h" | ||
71 | #include "llhudeffecttrail.h" | ||
72 | #include "llhudmanager.h" | ||
73 | #include "llhudtext.h" | ||
74 | #include "llinventorymodel.h" | ||
75 | #include "llinventoryview.h" | ||
76 | #include "llkeyframefallmotion.h" | ||
77 | #include "llkeyframemotion.h" | ||
78 | #include "llkeyframemotionparam.h" | ||
79 | #include "llkeyframestandmotion.h" | ||
80 | #include "llkeyframewalkmotion.h" | ||
81 | #include "llmenugl.h" | ||
82 | #include "llmutelist.h" | ||
83 | #include "llnetmap.h" | ||
84 | #include "llnotify.h" | ||
85 | #include "llquantize.h" | ||
86 | #include "llregionhandle.h" | ||
87 | #include "llresmgr.h" | ||
88 | #include "llselectmgr.h" | ||
89 | #include "llsky.h" | ||
90 | #include "llsprite.h" | ||
91 | #include "llstatusbar.h" | ||
92 | #include "lltargetingmotion.h" | ||
93 | #include "lltexlayer.h" | ||
94 | #include "lltoolbar.h" | ||
95 | #include "lltoolgrab.h" // for needsRenderBeam | ||
96 | #include "lltoolmgr.h" // for needsRenderBeam | ||
97 | #include "lltoolmorph.h" | ||
98 | #include "llviewercamera.h" | ||
99 | #include "llviewerimagelist.h" | ||
100 | #include "llviewerinventory.h" | ||
101 | #include "llviewermenu.h" | ||
102 | #include "llviewerobjectlist.h" | ||
103 | #include "llviewerparcelmgr.h" | ||
104 | #include "llviewerregion.h" | ||
105 | #include "llviewerstats.h" | ||
106 | #include "llviewerwindow.h" | ||
107 | #include "llvosky.h" | ||
108 | #include "llvovolume.h" | ||
109 | #include "llwearable.h" | ||
110 | #include "llwearablelist.h" | ||
111 | #include "llworld.h" | ||
112 | #include "pipeline.h" | ||
113 | #include "viewer.h" | ||
114 | #include "lscript_byteformat.h" | ||
115 | |||
116 | //#include "vtune/vtuneapi.h" | ||
117 | |||
118 | // Direct imports, evil | ||
119 | extern LLSky gSky; | ||
120 | extern void set_avatar_character(void* charNameArg); | ||
121 | extern BOOL gRenderForSelect; | ||
122 | |||
123 | LLXmlTree LLVOAvatar::sXMLTree; | ||
124 | LLXmlTree LLVOAvatar::sSkeletonXMLTree; | ||
125 | LLVOAvatarSkeletonInfo* LLVOAvatar::sSkeletonInfo = NULL; | ||
126 | LLVOAvatarInfo* LLVOAvatar::sAvatarInfo = NULL; | ||
127 | |||
128 | BOOL gDebugAvatarRotation = FALSE; | ||
129 | |||
130 | //extern BOOL gVelocityInterpolate; | ||
131 | |||
132 | //----------------------------------------------------------------------------- | ||
133 | // Constants | ||
134 | //----------------------------------------------------------------------------- | ||
135 | const F32 MIN_PIXEL_AREA_FOR_COMPOSITE = 200.f; | ||
136 | |||
137 | F32 SHADOW_OFFSET_AMT = 0.03f; | ||
138 | |||
139 | #define DELTA_TIME_MIN 0.01f // we clamp measured deltaTime to this | ||
140 | #define DELTA_TIME_MAX 0.2f // range to insure stability of computations. | ||
141 | |||
142 | const F32 PELVIS_LAG_FLYING = 0.22f;// pelvis follow half life while flying | ||
143 | |||
144 | const F32 PELVIS_LAG_WALKING = 0.4f; // ...while walking | ||
145 | |||
146 | const F32 PELVIS_LAG_MOUSELOOK = 0.15f; | ||
147 | const F32 MOUSELOOK_PELVIS_FOLLOW_FACTOR = 0.5f; | ||
148 | |||
149 | //Ventrella | ||
150 | const F32 PELVIS_LAG_WHEN_FOLLOW_CAM_IS_ON = 0.0001f; // not zero! - something gets divided by this! | ||
151 | //end Ventrella | ||
152 | |||
153 | #define PELVIS_ROT_THRESHOLD_SLOW 60.0f // amount of deviation allowed between | ||
154 | #define PELVIS_ROT_THRESHOLD_FAST 2.0f // the pelvis and the view direction | ||
155 | // when moving fast & slow | ||
156 | |||
157 | const F32 MIN_SPEED_PELVIS_FOLLOW = 0.1f; | ||
158 | |||
159 | #define TORSO_NOISE_AMOUNT 1.f // Amount of deviation from up-axis, in degrees | ||
160 | #define TORSO_NOISE_SPEED 0.2f // Time scale factor on torso noise. | ||
161 | |||
162 | const F32 BREATHE_ROT_MOTION_STRENGTH = 0.05f; | ||
163 | |||
164 | const F32 BREATHE_SCALE_MOTION_STRENGTH = 0.005f; | ||
165 | |||
166 | #define PELVIS_NOISE_FACTOR 0.5f // amount of random noise | ||
167 | |||
168 | #define AUDIO_STEP_PRI 0xC0000000 | ||
169 | #define AUDIO_STEP_LO_SPEED 0.01f // as average speed goes from lo to hi, | ||
170 | #define AUDIO_STEP_HI_SPEED 3.0f // from lo to hi | ||
171 | #define AUDIO_STEP_LO_GAIN 0.15f // the resulting gain will ramp linearly | ||
172 | #define AUDIO_STEP_HI_GAIN 0.15f | ||
173 | |||
174 | const F32 DAMPED_MOTION_TIME_SCALE = 0.15f; | ||
175 | |||
176 | const F32 LOOKAT_CAMERA_DIST_SQUARED = 25.f; | ||
177 | |||
178 | #define AVATAR_HEADER "Linden Avatar 1.0" | ||
179 | #define AVATAR_SECTION "[avatar]" | ||
180 | |||
181 | #define AVATAR_DEFAULT_CHAR "avatar" | ||
182 | |||
183 | const F32 MIN_SHADOW_HEIGHT = 0.f; | ||
184 | const F32 MAX_SHADOW_HEIGHT = 0.3f; | ||
185 | |||
186 | #define MIN_REQUIRED_PIXEL_AREA_BODY_NOISE (10000.f) | ||
187 | #define MIN_REQUIRED_PIXEL_AREA_BREATHE (10000.f) | ||
188 | #define MIN_REQUIRED_PIXEL_AREA_PELVIS_FIX (40.f) | ||
189 | |||
190 | const S32 LOCTEX_IMAGE_SIZE_SELF = 512; | ||
191 | const S32 LOCTEX_IMAGE_AREA_SELF = LOCTEX_IMAGE_SIZE_SELF * LOCTEX_IMAGE_SIZE_SELF; | ||
192 | const S32 LOCTEX_IMAGE_SIZE_OTHER = LOCTEX_IMAGE_SIZE_SELF / 4; // The size of local textures for other (!mIsSelf) avatars | ||
193 | const S32 LOCTEX_IMAGE_AREA_OTHER = LOCTEX_IMAGE_SIZE_OTHER * LOCTEX_IMAGE_SIZE_OTHER; | ||
194 | |||
195 | const F32 HEAD_MOVEMENT_AVG_TIME = 0.9f; | ||
196 | |||
197 | const S32 MORPH_MASK_REQUESTED_DISCARD = 0; | ||
198 | const S32 MIN_PIXEL_AREA_BUMP = 500; | ||
199 | |||
200 | // Discard level at which to switch to baked textures | ||
201 | // Should probably be 4 or 3, but didn't want to change it while change other logic - SJB | ||
202 | const S32 SWITCH_TO_BAKED_DISCARD = 5; | ||
203 | |||
204 | const F32 FOOT_COLLIDE_FUDGE = 0.04f; | ||
205 | |||
206 | const F32 HOVER_EFFECT_MAX_SPEED = 3.f; | ||
207 | const F32 HOVER_EFFECT_STRENGTH = 0.f; | ||
208 | F32 UNDERWATER_EFFECT_STRENGTH = 0.1f; | ||
209 | const F32 UNDERWATER_FREQUENCY_DAMP = 0.33f; | ||
210 | const F32 APPEARANCE_MORPH_TIME = 0.65f; | ||
211 | const F32 CAMERA_SHAKE_ACCEL_THRESHOLD_SQUARED = 5.f * 5.f; | ||
212 | const F32 TIME_BEFORE_MESH_CLEANUP = 5.f; // seconds | ||
213 | const S32 AVATAR_AGP_RELEASE_THRESHOLD = 10; // number of avatar instances before releasing AGP memory | ||
214 | const F32 FOOT_GROUND_COLLISION_TOLERANCE = 0.25f; | ||
215 | const F32 AVATAR_LOD_TWEAK_RANGE = 0.7f; | ||
216 | const S32 MAX_LOD_CHANGES_PER_FRAME = 2; | ||
217 | const S32 MAX_BUBBLE_CHAT_LENGTH = 1023; | ||
218 | const S32 MAX_BUBBLE_CHAT_UTTERANCES = 12; | ||
219 | const F32 CHAT_FADE_TIME = 8.0; | ||
220 | const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f; | ||
221 | const S32 MAX_BUBBLES = 7; | ||
222 | |||
223 | |||
224 | const bool USING_VENTRELLA_AVATAR_MOTION_TEST = false; | ||
225 | |||
226 | |||
227 | S32 LLVOAvatar::sMaxVisible = 50; | ||
228 | |||
229 | LLVOAvatar::ETextureIndex LLVOAvatar::sBakedTextureIndices[BAKED_TEXTURE_COUNT] = | ||
230 | { | ||
231 | LLVOAvatar::TEX_HEAD_BAKED, | ||
232 | LLVOAvatar::TEX_UPPER_BAKED, | ||
233 | LLVOAvatar::TEX_LOWER_BAKED, | ||
234 | LLVOAvatar::TEX_EYES_BAKED, | ||
235 | LLVOAvatar::TEX_SKIRT_BAKED | ||
236 | }; | ||
237 | |||
238 | //----------------------------------------------------------------------------- | ||
239 | // Utility functions | ||
240 | //----------------------------------------------------------------------------- | ||
241 | |||
242 | static F32 calc_bouncy_animation(F32 x) | ||
243 | { | ||
244 | return -(cosf(x * F_PI * 2.5f - F_PI_BY_TWO))*(0.4f + x * -0.1f) + x * 1.3f; | ||
245 | } | ||
246 | |||
247 | //----------------------------------------------------------------------------- | ||
248 | // Static Data | ||
249 | //----------------------------------------------------------------------------- | ||
250 | S32 LLVOAvatar::sMaxOtherAvatarsToComposite = 1; // Only this many avatars (other than yourself) can be composited at a time. Set in initClass(). | ||
251 | LLMap< LLGLenum, LLGLuint*> LLVOAvatar::sScratchTexNames; | ||
252 | LLMap< LLGLenum, F32*> LLVOAvatar::sScratchTexLastBindTime; | ||
253 | S32 LLVOAvatar::sScratchTexBytes = 0; | ||
254 | S32 LLVOAvatar::sNumVisibleAvatars = 0; | ||
255 | S32 LLVOAvatar::sNumLODChangesThisFrame = 0; | ||
256 | |||
257 | LLUUID LLVOAvatar::sStepSoundOnLand = LLUUID("e8af4a28-aa83-4310-a7c4-c047e15ea0df"); | ||
258 | LLUUID LLVOAvatar::sStepSounds[LL_MCODE_END] = | ||
259 | { | ||
260 | LLUUID(SND_STONE_RUBBER), | ||
261 | LLUUID(SND_METAL_RUBBER), | ||
262 | LLUUID(SND_GLASS_RUBBER), | ||
263 | LLUUID(SND_WOOD_RUBBER), | ||
264 | LLUUID(SND_FLESH_RUBBER), | ||
265 | LLUUID(SND_RUBBER_PLASTIC), | ||
266 | LLUUID(SND_RUBBER_RUBBER) | ||
267 | }; | ||
268 | |||
269 | S32 LLVOAvatar::sRenderName = RENDER_NAME_ALWAYS; | ||
270 | S32 LLVOAvatar::sNumVisibleChatBubbles = 0; | ||
271 | BOOL LLVOAvatar::sDebugInvisible = FALSE; | ||
272 | BOOL LLVOAvatar::sShowAttachmentPoints = FALSE; | ||
273 | BOOL LLVOAvatar::sShowAnimationDebug = FALSE; | ||
274 | BOOL LLVOAvatar::sShowFootPlane = FALSE; | ||
275 | BOOL LLVOAvatar::sShowCollisionVolumes = FALSE; | ||
276 | BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE; | ||
277 | BOOL LLVOAvatar::sAvatarLoadTest = FALSE; | ||
278 | F32 LLVOAvatar::sLODFactor = 1.f; | ||
279 | BOOL LLVOAvatar::sJointDebug = FALSE; | ||
280 | |||
281 | S32 LLVOAvatar::sCurJoint = 0; | ||
282 | S32 LLVOAvatar::sCurVolume = 0; | ||
283 | |||
284 | struct LLAvatarTexData | ||
285 | { | ||
286 | LLAvatarTexData( const LLUUID& id, LLVOAvatar::ELocTexIndex index ) | ||
287 | : mAvatarID(id), mIndex(index) {} | ||
288 | LLUUID mAvatarID; | ||
289 | LLVOAvatar::ELocTexIndex mIndex; | ||
290 | }; | ||
291 | |||
292 | struct LLTextureMaskData | ||
293 | { | ||
294 | LLTextureMaskData( const LLUUID& id ) | ||
295 | : mAvatarID(id), mLastDiscardLevel(S32_MAX) {} | ||
296 | LLUUID mAvatarID; | ||
297 | S32 mLastDiscardLevel; | ||
298 | }; | ||
299 | |||
300 | |||
301 | //----------------------------------------------------------------------------- | ||
302 | // class LLBodyNoiseMotion | ||
303 | //----------------------------------------------------------------------------- | ||
304 | class LLBodyNoiseMotion : | ||
305 | public LLMotion | ||
306 | { | ||
307 | public: | ||
308 | // Constructor | ||
309 | LLBodyNoiseMotion(const LLUUID &id) : LLMotion(id) {mName = "body_noise";} | ||
310 | |||
311 | // Destructor | ||
312 | virtual ~LLBodyNoiseMotion() { } | ||
313 | |||
314 | public: | ||
315 | //------------------------------------------------------------------------- | ||
316 | // functions to support MotionController and MotionRegistry | ||
317 | //------------------------------------------------------------------------- | ||
318 | // static constructor | ||
319 | // all subclasses must implement such a function and register it | ||
320 | static LLMotion *create(const LLUUID &id) { return new LLBodyNoiseMotion(id); } | ||
321 | |||
322 | public: | ||
323 | //------------------------------------------------------------------------- | ||
324 | // animation callbacks to be implemented by subclasses | ||
325 | //------------------------------------------------------------------------- | ||
326 | |||
327 | // motions must specify whether or not they loop | ||
328 | virtual BOOL getLoop() { return TRUE; } | ||
329 | |||
330 | // motions must report their total duration | ||
331 | virtual F32 getDuration() { return 0.0; } | ||
332 | |||
333 | // motions must report their "ease in" duration | ||
334 | virtual F32 getEaseInDuration() { return 0.0; } | ||
335 | |||
336 | // motions must report their "ease out" duration. | ||
337 | virtual F32 getEaseOutDuration() { return 0.0; } | ||
338 | |||
339 | // motions must report their priority | ||
340 | virtual LLJoint::JointPriority getPriority() { return LLJoint::HIGH_PRIORITY; } | ||
341 | |||
342 | virtual LLMotionBlendType getBlendType() { return ADDITIVE_BLEND; } | ||
343 | |||
344 | // called to determine when a motion should be activated/deactivated based on avatar pixel coverage | ||
345 | virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_BODY_NOISE; } | ||
346 | |||
347 | // run-time (post constructor) initialization, | ||
348 | // called after parameters have been set | ||
349 | // must return true to indicate success and be available for activation | ||
350 | virtual LLMotionInitStatus onInitialize(LLCharacter *character) | ||
351 | { | ||
352 | if( !mTorsoState.setJoint( character->getJoint("mTorso") )) | ||
353 | { | ||
354 | return STATUS_FAILURE; | ||
355 | } | ||
356 | |||
357 | mTorsoState.setUsage(LLJointState::ROT); | ||
358 | |||
359 | addJointState( &mTorsoState ); | ||
360 | return STATUS_SUCCESS; | ||
361 | } | ||
362 | |||
363 | // called when a motion is activated | ||
364 | // must return TRUE to indicate success, or else | ||
365 | // it will be deactivated | ||
366 | virtual BOOL onActivate() { return TRUE; } | ||
367 | |||
368 | // called per time step | ||
369 | // must return TRUE while it is active, and | ||
370 | // must return FALSE when the motion is completed. | ||
371 | virtual BOOL onUpdate(F32 time, U8* joint_mask) | ||
372 | { | ||
373 | F32 nx[2]; | ||
374 | nx[0]=time*TORSO_NOISE_SPEED; | ||
375 | nx[1]=0.0f; | ||
376 | F32 ny[2]; | ||
377 | ny[0]=0.0f; | ||
378 | ny[1]=time*TORSO_NOISE_SPEED; | ||
379 | F32 noiseX = noise2(nx); | ||
380 | F32 noiseY = noise2(ny); | ||
381 | |||
382 | F32 rx = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseX / 0.42f; | ||
383 | F32 ry = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseY / 0.42f; | ||
384 | LLQuaternion tQn; | ||
385 | tQn.setQuat( rx, ry, 0.0f ); | ||
386 | mTorsoState.setRotation( tQn ); | ||
387 | |||
388 | return TRUE; | ||
389 | } | ||
390 | |||
391 | // called when a motion is deactivated | ||
392 | virtual void onDeactivate() {} | ||
393 | |||
394 | public: | ||
395 | //------------------------------------------------------------------------- | ||
396 | // joint states to be animated | ||
397 | //------------------------------------------------------------------------- | ||
398 | LLJointState mTorsoState; | ||
399 | }; | ||
400 | |||
401 | //----------------------------------------------------------------------------- | ||
402 | // class LLBreatheMotionRot | ||
403 | //----------------------------------------------------------------------------- | ||
404 | class LLBreatheMotionRot : | ||
405 | public LLMotion | ||
406 | { | ||
407 | public: | ||
408 | // Constructor | ||
409 | LLBreatheMotionRot(const LLUUID &id) : | ||
410 | LLMotion(id), | ||
411 | mBreatheRate(1.f), | ||
412 | mCharacter(NULL) | ||
413 | { | ||
414 | mName = "breathe_rot"; | ||
415 | } | ||
416 | |||
417 | // Destructor | ||
418 | virtual ~LLBreatheMotionRot() { } | ||
419 | |||
420 | public: | ||
421 | //------------------------------------------------------------------------- | ||
422 | // functions to support MotionController and MotionRegistry | ||
423 | //------------------------------------------------------------------------- | ||
424 | // static constructor | ||
425 | // all subclasses must implement such a function and register it | ||
426 | static LLMotion *create(const LLUUID &id) { return new LLBreatheMotionRot(id); } | ||
427 | |||
428 | public: | ||
429 | //------------------------------------------------------------------------- | ||
430 | // animation callbacks to be implemented by subclasses | ||
431 | //------------------------------------------------------------------------- | ||
432 | |||
433 | // motions must specify whether or not they loop | ||
434 | virtual BOOL getLoop() { return TRUE; } | ||
435 | |||
436 | // motions must report their total duration | ||
437 | virtual F32 getDuration() { return 0.0; } | ||
438 | |||
439 | // motions must report their "ease in" duration | ||
440 | virtual F32 getEaseInDuration() { return 0.0; } | ||
441 | |||
442 | // motions must report their "ease out" duration. | ||
443 | virtual F32 getEaseOutDuration() { return 0.0; } | ||
444 | |||
445 | // motions must report their priority | ||
446 | virtual LLJoint::JointPriority getPriority() { return LLJoint::MEDIUM_PRIORITY; } | ||
447 | |||
448 | virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } | ||
449 | |||
450 | // called to determine when a motion should be activated/deactivated based on avatar pixel coverage | ||
451 | virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_BREATHE; } | ||
452 | |||
453 | // run-time (post constructor) initialization, | ||
454 | // called after parameters have been set | ||
455 | // must return true to indicate success and be available for activation | ||
456 | virtual LLMotionInitStatus onInitialize(LLCharacter *character) | ||
457 | { | ||
458 | //Ventrella | ||
459 | // I'm replacing the code below because I need to change | ||
460 | // the logic in order to add other body parts | ||
461 | /* | ||
462 | mCharacter = character; | ||
463 | |||
464 | if (!mChestState.setJoint( character->getJoint("mChest"))) | ||
465 | { | ||
466 | return STATUS_FAILURE; | ||
467 | } | ||
468 | |||
469 | mChestState.setUsage(LLJointState::ROT); | ||
470 | |||
471 | addJointState( &mChestState ); | ||
472 | return STATUS_SUCCESS; | ||
473 | */ | ||
474 | |||
475 | |||
476 | bool success = true; | ||
477 | |||
478 | if ( !mChestState.setJoint( character->getJoint( "mChest" ) ) ) { success = false; } | ||
479 | |||
480 | if ( USING_VENTRELLA_AVATAR_MOTION_TEST ) | ||
481 | { | ||
482 | if ( !mNeckState.setJoint ( character->getJoint( "mNeck" )) ) { success = false; } | ||
483 | |||
484 | if ( !mCollarLeftState.setJoint ( character->getJoint( "mCollarLeft" )) ) { success = false; } | ||
485 | if ( !mShoulderLeftState.setJoint ( character->getJoint( "mShoulderLeft" )) ) { success = false; } | ||
486 | if ( !mElbowLeftState.setJoint ( character->getJoint( "mElbowLeft" )) ) { success = false; } | ||
487 | if ( !mWristLeftState.setJoint ( character->getJoint( "mWristLeft" )) ) { success = false; } | ||
488 | |||
489 | if ( !mCollarRightState.setJoint ( character->getJoint( "mCollarRight" )) ) { success = false; } | ||
490 | if ( !mShoulderRightState.setJoint ( character->getJoint( "mShoulderRight" )) ) { success = false; } | ||
491 | if ( !mElbowRightState.setJoint ( character->getJoint( "mElbowRight" )) ) { success = false; } | ||
492 | if ( !mWristRightState.setJoint ( character->getJoint( "mWristRight" )) ) { success = false; } | ||
493 | |||
494 | if ( !mHipLeftState.setJoint ( character->getJoint( "mHipLeft" )) ) { success = false; } | ||
495 | if ( !mKneeLeftState.setJoint ( character->getJoint( "mKneeLeft" )) ) { success = false; } | ||
496 | if ( !mAnkleLeftState.setJoint ( character->getJoint( "mAnkleLeft" )) ) { success = false; } | ||
497 | |||
498 | if ( !mHipRightState.setJoint ( character->getJoint( "mHipRight" )) ) { success = false; } | ||
499 | if ( !mKneeRightState.setJoint ( character->getJoint( "mKneeRight" )) ) { success = false; } | ||
500 | if ( !mAnkleRightState.setJoint ( character->getJoint( "mAnkleRight" )) ) { success = false; } | ||
501 | } | ||
502 | |||
503 | if ( success ) | ||
504 | { | ||
505 | mChestState.setUsage(LLJointState::ROT); | ||
506 | addJointState( &mChestState ); | ||
507 | |||
508 | if ( USING_VENTRELLA_AVATAR_MOTION_TEST ) | ||
509 | { | ||
510 | //------------------------------------------- | ||
511 | // neck | ||
512 | //------------------------------------------- | ||
513 | mNeckState.setUsage(LLJointState::ROT); | ||
514 | addJointState( &mNeckState ); | ||
515 | |||
516 | //------------------------------------------- | ||
517 | // left arm | ||
518 | //------------------------------------------- | ||
519 | mCollarLeftState.setUsage(LLJointState::ROT); | ||
520 | addJointState( &mCollarLeftState ); | ||
521 | |||
522 | mShoulderLeftState.setUsage(LLJointState::ROT); | ||
523 | addJointState( &mShoulderLeftState ); | ||
524 | |||
525 | mElbowLeftState.setUsage(LLJointState::ROT); | ||
526 | addJointState( &mElbowLeftState ); | ||
527 | |||
528 | mWristLeftState.setUsage(LLJointState::ROT); | ||
529 | addJointState( &mWristLeftState ); | ||
530 | |||
531 | |||
532 | //------------------------------------------- | ||
533 | // right arm | ||
534 | //------------------------------------------- | ||
535 | mCollarRightState.setUsage(LLJointState::ROT); | ||
536 | addJointState( &mCollarRightState ); | ||
537 | |||
538 | mShoulderRightState.setUsage(LLJointState::ROT); | ||
539 | addJointState( &mShoulderRightState ); | ||
540 | |||
541 | mElbowRightState.setUsage(LLJointState::ROT); | ||
542 | addJointState( &mElbowRightState ); | ||
543 | |||
544 | mWristRightState.setUsage(LLJointState::ROT); | ||
545 | addJointState( &mWristRightState ); | ||
546 | |||
547 | //------------------------------------------- | ||
548 | // left leg | ||
549 | //------------------------------------------- | ||
550 | mHipLeftState.setUsage(LLJointState::ROT); | ||
551 | addJointState( &mHipLeftState ); | ||
552 | |||
553 | mKneeLeftState.setUsage(LLJointState::ROT); | ||
554 | addJointState( &mKneeLeftState ); | ||
555 | |||
556 | mAnkleLeftState.setUsage(LLJointState::ROT); | ||
557 | addJointState( &mAnkleLeftState ); | ||
558 | |||
559 | |||
560 | //------------------------------------------- | ||
561 | // right leg | ||
562 | //------------------------------------------- | ||
563 | mHipRightState.setUsage(LLJointState::ROT); | ||
564 | addJointState( &mHipRightState ); | ||
565 | |||
566 | mKneeRightState.setUsage(LLJointState::ROT); | ||
567 | addJointState( &mKneeRightState ); | ||
568 | |||
569 | mAnkleRightState.setUsage(LLJointState::ROT); | ||
570 | addJointState( &mAnkleRightState ); | ||
571 | } | ||
572 | } | ||
573 | |||
574 | if ( success ) | ||
575 | { | ||
576 | return STATUS_SUCCESS; | ||
577 | } | ||
578 | else | ||
579 | { | ||
580 | return STATUS_FAILURE; | ||
581 | } | ||
582 | //end Ventrella | ||
583 | } | ||
584 | |||
585 | // called when a motion is activated | ||
586 | // must return TRUE to indicate success, or else | ||
587 | // it will be deactivated | ||
588 | virtual BOOL onActivate() { return TRUE; } | ||
589 | |||
590 | // called per time step | ||
591 | // must return TRUE while it is active, and | ||
592 | // must return FALSE when the motion is completed. | ||
593 | virtual BOOL onUpdate(F32 time, U8* joint_mask) | ||
594 | { | ||
595 | mBreatheRate = 1.f; | ||
596 | |||
597 | F32 breathe_amt = (sinf(mBreatheRate * time) * BREATHE_ROT_MOTION_STRENGTH); | ||
598 | |||
599 | mChestState.setRotation(LLQuaternion(breathe_amt, LLVector3(0.f, 1.f, 0.f))); | ||
600 | |||
601 | //Ventrella | ||
602 | if ( USING_VENTRELLA_AVATAR_MOTION_TEST ) | ||
603 | { | ||
604 | F32 wave = ( sinf ( time * 2.0f ) * 0.5f ); | ||
605 | |||
606 | mChestState.setRotation ( LLQuaternion( wave, LLVector3( -1.0f, 0.0f, 0.0f ) ) ); | ||
607 | |||
608 | mCollarLeftState.setRotation ( LLQuaternion( wave, LLVector3( 1.0f, 0.0f, 0.0f ) ) ); | ||
609 | mShoulderLeftState.setRotation ( LLQuaternion( wave, LLVector3( 1.0f, 0.0f, 0.0f ) ) ); | ||
610 | mElbowLeftState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, 0.0f, 1.0f ) ) ); | ||
611 | mWristLeftState.setRotation ( LLQuaternion( wave, LLVector3( 1.0f, 0.0f, 0.0f ) ) ); | ||
612 | |||
613 | mCollarRightState.setRotation ( LLQuaternion( wave, LLVector3( -1.0f, 0.0f, 0.0f ) ) ); | ||
614 | mShoulderRightState.setRotation ( LLQuaternion( wave, LLVector3( 1.0f, 0.0f, 0.0f ) ) ); | ||
615 | mElbowRightState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, 0.0f, 1.0f ) ) ); | ||
616 | mWristRightState.setRotation ( LLQuaternion( wave, LLVector3( 1.0f, 0.0f, 0.0f ) ) ); | ||
617 | |||
618 | mHipLeftState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, 1.0f, 0.0f ) ) ); | ||
619 | mKneeLeftState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, -1.0f, 0.0f ) ) ); | ||
620 | mAnkleLeftState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, 1.0f, 0.0f ) ) ); | ||
621 | |||
622 | mHipRightState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, 1.0f, 0.0f ) ) ); | ||
623 | mKneeRightState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, -1.0f, 0.0f ) ) ); | ||
624 | mAnkleRightState.setRotation ( LLQuaternion( wave, LLVector3( 0.0f, 1.0f, 0.0f ) ) ); | ||
625 | } | ||
626 | //end Ventrella | ||
627 | |||
628 | return TRUE; | ||
629 | } | ||
630 | |||
631 | |||
632 | // called when a motion is deactivated | ||
633 | virtual void onDeactivate() {} | ||
634 | |||
635 | public: | ||
636 | //------------------------------------------------------------------------- | ||
637 | // joint states to be animated | ||
638 | //------------------------------------------------------------------------- | ||
639 | LLJointState mChestState; | ||
640 | |||
641 | //Ventrella | ||
642 | LLJointState mNeckState; | ||
643 | LLJointState mCollarLeftState; | ||
644 | LLJointState mShoulderLeftState; | ||
645 | LLJointState mElbowLeftState; | ||
646 | LLJointState mWristLeftState; | ||
647 | LLJointState mCollarRightState; | ||
648 | LLJointState mShoulderRightState; | ||
649 | LLJointState mElbowRightState; | ||
650 | LLJointState mWristRightState; | ||
651 | LLJointState mHipLeftState; | ||
652 | LLJointState mKneeLeftState; | ||
653 | LLJointState mAnkleLeftState; | ||
654 | LLJointState mHipRightState; | ||
655 | LLJointState mKneeRightState; | ||
656 | LLJointState mAnkleRightState; | ||
657 | //end Ventrella | ||
658 | |||
659 | F32 mBreatheRate; | ||
660 | LLCharacter* mCharacter; | ||
661 | }; | ||
662 | |||
663 | //----------------------------------------------------------------------------- | ||
664 | // class LLPelvisFixMotion | ||
665 | //----------------------------------------------------------------------------- | ||
666 | class LLPelvisFixMotion : | ||
667 | public LLMotion | ||
668 | { | ||
669 | public: | ||
670 | // Constructor | ||
671 | LLPelvisFixMotion(const LLUUID &id) : LLMotion(id), mCharacter(NULL) {mName = "pelvis_fix";} | ||
672 | |||
673 | // Destructor | ||
674 | virtual ~LLPelvisFixMotion() { } | ||
675 | |||
676 | public: | ||
677 | //------------------------------------------------------------------------- | ||
678 | // functions to support MotionController and MotionRegistry | ||
679 | //------------------------------------------------------------------------- | ||
680 | // static constructor | ||
681 | // all subclasses must implement such a function and register it | ||
682 | static LLMotion *create(const LLUUID& id) { return new LLPelvisFixMotion(id); } | ||
683 | |||
684 | public: | ||
685 | //------------------------------------------------------------------------- | ||
686 | // animation callbacks to be implemented by subclasses | ||
687 | //------------------------------------------------------------------------- | ||
688 | |||
689 | // motions must specify whether or not they loop | ||
690 | virtual BOOL getLoop() { return TRUE; } | ||
691 | |||
692 | // motions must report their total duration | ||
693 | virtual F32 getDuration() { return 0.0; } | ||
694 | |||
695 | // motions must report their "ease in" duration | ||
696 | virtual F32 getEaseInDuration() { return 0.5f; } | ||
697 | |||
698 | // motions must report their "ease out" duration. | ||
699 | virtual F32 getEaseOutDuration() { return 0.5f; } | ||
700 | |||
701 | // motions must report their priority | ||
702 | virtual LLJoint::JointPriority getPriority() { return LLJoint::LOW_PRIORITY; } | ||
703 | |||
704 | virtual LLMotionBlendType getBlendType() { return NORMAL_BLEND; } | ||
705 | |||
706 | // called to determine when a motion should be activated/deactivated based on avatar pixel coverage | ||
707 | virtual F32 getMinPixelArea() { return MIN_REQUIRED_PIXEL_AREA_PELVIS_FIX; } | ||
708 | |||
709 | // run-time (post constructor) initialization, | ||
710 | // called after parameters have been set | ||
711 | // must return true to indicate success and be available for activation | ||
712 | virtual LLMotionInitStatus onInitialize(LLCharacter *character) | ||
713 | { | ||
714 | mCharacter = character; | ||
715 | |||
716 | if (!mPelvisState.setJoint( character->getJoint("mPelvis"))) | ||
717 | { | ||
718 | return STATUS_FAILURE; | ||
719 | } | ||
720 | |||
721 | mPelvisState.setUsage(LLJointState::POS); | ||
722 | |||
723 | addJointState( &mPelvisState ); | ||
724 | return STATUS_SUCCESS; | ||
725 | } | ||
726 | |||
727 | // called when a motion is activated | ||
728 | // must return TRUE to indicate success, or else | ||
729 | // it will be deactivated | ||
730 | virtual BOOL onActivate() { return TRUE; } | ||
731 | |||
732 | // called per time step | ||
733 | // must return TRUE while it is active, and | ||
734 | // must return FALSE when the motion is completed. | ||
735 | virtual BOOL onUpdate(F32 time, U8* joint_mask) | ||
736 | { | ||
737 | mPelvisState.setPosition(LLVector3::zero); | ||
738 | |||
739 | return TRUE; | ||
740 | } | ||
741 | |||
742 | // called when a motion is deactivated | ||
743 | virtual void onDeactivate() {} | ||
744 | |||
745 | public: | ||
746 | //------------------------------------------------------------------------- | ||
747 | // joint states to be animated | ||
748 | //------------------------------------------------------------------------- | ||
749 | LLJointState mPelvisState; | ||
750 | LLCharacter* mCharacter; | ||
751 | }; | ||
752 | |||
753 | //----------------------------------------------------------------------------- | ||
754 | // LLVOAvatar() | ||
755 | //----------------------------------------------------------------------------- | ||
756 | LLVOAvatar::LLVOAvatar( | ||
757 | const LLUUID& id, | ||
758 | const LLPCode pcode, | ||
759 | LLViewerRegion* regionp) | ||
760 | : | ||
761 | LLViewerObject(id, pcode, regionp), | ||
762 | mHUDTargetZoom(1.f), | ||
763 | mHUDCurZoom(1.f), | ||
764 | mLastHeadBakedID( IMG_DEFAULT_AVATAR ), | ||
765 | mLastUpperBodyBakedID( IMG_DEFAULT_AVATAR ), | ||
766 | mLastLowerBodyBakedID( IMG_DEFAULT_AVATAR ), | ||
767 | mLastEyesBakedID( IMG_DEFAULT_AVATAR ), | ||
768 | mLastSkirtBakedID( IMG_DEFAULT_AVATAR ), | ||
769 | mIsDummy(FALSE), | ||
770 | mSpecialRenderMode(0), | ||
771 | mPelvisToFoot(0.f), | ||
772 | mLastSkeletonSerialNum( 0 ), | ||
773 | mTurning(FALSE), | ||
774 | mHeadOffset(), | ||
775 | mIsSitting(FALSE), | ||
776 | mTimeVisible(), | ||
777 | mTyping(FALSE), | ||
778 | mMeshValid(FALSE), | ||
779 | mVisible(FALSE), | ||
780 | mWindFreq(0.f), | ||
781 | mRipplePhase( 0.f ), | ||
782 | mBelowWater(FALSE), | ||
783 | mAppearanceAnimSetByUser(FALSE), | ||
784 | mLastAppearanceBlendTime(0.f), | ||
785 | mAppearanceAnimating(FALSE), | ||
786 | mHeadLayerSet( NULL ), | ||
787 | mUpperBodyLayerSet( NULL ), | ||
788 | mLowerBodyLayerSet( NULL ), | ||
789 | mEyesLayerSet( NULL ), | ||
790 | mSkirtLayerSet( NULL ), | ||
791 | mRenderPriority(1.0f), | ||
792 | mNumAGPVertices(0), | ||
793 | mNameString(), | ||
794 | mTitle(), | ||
795 | mNameAway(FALSE), | ||
796 | mNameBusy(FALSE), | ||
797 | mNameMute(FALSE), | ||
798 | mNameAppearance(FALSE), | ||
799 | mLastRegionHandle(0), | ||
800 | mRegionCrossingCount(0), | ||
801 | mFirstTEMessageReceived( FALSE ), | ||
802 | mFirstAppearanceMessageReceived( FALSE ), | ||
803 | mHeadBakedLoaded(FALSE), | ||
804 | mHeadMaskDiscard(-1), | ||
805 | mUpperBakedLoaded(FALSE), | ||
806 | mUpperMaskDiscard(-1), | ||
807 | mLowerBakedLoaded(FALSE), | ||
808 | mLowerMaskDiscard(-1), | ||
809 | mEyesBakedLoaded(FALSE), | ||
810 | mSkirtBakedLoaded(FALSE), | ||
811 | mHeadMaskTexName(0), | ||
812 | mUpperMaskTexName(0), | ||
813 | mLowerMaskTexName(0), | ||
814 | mCulled( FALSE ), | ||
815 | mTexSkinColor( NULL ), | ||
816 | mTexHairColor( NULL ), | ||
817 | mTexEyeColor( NULL ) | ||
818 | { | ||
819 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
820 | |||
821 | //VTResume(); // VTune | ||
822 | |||
823 | lldebugs << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << llendl; | ||
824 | |||
825 | mPelvisp = NULL; | ||
826 | |||
827 | for( S32 i=0; i<LOCTEX_NUM_ENTRIES; i++ ) | ||
828 | { | ||
829 | mLocalTextureBaked[i] = FALSE; | ||
830 | mLocalTextureDiscard[i] = MAX_DISCARD_LEVEL+1; | ||
831 | } | ||
832 | |||
833 | mDirtyMesh = TRUE; // Dirty geometry, need to regenerate. | ||
834 | mShadow0Facep = NULL; | ||
835 | mShadow1Facep = NULL; | ||
836 | mHeadp = NULL; | ||
837 | |||
838 | mIsBuilt = FALSE; | ||
839 | |||
840 | mNumJoints = 0; | ||
841 | mSkeleton = NULL; | ||
842 | mScreenp = NULL; | ||
843 | |||
844 | mNumCollisionVolumes = 0; | ||
845 | mCollisionVolumes = NULL; | ||
846 | |||
847 | // set up animation variables | ||
848 | mSpeed = 0.f; | ||
849 | setAnimationData("Speed", &mSpeed); | ||
850 | |||
851 | strcpy(mAvatarDefinition, AVATAR_DEFAULT_CHAR); | ||
852 | |||
853 | if (id == gAgentID) | ||
854 | { | ||
855 | mIsSelf = TRUE; | ||
856 | gAgent.setAvatarObject(this); | ||
857 | lldebugs << "Marking avatar as self " << id << llendl; | ||
858 | } | ||
859 | else | ||
860 | { | ||
861 | mIsSelf = FALSE; | ||
862 | } | ||
863 | |||
864 | setNumTEs(TEX_NUM_ENTRIES); | ||
865 | |||
866 | mbCanSelect = TRUE; | ||
867 | |||
868 | mSignaledAnimations.clear(); | ||
869 | mPlayingAnimations.clear(); | ||
870 | |||
871 | mWasOnGroundLeft = FALSE; | ||
872 | mWasOnGroundRight = FALSE; | ||
873 | |||
874 | mTimeLast = 0.0f; | ||
875 | mSpeedAccum = 0.0f; | ||
876 | |||
877 | mRippleTimeLast = 0.f; | ||
878 | |||
879 | mShadowImageID = LLUUID( gViewerArt.getString("foot_shadow.tga")); | ||
880 | mShadowImagep = gImageList.getImage(mShadowImageID); | ||
881 | mShadowImagep->bind(); | ||
882 | mShadowImagep->setClamp(TRUE, TRUE); | ||
883 | |||
884 | mInAir = FALSE; | ||
885 | |||
886 | mStepOnLand = TRUE; | ||
887 | mStepMaterial = 0; | ||
888 | |||
889 | //------------------------------------------------------------------------- | ||
890 | // initialize joint, mesh and shape members | ||
891 | //------------------------------------------------------------------------- | ||
892 | mRoot.setName( "mRoot" ); | ||
893 | |||
894 | // skinned mesh objects | ||
895 | mHairLOD.setName("mHairLOD"); | ||
896 | mHairMesh0.setName("mHairMesh0"); | ||
897 | mHairMesh0.setMeshID(MESH_ID_HAIR); | ||
898 | mHairMesh1.setName("mHairMesh1"); | ||
899 | mHairMesh2.setName("mHairMesh2"); | ||
900 | mHairMesh3.setName("mHairMesh3"); | ||
901 | mHairMesh4.setName("mHairMesh4"); | ||
902 | mHairMesh5.setName("mHairMesh5"); | ||
903 | |||
904 | mHairMesh0.setIsTransparent(TRUE); | ||
905 | mHairMesh1.setIsTransparent(TRUE); | ||
906 | mHairMesh2.setIsTransparent(TRUE); | ||
907 | mHairMesh3.setIsTransparent(TRUE); | ||
908 | mHairMesh4.setIsTransparent(TRUE); | ||
909 | mHairMesh5.setIsTransparent(TRUE); | ||
910 | |||
911 | mHeadLOD.setName("mHeadLOD"); | ||
912 | mHeadMesh0.setName("mHeadMesh0"); | ||
913 | mHeadMesh0.setMeshID(MESH_ID_HEAD); | ||
914 | mHeadMesh1.setName("mHeadMesh1"); | ||
915 | mHeadMesh2.setName("mHeadMesh2"); | ||
916 | mHeadMesh3.setName("mHeadMesh3"); | ||
917 | mHeadMesh4.setName("mHeadMesh4"); | ||
918 | |||
919 | mEyeLashLOD.setName("mEyeLashLOD"); | ||
920 | mEyeLashMesh0.setName("mEyeLashMesh0"); | ||
921 | mEyeLashMesh0.setMeshID(MESH_ID_HEAD); | ||
922 | mEyeLashMesh0.setIsTransparent(TRUE); | ||
923 | |||
924 | mUpperBodyLOD.setName("mUpperBodyLOD"); | ||
925 | mUpperBodyMesh0.setName("mUpperBodyMesh0"); | ||
926 | mUpperBodyMesh0.setMeshID(MESH_ID_UPPER_BODY); | ||
927 | mUpperBodyMesh1.setName("mUpperBodyMesh1"); | ||
928 | mUpperBodyMesh2.setName("mUpperBodyMesh2"); | ||
929 | mUpperBodyMesh3.setName("mUpperBodyMesh3"); | ||
930 | mUpperBodyMesh4.setName("mUpperBodyMesh4"); | ||
931 | |||
932 | mLowerBodyLOD.setName("mLowerBodyLOD"); | ||
933 | mLowerBodyMesh0.setName("mLowerBodyMesh0"); | ||
934 | mLowerBodyMesh0.setMeshID(MESH_ID_LOWER_BODY); | ||
935 | mLowerBodyMesh1.setName("mLowerBodyMesh1"); | ||
936 | mLowerBodyMesh2.setName("mLowerBodyMesh2"); | ||
937 | mLowerBodyMesh3.setName("mLowerBodyMesh3"); | ||
938 | mLowerBodyMesh4.setName("mLowerBodyMesh4"); | ||
939 | |||
940 | mEyeBallLeftLOD.setName("mEyeBallLeftLOD"); | ||
941 | mEyeBallLeftMesh0.setName("mEyeBallLeftMesh0"); | ||
942 | mEyeBallLeftMesh1.setName("mEyeBallLeftMesh1"); | ||
943 | |||
944 | mEyeBallRightLOD.setName("mEyeBallRightLOD"); | ||
945 | mEyeBallRightMesh0.setName("mEyeBallRightMesh0"); | ||
946 | mEyeBallRightMesh1.setName("mEyeBallRightMesh1"); | ||
947 | |||
948 | mSkirtLOD.setName("mSkirtLOD"); | ||
949 | mSkirtMesh0.setName("mSkirtMesh0"); | ||
950 | mSkirtMesh0.setMeshID(MESH_ID_SKIRT); | ||
951 | mSkirtMesh1.setName("mSkirtMesh1"); | ||
952 | mSkirtMesh2.setName("mSkirtMesh2"); | ||
953 | mSkirtMesh3.setName("mSkirtMesh3"); | ||
954 | mSkirtMesh4.setName("mSkirtMesh4"); | ||
955 | |||
956 | mSkirtMesh0.setIsTransparent(TRUE); | ||
957 | mSkirtMesh1.setIsTransparent(TRUE); | ||
958 | mSkirtMesh2.setIsTransparent(TRUE); | ||
959 | mSkirtMesh3.setIsTransparent(TRUE); | ||
960 | mSkirtMesh4.setIsTransparent(TRUE); | ||
961 | |||
962 | // set the pick names for the avatar | ||
963 | mHeadMesh0.setPickName( LLViewerJoint::PN_0 ); | ||
964 | mHeadMesh1.setPickName( LLViewerJoint::PN_0 ); | ||
965 | mHeadMesh2.setPickName( LLViewerJoint::PN_0 ); | ||
966 | mHeadMesh3.setPickName( LLViewerJoint::PN_0 ); | ||
967 | mHeadMesh4.setPickName( LLViewerJoint::PN_0 ); | ||
968 | mEyeLashMesh0.setPickName( LLViewerJoint::PN_0 ); | ||
969 | |||
970 | mUpperBodyMesh0.setPickName( LLViewerJoint::PN_1 ); | ||
971 | mUpperBodyMesh1.setPickName( LLViewerJoint::PN_1 ); | ||
972 | mUpperBodyMesh2.setPickName( LLViewerJoint::PN_1 ); | ||
973 | mUpperBodyMesh3.setPickName( LLViewerJoint::PN_1 ); | ||
974 | mUpperBodyMesh4.setPickName( LLViewerJoint::PN_1 ); | ||
975 | |||
976 | mLowerBodyMesh0.setPickName( LLViewerJoint::PN_2 ); | ||
977 | mLowerBodyMesh1.setPickName( LLViewerJoint::PN_2 ); | ||
978 | mLowerBodyMesh2.setPickName( LLViewerJoint::PN_2 ); | ||
979 | mLowerBodyMesh3.setPickName( LLViewerJoint::PN_2 ); | ||
980 | mLowerBodyMesh4.setPickName( LLViewerJoint::PN_2 ); | ||
981 | |||
982 | mEyeBallLeftMesh0.setPickName( LLViewerJoint::PN_3 ); | ||
983 | mEyeBallLeftMesh1.setPickName( LLViewerJoint::PN_3 ); | ||
984 | mEyeBallRightMesh0.setPickName( LLViewerJoint::PN_3 ); | ||
985 | mEyeBallRightMesh1.setPickName( LLViewerJoint::PN_3 ); | ||
986 | |||
987 | mHairMesh0.setPickName( LLViewerJoint::PN_4); | ||
988 | mHairMesh1.setPickName( LLViewerJoint::PN_4); | ||
989 | mHairMesh2.setPickName( LLViewerJoint::PN_4); | ||
990 | mHairMesh3.setPickName( LLViewerJoint::PN_4); | ||
991 | mHairMesh4.setPickName( LLViewerJoint::PN_4); | ||
992 | mHairMesh5.setPickName( LLViewerJoint::PN_4); | ||
993 | |||
994 | mSkirtMesh0.setPickName( LLViewerJoint::PN_5 ); | ||
995 | mSkirtMesh1.setPickName( LLViewerJoint::PN_5 ); | ||
996 | mSkirtMesh2.setPickName( LLViewerJoint::PN_5 ); | ||
997 | mSkirtMesh3.setPickName( LLViewerJoint::PN_5 ); | ||
998 | mSkirtMesh4.setPickName( LLViewerJoint::PN_5 ); | ||
999 | |||
1000 | // material settings | ||
1001 | |||
1002 | mEyeBallLeftMesh0.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); | ||
1003 | mEyeBallLeftMesh1.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); | ||
1004 | mEyeBallRightMesh0.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); | ||
1005 | mEyeBallRightMesh1.setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f ); | ||
1006 | |||
1007 | //------------------------------------------------------------------------- | ||
1008 | // register motions | ||
1009 | //------------------------------------------------------------------------- | ||
1010 | if (LLCharacter::sInstances.getLength() == 1) | ||
1011 | { | ||
1012 | LLKeyframeMotion::setVFS(gStaticVFS); | ||
1013 | addMotion( ANIM_AGENT_BUSY, LLNullMotion::create ); | ||
1014 | addMotion( ANIM_AGENT_CROUCH, LLKeyframeStandMotion::create ); | ||
1015 | addMotion( ANIM_AGENT_CROUCHWALK, LLKeyframeWalkMotion::create ); | ||
1016 | addMotion( ANIM_AGENT_EXPRESS_AFRAID, LLEmote::create ); | ||
1017 | addMotion( ANIM_AGENT_EXPRESS_ANGER, LLEmote::create ); | ||
1018 | addMotion( ANIM_AGENT_EXPRESS_BORED, LLEmote::create ); | ||
1019 | addMotion( ANIM_AGENT_EXPRESS_CRY, LLEmote::create ); | ||
1020 | addMotion( ANIM_AGENT_EXPRESS_DISDAIN, LLEmote::create ); | ||
1021 | addMotion( ANIM_AGENT_EXPRESS_EMBARRASSED, LLEmote::create ); | ||
1022 | addMotion( ANIM_AGENT_EXPRESS_FROWN, LLEmote::create ); | ||
1023 | addMotion( ANIM_AGENT_EXPRESS_KISS, LLEmote::create ); | ||
1024 | addMotion( ANIM_AGENT_EXPRESS_LAUGH, LLEmote::create ); | ||
1025 | addMotion( ANIM_AGENT_EXPRESS_OPEN_MOUTH, LLEmote::create ); | ||
1026 | addMotion( ANIM_AGENT_EXPRESS_REPULSED, LLEmote::create ); | ||
1027 | addMotion( ANIM_AGENT_EXPRESS_SAD, LLEmote::create ); | ||
1028 | addMotion( ANIM_AGENT_EXPRESS_SHRUG, LLEmote::create ); | ||
1029 | addMotion( ANIM_AGENT_EXPRESS_SMILE, LLEmote::create ); | ||
1030 | addMotion( ANIM_AGENT_EXPRESS_SURPRISE, LLEmote::create ); | ||
1031 | addMotion( ANIM_AGENT_EXPRESS_TONGUE_OUT, LLEmote::create ); | ||
1032 | addMotion( ANIM_AGENT_EXPRESS_TOOTHSMILE, LLEmote::create ); | ||
1033 | addMotion( ANIM_AGENT_EXPRESS_WINK, LLEmote::create ); | ||
1034 | addMotion( ANIM_AGENT_EXPRESS_WORRY, LLEmote::create ); | ||
1035 | addMotion( ANIM_AGENT_RUN, LLKeyframeWalkMotion::create ); | ||
1036 | addMotion( ANIM_AGENT_STAND, LLKeyframeStandMotion::create ); | ||
1037 | addMotion( ANIM_AGENT_STAND_1, LLKeyframeStandMotion::create ); | ||
1038 | addMotion( ANIM_AGENT_STAND_2, LLKeyframeStandMotion::create ); | ||
1039 | addMotion( ANIM_AGENT_STAND_3, LLKeyframeStandMotion::create ); | ||
1040 | addMotion( ANIM_AGENT_STAND_4, LLKeyframeStandMotion::create ); | ||
1041 | addMotion( ANIM_AGENT_STANDUP, LLKeyframeFallMotion::create ); | ||
1042 | addMotion( ANIM_AGENT_TURNLEFT, LLKeyframeWalkMotion::create ); | ||
1043 | addMotion( ANIM_AGENT_TURNRIGHT, LLKeyframeWalkMotion::create ); | ||
1044 | addMotion( ANIM_AGENT_WALK, LLKeyframeWalkMotion::create ); | ||
1045 | |||
1046 | // motions without a start/stop bit | ||
1047 | addMotion( ANIM_AGENT_BODY_NOISE, LLBodyNoiseMotion::create ); | ||
1048 | addMotion( ANIM_AGENT_BREATHE_ROT, LLBreatheMotionRot::create ); | ||
1049 | addMotion( ANIM_AGENT_EDITING, LLEditingMotion::create ); | ||
1050 | addMotion( ANIM_AGENT_EYE, LLEyeMotion::create ); | ||
1051 | addMotion( ANIM_AGENT_FEMALE_WALK, LLKeyframeWalkMotion::create ); | ||
1052 | addMotion( ANIM_AGENT_FLY_ADJUST, LLFlyAdjustMotion::create ); | ||
1053 | addMotion( ANIM_AGENT_HAND_MOTION, LLHandMotion::create ); | ||
1054 | addMotion( ANIM_AGENT_HEAD_ROT, LLHeadRotMotion::create ); | ||
1055 | addMotion( ANIM_AGENT_PELVIS_FIX, LLPelvisFixMotion::create ); | ||
1056 | addMotion( ANIM_AGENT_SIT_FEMALE, LLKeyframeMotion::create ); | ||
1057 | addMotion( ANIM_AGENT_TARGET, LLTargetingMotion::create ); | ||
1058 | addMotion( ANIM_AGENT_WALK_ADJUST, LLWalkAdjustMotion::create ); | ||
1059 | } | ||
1060 | |||
1061 | if (gNoRender) | ||
1062 | { | ||
1063 | return; | ||
1064 | } | ||
1065 | buildCharacter(); | ||
1066 | |||
1067 | // preload specific motions here | ||
1068 | createMotion( ANIM_AGENT_CUSTOMIZE); | ||
1069 | createMotion( ANIM_AGENT_CUSTOMIZE_DONE); | ||
1070 | |||
1071 | //VTPause(); // VTune | ||
1072 | } | ||
1073 | |||
1074 | |||
1075 | //------------------------------------------------------------------------ | ||
1076 | // LLVOAvatar::~LLVOAvatar() | ||
1077 | //------------------------------------------------------------------------ | ||
1078 | LLVOAvatar::~LLVOAvatar() | ||
1079 | { | ||
1080 | lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl; | ||
1081 | |||
1082 | if (mIsSelf) | ||
1083 | { | ||
1084 | gAgent.setAvatarObject(NULL); | ||
1085 | } | ||
1086 | |||
1087 | mRoot.removeAllChildren(); | ||
1088 | |||
1089 | delete [] mSkeleton; | ||
1090 | mSkeleton = NULL; | ||
1091 | |||
1092 | delete mScreenp; | ||
1093 | mScreenp = NULL; | ||
1094 | |||
1095 | delete [] mCollisionVolumes; | ||
1096 | mCollisionVolumes = NULL; | ||
1097 | |||
1098 | |||
1099 | mNumJoints = 0; | ||
1100 | |||
1101 | delete mHeadLayerSet; | ||
1102 | mHeadLayerSet = NULL; | ||
1103 | |||
1104 | delete mUpperBodyLayerSet; | ||
1105 | mUpperBodyLayerSet = NULL; | ||
1106 | |||
1107 | delete mLowerBodyLayerSet; | ||
1108 | mLowerBodyLayerSet = NULL; | ||
1109 | |||
1110 | delete mEyesLayerSet; | ||
1111 | mEyesLayerSet = NULL; | ||
1112 | |||
1113 | delete mSkirtLayerSet; | ||
1114 | mSkirtLayerSet = NULL; | ||
1115 | |||
1116 | mAttachmentPoints.deleteAllData(); | ||
1117 | |||
1118 | delete mTexSkinColor; | ||
1119 | mTexSkinColor = NULL; | ||
1120 | delete mTexHairColor; | ||
1121 | mTexHairColor = NULL; | ||
1122 | delete mTexEyeColor; | ||
1123 | mTexEyeColor = NULL; | ||
1124 | |||
1125 | std::for_each(mMeshes.begin(), mMeshes.end(), DeletePairedPointer()); | ||
1126 | |||
1127 | mDead = TRUE; | ||
1128 | |||
1129 | // Clean up class data | ||
1130 | LLVOAvatar::cullAvatarsByPixelArea(); | ||
1131 | |||
1132 | mAnimationSources.clear(); | ||
1133 | |||
1134 | lldebugs << "LLVOAvatar Destructor end" << llendl; | ||
1135 | } | ||
1136 | |||
1137 | void LLVOAvatar::markDead() | ||
1138 | { | ||
1139 | if (mNameText) | ||
1140 | { | ||
1141 | mNameText->markDead(); | ||
1142 | mNameText = NULL; | ||
1143 | sNumVisibleChatBubbles--; | ||
1144 | } | ||
1145 | |||
1146 | mBeam = NULL; | ||
1147 | LLViewerObject::markDead(); | ||
1148 | } | ||
1149 | |||
1150 | |||
1151 | BOOL LLVOAvatar::isFullyBaked() | ||
1152 | { | ||
1153 | if (mIsDummy) return TRUE; | ||
1154 | |||
1155 | BOOL head_baked = ( getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
1156 | BOOL upper_baked = ( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
1157 | BOOL lower_baked = ( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
1158 | BOOL eyes_baked = ( getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
1159 | BOOL skirt_baked = ( getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
1160 | |||
1161 | if (isWearingWearableType(WT_SKIRT)) | ||
1162 | { | ||
1163 | return head_baked && upper_baked && lower_baked && eyes_baked && skirt_baked; | ||
1164 | } | ||
1165 | else | ||
1166 | { | ||
1167 | return head_baked && upper_baked && lower_baked && eyes_baked; | ||
1168 | } | ||
1169 | } | ||
1170 | |||
1171 | void LLVOAvatar::deleteLayerSetCaches() | ||
1172 | { | ||
1173 | if( mHeadLayerSet ) mHeadLayerSet->deleteCaches(); | ||
1174 | if( mUpperBodyLayerSet ) mUpperBodyLayerSet->deleteCaches(); | ||
1175 | if( mLowerBodyLayerSet ) mLowerBodyLayerSet->deleteCaches(); | ||
1176 | if( mEyesLayerSet ) mEyesLayerSet->deleteCaches(); | ||
1177 | if( mSkirtLayerSet ) mSkirtLayerSet->deleteCaches(); | ||
1178 | } | ||
1179 | |||
1180 | // static | ||
1181 | BOOL LLVOAvatar::areAllNearbyInstancesBaked() | ||
1182 | { | ||
1183 | for( LLVOAvatar* inst = (LLVOAvatar*)LLCharacter::sInstances.getFirstData(); | ||
1184 | inst; | ||
1185 | inst = (LLVOAvatar*)LLCharacter::sInstances.getNextData() ) | ||
1186 | { | ||
1187 | if( inst->isDead() ) | ||
1188 | { | ||
1189 | continue; | ||
1190 | } | ||
1191 | else | ||
1192 | if( inst->getPixelArea() < MIN_PIXEL_AREA_FOR_COMPOSITE ) | ||
1193 | { | ||
1194 | return TRUE; // Assumes sInstances is sorted by pixel area. | ||
1195 | } | ||
1196 | else | ||
1197 | if( !inst->isFullyBaked() ) | ||
1198 | { | ||
1199 | return FALSE; | ||
1200 | } | ||
1201 | } | ||
1202 | return TRUE; | ||
1203 | } | ||
1204 | |||
1205 | // static | ||
1206 | void LLVOAvatar::dumpScratchTextureByteCount() | ||
1207 | { | ||
1208 | llinfos << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << llendl; | ||
1209 | } | ||
1210 | |||
1211 | // static | ||
1212 | void LLVOAvatar::dumpBakedStatus() | ||
1213 | { | ||
1214 | LLVector3d camera_pos_global = gAgent.getCameraPositionGlobal(); | ||
1215 | |||
1216 | for( LLVOAvatar* inst = (LLVOAvatar*)LLCharacter::sInstances.getFirstData(); | ||
1217 | inst; | ||
1218 | inst = (LLVOAvatar*)LLCharacter::sInstances.getNextData() ) | ||
1219 | { | ||
1220 | llinfos << "Avatar "; | ||
1221 | |||
1222 | LLNameValue* firstname = inst->getNVPair("FirstName"); | ||
1223 | LLNameValue* lastname = inst->getNVPair("LastName"); | ||
1224 | |||
1225 | if( firstname ) | ||
1226 | { | ||
1227 | llcont << firstname->getString(); | ||
1228 | } | ||
1229 | if( lastname ) | ||
1230 | { | ||
1231 | llcont << " " << lastname->getString(); | ||
1232 | } | ||
1233 | |||
1234 | llcont << " " << inst->mID; | ||
1235 | |||
1236 | if( inst->isDead() ) | ||
1237 | { | ||
1238 | llcont << " DEAD ("<< inst->getNumRefs() << " refs)"; | ||
1239 | } | ||
1240 | |||
1241 | if( inst->mIsSelf ) | ||
1242 | { | ||
1243 | llcont << " (self)"; | ||
1244 | } | ||
1245 | |||
1246 | |||
1247 | F64 dist_to_camera = (inst->getPositionGlobal() - camera_pos_global).magVec(); | ||
1248 | llcont << " " << dist_to_camera << "m "; | ||
1249 | |||
1250 | llcont << " " << inst->mPixelArea << " pixels"; | ||
1251 | |||
1252 | if( inst->isVisible() ) | ||
1253 | { | ||
1254 | llcont << " (visible)"; | ||
1255 | } | ||
1256 | else | ||
1257 | { | ||
1258 | llcont << " (not visible)"; | ||
1259 | } | ||
1260 | |||
1261 | if( inst->isFullyBaked() ) | ||
1262 | { | ||
1263 | llcont << " Baked"; | ||
1264 | } | ||
1265 | else | ||
1266 | { | ||
1267 | llcont << " Unbaked ("; | ||
1268 | if( inst->getTEImage( TEX_HEAD_BAKED )->getID() == IMG_DEFAULT_AVATAR ) | ||
1269 | { | ||
1270 | llcont << " head"; | ||
1271 | } | ||
1272 | |||
1273 | if( inst->getTEImage( TEX_UPPER_BAKED )->getID() == IMG_DEFAULT_AVATAR ) | ||
1274 | { | ||
1275 | llcont << " upper"; | ||
1276 | } | ||
1277 | |||
1278 | if( inst->getTEImage( TEX_LOWER_BAKED )->getID() == IMG_DEFAULT_AVATAR ) | ||
1279 | { | ||
1280 | llcont << " lower"; | ||
1281 | } | ||
1282 | |||
1283 | if( inst->getTEImage( TEX_EYES_BAKED )->getID() == IMG_DEFAULT_AVATAR ) | ||
1284 | { | ||
1285 | llcont << " eyes"; | ||
1286 | } | ||
1287 | |||
1288 | if (inst->isWearingWearableType(WT_SKIRT)) | ||
1289 | { | ||
1290 | if( inst->getTEImage( TEX_SKIRT_BAKED )->getID() == IMG_DEFAULT_AVATAR ) | ||
1291 | { | ||
1292 | llcont << " skirt"; | ||
1293 | } | ||
1294 | } | ||
1295 | |||
1296 | llcont << " ) " << inst->getUnbakedPixelAreaRank() << "/" << LLVOAvatar::sMaxOtherAvatarsToComposite; | ||
1297 | if( inst->isCulled() ) | ||
1298 | { | ||
1299 | llcont << " culled"; | ||
1300 | } | ||
1301 | } | ||
1302 | llcont << llendl; | ||
1303 | /* | ||
1304 | if( inst->isDead() ) | ||
1305 | { | ||
1306 | llinfos << "DEAD LIST " << llendl; | ||
1307 | |||
1308 | |||
1309 | for( S32 i = 0; i < inst->mOwners.count(); i++ ) | ||
1310 | { | ||
1311 | llinfos << i << llendl; | ||
1312 | LLPointer<LLViewerObject>* owner = (LLPointer<LLViewerObject>*)(inst->mOwners[i]); | ||
1313 | LLPointer<LLViewerObject>* cur; | ||
1314 | if( !owner->mName.isEmpty() ) | ||
1315 | { | ||
1316 | llinfos << " " << owner->mName << llendl; | ||
1317 | } | ||
1318 | |||
1319 | LLViewerObject* key_vo; | ||
1320 | for( key_vo = gObjectList.mActiveObjects.getFirstKey(); key_vo; key_vo = gObjectList.mActiveObjects.getNextKey() ) | ||
1321 | { | ||
1322 | cur = &(gObjectList.mActiveObjects.getCurrentDataWithoutIncrement()); | ||
1323 | if( cur == owner ) | ||
1324 | { | ||
1325 | llinfos << " gObjectList.mActiveObjects" << llendl; | ||
1326 | } | ||
1327 | } | ||
1328 | |||
1329 | for( key_vo = gObjectList.mAvatarObjects.getFirstKey(); key_vo; key_vo = gObjectList.mAvatarObjects.getNextKey() ) | ||
1330 | { | ||
1331 | cur = &(gObjectList.mAvatarObjects.getCurrentDataWithoutIncrement()); | ||
1332 | if( cur == owner ) | ||
1333 | { | ||
1334 | llinfos << " gObjectList.mAvatarObjects" << llendl; | ||
1335 | } | ||
1336 | } | ||
1337 | |||
1338 | LLUUID id; | ||
1339 | for( id = gObjectList.mDeadObjects.getFirstKey(); id; id = gObjectList.mDeadObjects.getNextKey() ) | ||
1340 | { | ||
1341 | cur = &(gObjectList.mDeadObjects.getCurrentDataWithoutIncrement()); | ||
1342 | if( cur == owner ) | ||
1343 | { | ||
1344 | llinfos << " gObjectList.mDeadObjects" << llendl; | ||
1345 | } | ||
1346 | } | ||
1347 | |||
1348 | |||
1349 | for( id = gObjectList.mUUIDObjectMap.getFirstKey(); id; id = gObjectList.mUUIDObjectMap.getNextKey() ) | ||
1350 | { | ||
1351 | cur = &(gObjectList.mUUIDObjectMap.getCurrentDataWithoutIncrement()); | ||
1352 | if( cur == owner ) | ||
1353 | { | ||
1354 | llinfos << " gObjectList.mUUIDObjectMap" << llendl; | ||
1355 | } | ||
1356 | } | ||
1357 | |||
1358 | S32 j; | ||
1359 | S32 k; | ||
1360 | for( j = 0; j < 16; j++ ) | ||
1361 | { | ||
1362 | for( k = 0; k < 10; k++ ) | ||
1363 | { | ||
1364 | cur = &(gObjectList.mCloseObjects[j][k]); | ||
1365 | if( cur == owner ) | ||
1366 | { | ||
1367 | llinfos << " gObjectList.mCloseObjects" << llendl; | ||
1368 | } | ||
1369 | } | ||
1370 | } | ||
1371 | |||
1372 | for( j = 0; j < gObjectList.mObjects.count(); j++ ) | ||
1373 | { | ||
1374 | cur = &(gObjectList.mObjects[j]); | ||
1375 | if( cur == owner ) | ||
1376 | { | ||
1377 | llinfos << " gObjectList.mObjects" << llendl; | ||
1378 | } | ||
1379 | } | ||
1380 | |||
1381 | for( j = 0; j < gObjectList.mMapObjects.count(); j++ ) | ||
1382 | { | ||
1383 | cur = &(gObjectList.mMapObjects[j]); | ||
1384 | if( cur == owner ) | ||
1385 | { | ||
1386 | llinfos << " gObjectList.mMapObjects" << llendl; | ||
1387 | } | ||
1388 | } | ||
1389 | } | ||
1390 | } | ||
1391 | */ | ||
1392 | } | ||
1393 | } | ||
1394 | |||
1395 | //static | ||
1396 | void LLVOAvatar::cleanupVertexPrograms() | ||
1397 | { | ||
1398 | } | ||
1399 | |||
1400 | //static | ||
1401 | void LLVOAvatar::initVertexPrograms() | ||
1402 | { | ||
1403 | } | ||
1404 | |||
1405 | //static | ||
1406 | void LLVOAvatar::restoreGL() | ||
1407 | { | ||
1408 | LLVOAvatar* inst; | ||
1409 | for( inst = (LLVOAvatar*)LLCharacter::sInstances.getFirstData(); | ||
1410 | inst; | ||
1411 | inst = (LLVOAvatar*)LLCharacter::sInstances.getNextData() ) | ||
1412 | { | ||
1413 | inst->setCompositeUpdatesEnabled( TRUE ); | ||
1414 | inst->invalidateComposite( inst->mHeadLayerSet, FALSE ); | ||
1415 | inst->invalidateComposite( inst->mLowerBodyLayerSet, FALSE ); | ||
1416 | inst->invalidateComposite( inst->mUpperBodyLayerSet, FALSE ); | ||
1417 | inst->invalidateComposite( inst->mEyesLayerSet, FALSE ); | ||
1418 | inst->invalidateComposite( inst->mSkirtLayerSet, FALSE ); | ||
1419 | inst->updateMeshTextures(); | ||
1420 | } | ||
1421 | } | ||
1422 | |||
1423 | //static | ||
1424 | void LLVOAvatar::destroyGL() | ||
1425 | { | ||
1426 | deleteCachedImages(); | ||
1427 | cleanupVertexPrograms(); | ||
1428 | } | ||
1429 | |||
1430 | // static | ||
1431 | void LLVOAvatar::deleteCachedImages() | ||
1432 | { | ||
1433 | if (LLTexLayerSet::sHasCaches) | ||
1434 | { | ||
1435 | lldebugs << "Deleting layer set caches" << llendl; | ||
1436 | for( LLVOAvatar* inst = (LLVOAvatar*)LLCharacter::sInstances.getFirstData(); | ||
1437 | inst; | ||
1438 | inst = (LLVOAvatar*)LLCharacter::sInstances.getNextData() ) | ||
1439 | { | ||
1440 | inst->deleteLayerSetCaches(); | ||
1441 | } | ||
1442 | LLTexLayerSet::sHasCaches = FALSE; | ||
1443 | } | ||
1444 | |||
1445 | for( GLuint* namep = (GLuint*)sScratchTexNames.getFirstData(); | ||
1446 | namep; | ||
1447 | namep = (GLuint*)sScratchTexNames.getNextData() ) | ||
1448 | { | ||
1449 | glDeleteTextures(1, namep ); | ||
1450 | stop_glerror(); | ||
1451 | } | ||
1452 | |||
1453 | if( sScratchTexBytes ) | ||
1454 | { | ||
1455 | lldebugs << "Clearing Scratch Textures " << (sScratchTexBytes/1024) << "KB" << llendl; | ||
1456 | |||
1457 | sScratchTexNames.deleteAllData(); | ||
1458 | LLVOAvatar::sScratchTexLastBindTime.deleteAllData(); | ||
1459 | LLImageGL::sGlobalTextureMemory -= sScratchTexBytes; | ||
1460 | sScratchTexBytes = 0; | ||
1461 | } | ||
1462 | |||
1463 | gTexStaticImageList.deleteCachedImages(); | ||
1464 | } | ||
1465 | |||
1466 | |||
1467 | //------------------------------------------------------------------------ | ||
1468 | // static | ||
1469 | // LLVOAvatar::initClass() | ||
1470 | //------------------------------------------------------------------------ | ||
1471 | void LLVOAvatar::initClass() | ||
1472 | { | ||
1473 | LLVOAvatar::sMaxOtherAvatarsToComposite = gSavedSettings.getS32("AvatarCompositeLimit"); | ||
1474 | |||
1475 | char xmlFile[MAX_PATH]; | ||
1476 | |||
1477 | sprintf(xmlFile, "%s_lad.xml", gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR).c_str()); | ||
1478 | BOOL success = sXMLTree.parseFile( xmlFile, FALSE ); | ||
1479 | if (!success) | ||
1480 | { | ||
1481 | llerrs << "Problem reading avatar configuration file:" << xmlFile << llendl; | ||
1482 | } | ||
1483 | |||
1484 | // now sanity check xml file | ||
1485 | LLXmlTreeNode* root = sXMLTree.getRoot(); | ||
1486 | if (!root) | ||
1487 | { | ||
1488 | llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl; | ||
1489 | } | ||
1490 | |||
1491 | //------------------------------------------------------------------------- | ||
1492 | // <linden_avatar version="1.0"> (root) | ||
1493 | //------------------------------------------------------------------------- | ||
1494 | if( !root->hasName( "linden_avatar" ) ) | ||
1495 | { | ||
1496 | llerrs << "Invalid avatar file header: " << xmlFile << llendl; | ||
1497 | } | ||
1498 | |||
1499 | LLString version; | ||
1500 | static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); | ||
1501 | if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) | ||
1502 | { | ||
1503 | llerrs << "Invalid avatar file version: " << version << " in file: " << xmlFile << llendl; | ||
1504 | } | ||
1505 | |||
1506 | S32 wearable_def_version = 1; | ||
1507 | static LLStdStringHandle wearable_definition_version_string = LLXmlTree::addAttributeString("wearable_definition_version"); | ||
1508 | root->getFastAttributeS32( wearable_definition_version_string, wearable_def_version ); | ||
1509 | LLWearable::setCurrentDefinitionVersion( wearable_def_version ); | ||
1510 | |||
1511 | LLString mesh_file_name; | ||
1512 | |||
1513 | LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" ); | ||
1514 | if (!skeleton_node) | ||
1515 | { | ||
1516 | llerrs << "No skeleton in avatar configuration file: " << xmlFile << llendl; | ||
1517 | } | ||
1518 | |||
1519 | LLString skeleton_file_name; | ||
1520 | static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name"); | ||
1521 | if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name)) | ||
1522 | { | ||
1523 | llerrs << "No file name in skeleton node in avatar config file: " << xmlFile << llendl; | ||
1524 | } | ||
1525 | |||
1526 | std::string skeleton_path; | ||
1527 | skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name); | ||
1528 | if (!parseSkeletonFile(skeleton_path)) | ||
1529 | { | ||
1530 | llerrs << "Error parsing skeleton file: " << skeleton_path << llendl; | ||
1531 | } | ||
1532 | |||
1533 | // Process XML data | ||
1534 | |||
1535 | // avatar_skeleton.xml | ||
1536 | llassert(!sSkeletonInfo); | ||
1537 | sSkeletonInfo = new LLVOAvatarSkeletonInfo; | ||
1538 | if (!sSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot())) | ||
1539 | { | ||
1540 | llerrs << "Error parsing skeleton XML file" << llendl; | ||
1541 | } | ||
1542 | // parse avatar_lad.xml | ||
1543 | llassert(!sAvatarInfo); | ||
1544 | sAvatarInfo = new LLVOAvatarInfo; | ||
1545 | if (!sAvatarInfo->parseXmlSkeletonNode(root)) | ||
1546 | { | ||
1547 | llerrs << "Error parsing skeleton node in avatar XML file" << llendl; | ||
1548 | } | ||
1549 | if (!sAvatarInfo->parseXmlMeshNodes(root)) | ||
1550 | { | ||
1551 | llerrs << "Error parsing skeleton node in avatar XML file" << llendl; | ||
1552 | } | ||
1553 | if (!sAvatarInfo->parseXmlColorNodes(root)) | ||
1554 | { | ||
1555 | llerrs << "Error parsing skeleton node in avatar XML file" << llendl; | ||
1556 | } | ||
1557 | if (!sAvatarInfo->parseXmlLayerNodes(root)) | ||
1558 | { | ||
1559 | llerrs << "Error parsing skeleton node in avatar XML file" << llendl; | ||
1560 | } | ||
1561 | if (!sAvatarInfo->parseXmlDriverNodes(root)) | ||
1562 | { | ||
1563 | llerrs << "Error parsing skeleton node in avatar XML file" << llendl; | ||
1564 | } | ||
1565 | } | ||
1566 | |||
1567 | |||
1568 | void LLVOAvatar::cleanupClass() | ||
1569 | { | ||
1570 | delete sAvatarInfo; | ||
1571 | sAvatarInfo = NULL; | ||
1572 | delete sSkeletonInfo; | ||
1573 | sSkeletonInfo = NULL; | ||
1574 | sSkeletonXMLTree.cleanup(); | ||
1575 | sXMLTree.cleanup(); | ||
1576 | } | ||
1577 | |||
1578 | |||
1579 | //----------------------------------------------------------------------------- | ||
1580 | // parseSkeletonFile() | ||
1581 | //----------------------------------------------------------------------------- | ||
1582 | BOOL LLVOAvatar::parseSkeletonFile(const LLString& filename) | ||
1583 | { | ||
1584 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
1585 | |||
1586 | //------------------------------------------------------------------------- | ||
1587 | // parse the file | ||
1588 | //------------------------------------------------------------------------- | ||
1589 | BOOL success = sSkeletonXMLTree.parseFile( filename, FALSE ); | ||
1590 | |||
1591 | if (!success) | ||
1592 | { | ||
1593 | llerrs << "Can't parse skeleton file: " << filename << llendl; | ||
1594 | return FALSE; | ||
1595 | } | ||
1596 | |||
1597 | // now sanity check xml file | ||
1598 | LLXmlTreeNode* root = sSkeletonXMLTree.getRoot(); | ||
1599 | if (!root) | ||
1600 | { | ||
1601 | llerrs << "No root node found in avatar skeleton file: " << filename << llendl; | ||
1602 | } | ||
1603 | |||
1604 | if( !root->hasName( "linden_skeleton" ) ) | ||
1605 | { | ||
1606 | llerrs << "Invalid avatar skeleton file header: " << filename << llendl; | ||
1607 | } | ||
1608 | |||
1609 | LLString version; | ||
1610 | static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version"); | ||
1611 | if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") ) | ||
1612 | { | ||
1613 | llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl; | ||
1614 | } | ||
1615 | |||
1616 | return TRUE; | ||
1617 | } | ||
1618 | |||
1619 | //----------------------------------------------------------------------------- | ||
1620 | // setupBone() | ||
1621 | //----------------------------------------------------------------------------- | ||
1622 | BOOL LLVOAvatar::setupBone(LLVOAvatarBoneInfo* info, LLViewerJoint* parent) | ||
1623 | { | ||
1624 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
1625 | |||
1626 | LLViewerJoint* joint = NULL; | ||
1627 | |||
1628 | if (info->mIsJoint) | ||
1629 | { | ||
1630 | joint = (LLViewerJoint*)getCharacterJoint(sCurJoint); | ||
1631 | if (!joint) | ||
1632 | { | ||
1633 | llwarns << "Too many bones" << llendl; | ||
1634 | return FALSE; | ||
1635 | } | ||
1636 | joint->setName( info->mName ); | ||
1637 | } | ||
1638 | else // collision volume | ||
1639 | { | ||
1640 | if (sCurVolume >= (S32)mNumCollisionVolumes) | ||
1641 | { | ||
1642 | llwarns << "Too many bones" << llendl; | ||
1643 | return FALSE; | ||
1644 | } | ||
1645 | joint = (LLViewerJoint*)(&mCollisionVolumes[sCurVolume]); | ||
1646 | |||
1647 | joint->setName( info->mName ); | ||
1648 | } | ||
1649 | |||
1650 | // add to parent | ||
1651 | if (parent) | ||
1652 | { | ||
1653 | parent->addChild( joint ); | ||
1654 | } | ||
1655 | |||
1656 | joint->setPosition(info->mPos); | ||
1657 | |||
1658 | joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY], | ||
1659 | info->mRot.mV[VZ], LLQuaternion::XYZ)); | ||
1660 | |||
1661 | joint->setScale(info->mScale); | ||
1662 | |||
1663 | |||
1664 | if (info->mIsJoint) | ||
1665 | { | ||
1666 | joint->setSkinOffset( info->mPivot ); | ||
1667 | sCurJoint++; | ||
1668 | } | ||
1669 | else // collision volume | ||
1670 | { | ||
1671 | sCurVolume++; | ||
1672 | } | ||
1673 | |||
1674 | // setup children | ||
1675 | LLVOAvatarBoneInfo::child_list_t::iterator iter; | ||
1676 | for (iter = info->mChildList.begin(); iter != info->mChildList.end(); iter++) | ||
1677 | { | ||
1678 | LLVOAvatarBoneInfo *child_info = *iter; | ||
1679 | if (!setupBone(child_info, joint)) | ||
1680 | { | ||
1681 | return FALSE; | ||
1682 | } | ||
1683 | } | ||
1684 | |||
1685 | return TRUE; | ||
1686 | } | ||
1687 | |||
1688 | //----------------------------------------------------------------------------- | ||
1689 | // buildSkeleton() | ||
1690 | //----------------------------------------------------------------------------- | ||
1691 | BOOL LLVOAvatar::buildSkeleton(LLVOAvatarSkeletonInfo *info) | ||
1692 | { | ||
1693 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
1694 | |||
1695 | //------------------------------------------------------------------------- | ||
1696 | // allocate joints | ||
1697 | //------------------------------------------------------------------------- | ||
1698 | if (!allocateCharacterJoints(info->mNumBones)) | ||
1699 | { | ||
1700 | llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl; | ||
1701 | return FALSE; | ||
1702 | } | ||
1703 | |||
1704 | //------------------------------------------------------------------------- | ||
1705 | // allocate volumes | ||
1706 | //------------------------------------------------------------------------- | ||
1707 | if (info->mNumCollisionVolumes) | ||
1708 | { | ||
1709 | if (!allocateCollisionVolumes(info->mNumCollisionVolumes)) | ||
1710 | { | ||
1711 | llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl; | ||
1712 | return FALSE; | ||
1713 | } | ||
1714 | } | ||
1715 | |||
1716 | sCurJoint = 0; | ||
1717 | sCurVolume = 0; | ||
1718 | |||
1719 | LLVOAvatarSkeletonInfo::bone_info_list_t::iterator iter; | ||
1720 | for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); iter++) | ||
1721 | { | ||
1722 | LLVOAvatarBoneInfo *info = *iter; | ||
1723 | if (!setupBone(info, NULL)) | ||
1724 | { | ||
1725 | llerrs << "Error parsing bone in skeleton file" << llendl; | ||
1726 | return FALSE; | ||
1727 | } | ||
1728 | } | ||
1729 | |||
1730 | // add special-purpose "screen" joint | ||
1731 | mScreenp = new LLViewerJoint("mScreen", NULL); | ||
1732 | // for now, put screen at origin, as it is only used during special | ||
1733 | // HUD rendering mode | ||
1734 | mScreenp->setWorldPosition(LLVector3::zero); | ||
1735 | |||
1736 | return TRUE; | ||
1737 | } | ||
1738 | |||
1739 | //----------------------------------------------------------------------------- | ||
1740 | // LLVOAvatar::buildCharacter() | ||
1741 | // Deferred initialization and rebuild of the avatar. | ||
1742 | //----------------------------------------------------------------------------- | ||
1743 | extern BOOL gPrintMessagesThisFrame; | ||
1744 | void LLVOAvatar::buildCharacter() | ||
1745 | { | ||
1746 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
1747 | |||
1748 | //------------------------------------------------------------------------- | ||
1749 | // remove all references to our existing skeleton | ||
1750 | // so we can rebuild it | ||
1751 | //------------------------------------------------------------------------- | ||
1752 | flushAllMotions(); | ||
1753 | |||
1754 | //------------------------------------------------------------------------- | ||
1755 | // remove all of mRoot's children | ||
1756 | //------------------------------------------------------------------------- | ||
1757 | mRoot.removeAllChildren(); | ||
1758 | mIsBuilt = FALSE; | ||
1759 | |||
1760 | //------------------------------------------------------------------------- | ||
1761 | // clear mesh data | ||
1762 | //------------------------------------------------------------------------- | ||
1763 | mHairMesh0.setMesh(NULL); | ||
1764 | mHairMesh1.setMesh(NULL); | ||
1765 | mHairMesh2.setMesh(NULL); | ||
1766 | mHairMesh3.setMesh(NULL); | ||
1767 | mHairMesh4.setMesh(NULL); | ||
1768 | mHairMesh5.setMesh(NULL); | ||
1769 | |||
1770 | mHeadMesh0.setMesh(NULL); | ||
1771 | mHeadMesh1.setMesh(NULL); | ||
1772 | mHeadMesh2.setMesh(NULL); | ||
1773 | mHeadMesh3.setMesh(NULL); | ||
1774 | mHeadMesh4.setMesh(NULL); | ||
1775 | |||
1776 | mEyeLashMesh0.setMesh(NULL); | ||
1777 | |||
1778 | mUpperBodyMesh0.setMesh(NULL); | ||
1779 | mUpperBodyMesh1.setMesh(NULL); | ||
1780 | mUpperBodyMesh2.setMesh(NULL); | ||
1781 | mUpperBodyMesh3.setMesh(NULL); | ||
1782 | mUpperBodyMesh4.setMesh(NULL); | ||
1783 | |||
1784 | mLowerBodyMesh0.setMesh(NULL); | ||
1785 | mLowerBodyMesh1.setMesh(NULL); | ||
1786 | mLowerBodyMesh2.setMesh(NULL); | ||
1787 | mLowerBodyMesh3.setMesh(NULL); | ||
1788 | mLowerBodyMesh4.setMesh(NULL); | ||
1789 | |||
1790 | mEyeBallLeftMesh0.setMesh(NULL); | ||
1791 | mEyeBallLeftMesh1.setMesh(NULL); | ||
1792 | mEyeBallRightMesh0.setMesh(NULL); | ||
1793 | mEyeBallRightMesh1.setMesh(NULL); | ||
1794 | |||
1795 | mSkirtMesh0.setMesh(NULL); | ||
1796 | mSkirtMesh1.setMesh(NULL); | ||
1797 | mSkirtMesh2.setMesh(NULL); | ||
1798 | mSkirtMesh3.setMesh(NULL); | ||
1799 | mSkirtMesh4.setMesh(NULL); | ||
1800 | |||
1801 | //------------------------------------------------------------------------- | ||
1802 | // (re)load our skeleton and meshes | ||
1803 | //------------------------------------------------------------------------- | ||
1804 | LLTimer timer; | ||
1805 | |||
1806 | BOOL status = loadAvatar(); | ||
1807 | stop_glerror(); | ||
1808 | |||
1809 | if (gNoRender) | ||
1810 | { | ||
1811 | // Still want to load the avatar skeleton so visual parameters work. | ||
1812 | return; | ||
1813 | } | ||
1814 | |||
1815 | gPrintMessagesThisFrame = TRUE; | ||
1816 | lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl; | ||
1817 | |||
1818 | if ( ! status ) | ||
1819 | { | ||
1820 | if ( mIsSelf ) | ||
1821 | { | ||
1822 | llerrs << "Unable to load user's avatar" << llendl; | ||
1823 | //set_avatar_character( &LLString(AVATAR_DEFAULT_CHAR)); | ||
1824 | } | ||
1825 | else | ||
1826 | { | ||
1827 | llwarns << "Unable to load other's avatar" << llendl; | ||
1828 | } | ||
1829 | return; | ||
1830 | } | ||
1831 | |||
1832 | //------------------------------------------------------------------------- | ||
1833 | // initialize "well known" joint pointers | ||
1834 | //------------------------------------------------------------------------- | ||
1835 | mPelvisp = (LLViewerJoint*)mRoot.findJoint("mPelvis"); | ||
1836 | mTorsop = (LLViewerJoint*)mRoot.findJoint("mTorso"); | ||
1837 | mChestp = (LLViewerJoint*)mRoot.findJoint("mChest"); | ||
1838 | mNeckp = (LLViewerJoint*)mRoot.findJoint("mNeck"); | ||
1839 | mHeadp = (LLViewerJoint*)mRoot.findJoint("mHead"); | ||
1840 | mSkullp = (LLViewerJoint*)mRoot.findJoint("mSkull"); | ||
1841 | mHipLeftp = (LLViewerJoint*)mRoot.findJoint("mHipLeft"); | ||
1842 | mHipRightp = (LLViewerJoint*)mRoot.findJoint("mHipRight"); | ||
1843 | mKneeLeftp = (LLViewerJoint*)mRoot.findJoint("mKneeLeft"); | ||
1844 | mKneeRightp = (LLViewerJoint*)mRoot.findJoint("mKneeRight"); | ||
1845 | mAnkleLeftp = (LLViewerJoint*)mRoot.findJoint("mAnkleLeft"); | ||
1846 | mAnkleRightp = (LLViewerJoint*)mRoot.findJoint("mAnkleRight"); | ||
1847 | mFootLeftp = (LLViewerJoint*)mRoot.findJoint("mFootLeft"); | ||
1848 | mFootRightp = (LLViewerJoint*)mRoot.findJoint("mFootRight"); | ||
1849 | mWristLeftp = (LLViewerJoint*)mRoot.findJoint("mWristLeft"); | ||
1850 | mWristRightp = (LLViewerJoint*)mRoot.findJoint("mWristRight"); | ||
1851 | mEyeLeftp = (LLViewerJoint*)mRoot.findJoint("mEyeLeft"); | ||
1852 | mEyeRightp = (LLViewerJoint*)mRoot.findJoint("mEyeRight"); | ||
1853 | |||
1854 | //------------------------------------------------------------------------- | ||
1855 | // Make sure "well known" pointers exist | ||
1856 | //------------------------------------------------------------------------- | ||
1857 | if (!(mPelvisp && | ||
1858 | mTorsop && | ||
1859 | mChestp && | ||
1860 | mNeckp && | ||
1861 | mHeadp && | ||
1862 | mSkullp && | ||
1863 | mHipLeftp && | ||
1864 | mHipRightp && | ||
1865 | mKneeLeftp && | ||
1866 | mKneeRightp && | ||
1867 | mAnkleLeftp && | ||
1868 | mAnkleRightp && | ||
1869 | mFootLeftp && | ||
1870 | mFootRightp && | ||
1871 | mWristLeftp && | ||
1872 | mWristRightp && | ||
1873 | mEyeLeftp && | ||
1874 | mEyeRightp)) | ||
1875 | { | ||
1876 | llerrs << "Failed to create avatar." << llendl; | ||
1877 | } | ||
1878 | |||
1879 | //------------------------------------------------------------------------- | ||
1880 | // initialize the pelvis | ||
1881 | //------------------------------------------------------------------------- | ||
1882 | mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) ); | ||
1883 | |||
1884 | //------------------------------------------------------------------------- | ||
1885 | // set head offset from pelvis | ||
1886 | //------------------------------------------------------------------------- | ||
1887 | updateHeadOffset(); | ||
1888 | |||
1889 | //------------------------------------------------------------------------- | ||
1890 | // start default motions | ||
1891 | //------------------------------------------------------------------------- | ||
1892 | startMotion( ANIM_AGENT_HEAD_ROT ); | ||
1893 | startMotion( ANIM_AGENT_EYE ); | ||
1894 | startMotion( ANIM_AGENT_BODY_NOISE ); | ||
1895 | startMotion( ANIM_AGENT_BREATHE_ROT ); | ||
1896 | startMotion( ANIM_AGENT_HAND_MOTION ); | ||
1897 | startMotion( ANIM_AGENT_PELVIS_FIX ); | ||
1898 | |||
1899 | //------------------------------------------------------------------------- | ||
1900 | // restart any currently active motions | ||
1901 | //------------------------------------------------------------------------- | ||
1902 | processAnimationStateChanges(); | ||
1903 | |||
1904 | mIsBuilt = TRUE; | ||
1905 | stop_glerror(); | ||
1906 | |||
1907 | //------------------------------------------------------------------------- | ||
1908 | // build the attach and detach menus | ||
1909 | //------------------------------------------------------------------------- | ||
1910 | if (mIsSelf) | ||
1911 | { | ||
1912 | gAttachBodyPartPieMenus[0] = NULL; | ||
1913 | gAttachBodyPartPieMenus[1] = new LLPieMenu("Right Arm >"); | ||
1914 | gAttachBodyPartPieMenus[2] = new LLPieMenu("Head >"); | ||
1915 | gAttachBodyPartPieMenus[3] = new LLPieMenu("Left Arm >"); | ||
1916 | gAttachBodyPartPieMenus[4] = NULL; | ||
1917 | gAttachBodyPartPieMenus[5] = new LLPieMenu("Left Leg >"); | ||
1918 | gAttachBodyPartPieMenus[6] = new LLPieMenu("Torso >"); | ||
1919 | gAttachBodyPartPieMenus[7] = new LLPieMenu("Right Leg >"); | ||
1920 | |||
1921 | gDetachBodyPartPieMenus[0] = NULL; | ||
1922 | gDetachBodyPartPieMenus[1] = new LLPieMenu("Right Arm >"); | ||
1923 | gDetachBodyPartPieMenus[2] = new LLPieMenu("Head >"); | ||
1924 | gDetachBodyPartPieMenus[3] = new LLPieMenu("Left Arm >"); | ||
1925 | gDetachBodyPartPieMenus[4] = NULL; | ||
1926 | gDetachBodyPartPieMenus[5] = new LLPieMenu("Left Leg >"); | ||
1927 | gDetachBodyPartPieMenus[6] = new LLPieMenu("Torso >"); | ||
1928 | gDetachBodyPartPieMenus[7] = new LLPieMenu("Right Leg >"); | ||
1929 | |||
1930 | for (S32 i = 0; i < 8; i++) | ||
1931 | { | ||
1932 | if (gAttachBodyPartPieMenus[i]) | ||
1933 | { | ||
1934 | gAttachPieMenu->appendMenu( gAttachBodyPartPieMenus[i] ); | ||
1935 | } | ||
1936 | else | ||
1937 | { | ||
1938 | BOOL attachment_found = FALSE; | ||
1939 | for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); | ||
1940 | attachment; | ||
1941 | attachment = mAttachmentPoints.getNextData()) | ||
1942 | { | ||
1943 | if (attachment->getGroup() == i) | ||
1944 | { | ||
1945 | LLMenuItemCallGL* item; | ||
1946 | item = new LLMenuItemCallGL(attachment->getName(), | ||
1947 | &handle_attach_to_avatar, | ||
1948 | object_selected_and_point_valid, | ||
1949 | attachment); | ||
1950 | gAttachPieMenu->append(item); | ||
1951 | |||
1952 | attachment_found = TRUE; | ||
1953 | break; | ||
1954 | |||
1955 | } | ||
1956 | } | ||
1957 | |||
1958 | if (!attachment_found) | ||
1959 | { | ||
1960 | gAttachPieMenu->appendSeparator(); | ||
1961 | } | ||
1962 | } | ||
1963 | |||
1964 | if (gDetachBodyPartPieMenus[i]) | ||
1965 | { | ||
1966 | gDetachPieMenu->appendMenu( gDetachBodyPartPieMenus[i] ); | ||
1967 | } | ||
1968 | else | ||
1969 | { | ||
1970 | BOOL attachment_found = FALSE; | ||
1971 | for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); | ||
1972 | attachment; | ||
1973 | attachment = mAttachmentPoints.getNextData()) | ||
1974 | { | ||
1975 | if (attachment->getGroup() == i) | ||
1976 | { | ||
1977 | gDetachPieMenu->append(new LLMenuItemCallGL(attachment->getName(), | ||
1978 | &handle_detach_from_avatar, object_attached, attachment)); | ||
1979 | |||
1980 | attachment_found = TRUE; | ||
1981 | break; | ||
1982 | } | ||
1983 | } | ||
1984 | |||
1985 | if (!attachment_found) | ||
1986 | { | ||
1987 | gDetachPieMenu->appendSeparator(); | ||
1988 | } | ||
1989 | } | ||
1990 | } | ||
1991 | |||
1992 | // add screen attachments | ||
1993 | for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); | ||
1994 | attachment; | ||
1995 | attachment = mAttachmentPoints.getNextData()) | ||
1996 | { | ||
1997 | if (attachment->getGroup() == 8) | ||
1998 | { | ||
1999 | LLMenuItemCallGL* item; | ||
2000 | item = new LLMenuItemCallGL(attachment->getName(), | ||
2001 | &handle_attach_to_avatar, | ||
2002 | object_selected_and_point_valid, | ||
2003 | attachment); | ||
2004 | gAttachScreenPieMenu->append(item); | ||
2005 | gDetachScreenPieMenu->append(new LLMenuItemCallGL(attachment->getName(), | ||
2006 | &handle_detach_from_avatar, object_attached, attachment)); | ||
2007 | } | ||
2008 | } | ||
2009 | |||
2010 | for (S32 pass = 0; pass < 2; pass++) | ||
2011 | { | ||
2012 | for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); | ||
2013 | attachment; | ||
2014 | attachment = mAttachmentPoints.getNextData()) | ||
2015 | { | ||
2016 | if (attachment->getIsHUDAttachment() != (pass == 1)) | ||
2017 | { | ||
2018 | continue; | ||
2019 | } | ||
2020 | gAttachSubMenu->append(new LLMenuItemCallGL(attachment->getName(), | ||
2021 | &handle_attach_to_avatar, object_selected_and_point_valid, &attach_label, attachment)); | ||
2022 | gDetachSubMenu->append(new LLMenuItemCallGL(attachment->getName(), | ||
2023 | &handle_detach_from_avatar, object_attached, &detach_label, attachment)); | ||
2024 | |||
2025 | } | ||
2026 | if (pass == 0) | ||
2027 | { | ||
2028 | // put separator between non-hud and hud attachments | ||
2029 | gAttachSubMenu->appendSeparator(); | ||
2030 | gDetachSubMenu->appendSeparator(); | ||
2031 | } | ||
2032 | } | ||
2033 | |||
2034 | for (S32 group = 0; group < 8; group++) | ||
2035 | { | ||
2036 | // skip over groups that don't have sub menus | ||
2037 | if (!gAttachBodyPartPieMenus[group] || !gDetachBodyPartPieMenus[group]) | ||
2038 | { | ||
2039 | continue; | ||
2040 | } | ||
2041 | |||
2042 | std::multimap<S32, LLViewerJointAttachment*> attachment_pie_menu_map; | ||
2043 | |||
2044 | // gather up all attachment points assigned to this group, and throw into map sorted by pie slice number | ||
2045 | for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); | ||
2046 | attachment; | ||
2047 | attachment = mAttachmentPoints.getNextData()) | ||
2048 | { | ||
2049 | if(attachment->getGroup() == group) | ||
2050 | { | ||
2051 | // use multimap to provide a partial order off of the pie slice key | ||
2052 | attachment_pie_menu_map.insert(std::pair<S32, LLViewerJointAttachment*>(attachment->getPieSlice(), attachment)); | ||
2053 | } | ||
2054 | } | ||
2055 | |||
2056 | // add in requested order to pie menu, inserting separators as necessary | ||
2057 | std::multimap<S32, LLViewerJointAttachment*>::iterator attach_it; | ||
2058 | S32 cur_pie_slice = 0; | ||
2059 | for (attach_it = attachment_pie_menu_map.begin(); attach_it != attachment_pie_menu_map.end(); ++attach_it) | ||
2060 | { | ||
2061 | S32 requested_pie_slice = attach_it->first; | ||
2062 | while (cur_pie_slice < requested_pie_slice) | ||
2063 | { | ||
2064 | gAttachBodyPartPieMenus[group]->appendSeparator(); | ||
2065 | gDetachBodyPartPieMenus[group]->appendSeparator(); | ||
2066 | cur_pie_slice++; | ||
2067 | } | ||
2068 | |||
2069 | LLViewerJointAttachment* attachment = attach_it->second; | ||
2070 | |||
2071 | gAttachBodyPartPieMenus[group]->append(new LLMenuItemCallGL(attachment->getName(), | ||
2072 | &handle_attach_to_avatar, object_selected_and_point_valid, attachment)); | ||
2073 | gDetachBodyPartPieMenus[group]->append(new LLMenuItemCallGL(attachment->getName(), | ||
2074 | &handle_detach_from_avatar, object_attached, attachment)); | ||
2075 | |||
2076 | cur_pie_slice++; | ||
2077 | } | ||
2078 | } | ||
2079 | } | ||
2080 | |||
2081 | mMeshValid = TRUE; | ||
2082 | } | ||
2083 | |||
2084 | |||
2085 | //----------------------------------------------------------------------------- | ||
2086 | // releaseMeshData() | ||
2087 | //----------------------------------------------------------------------------- | ||
2088 | void LLVOAvatar::releaseMeshData() | ||
2089 | { | ||
2090 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
2091 | |||
2092 | if (sInstances.getLength() < AVATAR_AGP_RELEASE_THRESHOLD || mIsDummy) | ||
2093 | { | ||
2094 | return; | ||
2095 | } | ||
2096 | |||
2097 | //llinfos << "Releasing" << llendl; | ||
2098 | |||
2099 | // cleanup mesh data | ||
2100 | mHairLOD.setValid(FALSE, TRUE); | ||
2101 | mHeadLOD.setValid(FALSE, TRUE); | ||
2102 | mEyeLashLOD.setValid(FALSE, TRUE); | ||
2103 | mUpperBodyLOD.setValid(FALSE, TRUE); | ||
2104 | mLowerBodyLOD.setValid(FALSE, TRUE); | ||
2105 | mEyeBallLeftLOD.setValid(FALSE, TRUE); | ||
2106 | mEyeBallRightLOD.setValid(FALSE, TRUE); | ||
2107 | mSkirtLOD.setValid(FALSE, TRUE); | ||
2108 | |||
2109 | //cleanup AGP data | ||
2110 | if (mDrawable.notNull()) | ||
2111 | { | ||
2112 | LLFace* facep = mDrawable->getFace(0); | ||
2113 | facep->setSize(0, 0); | ||
2114 | mNumAGPVertices = 0; | ||
2115 | |||
2116 | // You need to reset the vertex data in order to guarantee | ||
2117 | // that the data is deallocated, AND you start at the 0 index | ||
2118 | // when you restore the face. We're assuming ONLY ONE FACE per | ||
2119 | // avatar pool, this logic is broken if that isn't the case! | ||
2120 | facep->getPool()->resetVertexData(0); | ||
2121 | } | ||
2122 | |||
2123 | for (LLViewerJointAttachment *attachmentPoint = mAttachmentPoints.getFirstData(); | ||
2124 | attachmentPoint; | ||
2125 | attachmentPoint = mAttachmentPoints.getNextData()) | ||
2126 | { | ||
2127 | if (!attachmentPoint->getIsHUDAttachment()) | ||
2128 | { | ||
2129 | attachmentPoint->setAttachmentVisibility(FALSE); | ||
2130 | } | ||
2131 | } | ||
2132 | mMeshValid = FALSE; | ||
2133 | } | ||
2134 | |||
2135 | //----------------------------------------------------------------------------- | ||
2136 | // restoreMeshData() | ||
2137 | //----------------------------------------------------------------------------- | ||
2138 | void LLVOAvatar::restoreMeshData() | ||
2139 | { | ||
2140 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
2141 | |||
2142 | //llinfos << "Restoring" << llendl; | ||
2143 | mMeshValid = TRUE; | ||
2144 | updateJointLODs(); | ||
2145 | |||
2146 | if (mIsSelf) | ||
2147 | { | ||
2148 | updateAttachmentVisibility(gAgent.getCameraMode()); | ||
2149 | } | ||
2150 | else | ||
2151 | { | ||
2152 | for (LLViewerJointAttachment *attachmentPoint = mAttachmentPoints.getFirstData(); | ||
2153 | attachmentPoint; | ||
2154 | attachmentPoint = mAttachmentPoints.getNextData()) | ||
2155 | { | ||
2156 | if (!attachmentPoint->getIsHUDAttachment()) | ||
2157 | { | ||
2158 | attachmentPoint->setAttachmentVisibility(TRUE); | ||
2159 | } | ||
2160 | } | ||
2161 | } | ||
2162 | |||
2163 | // force mesh update as LOD might not have changed to trigger this | ||
2164 | updateMeshData(); | ||
2165 | } | ||
2166 | |||
2167 | //----------------------------------------------------------------------------- | ||
2168 | // updateMeshData() | ||
2169 | //----------------------------------------------------------------------------- | ||
2170 | void LLVOAvatar::updateMeshData() | ||
2171 | { | ||
2172 | if (mDrawable.notNull()) | ||
2173 | { | ||
2174 | LLFace* facep = mDrawable->getFace(0); | ||
2175 | |||
2176 | U32 num_vertices = 0; | ||
2177 | |||
2178 | // this order is determined by number of LODS | ||
2179 | // if a mesh earlier in this list changed LODs while a later mesh doesn't, | ||
2180 | // the later mesh's index offset will be inaccurate | ||
2181 | mEyeBallLeftLOD.updateFaceSizes(num_vertices, mAdjustedPixelArea); | ||
2182 | mEyeBallRightLOD.updateFaceSizes(num_vertices, mAdjustedPixelArea); | ||
2183 | mEyeLashLOD.updateFaceSizes(num_vertices, mAdjustedPixelArea); | ||
2184 | mHeadLOD.updateFaceSizes(num_vertices, mAdjustedPixelArea); | ||
2185 | mLowerBodyLOD.updateFaceSizes(num_vertices, mAdjustedPixelArea); | ||
2186 | mSkirtLOD.updateFaceSizes(num_vertices, mAdjustedPixelArea); | ||
2187 | mUpperBodyLOD.updateFaceSizes(num_vertices, mAdjustedPixelArea); | ||
2188 | mHairLOD.updateFaceSizes(num_vertices, mAdjustedPixelArea); | ||
2189 | |||
2190 | if (num_vertices != mNumAGPVertices) | ||
2191 | { | ||
2192 | // resize immediately | ||
2193 | // llinfos << "Resizing avatar AGP buffer!" << llendl; | ||
2194 | facep->getPool()->resetVertexData(num_vertices); | ||
2195 | facep->setSize(0,0); | ||
2196 | facep->setSize(num_vertices, 0); | ||
2197 | mNumAGPVertices = num_vertices; | ||
2198 | } | ||
2199 | |||
2200 | // This is a hack! Avatars have their own pool, so we are detecting | ||
2201 | // the case of more than one avatar in the pool (thus > 0 instead of >= 0) | ||
2202 | if (facep->getGeomIndex() > 0) | ||
2203 | { | ||
2204 | llerrs << "non-zero geom index: " << facep->getGeomIndex() << " in LLVOAvatar::restoreMeshData" << llendl; | ||
2205 | } | ||
2206 | |||
2207 | mEyeBallLeftLOD.updateFaceData(facep, mAdjustedPixelArea); | ||
2208 | mEyeBallRightLOD.updateFaceData(facep, mAdjustedPixelArea); | ||
2209 | mEyeLashLOD.updateFaceData(facep, mAdjustedPixelArea); | ||
2210 | mHeadLOD.updateFaceData(facep, mAdjustedPixelArea); | ||
2211 | mLowerBodyLOD.updateFaceData(facep, mAdjustedPixelArea); | ||
2212 | mSkirtLOD.updateFaceData(facep, mAdjustedPixelArea); | ||
2213 | mUpperBodyLOD.updateFaceData(facep, mAdjustedPixelArea); | ||
2214 | mHairLOD.updateFaceData(facep, mAdjustedPixelArea, TRUE); | ||
2215 | } | ||
2216 | } | ||
2217 | |||
2218 | //------------------------------------------------------------------------ | ||
2219 | |||
2220 | //------------------------------------------------------------------------ | ||
2221 | // The viewer can only suggest a good size for the agent, | ||
2222 | // the simulator will keep it inside a reasonable range. | ||
2223 | void LLVOAvatar::computeBodySize() | ||
2224 | { | ||
2225 | LLVector3 pelvis_scale = mPelvisp->getScale(); | ||
2226 | |||
2227 | // some of the joints have not been cached | ||
2228 | LLVector3 skull = mSkullp->getPosition(); | ||
2229 | LLVector3 skull_scale = mSkullp->getScale(); | ||
2230 | |||
2231 | LLVector3 neck = mNeckp->getPosition(); | ||
2232 | LLVector3 neck_scale = mNeckp->getScale(); | ||
2233 | |||
2234 | LLVector3 chest = mChestp->getPosition(); | ||
2235 | LLVector3 chest_scale = mChestp->getScale(); | ||
2236 | |||
2237 | // the rest of the joints have been cached | ||
2238 | LLVector3 head = mHeadp->getPosition(); | ||
2239 | LLVector3 head_scale = mHeadp->getScale(); | ||
2240 | |||
2241 | LLVector3 torso = mTorsop->getPosition(); | ||
2242 | LLVector3 torso_scale = mTorsop->getScale(); | ||
2243 | |||
2244 | LLVector3 hip = mHipLeftp->getPosition(); | ||
2245 | LLVector3 hip_scale = mHipLeftp->getScale(); | ||
2246 | |||
2247 | LLVector3 knee = mKneeLeftp->getPosition(); | ||
2248 | LLVector3 knee_scale = mKneeLeftp->getScale(); | ||
2249 | |||
2250 | LLVector3 ankle = mAnkleLeftp->getPosition(); | ||
2251 | LLVector3 ankle_scale = mAnkleLeftp->getScale(); | ||
2252 | |||
2253 | LLVector3 foot = mFootLeftp->getPosition(); | ||
2254 | |||
2255 | mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] - | ||
2256 | knee.mV[VZ] * hip_scale.mV[VZ] - | ||
2257 | ankle.mV[VZ] * knee_scale.mV[VZ] - | ||
2258 | foot.mV[VZ] * ankle_scale.mV[VZ]; | ||
2259 | |||
2260 | mBodySize.mV[VZ] = mPelvisToFoot + | ||
2261 | // the sqrt(2) correction below is an approximate | ||
2262 | // correction to get to the top of the head | ||
2263 | F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) + | ||
2264 | head.mV[VZ] * neck_scale.mV[VZ] + | ||
2265 | neck.mV[VZ] * chest_scale.mV[VZ] + | ||
2266 | chest.mV[VZ] * torso_scale.mV[VZ] + | ||
2267 | torso.mV[VZ] * pelvis_scale.mV[VZ]; | ||
2268 | |||
2269 | // TODO -- measure the real depth and width | ||
2270 | mBodySize.mV[VX] = DEFAULT_AGENT_DEPTH; | ||
2271 | mBodySize.mV[VY] = DEFAULT_AGENT_WIDTH; | ||
2272 | |||
2273 | /* debug spam | ||
2274 | std::cout << "skull = " << skull << std::endl; // adebug | ||
2275 | std::cout << "head = " << head << std::endl; // adebug | ||
2276 | std::cout << "head_scale = " << head_scale << std::endl; // adebug | ||
2277 | std::cout << "neck = " << neck << std::endl; // adebug | ||
2278 | std::cout << "neck_scale = " << neck_scale << std::endl; // adebug | ||
2279 | std::cout << "chest = " << chest << std::endl; // adebug | ||
2280 | std::cout << "chest_scale = " << chest_scale << std::endl; // adebug | ||
2281 | std::cout << "torso = " << torso << std::endl; // adebug | ||
2282 | std::cout << "torso_scale = " << torso_scale << std::endl; // adebug | ||
2283 | std::cout << std::endl; // adebug | ||
2284 | |||
2285 | std::cout << "pelvis_scale = " << pelvis_scale << std::endl;// adebug | ||
2286 | std::cout << std::endl; // adebug | ||
2287 | |||
2288 | std::cout << "hip = " << hip << std::endl; // adebug | ||
2289 | std::cout << "hip_scale = " << hip_scale << std::endl; // adebug | ||
2290 | std::cout << "ankle = " << ankle << std::endl; // adebug | ||
2291 | std::cout << "ankle_scale = " << ankle_scale << std::endl; // adebug | ||
2292 | std::cout << "foot = " << foot << std::endl; // adebug | ||
2293 | std::cout << "mBodySize = " << mBodySize << std::endl; // adebug | ||
2294 | std::cout << "mPelvisToFoot = " << mPelvisToFoot << std::endl; // adebug | ||
2295 | std::cout << std::endl; // adebug | ||
2296 | */ | ||
2297 | } | ||
2298 | |||
2299 | //------------------------------------------------------------------------ | ||
2300 | // LLVOAvatar::processUpdateMessage() | ||
2301 | //------------------------------------------------------------------------ | ||
2302 | U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys, | ||
2303 | void **user_data, | ||
2304 | U32 block_num, const EObjectUpdateType update_type, | ||
2305 | LLDataPacker *dp) | ||
2306 | { | ||
2307 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
2308 | |||
2309 | LLVector3 old_vel = getVelocity(); | ||
2310 | // Do base class updates... | ||
2311 | U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp); | ||
2312 | |||
2313 | //llinfos << getRotation() << llendl; | ||
2314 | //llinfos << getPosition() << llendl; | ||
2315 | if (update_type == OUT_FULL ) | ||
2316 | { | ||
2317 | if( !mIsSelf || !mFirstTEMessageReceived ) | ||
2318 | { | ||
2319 | // dumpAvatarTEs( "PRE processUpdateMessage()" ); | ||
2320 | unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num); | ||
2321 | // dumpAvatarTEs( "POST processUpdateMessage()" ); | ||
2322 | |||
2323 | if( !mFirstTEMessageReceived ) | ||
2324 | { | ||
2325 | onFirstTEMessageReceived(); | ||
2326 | } | ||
2327 | |||
2328 | // Disable updates to composites. We'll decide whether we need to do | ||
2329 | // any updates after we find out whether this update message has any | ||
2330 | // "baked" (pre-composited) textures. | ||
2331 | setCompositeUpdatesEnabled( FALSE ); | ||
2332 | updateMeshTextures(); | ||
2333 | setCompositeUpdatesEnabled( TRUE ); | ||
2334 | } | ||
2335 | } | ||
2336 | |||
2337 | return retval; | ||
2338 | } | ||
2339 | |||
2340 | // virtual | ||
2341 | S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid) | ||
2342 | { | ||
2343 | // The core setTETexture() method requests images, so we need | ||
2344 | // to redirect certain avatar texture requests to different sims. | ||
2345 | if (isTextureIndexBaked(te)) | ||
2346 | { | ||
2347 | LLHost target_host = getObjectHost(); | ||
2348 | return setTETextureCore(te, uuid, target_host); | ||
2349 | } | ||
2350 | else | ||
2351 | { | ||
2352 | return setTETextureCore(te, uuid, LLHost::invalid); | ||
2353 | } | ||
2354 | } | ||
2355 | |||
2356 | |||
2357 | // setTEImage | ||
2358 | |||
2359 | //------------------------------------------------------------------------ | ||
2360 | // idleUpdate() | ||
2361 | //------------------------------------------------------------------------ | ||
2362 | BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time) | ||
2363 | { | ||
2364 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
2365 | LLFastTimer t(LLFastTimer::FTM_AVATAR_UPDATE); | ||
2366 | |||
2367 | if (isDead()) | ||
2368 | { | ||
2369 | llinfos << "Warning! Idle on dead avatar" << llendl; | ||
2370 | return TRUE; | ||
2371 | } | ||
2372 | |||
2373 | if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))) | ||
2374 | { | ||
2375 | return TRUE; | ||
2376 | } | ||
2377 | |||
2378 | // force immediate pixel area update on avatars using last frames data (before drawable or camera updates) | ||
2379 | setPixelAreaAndAngle(gAgent); | ||
2380 | |||
2381 | // Update the LOD of the joints | ||
2382 | static const F32 UPDATE_TIME = .5f; | ||
2383 | if (mUpdateLODTimer.hasExpired()) | ||
2384 | { | ||
2385 | mUpdateLODTimer.setTimerExpirySec(UPDATE_TIME * (.75f + frand(0.5f))); | ||
2386 | updateJointLODs(); | ||
2387 | } | ||
2388 | |||
2389 | // force asynchronous drawable update | ||
2390 | if(mDrawable.notNull() && !gNoRender) | ||
2391 | { | ||
2392 | LLFastTimer t(LLFastTimer::FTM_JOINT_UPDATE); | ||
2393 | |||
2394 | if (mIsSitting && getParent()) | ||
2395 | { | ||
2396 | LLViewerObject *root_object = (LLViewerObject*)getRoot(); | ||
2397 | LLDrawable* drawablep = root_object->mDrawable; | ||
2398 | // if this object hasn't already been updated by another avatar... | ||
2399 | if (drawablep) // && !drawablep->isState(LLDrawable::EARLY_MOVE)) | ||
2400 | { | ||
2401 | if (root_object->isSelected()) | ||
2402 | { | ||
2403 | gPipeline.updateMoveNormalAsync(drawablep); | ||
2404 | } | ||
2405 | else | ||
2406 | { | ||
2407 | gPipeline.updateMoveDampedAsync(drawablep); | ||
2408 | } | ||
2409 | } | ||
2410 | } | ||
2411 | else | ||
2412 | { | ||
2413 | gPipeline.updateMoveDampedAsync(mDrawable); | ||
2414 | } | ||
2415 | } | ||
2416 | |||
2417 | //-------------------------------------------------------------------- | ||
2418 | // set alpha flag depending on state | ||
2419 | //-------------------------------------------------------------------- | ||
2420 | |||
2421 | if (mIsSelf) | ||
2422 | { | ||
2423 | LLViewerObject::idleUpdate(agent, world, time); | ||
2424 | |||
2425 | // trigger fidget anims | ||
2426 | if (isAnyAnimationSignaled(AGENT_STAND_ANIMS, NUM_AGENT_STAND_ANIMS)) | ||
2427 | { | ||
2428 | agent.fidget(); | ||
2429 | } | ||
2430 | } | ||
2431 | else | ||
2432 | { | ||
2433 | // Should override the idleUpdate stuff and leave out the angular update part. | ||
2434 | LLQuaternion rotation = getRotation(); | ||
2435 | LLViewerObject::idleUpdate(agent, world, time); | ||
2436 | setRotation(rotation); | ||
2437 | } | ||
2438 | |||
2439 | // attach objects that were waiting for a drawable | ||
2440 | lazyAttach(); | ||
2441 | |||
2442 | // animate the character | ||
2443 | // store off last frame's root position to be consistent with camera position | ||
2444 | LLVector3 root_pos_last = mRoot.getWorldPosition(); | ||
2445 | |||
2446 | updateCharacter(agent); | ||
2447 | |||
2448 | if (gNoRender) | ||
2449 | { | ||
2450 | return TRUE; | ||
2451 | } | ||
2452 | |||
2453 | // *NOTE: this is necessary for the floating name text above your head. | ||
2454 | if (mDrawable.notNull()) | ||
2455 | { | ||
2456 | gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); | ||
2457 | } | ||
2458 | |||
2459 | // update attachments positions | ||
2460 | { | ||
2461 | LLFastTimer t(LLFastTimer::FTM_ATTACHMENT_UPDATE); | ||
2462 | for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData(); | ||
2463 | attachment; | ||
2464 | attachment = mAttachmentPoints.getNextData()) | ||
2465 | { | ||
2466 | LLViewerObject *attached_object = attachment->getObject(0); | ||
2467 | if (attached_object && !attached_object->isDead() && attachment->getValid()) | ||
2468 | { | ||
2469 | // if selecting any attachments, update all of them as non-damped | ||
2470 | if (gSelectMgr->getObjectCount() && gSelectMgr->selectionIsAttachment()) | ||
2471 | { | ||
2472 | gPipeline.updateMoveNormalAsync(attached_object->mDrawable); | ||
2473 | } | ||
2474 | else | ||
2475 | { | ||
2476 | gPipeline.updateMoveDampedAsync(attached_object->mDrawable); | ||
2477 | } | ||
2478 | attached_object->updateText(); | ||
2479 | } | ||
2480 | } | ||
2481 | } | ||
2482 | |||
2483 | //force a move if sitting on an active object | ||
2484 | if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive()) | ||
2485 | { | ||
2486 | gPipeline.markMoved(mDrawable, TRUE); | ||
2487 | } | ||
2488 | |||
2489 | // update morphing params | ||
2490 | if (mAppearanceAnimating) | ||
2491 | { | ||
2492 | ESex avatar_sex = getSex(); | ||
2493 | F32 appearance_anim_time = mAppearanceMorphTimer.getElapsedTimeF32(); | ||
2494 | if (appearance_anim_time >= APPEARANCE_MORPH_TIME) | ||
2495 | { | ||
2496 | mAppearanceAnimating = FALSE; | ||
2497 | for (LLVisualParam *param = getFirstVisualParam(); | ||
2498 | param; | ||
2499 | param = getNextVisualParam()) | ||
2500 | { | ||
2501 | if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) | ||
2502 | { | ||
2503 | param->stopAnimating(mAppearanceAnimSetByUser); | ||
2504 | } | ||
2505 | } | ||
2506 | updateVisualParams(); | ||
2507 | if (mIsSelf) | ||
2508 | { | ||
2509 | gAgent.sendAgentSetAppearance(); | ||
2510 | } | ||
2511 | } | ||
2512 | else | ||
2513 | { | ||
2514 | F32 blend_frac = calc_bouncy_animation(appearance_anim_time / APPEARANCE_MORPH_TIME); | ||
2515 | F32 last_blend_frac = calc_bouncy_animation(mLastAppearanceBlendTime / APPEARANCE_MORPH_TIME); | ||
2516 | F32 morph_amt; | ||
2517 | if (last_blend_frac == 1.f) | ||
2518 | { | ||
2519 | morph_amt = 1.f; | ||
2520 | } | ||
2521 | else | ||
2522 | { | ||
2523 | morph_amt = (blend_frac - last_blend_frac) / (1.f - last_blend_frac); | ||
2524 | } | ||
2525 | |||
2526 | LLVisualParam *param; | ||
2527 | |||
2528 | // animate only top level params | ||
2529 | for (param = getFirstVisualParam(); | ||
2530 | param; | ||
2531 | param = getNextVisualParam()) | ||
2532 | { | ||
2533 | if (param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) | ||
2534 | { | ||
2535 | param->animate(morph_amt, mAppearanceAnimSetByUser); | ||
2536 | } | ||
2537 | } | ||
2538 | |||
2539 | // apply all params | ||
2540 | for (param = getFirstVisualParam(); | ||
2541 | param; | ||
2542 | param = getNextVisualParam()) | ||
2543 | { | ||
2544 | param->apply(avatar_sex); | ||
2545 | } | ||
2546 | |||
2547 | mLastAppearanceBlendTime = appearance_anim_time; | ||
2548 | } | ||
2549 | dirtyMesh(); | ||
2550 | } | ||
2551 | |||
2552 | // update wind effect | ||
2553 | if ((gPipeline.getVertexShaderLevel(LLPipeline::SHADER_AVATAR) >= LLDrawPoolAvatar::SHADER_LEVEL_CLOTH)) | ||
2554 | { | ||
2555 | F32 hover_strength = 0.f; | ||
2556 | F32 time_delta = mRippleTimer.getElapsedTimeF32() - mRippleTimeLast; | ||
2557 | mRippleTimeLast = mRippleTimer.getElapsedTimeF32(); | ||
2558 | LLVector3 velocity = getVelocity(); | ||
2559 | F32 speed = velocity.magVec(); | ||
2560 | //RN: velocity varies too much frame to frame for this to work | ||
2561 | mRippleAccel.clearVec();//lerp(mRippleAccel, (velocity - mLastVel) * time_delta, LLCriticalDamp::getInterpolant(0.02f)); | ||
2562 | mLastVel = velocity; | ||
2563 | LLVector4 wind; | ||
2564 | wind.setVec(getRegion()->mWind.getVelocityNoisy(getPositionAgent(), 4.f) - velocity); | ||
2565 | |||
2566 | if (mInAir) | ||
2567 | { | ||
2568 | hover_strength = HOVER_EFFECT_STRENGTH * llmax(0.f, HOVER_EFFECT_MAX_SPEED - speed); | ||
2569 | } | ||
2570 | |||
2571 | if (mBelowWater) | ||
2572 | { | ||
2573 | // TODO: make cloth flow more gracefully when underwater | ||
2574 | hover_strength += UNDERWATER_EFFECT_STRENGTH; | ||
2575 | } | ||
2576 | |||
2577 | wind.mV[VZ] += hover_strength; | ||
2578 | wind.normVec(); | ||
2579 | |||
2580 | wind.mV[VW] = llmin(0.025f + (speed * 0.015f) + hover_strength, 0.5f); | ||
2581 | F32 interp; | ||
2582 | if (wind.mV[VW] > mWindVec.mV[VW]) | ||
2583 | { | ||
2584 | interp = LLCriticalDamp::getInterpolant(0.2f); | ||
2585 | } | ||
2586 | else | ||
2587 | { | ||
2588 | interp = LLCriticalDamp::getInterpolant(0.4f); | ||
2589 | } | ||
2590 | mWindVec = lerp(mWindVec, wind, interp); | ||
2591 | |||
2592 | F32 wind_freq = hover_strength + llclamp(8.f + (speed * 0.7f) + (noise1(mRipplePhase) * 4.f), 8.f, 25.f); | ||
2593 | mWindFreq = lerp(mWindFreq, wind_freq, interp); | ||
2594 | |||
2595 | if (mBelowWater) | ||
2596 | { | ||
2597 | mWindFreq *= UNDERWATER_FREQUENCY_DAMP; | ||
2598 | } | ||
2599 | |||
2600 | mRipplePhase += (time_delta * mWindFreq); | ||
2601 | if (mRipplePhase > F_TWO_PI) | ||
2602 | { | ||
2603 | mRipplePhase = fmodf(mRipplePhase, F_TWO_PI); | ||
2604 | } | ||
2605 | } | ||
2606 | |||
2607 | // update chat bubble | ||
2608 | //-------------------------------------------------------------------- | ||
2609 | // draw text label over characters head | ||
2610 | //-------------------------------------------------------------------- | ||
2611 | if (mChatTimer.getElapsedTimeF32() > BUBBLE_CHAT_TIME) | ||
2612 | { | ||
2613 | mChats.clear(); | ||
2614 | } | ||
2615 | |||
2616 | const F32 time_visible = mTimeVisible.getElapsedTimeF32(); | ||
2617 | const F32 NAME_SHOW_TIME = gSavedSettings.getF32("RenderNameShowTime"); // seconds | ||
2618 | const F32 FADE_DURATION = gSavedSettings.getF32("RenderNameFadeDuration"); // seconds | ||
2619 | BOOL visible_chat = gSavedSettings.getBOOL("UseChatBubbles") && (mChats.size() || mTyping); | ||
2620 | BOOL render_name = visible_chat || | ||
2621 | (mVisible && | ||
2622 | (sRenderName == RENDER_NAME_ALWAYS) || | ||
2623 | (sRenderName == RENDER_NAME_FADE && time_visible < NAME_SHOW_TIME)); | ||
2624 | // If it's your own avatar, don't draw in mouselook, and don't | ||
2625 | // draw if we're specifically hiding our own name. | ||
2626 | if (mIsSelf) | ||
2627 | { | ||
2628 | render_name = render_name | ||
2629 | && !gAgent.cameraMouselook() | ||
2630 | && (visible_chat || !gSavedSettings.getBOOL("RenderNameHideSelf")); | ||
2631 | } | ||
2632 | |||
2633 | if ( render_name ) | ||
2634 | { | ||
2635 | BOOL new_name = FALSE; | ||
2636 | if (visible_chat != mVisibleChat) | ||
2637 | { | ||
2638 | mVisibleChat = visible_chat; | ||
2639 | new_name = TRUE; | ||
2640 | } | ||
2641 | |||
2642 | // First Calculate Alpha | ||
2643 | // If alpha > 0, create mNameText if necessary, otherwise delete it | ||
2644 | { | ||
2645 | F32 alpha = 0.f; | ||
2646 | if (mAppAngle > 5.f) | ||
2647 | { | ||
2648 | const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION; | ||
2649 | if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME) | ||
2650 | { | ||
2651 | alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION; | ||
2652 | } | ||
2653 | else | ||
2654 | { | ||
2655 | // ...not fading, full alpha | ||
2656 | alpha = 1.f; | ||
2657 | } | ||
2658 | } | ||
2659 | else if (mAppAngle > 2.f) | ||
2660 | { | ||
2661 | // far away is faded out also | ||
2662 | alpha = (mAppAngle-2.f)/3.f; | ||
2663 | } | ||
2664 | |||
2665 | if (alpha > 0.f) | ||
2666 | { | ||
2667 | if (!mNameText) | ||
2668 | { | ||
2669 | mNameText = (LLHUDText *)LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT); | ||
2670 | mNameText->setMass(10.f); | ||
2671 | mNameText->setSourceObject(this); | ||
2672 | mNameText->setVertAlignment(LLHUDText::ALIGN_VERT_TOP); | ||
2673 | mNameText->setVisibleOffScreen(TRUE); | ||
2674 | mNameText->setMaxLines(11); | ||
2675 | mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); | ||
2676 | mNameText->setUseBubble(TRUE); | ||
2677 | sNumVisibleChatBubbles++; | ||
2678 | new_name = TRUE; | ||
2679 | } | ||
2680 | |||
2681 | LLColor4 avatar_name_color = gColors.getColor( "AvatarNameColor" ); | ||
2682 | avatar_name_color.setAlpha(alpha); | ||
2683 | mNameText->setColor(avatar_name_color); | ||
2684 | |||
2685 | LLQuaternion root_rot = mRoot.getWorldRotation(); | ||
2686 | mNameText->setUsePixelSize(TRUE); | ||
2687 | LLVector3 pixel_right_vec; | ||
2688 | LLVector3 pixel_up_vec; | ||
2689 | gCamera->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec); | ||
2690 | LLVector3 camera_to_av = root_pos_last - gCamera->getOrigin(); | ||
2691 | camera_to_av.normVec(); | ||
2692 | LLVector3 local_camera_at = camera_to_av * ~root_rot; | ||
2693 | LLVector3 local_camera_up = camera_to_av % gCamera->getLeftAxis(); | ||
2694 | local_camera_up.normVec(); | ||
2695 | local_camera_up = local_camera_up * ~root_rot; | ||
2696 | |||
2697 | local_camera_up.scaleVec(mBodySize * 0.5f); | ||
2698 | local_camera_at.scaleVec(mBodySize * 0.5f); | ||
2699 | |||
2700 | LLVector3 name_position = mRoot.getWorldPosition() + | ||
2701 | (local_camera_up * root_rot) - | ||
2702 | (projected_vec(local_camera_at * root_rot, camera_to_av)); | ||
2703 | name_position += pixel_up_vec * 15.f; | ||
2704 | mNameText->setPositionAgent(name_position); | ||
2705 | } | ||
2706 | else if (mNameText) | ||
2707 | { | ||
2708 | mNameText->markDead(); | ||
2709 | mNameText = NULL; | ||
2710 | sNumVisibleChatBubbles--; | ||
2711 | } | ||
2712 | } | ||
2713 | |||
2714 | LLNameValue *title = getNVPair("Title"); | ||
2715 | LLNameValue* firstname = getNVPair("FirstName"); | ||
2716 | LLNameValue* lastname = getNVPair("LastName"); | ||
2717 | |||
2718 | if (mNameText.notNull() && firstname && lastname) | ||
2719 | { | ||
2720 | BOOL is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY) != mSignaledAnimations.end(); | ||
2721 | BOOL is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end(); | ||
2722 | BOOL is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end(); | ||
2723 | BOOL is_muted; | ||
2724 | if (mIsSelf) | ||
2725 | { | ||
2726 | is_muted = FALSE; | ||
2727 | } | ||
2728 | else | ||
2729 | { | ||
2730 | is_muted = gMuteListp->isMuted(getID()); | ||
2731 | } | ||
2732 | |||
2733 | if (mNameString.empty() || | ||
2734 | new_name || | ||
2735 | (!title && !mTitle.empty()) || | ||
2736 | (title && mTitle != title->getString()) || | ||
2737 | (is_away != mNameAway || is_busy != mNameBusy || is_muted != mNameMute) | ||
2738 | || is_appearance != mNameAppearance) | ||
2739 | { | ||
2740 | char line[MAX_STRING]; | ||
2741 | if (title && title->getString() && title->getString()[0] != '\0') | ||
2742 | { | ||
2743 | strcpy(line, title->getString() ); | ||
2744 | strcat(line, "\n"); | ||
2745 | strcat(line, firstname->getString() ); | ||
2746 | } | ||
2747 | else | ||
2748 | { | ||
2749 | strcpy(line, firstname->getString() ); | ||
2750 | } | ||
2751 | |||
2752 | strcat(line, " "); | ||
2753 | strcat(line, lastname->getString()); | ||
2754 | BOOL need_comma = FALSE; | ||
2755 | |||
2756 | if (is_away || is_muted || is_busy) | ||
2757 | { | ||
2758 | strcat(line, " ("); | ||
2759 | if (is_away) | ||
2760 | { | ||
2761 | strcat(line, "Away"); | ||
2762 | need_comma = TRUE; | ||
2763 | } | ||
2764 | if (is_busy) | ||
2765 | { | ||
2766 | if (need_comma) | ||
2767 | { | ||
2768 | strcat(line, ", "); | ||
2769 | } | ||
2770 | strcat(line, "Busy"); | ||
2771 | need_comma = TRUE; | ||
2772 | } | ||
2773 | if (is_muted) | ||
2774 | { | ||
2775 | if (need_comma) | ||
2776 | { | ||
2777 | strcat(line, ", "); | ||
2778 | } | ||
2779 | strcat(line, "Muted"); | ||
2780 | need_comma = TRUE; | ||
2781 | } | ||
2782 | strcat(line,")"); | ||
2783 | } | ||
2784 | if (is_appearance) | ||
2785 | { | ||
2786 | strcat(line, "\n(Editing Appearance)"); | ||
2787 | } | ||
2788 | mNameAway = is_away; | ||
2789 | mNameBusy = is_busy; | ||
2790 | mNameMute = is_muted; | ||
2791 | mNameAppearance = is_appearance; | ||
2792 | mTitle = title ? title->getString() : ""; | ||
2793 | mNameString = utf8str_to_wstring(line); | ||
2794 | new_name = TRUE; | ||
2795 | } | ||
2796 | |||
2797 | if (visible_chat) | ||
2798 | { | ||
2799 | mNameText->setDropShadow(TRUE); | ||
2800 | mNameText->setFont(LLFontGL::sSansSerif); | ||
2801 | mNameText->setTextAlignment(LLHUDText::ALIGN_TEXT_LEFT); | ||
2802 | mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f); | ||
2803 | if (new_name) | ||
2804 | { | ||
2805 | mNameText->setLabel(mNameString); | ||
2806 | } | ||
2807 | |||
2808 | char line[MAX_STRING]; | ||
2809 | line[0] = '\0'; | ||
2810 | std::deque<LLChat>::iterator chat_iter = mChats.begin(); | ||
2811 | mNameText->clearString(); | ||
2812 | |||
2813 | LLColor4 new_chat = gColors.getColor( "AvatarNameColor" ); | ||
2814 | LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f); | ||
2815 | LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f); | ||
2816 | if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) | ||
2817 | { | ||
2818 | ++chat_iter; | ||
2819 | } | ||
2820 | |||
2821 | for(; chat_iter != mChats.end(); ++chat_iter) | ||
2822 | { | ||
2823 | F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f); | ||
2824 | LLFontGL::StyleFlags style; | ||
2825 | switch(chat_iter->mChatType) | ||
2826 | { | ||
2827 | case CHAT_TYPE_WHISPER: | ||
2828 | style = LLFontGL::ITALIC; | ||
2829 | break; | ||
2830 | case CHAT_TYPE_SHOUT: | ||
2831 | style = LLFontGL::BOLD; | ||
2832 | break; | ||
2833 | default: | ||
2834 | style = LLFontGL::NORMAL; | ||
2835 | break; | ||
2836 | } | ||
2837 | if (chat_fade_amt < 1.f) | ||
2838 | { | ||
2839 | F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f); | ||
2840 | mNameText->addLine(utf8str_to_wstring(chat_iter->mText), lerp(new_chat, normal_chat, u), style); | ||
2841 | } | ||
2842 | else if (chat_fade_amt < 2.f) | ||
2843 | { | ||
2844 | F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f); | ||
2845 | mNameText->addLine(utf8str_to_wstring(chat_iter->mText), lerp(normal_chat, old_chat, u), style); | ||
2846 | } | ||
2847 | else if (chat_fade_amt < 3.f) | ||
2848 | { | ||
2849 | // *NOTE: only remove lines down to minimum number | ||
2850 | mNameText->addLine(utf8str_to_wstring(chat_iter->mText), old_chat, style); | ||
2851 | } | ||
2852 | } | ||
2853 | mNameText->setVisibleOffScreen(TRUE); | ||
2854 | |||
2855 | if (mTyping) | ||
2856 | { | ||
2857 | S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1; | ||
2858 | switch(dot_count) | ||
2859 | { | ||
2860 | case 1: | ||
2861 | mNameText->addLine(".", new_chat); | ||
2862 | break; | ||
2863 | case 2: | ||
2864 | mNameText->addLine("..", new_chat); | ||
2865 | break; | ||
2866 | case 3: | ||
2867 | mNameText->addLine("...", new_chat); | ||
2868 | break; | ||
2869 | } | ||
2870 | |||
2871 | } | ||
2872 | } | ||
2873 | else | ||
2874 | { | ||
2875 | if (gSavedSettings.getBOOL("SmallAvatarNames")) | ||
2876 | { | ||
2877 | mNameText->setFont(LLFontGL::sSansSerif); | ||
2878 | } | ||
2879 | else | ||
2880 | { | ||
2881 | mNameText->setFont(LLFontGL::sSansSerifBig); | ||
2882 | } | ||
2883 | mNameText->setTextAlignment(LLHUDText::ALIGN_TEXT_CENTER); | ||
2884 | mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f); | ||
2885 | mNameText->setVisibleOffScreen(FALSE); | ||
2886 | if (new_name) | ||
2887 | { | ||
2888 | mNameText->setLabel(""); | ||
2889 | mNameText->setString(mNameString); | ||
2890 | } | ||
2891 | } | ||
2892 | } | ||
2893 | } | ||
2894 | else if (mNameText) | ||
2895 | { | ||
2896 | mNameText->markDead(); | ||
2897 | mNameText = NULL; | ||
2898 | sNumVisibleChatBubbles--; | ||
2899 | } | ||
2900 | |||
2901 | //-------------------------------------------------------------------- | ||
2902 | // draw tractor beam when editing objects | ||
2903 | //-------------------------------------------------------------------- | ||
2904 | if (!mIsSelf) | ||
2905 | { | ||
2906 | return TRUE; | ||
2907 | } | ||
2908 | |||
2909 | // This is only done for yourself (maybe it should be in the agent?) | ||
2910 | if (!needsRenderBeam() || !mIsBuilt) | ||
2911 | { | ||
2912 | mBeam = NULL; | ||
2913 | } | ||
2914 | else if (!mBeam || mBeam->isDead()) | ||
2915 | { | ||
2916 | // VEFFECT: Tractor Beam | ||
2917 | mBeam = (LLHUDEffectSpiral *)gHUDManager->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BEAM); | ||
2918 | mBeam->setColor(LLColor4U(gAgent.getEffectColor())); | ||
2919 | mBeam->setSourceObject(this); | ||
2920 | mBeamTimer.reset(); | ||
2921 | } | ||
2922 | |||
2923 | if (!mBeam.isNull()) | ||
2924 | { | ||
2925 | if (gAgent.mPointAt.notNull()) | ||
2926 | { | ||
2927 | // get point from pointat effect | ||
2928 | mBeam->setPositionGlobal(gAgent.mPointAt->getPointAtPosGlobal()); | ||
2929 | mBeam->triggerLocal(); | ||
2930 | } | ||
2931 | else if (gSelectMgr->getFirstRootObject() && | ||
2932 | gSelectMgr->getSelectType() != SELECT_TYPE_HUD) | ||
2933 | { | ||
2934 | LLViewerObject* objectp = gSelectMgr->getFirstRootObject(); | ||
2935 | mBeam->setTargetObject(objectp); | ||
2936 | } | ||
2937 | else | ||
2938 | { | ||
2939 | mBeam->setTargetObject(NULL); | ||
2940 | LLTool *tool = gToolMgr->getCurrentTool( gKeyboard->currentMask(TRUE) ); | ||
2941 | if (tool->isEditing()) | ||
2942 | { | ||
2943 | if (tool->getEditingObject()) | ||
2944 | { | ||
2945 | mBeam->setTargetObject(tool->getEditingObject()); | ||
2946 | } | ||
2947 | else | ||
2948 | { | ||
2949 | mBeam->setPositionGlobal(tool->getEditingPointGlobal()); | ||
2950 | } | ||
2951 | } | ||
2952 | else | ||
2953 | { | ||
2954 | mBeam->setPositionGlobal(gLastHitNonFloraPosGlobal + gLastHitNonFloraObjectOffset); | ||
2955 | } | ||
2956 | |||
2957 | } | ||
2958 | if (mBeamTimer.getElapsedTimeF32() > 0.25f) | ||
2959 | { | ||
2960 | mBeam->setColor(LLColor4U(gAgent.getEffectColor())); | ||
2961 | mBeam->setNeedsSendToSim(TRUE); | ||
2962 | mBeamTimer.reset(); | ||
2963 | } | ||
2964 | } | ||
2965 | |||
2966 | F32 avatar_height = (F32)(getPositionGlobal().mdV[VZ]); | ||
2967 | |||
2968 | F32 water_height; | ||
2969 | water_height = getRegion()->getWaterHeight(); | ||
2970 | |||
2971 | mBelowWater = avatar_height < water_height; | ||
2972 | |||
2973 | return TRUE; | ||
2974 | } | ||
2975 | |||
2976 | void LLVOAvatar::slamPosition() | ||
2977 | { | ||
2978 | gAgent.setPositionAgent(getPositionAgent()); | ||
2979 | mRoot.setWorldPosition(getPositionAgent()); // teleport | ||
2980 | setChanged(TRANSLATED); | ||
2981 | if (mDrawable.notNull()) | ||
2982 | { | ||
2983 | gPipeline.updateMoveNormalAsync(mDrawable); | ||
2984 | } | ||
2985 | mRoot.updateWorldMatrixChildren(); | ||
2986 | } | ||
2987 | |||
2988 | //------------------------------------------------------------------------ | ||
2989 | // updateCharacter() | ||
2990 | // called on both your avatar and other avatars | ||
2991 | //------------------------------------------------------------------------ | ||
2992 | void LLVOAvatar::updateCharacter(LLAgent &agent) | ||
2993 | { | ||
2994 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
2995 | |||
2996 | // clear debug text | ||
2997 | mDebugText.clear(); | ||
2998 | |||
2999 | if (LLVOAvatar::sShowAnimationDebug) | ||
3000 | { | ||
3001 | LLString playing_anims; | ||
3002 | for (LLMotion* motionp = mMotionController.getFirstActiveMotion(); | ||
3003 | motionp; | ||
3004 | motionp = mMotionController.getNextActiveMotion()) | ||
3005 | { | ||
3006 | if (motionp->getMinPixelArea() < getPixelArea()) | ||
3007 | { | ||
3008 | char output[256]; | ||
3009 | if (motionp->getName().empty()) | ||
3010 | { | ||
3011 | sprintf(output, "%s - %d", motionp->getID().getString().c_str(), (U32)motionp->getPriority()); | ||
3012 | } | ||
3013 | else | ||
3014 | { | ||
3015 | sprintf(output, "%s - %d", motionp->getName().c_str(), (U32)motionp->getPriority()); | ||
3016 | } | ||
3017 | addDebugText(output); | ||
3018 | } | ||
3019 | } | ||
3020 | } | ||
3021 | |||
3022 | if (LLVOAvatar::sJointDebug) | ||
3023 | { | ||
3024 | llinfos << getNVPair("FirstName")->getString() << ": joint touches: " << LLJoint::sNumTouches << " updates: " << LLJoint::sNumUpdates << llendl; | ||
3025 | |||
3026 | LLJoint::sNumUpdates = 0; | ||
3027 | LLJoint::sNumTouches = 0; | ||
3028 | } | ||
3029 | // llinfos << mPixelArea << llendl; | ||
3030 | if (gNoRender) | ||
3031 | { | ||
3032 | // Hack if we're running drones... | ||
3033 | if (mIsSelf) | ||
3034 | { | ||
3035 | gAgent.setPositionAgent(getPositionAgent()); | ||
3036 | } | ||
3037 | return; | ||
3038 | } | ||
3039 | |||
3040 | |||
3041 | LLVector3d root_pos_global; | ||
3042 | |||
3043 | if (!mIsBuilt) | ||
3044 | { | ||
3045 | return; | ||
3046 | } | ||
3047 | |||
3048 | // change animation time quanta based on avatar render load | ||
3049 | if (!mIsSelf) | ||
3050 | { | ||
3051 | F32 time_quantum = clamp_rescale((F32)sInstances.getLength(), 10.f, 35.f, 0.f, 0.25f); | ||
3052 | F32 pixel_area_scale = clamp_rescale(mPixelArea, 100, 5000, 1.f, 0.f); | ||
3053 | F32 time_step = time_quantum * pixel_area_scale; | ||
3054 | if (time_step != 0.f) | ||
3055 | { | ||
3056 | // disable walk motion servo controller as it doesn't work with motion timesteps | ||
3057 | stopMotion(ANIM_AGENT_WALK_ADJUST); | ||
3058 | removeAnimationData("Walk Speed"); | ||
3059 | } | ||
3060 | mMotionController.setTimeStep(time_step); | ||
3061 | // llinfos << "Setting timestep to " << time_quantum * pixel_area_scale << llendl; | ||
3062 | } | ||
3063 | |||
3064 | if (getParent() && !mIsSitting) | ||
3065 | { | ||
3066 | sitOnObject((LLViewerObject*)getParent()); | ||
3067 | } | ||
3068 | else if (!getParent() && mIsSitting && !isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED)) | ||
3069 | { | ||
3070 | getOffObject(); | ||
3071 | } | ||
3072 | |||
3073 | // For fading out the names above heads, only let the timer | ||
3074 | // run if we're visible. | ||
3075 | if (mDrawable.notNull() && !mDrawable->isVisible()) | ||
3076 | { | ||
3077 | mTimeVisible.reset(); | ||
3078 | } | ||
3079 | |||
3080 | // update screen joint size | ||
3081 | mScreenp->setScale(LLVector3(1.f, gCamera->getAspect(), 1.f)); | ||
3082 | mScreenp->updateWorldMatrixChildren(); | ||
3083 | |||
3084 | //-------------------------------------------------------------------- | ||
3085 | // create local variables in world coords for region position values | ||
3086 | //-------------------------------------------------------------------- | ||
3087 | F32 speed; | ||
3088 | LLVector3 normal; | ||
3089 | |||
3090 | LLVector3 xyVel = getVelocity(); | ||
3091 | xyVel.mV[VZ] = 0.0f; | ||
3092 | speed = xyVel.magVec(); | ||
3093 | |||
3094 | if (!(mIsSitting && getParent())) | ||
3095 | { | ||
3096 | //-------------------------------------------------------------------- | ||
3097 | // get timing info | ||
3098 | // handle initial condition case | ||
3099 | //-------------------------------------------------------------------- | ||
3100 | F32 animation_time = mAnimTimer.getElapsedTimeF32(); | ||
3101 | if (mTimeLast == 0.0f) | ||
3102 | { | ||
3103 | mTimeLast = animation_time; | ||
3104 | |||
3105 | // put the pelvis at slaved position/mRotation | ||
3106 | mRoot.setWorldPosition( getPositionAgent() ); // first frame | ||
3107 | mRoot.setWorldRotation( getRotation() ); | ||
3108 | } | ||
3109 | |||
3110 | //-------------------------------------------------------------------- | ||
3111 | // dont' let dT get larger than 1/5th of a second | ||
3112 | //-------------------------------------------------------------------- | ||
3113 | F32 deltaTime = animation_time - mTimeLast; | ||
3114 | |||
3115 | deltaTime = llclamp( deltaTime, DELTA_TIME_MIN, DELTA_TIME_MAX ); | ||
3116 | mTimeLast = animation_time; | ||
3117 | |||
3118 | mSpeedAccum = (mSpeedAccum * 0.95f) + (speed * 0.05f); | ||
3119 | |||
3120 | //-------------------------------------------------------------------- | ||
3121 | // compute the position of the avatar's root | ||
3122 | //-------------------------------------------------------------------- | ||
3123 | LLVector3d root_pos; | ||
3124 | LLVector3d ground_under_pelvis; | ||
3125 | |||
3126 | if (mIsSelf) | ||
3127 | { | ||
3128 | gAgent.setPositionAgent(getRenderPosition()); | ||
3129 | } | ||
3130 | |||
3131 | root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition()); | ||
3132 | |||
3133 | resolveHeightGlobal(root_pos, ground_under_pelvis, normal); | ||
3134 | F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]); | ||
3135 | BOOL in_air = ( (!gWorldPointer->getRegionFromPosGlobal(ground_under_pelvis)) || | ||
3136 | foot_to_ground > FOOT_GROUND_COLLISION_TOLERANCE); | ||
3137 | |||
3138 | if (in_air && !mInAir) | ||
3139 | { | ||
3140 | mTimeInAir.reset(); | ||
3141 | } | ||
3142 | mInAir = in_air; | ||
3143 | |||
3144 | // correct for the fact that the pelvis is not necessarily the center | ||
3145 | // of the agent's physical representation | ||
3146 | root_pos.mdV[VZ] -= (0.5f * mBodySize.mV[VZ]) - mPelvisToFoot; | ||
3147 | mRoot.setWorldPosition(gAgent.getPosAgentFromGlobal(root_pos) ); // regular update | ||
3148 | |||
3149 | //-------------------------------------------------------------------- | ||
3150 | // Propagate viewer object rotation to root of avatar | ||
3151 | //-------------------------------------------------------------------- | ||
3152 | if (!isAnyAnimationSignaled(AGENT_NO_ROTATE_ANIMS, NUM_AGENT_NO_ROTATE_ANIMS)) | ||
3153 | { | ||
3154 | LLQuaternion iQ; | ||
3155 | LLVector3 upDir( 0.0f, 0.0f, 1.0f ); | ||
3156 | |||
3157 | // Compute a forward direction vector derived from the primitive rotation | ||
3158 | // and the velocity vector. When walking or jumping, don't let body deviate | ||
3159 | // more than 90 from the view, if necessary, flip the velocity vector. | ||
3160 | |||
3161 | LLVector3 primDir; | ||
3162 | if (mIsSelf) | ||
3163 | { | ||
3164 | primDir = agent.getAtAxis() - projected_vec(agent.getAtAxis(), agent.getReferenceUpVector()); | ||
3165 | primDir.normVec(); | ||
3166 | } | ||
3167 | else | ||
3168 | { | ||
3169 | primDir = getRotation().getMatrix3().getFwdRow(); | ||
3170 | } | ||
3171 | LLVector3 velDir = getVelocity(); | ||
3172 | velDir.normVec(); | ||
3173 | if ( mSignaledAnimations.find(ANIM_AGENT_WALK) != mSignaledAnimations.end()) | ||
3174 | { | ||
3175 | F32 vpD = velDir * primDir; | ||
3176 | if (vpD < -0.5f) | ||
3177 | { | ||
3178 | velDir *= -1.0f; | ||
3179 | } | ||
3180 | } | ||
3181 | LLVector3 fwdDir = lerp(primDir, velDir, clamp_rescale(speed, 0.5f, 2.0f, 0.0f, 1.0f)); | ||
3182 | if (mIsSelf && gAgent.cameraMouselook()) | ||
3183 | { | ||
3184 | // make sure fwdDir stays in same general direction as primdir | ||
3185 | if (gAgent.getFlying()) | ||
3186 | { | ||
3187 | fwdDir = gCamera->getAtAxis(); | ||
3188 | } | ||
3189 | else | ||
3190 | { | ||
3191 | LLVector3 at_axis = gCamera->getAtAxis(); | ||
3192 | LLVector3 up_vector = gAgent.getReferenceUpVector(); | ||
3193 | at_axis -= up_vector * (at_axis * up_vector); | ||
3194 | at_axis.normVec(); | ||
3195 | |||
3196 | F32 dot = fwdDir * at_axis; | ||
3197 | if (dot < 0.f) | ||
3198 | { | ||
3199 | fwdDir -= 2.f * at_axis * dot; | ||
3200 | fwdDir.normVec(); | ||
3201 | } | ||
3202 | } | ||
3203 | |||
3204 | } | ||
3205 | |||
3206 | LLQuaternion root_rotation = mRoot.getWorldMatrix().quaternion(); | ||
3207 | F32 root_roll, root_pitch, root_yaw; | ||
3208 | root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw); | ||
3209 | |||
3210 | if (gDebugAvatarRotation) | ||
3211 | { | ||
3212 | llinfos << "root_roll " << RAD_TO_DEG * root_roll | ||
3213 | << " root_pitch " << RAD_TO_DEG * root_pitch | ||
3214 | << " root_yaw " << RAD_TO_DEG * root_yaw | ||
3215 | << llendl; | ||
3216 | } | ||
3217 | |||
3218 | // When moving very slow, the pelvis is allowed to deviate from the | ||
3219 | // forward direction to allow it to hold it's position while the torso | ||
3220 | // and head turn. Once in motion, it must conform however. | ||
3221 | BOOL self_in_mouselook = mIsSelf && gAgent.cameraMouselook(); | ||
3222 | |||
3223 | LLVector3 pelvisDir( mRoot.getWorldMatrix().getFwdRow4().mV ); | ||
3224 | F32 pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, PELVIS_ROT_THRESHOLD_SLOW, PELVIS_ROT_THRESHOLD_FAST); | ||
3225 | |||
3226 | //Ventrella | ||
3227 | //if ( gAgent.getCameraMode() == CAMERA_MODE_FOLLOW ) | ||
3228 | //{ | ||
3229 | // pelvis_rot_threshold = clamp_rescale(speed, 0.1f, 1.0f, 1.0f, 1.0f); | ||
3230 | //} | ||
3231 | //end Ventrella | ||
3232 | |||
3233 | if (self_in_mouselook) | ||
3234 | { | ||
3235 | pelvis_rot_threshold *= MOUSELOOK_PELVIS_FOLLOW_FACTOR; | ||
3236 | } | ||
3237 | pelvis_rot_threshold *= DEG_TO_RAD; | ||
3238 | |||
3239 | F32 angle = angle_between( pelvisDir, fwdDir ); | ||
3240 | |||
3241 | // The avatar's root is allowed to have a yaw that deviates widely | ||
3242 | // from the forward direction, but if roll or pitch are off even | ||
3243 | // a little bit we need to correct the rotation. | ||
3244 | if(root_roll < 1.f * DEG_TO_RAD | ||
3245 | && root_pitch < 5.f * DEG_TO_RAD) | ||
3246 | { | ||
3247 | // smaller correction vector means pelvis follows prim direction more closely | ||
3248 | if (!mTurning && angle > pelvis_rot_threshold*0.75f) | ||
3249 | { | ||
3250 | mTurning = TRUE; | ||
3251 | } | ||
3252 | |||
3253 | // use tighter threshold when turning | ||
3254 | if (mTurning) | ||
3255 | { | ||
3256 | pelvis_rot_threshold *= 0.4f; | ||
3257 | } | ||
3258 | |||
3259 | // am I done turning? | ||
3260 | if (angle < pelvis_rot_threshold) | ||
3261 | { | ||
3262 | mTurning = FALSE; | ||
3263 | } | ||
3264 | |||
3265 | LLVector3 correction_vector = (pelvisDir - fwdDir) * clamp_rescale(angle, pelvis_rot_threshold*0.75f, pelvis_rot_threshold, 1.0f, 0.0f); | ||
3266 | fwdDir += correction_vector; | ||
3267 | } | ||
3268 | else | ||
3269 | { | ||
3270 | mTurning = FALSE; | ||
3271 | } | ||
3272 | |||
3273 | // Now compute the full world space rotation for the whole body (wQv) | ||
3274 | LLVector3 leftDir = upDir % fwdDir; | ||
3275 | leftDir.normVec(); | ||
3276 | fwdDir = leftDir % upDir; | ||
3277 | LLQuaternion wQv( fwdDir, leftDir, upDir ); | ||
3278 | |||
3279 | if (mIsSelf && mTurning) | ||
3280 | { | ||
3281 | if ((fwdDir % pelvisDir) * upDir > 0.f) | ||
3282 | { | ||
3283 | gAgent.setControlFlags(AGENT_CONTROL_TURN_RIGHT); | ||
3284 | } | ||
3285 | else | ||
3286 | { | ||
3287 | gAgent.setControlFlags(AGENT_CONTROL_TURN_LEFT); | ||
3288 | } | ||
3289 | } | ||
3290 | |||
3291 | // Set the root rotation, but do so incrementally so that it | ||
3292 | // lags in time by some fixed amount. | ||
3293 | //F32 u = LLCriticalDamp::getInterpolant(PELVIS_LAG); | ||
3294 | F32 pelvis_lag_time = 0.f; | ||
3295 | if (self_in_mouselook) | ||
3296 | { | ||
3297 | pelvis_lag_time = PELVIS_LAG_MOUSELOOK; | ||
3298 | } | ||
3299 | else if (mInAir) | ||
3300 | { | ||
3301 | pelvis_lag_time = PELVIS_LAG_FLYING; | ||
3302 | // increase pelvis lag time when moving slowly | ||
3303 | pelvis_lag_time *= clamp_rescale(mSpeedAccum, 0.f, 15.f, 3.f, 1.f); | ||
3304 | } | ||
3305 | else | ||
3306 | { | ||
3307 | pelvis_lag_time = PELVIS_LAG_WALKING; | ||
3308 | } | ||
3309 | |||
3310 | //Ventrella | ||
3311 | //if ( gAgent.getCameraMode() == CAMERA_MODE_FOLLOW ) | ||
3312 | //{ | ||
3313 | // pelvis_lag_time = PELVIS_LAG_WHEN_FOLLOW_CAM_IS_ON; | ||
3314 | //} | ||
3315 | //end Ventrella | ||
3316 | |||
3317 | F32 u = llclamp((deltaTime / pelvis_lag_time), 0.0f, 1.0f); | ||
3318 | |||
3319 | mRoot.setWorldRotation( slerp(u, mRoot.getWorldRotation(), wQv) ); | ||
3320 | } | ||
3321 | } | ||
3322 | else if (mDrawable.notNull()) | ||
3323 | { | ||
3324 | mRoot.setPosition(mDrawable->getPosition()); | ||
3325 | mRoot.setRotation(mDrawable->getRotation()); | ||
3326 | } | ||
3327 | |||
3328 | //-------------------------------------------------------------------- | ||
3329 | // the rest should only be done when close enough to see it | ||
3330 | //-------------------------------------------------------------------- | ||
3331 | if ( !(mIsSitting && getParent()) && | ||
3332 | ((mPixelArea < 12.0f) || | ||
3333 | (!isVisible() && (mPixelArea < MIN_PIXEL_AREA_FOR_COMPOSITE))) ) | ||
3334 | { | ||
3335 | mRoot.setWorldRotation( getRotation() ); | ||
3336 | mRoot.updateWorldMatrixChildren(); | ||
3337 | return; | ||
3338 | } | ||
3339 | |||
3340 | //------------------------------------------------------------------------- | ||
3341 | // Update character motions | ||
3342 | //------------------------------------------------------------------------- | ||
3343 | // store data relevant to motions | ||
3344 | mSpeed = speed; | ||
3345 | |||
3346 | // update animations | ||
3347 | { | ||
3348 | LLFastTimer t(LLFastTimer::FTM_UPDATE_ANIMATION); | ||
3349 | updateMotion(); | ||
3350 | } | ||
3351 | |||
3352 | // update head position | ||
3353 | updateHeadOffset(); | ||
3354 | |||
3355 | //------------------------------------------------------------------------- | ||
3356 | // Find the ground under each foot, these are used for a variety | ||
3357 | // of things that follow | ||
3358 | //------------------------------------------------------------------------- | ||
3359 | LLVector3 ankle_left_pos_agent = mFootLeftp->getWorldPosition(); | ||
3360 | LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition(); | ||
3361 | |||
3362 | LLVector3 ankle_left_ground_agent = ankle_left_pos_agent; | ||
3363 | LLVector3 ankle_right_ground_agent = ankle_right_pos_agent; | ||
3364 | resolveHeightAgent(ankle_left_pos_agent, ankle_left_ground_agent, normal); | ||
3365 | resolveHeightAgent(ankle_right_pos_agent, ankle_right_ground_agent, normal); | ||
3366 | |||
3367 | F32 leftElev = llmax(-0.2f, ankle_left_pos_agent.mV[VZ] - ankle_left_ground_agent.mV[VZ]); | ||
3368 | F32 rightElev = llmax(-0.2f, ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]); | ||
3369 | |||
3370 | if (!mIsSitting) | ||
3371 | { | ||
3372 | //------------------------------------------------------------------------- | ||
3373 | // Figure out which foot is on ground | ||
3374 | //------------------------------------------------------------------------- | ||
3375 | if (!mInAir) | ||
3376 | { | ||
3377 | if ((leftElev < 0.0f) || (rightElev < 0.0f)) | ||
3378 | { | ||
3379 | ankle_left_pos_agent = mFootLeftp->getWorldPosition(); | ||
3380 | ankle_right_pos_agent = mFootRightp->getWorldPosition(); | ||
3381 | leftElev = ankle_left_pos_agent.mV[VZ] - ankle_left_ground_agent.mV[VZ]; | ||
3382 | rightElev = ankle_right_pos_agent.mV[VZ] - ankle_right_ground_agent.mV[VZ]; | ||
3383 | } | ||
3384 | } | ||
3385 | } | ||
3386 | |||
3387 | //------------------------------------------------------------------------- | ||
3388 | // Generate footstep sounds when feet hit the ground | ||
3389 | //------------------------------------------------------------------------- | ||
3390 | const LLUUID AGENT_FOOTSTEP_ANIMS[] = {ANIM_AGENT_WALK, ANIM_AGENT_RUN, ANIM_AGENT_LAND}; | ||
3391 | const S32 NUM_AGENT_FOOTSTEP_ANIMS = sizeof(AGENT_FOOTSTEP_ANIMS) / sizeof(LLUUID); | ||
3392 | |||
3393 | if ( gAudiop && isAnyAnimationSignaled(AGENT_FOOTSTEP_ANIMS, NUM_AGENT_FOOTSTEP_ANIMS) ) | ||
3394 | { | ||
3395 | BOOL playSound = FALSE; | ||
3396 | LLVector3 foot_pos_agent; | ||
3397 | |||
3398 | BOOL onGroundLeft = (leftElev <= 0.05f); | ||
3399 | BOOL onGroundRight = (rightElev <= 0.05f); | ||
3400 | |||
3401 | // did left foot hit the ground? | ||
3402 | if ( onGroundLeft && !mWasOnGroundLeft ) | ||
3403 | { | ||
3404 | foot_pos_agent = ankle_left_pos_agent; | ||
3405 | playSound = TRUE; | ||
3406 | } | ||
3407 | |||
3408 | // did right foot hit the ground? | ||
3409 | if ( onGroundRight && !mWasOnGroundRight ) | ||
3410 | { | ||
3411 | foot_pos_agent = ankle_right_pos_agent; | ||
3412 | playSound = TRUE; | ||
3413 | } | ||
3414 | |||
3415 | mWasOnGroundLeft = onGroundLeft; | ||
3416 | mWasOnGroundRight = onGroundRight; | ||
3417 | |||
3418 | if ( playSound ) | ||
3419 | { | ||
3420 | // F32 gain = clamp_rescale( mSpeedAccum, | ||
3421 | // AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED, | ||
3422 | // AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN ); | ||
3423 | |||
3424 | F32 gain = gSavedSettings.getF32("AudioLevelFootsteps"); | ||
3425 | LLUUID& step_sound_id = getStepSound(); | ||
3426 | |||
3427 | LLVector3d foot_pos_global = gAgent.getPosGlobalFromAgent(foot_pos_agent); | ||
3428 | |||
3429 | if (gParcelMgr && gParcelMgr->canHearSound(foot_pos_global) | ||
3430 | && gMuteListp && !gMuteListp->isMuted(getID())) | ||
3431 | { | ||
3432 | gAudiop->triggerSound(step_sound_id, getID(), gain, foot_pos_global); | ||
3433 | } | ||
3434 | } | ||
3435 | } | ||
3436 | |||
3437 | mRoot.updateWorldMatrixChildren(); | ||
3438 | |||
3439 | if (!mDebugText.size() && mText.notNull()) | ||
3440 | { | ||
3441 | mText->markDead(); | ||
3442 | mText = NULL; | ||
3443 | } | ||
3444 | else if (mDebugText.size()) | ||
3445 | { | ||
3446 | setDebugText(mDebugText); | ||
3447 | } | ||
3448 | } | ||
3449 | |||
3450 | //----------------------------------------------------------------------------- | ||
3451 | // updateHeadOffset() | ||
3452 | //----------------------------------------------------------------------------- | ||
3453 | void LLVOAvatar::updateHeadOffset() | ||
3454 | { | ||
3455 | // since we only care about Z, just grab one of the eyes | ||
3456 | LLVector3 midEyePt = mEyeLeftp->getWorldPosition(); | ||
3457 | midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot.getWorldPosition(); | ||
3458 | midEyePt.mV[VZ] = llmax(-mPelvisToFoot + gCamera->getNear(), midEyePt.mV[VZ]); | ||
3459 | |||
3460 | if (mDrawable.notNull()) | ||
3461 | { | ||
3462 | midEyePt = midEyePt * ~mDrawable->getWorldRotation(); | ||
3463 | } | ||
3464 | if (mIsSitting) | ||
3465 | { | ||
3466 | mHeadOffset = midEyePt; | ||
3467 | } | ||
3468 | else | ||
3469 | { | ||
3470 | F32 u = llmax(0.f, HEAD_MOVEMENT_AVG_TIME - (1.f / gFPSClamped)); | ||
3471 | mHeadOffset = lerp(midEyePt, mHeadOffset, u); | ||
3472 | } | ||
3473 | } | ||
3474 | |||
3475 | //------------------------------------------------------------------------ | ||
3476 | // updateVisibility() | ||
3477 | //------------------------------------------------------------------------ | ||
3478 | void LLVOAvatar::updateVisibility(BOOL force_invisible) | ||
3479 | { | ||
3480 | BOOL visible = FALSE; | ||
3481 | |||
3482 | if (mIsDummy) | ||
3483 | { | ||
3484 | visible = TRUE; | ||
3485 | } | ||
3486 | else if (mDrawable.isNull()) | ||
3487 | { | ||
3488 | visible = FALSE; | ||
3489 | } | ||
3490 | else if (!force_invisible) | ||
3491 | { | ||
3492 | // calculate avatar distance wrt head | ||
3493 | LLVector3 pos = mDrawable->getPositionAgent(); | ||
3494 | pos -= gCamera->getOrigin(); | ||
3495 | mDrawable->mDistanceWRTCamera = pos.magVec(); | ||
3496 | |||
3497 | if (!mDrawable->getSpatialGroup() || mDrawable->getSpatialGroup()->isVisible()) | ||
3498 | { | ||
3499 | visible = TRUE; | ||
3500 | } | ||
3501 | else | ||
3502 | { | ||
3503 | visible = FALSE; | ||
3504 | } | ||
3505 | |||
3506 | if( mIsSelf ) | ||
3507 | { | ||
3508 | if( !gAgent.areWearablesLoaded()) | ||
3509 | { | ||
3510 | visible = FALSE; | ||
3511 | } | ||
3512 | } | ||
3513 | else | ||
3514 | if( !mFirstAppearanceMessageReceived ) | ||
3515 | { | ||
3516 | visible = FALSE; | ||
3517 | } | ||
3518 | |||
3519 | if (sDebugInvisible) | ||
3520 | { | ||
3521 | LLNameValue* firstname = getNVPair("FirstName"); | ||
3522 | if (firstname) | ||
3523 | { | ||
3524 | llinfos << "Avatar " << firstname->getString() << " updating visiblity" << llendl; | ||
3525 | } | ||
3526 | else | ||
3527 | { | ||
3528 | llinfos << "Avatar " << this << " updating visiblity" << llendl; | ||
3529 | } | ||
3530 | |||
3531 | if (visible) | ||
3532 | { | ||
3533 | llinfos << "Visible" << llendl; | ||
3534 | } | ||
3535 | else | ||
3536 | { | ||
3537 | llinfos << "Not visible" << llendl; | ||
3538 | } | ||
3539 | |||
3540 | /*if (avatar_in_frustum) | ||
3541 | { | ||
3542 | llinfos << "Avatar in frustum" << llendl; | ||
3543 | } | ||
3544 | else | ||
3545 | { | ||
3546 | llinfos << "Avatar not in frustum" << llendl; | ||
3547 | }*/ | ||
3548 | |||
3549 | /*if (gCamera->sphereInFrustum(sel_pos_agent, 2.0f)) | ||
3550 | { | ||
3551 | llinfos << "Sel pos visible" << llendl; | ||
3552 | } | ||
3553 | if (gCamera->sphereInFrustum(wrist_right_pos_agent, 0.2f)) | ||
3554 | { | ||
3555 | llinfos << "Wrist pos visible" << llendl; | ||
3556 | } | ||
3557 | if (gCamera->sphereInFrustum(getPositionAgent(), getMaxScale()*2.f)) | ||
3558 | { | ||
3559 | llinfos << "Agent visible" << llendl; | ||
3560 | }*/ | ||
3561 | llinfos << "PA: " << getPositionAgent() << llendl; | ||
3562 | /*llinfos << "SPA: " << sel_pos_agent << llendl; | ||
3563 | llinfos << "WPA: " << wrist_right_pos_agent << llendl;*/ | ||
3564 | for (LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); | ||
3565 | attachment; | ||
3566 | attachment = mAttachmentPoints.getNextData()) | ||
3567 | { | ||
3568 | if (attachment->getObject(0)) | ||
3569 | { | ||
3570 | if(attachment->getObject(0)->mDrawable->isVisible()) | ||
3571 | { | ||
3572 | llinfos << attachment->getName() << " visible" << llendl; | ||
3573 | } | ||
3574 | else | ||
3575 | { | ||
3576 | llinfos << attachment->getName() << " not visible at " << mDrawable->getWorldPosition() << " and radius " << mDrawable->getRadius() << llendl; | ||
3577 | } | ||
3578 | } | ||
3579 | } | ||
3580 | } | ||
3581 | } | ||
3582 | |||
3583 | if (!visible && mVisible) | ||
3584 | { | ||
3585 | mMeshInvisibleTime.reset(); | ||
3586 | } | ||
3587 | |||
3588 | if (visible) | ||
3589 | { | ||
3590 | if (!mMeshValid) | ||
3591 | { | ||
3592 | restoreMeshData(); | ||
3593 | } | ||
3594 | gPipeline.markVisible(mDrawable); | ||
3595 | } | ||
3596 | else | ||
3597 | { | ||
3598 | if (mMeshValid && mMeshInvisibleTime.getElapsedTimeF32() > TIME_BEFORE_MESH_CLEANUP) | ||
3599 | { | ||
3600 | releaseMeshData(); | ||
3601 | } | ||
3602 | // this breaks off-screen chat bubbles | ||
3603 | //if (mNameText) | ||
3604 | //{ | ||
3605 | // mNameText->markDead(); | ||
3606 | // mNameText = NULL; | ||
3607 | // sNumVisibleChatBubbles--; | ||
3608 | //} | ||
3609 | } | ||
3610 | |||
3611 | mVisible = visible; | ||
3612 | } | ||
3613 | |||
3614 | //------------------------------------------------------------------------ | ||
3615 | // updateAllVisibility() | ||
3616 | //------------------------------------------------------------------------ | ||
3617 | //static | ||
3618 | void LLVOAvatar::updateAllAvatarVisiblity() | ||
3619 | { | ||
3620 | LLVOAvatar::sNumVisibleAvatars = 0; | ||
3621 | LLVOAvatar *avatarp; | ||
3622 | |||
3623 | F32 render_priority = (F32)LLVOAvatar::sMaxVisible; | ||
3624 | for (avatarp = (LLVOAvatar*)sInstances.getFirstData(); avatarp; avatarp = (LLVOAvatar*)sInstances.getNextData()) | ||
3625 | { | ||
3626 | if (avatarp->isDead()) | ||
3627 | { | ||
3628 | continue; | ||
3629 | } | ||
3630 | if (avatarp->isSelf()) | ||
3631 | { | ||
3632 | avatarp->mRenderPriority = 1000.f; | ||
3633 | } | ||
3634 | else | ||
3635 | { | ||
3636 | avatarp->mRenderPriority = render_priority * 10.f; // 500 -> 10 | ||
3637 | if (render_priority > 0.f) | ||
3638 | { | ||
3639 | render_priority -= 1.f; | ||
3640 | } | ||
3641 | } | ||
3642 | avatarp->updateVisibility(LLVOAvatar::sNumVisibleAvatars > LLVOAvatar::sMaxVisible); | ||
3643 | |||
3644 | if (avatarp->mDrawable.isNull()) | ||
3645 | { | ||
3646 | llwarns << "Avatar with no drawable" << llendl; | ||
3647 | } | ||
3648 | else if (avatarp->mDrawable->isVisible()) | ||
3649 | { | ||
3650 | LLVOAvatar::sNumVisibleAvatars++; | ||
3651 | } | ||
3652 | } | ||
3653 | } | ||
3654 | |||
3655 | //------------------------------------------------------------------------ | ||
3656 | // needsRenderBeam() | ||
3657 | //------------------------------------------------------------------------ | ||
3658 | BOOL LLVOAvatar::needsRenderBeam() | ||
3659 | { | ||
3660 | if (gNoRender) | ||
3661 | { | ||
3662 | return FALSE; | ||
3663 | } | ||
3664 | LLTool *tool = gToolMgr->getCurrentTool( gKeyboard->currentMask(TRUE) ); | ||
3665 | |||
3666 | BOOL is_touching_or_grabbing = (tool == gToolGrab && gToolGrab->isEditing()); | ||
3667 | if (gToolGrab->getEditingObject() && | ||
3668 | gToolGrab->getEditingObject()->isAttachment()) | ||
3669 | { | ||
3670 | // don't render selection beam on hud objects | ||
3671 | is_touching_or_grabbing = FALSE; | ||
3672 | } | ||
3673 | return is_touching_or_grabbing || (mState & AGENT_STATE_EDITING && gSelectMgr->shouldShowSelection()); | ||
3674 | } | ||
3675 | |||
3676 | //----------------------------------------------------------------------------- | ||
3677 | // renderSkinned() | ||
3678 | //----------------------------------------------------------------------------- | ||
3679 | U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass) | ||
3680 | { | ||
3681 | U32 num_indices = 0; | ||
3682 | |||
3683 | if (!mIsBuilt) | ||
3684 | { | ||
3685 | return num_indices; | ||
3686 | } | ||
3687 | |||
3688 | if (sDebugInvisible) | ||
3689 | { | ||
3690 | LLNameValue* firstname = getNVPair("FirstName"); | ||
3691 | if (firstname) | ||
3692 | { | ||
3693 | llinfos << "Avatar " << firstname->getString() << " in render" << llendl; | ||
3694 | } | ||
3695 | else | ||
3696 | { | ||
3697 | llinfos << "Avatar " << this << " in render" << llendl; | ||
3698 | } | ||
3699 | if (!mIsBuilt) | ||
3700 | { | ||
3701 | llinfos << "Not built!" << llendl; | ||
3702 | } | ||
3703 | else if (!gAgent.needsRenderAvatar()) | ||
3704 | { | ||
3705 | llinfos << "Doesn't need avatar render!" << llendl; | ||
3706 | } | ||
3707 | else | ||
3708 | { | ||
3709 | llinfos << "Rendering!" << llendl; | ||
3710 | } | ||
3711 | } | ||
3712 | |||
3713 | if (!mIsBuilt) | ||
3714 | { | ||
3715 | return num_indices; | ||
3716 | } | ||
3717 | |||
3718 | if (mIsSelf && !gAgent.needsRenderAvatar()) | ||
3719 | { | ||
3720 | return num_indices; | ||
3721 | } | ||
3722 | |||
3723 | // render collision normal | ||
3724 | if (sShowFootPlane && mDrawable.notNull()) | ||
3725 | { | ||
3726 | LLVector3 slaved_pos = mDrawable->getPositionAgent(); | ||
3727 | LLVector3 foot_plane_normal(mFootPlane.mV[VX], mFootPlane.mV[VY], mFootPlane.mV[VZ]); | ||
3728 | F32 dist_from_plane = (slaved_pos * foot_plane_normal) - mFootPlane.mV[VW]; | ||
3729 | LLVector3 collide_point = slaved_pos; | ||
3730 | collide_point.mV[VZ] -= foot_plane_normal.mV[VZ] * (dist_from_plane + COLLISION_TOLERANCE - FOOT_COLLIDE_FUDGE); | ||
3731 | |||
3732 | glBegin(GL_LINES); | ||
3733 | { | ||
3734 | F32 SQUARE_SIZE = 0.2f; | ||
3735 | glColor4f(1.f, 0.f, 0.f, 1.f); | ||
3736 | |||
3737 | glVertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); | ||
3738 | glVertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); | ||
3739 | |||
3740 | glVertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); | ||
3741 | glVertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); | ||
3742 | |||
3743 | glVertex3f(collide_point.mV[VX] + SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); | ||
3744 | glVertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); | ||
3745 | |||
3746 | glVertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] + SQUARE_SIZE, collide_point.mV[VZ]); | ||
3747 | glVertex3f(collide_point.mV[VX] - SQUARE_SIZE, collide_point.mV[VY] - SQUARE_SIZE, collide_point.mV[VZ]); | ||
3748 | |||
3749 | glVertex3f(collide_point.mV[VX], collide_point.mV[VY], collide_point.mV[VZ]); | ||
3750 | glVertex3f(collide_point.mV[VX] + mFootPlane.mV[VX], collide_point.mV[VY] + mFootPlane.mV[VY], collide_point.mV[VZ] + mFootPlane.mV[VZ]); | ||
3751 | |||
3752 | }glEnd(); | ||
3753 | } | ||
3754 | //-------------------------------------------------------------------- | ||
3755 | // render all geomety attached to the skeleton | ||
3756 | //-------------------------------------------------------------------- | ||
3757 | static LLStat render_stat; | ||
3758 | |||
3759 | LLViewerJointMesh::sRenderPass = pass; | ||
3760 | |||
3761 | if (pass == AVATAR_RENDER_PASS_SINGLE) | ||
3762 | { | ||
3763 | if (!mIsSelf || gAgent.needsRenderHead()) | ||
3764 | { | ||
3765 | num_indices += mHeadLOD.render(mAdjustedPixelArea); | ||
3766 | } | ||
3767 | num_indices += mUpperBodyLOD.render(mAdjustedPixelArea); | ||
3768 | num_indices += mLowerBodyLOD.render(mAdjustedPixelArea); | ||
3769 | if( isWearingWearableType( WT_SKIRT ) ) | ||
3770 | { | ||
3771 | glAlphaFunc(GL_GREATER,0.25f); | ||
3772 | num_indices += mSkirtLOD.render(mAdjustedPixelArea); | ||
3773 | glAlphaFunc(GL_GREATER,0.01f); | ||
3774 | } | ||
3775 | |||
3776 | if (!mIsSelf || gAgent.needsRenderHead()) | ||
3777 | { | ||
3778 | num_indices += mEyeLashLOD.render(mAdjustedPixelArea); | ||
3779 | num_indices += mHairLOD.render(mAdjustedPixelArea); | ||
3780 | } | ||
3781 | } | ||
3782 | else if (pass == AVATAR_RENDER_PASS_CLOTHING_INNER) | ||
3783 | { | ||
3784 | if (!mIsSelf || gAgent.needsRenderHead()) | ||
3785 | { | ||
3786 | num_indices += mHeadLOD.render(mAdjustedPixelArea); | ||
3787 | } | ||
3788 | LLViewerJointMesh::sClothingInnerColor = mTexSkinColor->getColor() * 0.5f; | ||
3789 | LLViewerJointMesh::sClothingMaskImageName = mUpperMaskTexName; | ||
3790 | num_indices += mUpperBodyLOD.render(mAdjustedPixelArea); | ||
3791 | LLViewerJointMesh::sClothingMaskImageName = mLowerMaskTexName; | ||
3792 | num_indices += mLowerBodyLOD.render(mAdjustedPixelArea); | ||
3793 | LLViewerJointMesh::sClothingMaskImageName = 0; | ||
3794 | if( isWearingWearableType( WT_SKIRT ) ) | ||
3795 | { | ||
3796 | glAlphaFunc(GL_GREATER,0.25f); | ||
3797 | num_indices += mSkirtLOD.render(mAdjustedPixelArea); | ||
3798 | glAlphaFunc(GL_GREATER,0.01f); | ||
3799 | } | ||
3800 | |||
3801 | if (!mIsSelf || gAgent.needsRenderHead()) | ||
3802 | { | ||
3803 | num_indices += mEyeLashLOD.render(mAdjustedPixelArea); | ||
3804 | num_indices += mHairLOD.render(mAdjustedPixelArea); | ||
3805 | } | ||
3806 | } | ||
3807 | else if (pass == AVATAR_RENDER_PASS_CLOTHING_OUTER) | ||
3808 | { | ||
3809 | LLViewerJointMesh::sClothingInnerColor = mTexSkinColor->getColor() * 0.5f; | ||
3810 | LLViewerJointMesh::sClothingMaskImageName = mUpperMaskTexName; | ||
3811 | num_indices += mUpperBodyLOD.render(mAdjustedPixelArea); | ||
3812 | LLViewerJointMesh::sClothingMaskImageName = mLowerMaskTexName; | ||
3813 | num_indices += mLowerBodyLOD.render(mAdjustedPixelArea); | ||
3814 | LLViewerJointMesh::sClothingMaskImageName = 0; | ||
3815 | } | ||
3816 | |||
3817 | LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE; | ||
3818 | |||
3819 | //llinfos << "Avatar render: " << render_timer.getElapsedTimeF32() << llendl; | ||
3820 | |||
3821 | //render_stat.addValue(render_timer.getElapsedTimeF32()*1000.f); | ||
3822 | |||
3823 | return num_indices; | ||
3824 | } | ||
3825 | |||
3826 | //----------------------------------------------------------------------------- | ||
3827 | // renderRigid() | ||
3828 | //----------------------------------------------------------------------------- | ||
3829 | U32 LLVOAvatar::renderRigid() | ||
3830 | { | ||
3831 | U32 num_indices = 0; | ||
3832 | |||
3833 | if (!mIsBuilt) | ||
3834 | { | ||
3835 | return 0; | ||
3836 | } | ||
3837 | |||
3838 | if (mIsSelf && (!gAgent.needsRenderAvatar() || !gAgent.needsRenderHead())) | ||
3839 | { | ||
3840 | return 0; | ||
3841 | } | ||
3842 | |||
3843 | if (!mIsBuilt) | ||
3844 | { | ||
3845 | return 0; | ||
3846 | } | ||
3847 | |||
3848 | num_indices += mEyeBallLeftLOD.render(mAdjustedPixelArea); | ||
3849 | num_indices += mEyeBallRightLOD.render(mAdjustedPixelArea); | ||
3850 | |||
3851 | return num_indices; | ||
3852 | } | ||
3853 | |||
3854 | //----------------------------------------------------------------------------- | ||
3855 | // renderCollisionVolumes() | ||
3856 | //----------------------------------------------------------------------------- | ||
3857 | void LLVOAvatar::renderCollisionVolumes() | ||
3858 | { | ||
3859 | for (S32 i = 0; i < mNumCollisionVolumes; i++) | ||
3860 | { | ||
3861 | mCollisionVolumes[i].render(); | ||
3862 | } | ||
3863 | } | ||
3864 | |||
3865 | //------------------------------------------------------------------------ | ||
3866 | // LLVOAvatar::updateTextures() | ||
3867 | //------------------------------------------------------------------------ | ||
3868 | void LLVOAvatar::updateTextures(LLAgent &agent) | ||
3869 | { | ||
3870 | BOOL render_avatar = TRUE; | ||
3871 | |||
3872 | if (mIsDummy || gNoRender) | ||
3873 | { | ||
3874 | return; | ||
3875 | } | ||
3876 | |||
3877 | BOOL head_baked = ( getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
3878 | BOOL upper_baked = ( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
3879 | BOOL lower_baked = ( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
3880 | BOOL eyes_baked = ( getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
3881 | BOOL skirt_baked = ( getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
3882 | |||
3883 | if( mIsSelf ) | ||
3884 | { | ||
3885 | render_avatar = TRUE; | ||
3886 | } | ||
3887 | else | ||
3888 | { | ||
3889 | render_avatar = isVisible() && !mCulled; | ||
3890 | } | ||
3891 | |||
3892 | // bind the texture so that they'll be decoded | ||
3893 | // slightly inefficient, we can short-circuit this | ||
3894 | // if we have to | ||
3895 | if( render_avatar && !gGLManager.mIsDisabled ) | ||
3896 | { | ||
3897 | if( head_baked && ! mHeadBakedLoaded ) | ||
3898 | { | ||
3899 | getTEImage( TEX_HEAD_BAKED )->bind(); | ||
3900 | } | ||
3901 | if( upper_baked && ! mUpperBakedLoaded ) | ||
3902 | { | ||
3903 | getTEImage( TEX_UPPER_BAKED )->bind(); | ||
3904 | } | ||
3905 | if( lower_baked && ! mLowerBakedLoaded ) | ||
3906 | { | ||
3907 | getTEImage( TEX_LOWER_BAKED )->bind(); | ||
3908 | } | ||
3909 | if( eyes_baked && ! mEyesBakedLoaded ) | ||
3910 | { | ||
3911 | getTEImage( TEX_EYES_BAKED )->bind(); | ||
3912 | } | ||
3913 | if( skirt_baked && ! mSkirtBakedLoaded ) | ||
3914 | { | ||
3915 | getTEImage( TEX_SKIRT_BAKED )->bind(); | ||
3916 | } | ||
3917 | } | ||
3918 | |||
3919 | /* | ||
3920 | // JAMESDEBUG | ||
3921 | if (mIsSelf) | ||
3922 | { | ||
3923 | S32 null_count = 0; | ||
3924 | S32 default_count = 0; | ||
3925 | for (U32 i = 0; i < getNumTEs(); i++) | ||
3926 | { | ||
3927 | const LLTextureEntry* te = getTE(i); | ||
3928 | if (te) | ||
3929 | { | ||
3930 | if (te->getID() == LLUUID::null) | ||
3931 | { | ||
3932 | null_count++; | ||
3933 | } | ||
3934 | else if (te->getID() == IMG_DEFAULT_AVATAR) | ||
3935 | { | ||
3936 | default_count++; | ||
3937 | } | ||
3938 | } | ||
3939 | } | ||
3940 | llinfos << "JAMESDEBUG my avatar TE null " << null_count << " default " << default_count << llendl; | ||
3941 | } | ||
3942 | */ | ||
3943 | |||
3944 | for (U32 i = 0; i < getNumTEs(); i++) | ||
3945 | { | ||
3946 | LLViewerImage *imagep = getTEImage(i); | ||
3947 | if (imagep) | ||
3948 | { | ||
3949 | // Debugging code - maybe non-self avatars are downloading textures? | ||
3950 | //llinfos << "avatar self " << mIsSelf << " tex " << i | ||
3951 | // << " decode " << imagep->getDecodePriority() | ||
3952 | // << " boost " << boost_avatar | ||
3953 | // << " size " << imagep->getWidth() << "x" << imagep->getHeight() | ||
3954 | // << " discard " << imagep->getDiscardLevel() | ||
3955 | // << " desired " << imagep->getDesiredDiscardLevel() | ||
3956 | // << llendl; | ||
3957 | |||
3958 | const LLTextureEntry *te = getTE(i); | ||
3959 | F32 texel_area_ratio = fabs(te->mScaleS * te->mScaleT); | ||
3960 | // BOOL boost_aux = (imagep->needsAux() && (!imagep->mFullWidth || !imagep->mFullHeight)); | ||
3961 | S32 boost_level = mIsSelf ? LLViewerImage::BOOST_AVATAR_BAKED_SELF : LLViewerImage::BOOST_AVATAR_BAKED; | ||
3962 | |||
3963 | // Spam if this is a baked texture, not set to default image, without valid host info | ||
3964 | if (isTextureIndexBaked(i) | ||
3965 | && imagep->getID() != IMG_DEFAULT_AVATAR | ||
3966 | && !imagep->getTargetHost().isOk()) | ||
3967 | { | ||
3968 | llwarns << "LLVOAvatar::updateTextures No host for texture " << imagep->getID() | ||
3969 | << " for avatar " << (mIsSelf ? "<myself>" : getID().getString()) | ||
3970 | << " on host " << getRegion()->getHost() << llendl; | ||
3971 | } | ||
3972 | |||
3973 | switch( i ) | ||
3974 | { | ||
3975 | // Head | ||
3976 | case TEX_HEAD_BODYPAINT: | ||
3977 | addLocalTextureStats( LOCTEX_HEAD_BODYPAINT, imagep, texel_area_ratio, render_avatar, head_baked ); | ||
3978 | break; | ||
3979 | |||
3980 | // Upper | ||
3981 | case TEX_UPPER_JACKET: | ||
3982 | addLocalTextureStats( LOCTEX_UPPER_JACKET, imagep, texel_area_ratio, render_avatar, upper_baked ); | ||
3983 | break; | ||
3984 | |||
3985 | case TEX_UPPER_SHIRT: | ||
3986 | addLocalTextureStats( LOCTEX_UPPER_SHIRT, imagep, texel_area_ratio, render_avatar, upper_baked ); | ||
3987 | break; | ||
3988 | |||
3989 | case TEX_UPPER_GLOVES: | ||
3990 | addLocalTextureStats( LOCTEX_UPPER_GLOVES, imagep, texel_area_ratio, render_avatar, upper_baked ); | ||
3991 | break; | ||
3992 | |||
3993 | case TEX_UPPER_UNDERSHIRT: | ||
3994 | addLocalTextureStats( LOCTEX_UPPER_UNDERSHIRT, imagep, texel_area_ratio, render_avatar, upper_baked ); | ||
3995 | break; | ||
3996 | |||
3997 | case TEX_UPPER_BODYPAINT: | ||
3998 | addLocalTextureStats( LOCTEX_UPPER_BODYPAINT, imagep, texel_area_ratio, render_avatar, upper_baked ); | ||
3999 | break; | ||
4000 | |||
4001 | // Lower | ||
4002 | case TEX_LOWER_JACKET: | ||
4003 | addLocalTextureStats( LOCTEX_LOWER_JACKET, imagep, texel_area_ratio, render_avatar, lower_baked ); | ||
4004 | break; | ||
4005 | |||
4006 | case TEX_LOWER_PANTS: | ||
4007 | addLocalTextureStats( LOCTEX_LOWER_PANTS, imagep, texel_area_ratio, render_avatar, lower_baked ); | ||
4008 | break; | ||
4009 | |||
4010 | case TEX_LOWER_SHOES: | ||
4011 | addLocalTextureStats( LOCTEX_LOWER_SHOES, imagep, texel_area_ratio, render_avatar, lower_baked ); | ||
4012 | break; | ||
4013 | |||
4014 | case TEX_LOWER_SOCKS: | ||
4015 | addLocalTextureStats( LOCTEX_LOWER_SOCKS, imagep, texel_area_ratio, render_avatar, lower_baked ); | ||
4016 | break; | ||
4017 | |||
4018 | case TEX_LOWER_UNDERPANTS: | ||
4019 | addLocalTextureStats( LOCTEX_LOWER_UNDERPANTS, imagep, texel_area_ratio, render_avatar, lower_baked ); | ||
4020 | break; | ||
4021 | |||
4022 | case TEX_LOWER_BODYPAINT: | ||
4023 | addLocalTextureStats( LOCTEX_LOWER_BODYPAINT, imagep, texel_area_ratio, render_avatar, lower_baked ); | ||
4024 | break; | ||
4025 | |||
4026 | // Eyes | ||
4027 | case TEX_EYES_IRIS: | ||
4028 | addLocalTextureStats( LOCTEX_EYES_IRIS, imagep, texel_area_ratio, render_avatar, eyes_baked ); | ||
4029 | break; | ||
4030 | |||
4031 | // Skirt | ||
4032 | case TEX_SKIRT: | ||
4033 | addLocalTextureStats( LOCTEX_SKIRT, imagep, texel_area_ratio, render_avatar, skirt_baked ); | ||
4034 | break; | ||
4035 | |||
4036 | // Baked | ||
4037 | case TEX_HEAD_BAKED: | ||
4038 | if (head_baked) | ||
4039 | { | ||
4040 | imagep->setBoostLevel(boost_level); | ||
4041 | imagep->addTextureStats(mPixelArea, texel_area_ratio); | ||
4042 | } | ||
4043 | break; | ||
4044 | |||
4045 | case TEX_UPPER_BAKED: | ||
4046 | if (upper_baked) | ||
4047 | { | ||
4048 | imagep->setBoostLevel(boost_level); | ||
4049 | imagep->addTextureStats(mPixelArea, texel_area_ratio); | ||
4050 | } | ||
4051 | break; | ||
4052 | |||
4053 | case TEX_LOWER_BAKED: | ||
4054 | if (lower_baked) | ||
4055 | { | ||
4056 | imagep->setBoostLevel(boost_level); | ||
4057 | imagep->addTextureStats(mPixelArea, texel_area_ratio); | ||
4058 | } | ||
4059 | break; | ||
4060 | |||
4061 | case TEX_EYES_BAKED: | ||
4062 | if (eyes_baked) | ||
4063 | { | ||
4064 | imagep->setBoostLevel(boost_level); | ||
4065 | imagep->addTextureStats(mPixelArea, texel_area_ratio); | ||
4066 | } | ||
4067 | break; | ||
4068 | |||
4069 | case TEX_SKIRT_BAKED: | ||
4070 | if (skirt_baked) | ||
4071 | { | ||
4072 | imagep->setBoostLevel(boost_level); | ||
4073 | imagep->addTextureStats(mPixelArea, texel_area_ratio); | ||
4074 | } | ||
4075 | break; | ||
4076 | |||
4077 | case TEX_HAIR: | ||
4078 | // Hair is neither a local texture used for baking, nor the output | ||
4079 | // of the baking process. It's just a texture that happens to be | ||
4080 | // used to draw avatars. Hence BOOST_AVATAR. JC | ||
4081 | if (mIsSelf) | ||
4082 | { | ||
4083 | imagep->setBoostLevel(LLViewerImage::BOOST_AVATAR_SELF); | ||
4084 | } | ||
4085 | else | ||
4086 | { | ||
4087 | imagep->setBoostLevel(LLViewerImage::BOOST_AVATAR); | ||
4088 | } | ||
4089 | imagep->addTextureStats(mPixelArea, texel_area_ratio); | ||
4090 | break; | ||
4091 | |||
4092 | default: | ||
4093 | llassert(0); | ||
4094 | break; | ||
4095 | } | ||
4096 | } | ||
4097 | } | ||
4098 | |||
4099 | if( render_avatar ) | ||
4100 | { | ||
4101 | mShadowImagep->addTextureStats(mPixelArea, 1.f); | ||
4102 | } | ||
4103 | } | ||
4104 | |||
4105 | |||
4106 | void LLVOAvatar::addLocalTextureStats( LLVOAvatar::ELocTexIndex idx, LLViewerImage* imagep, | ||
4107 | F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked ) | ||
4108 | { | ||
4109 | if (!covered_by_baked && | ||
4110 | render_avatar && // always true if mIsSelf | ||
4111 | mLocalTexture[ idx ].notNull() && mLocalTexture[idx]->getID() != IMG_DEFAULT_AVATAR) | ||
4112 | { | ||
4113 | F32 desired_pixels; | ||
4114 | if( mIsSelf ) | ||
4115 | { | ||
4116 | desired_pixels = llmin(mPixelArea, (F32)LOCTEX_IMAGE_AREA_SELF ); | ||
4117 | imagep->setBoostLevel(LLViewerImage::BOOST_AVATAR_SELF); | ||
4118 | } | ||
4119 | else | ||
4120 | { | ||
4121 | desired_pixels = llmin(mPixelArea, (F32)LOCTEX_IMAGE_AREA_OTHER ); | ||
4122 | imagep->setBoostLevel(LLViewerImage::BOOST_AVATAR); | ||
4123 | } | ||
4124 | imagep->addTextureStats( desired_pixels, texel_area_ratio ); | ||
4125 | } | ||
4126 | } | ||
4127 | |||
4128 | //----------------------------------------------------------------------------- | ||
4129 | // resolveHeight() | ||
4130 | //----------------------------------------------------------------------------- | ||
4131 | |||
4132 | void LLVOAvatar::resolveHeightAgent(const LLVector3 &in_pos_agent, LLVector3 &out_pos_agent, LLVector3 &out_norm) | ||
4133 | { | ||
4134 | LLVector3d in_pos_global, out_pos_global; | ||
4135 | |||
4136 | in_pos_global = gAgent.getPosGlobalFromAgent(in_pos_agent); | ||
4137 | resolveHeightGlobal(in_pos_global, out_pos_global, out_norm); | ||
4138 | out_pos_agent = gAgent.getPosAgentFromGlobal(out_pos_global); | ||
4139 | } | ||
4140 | |||
4141 | |||
4142 | void LLVOAvatar::resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm) | ||
4143 | { | ||
4144 | LLViewerObject *obj; | ||
4145 | gWorldPointer->resolveStepHeightGlobal(this, start_pt, end_pt, out_pos, out_norm, &obj); | ||
4146 | } | ||
4147 | |||
4148 | |||
4149 | void LLVOAvatar::resolveHeightGlobal(const LLVector3d &inPos, LLVector3d &outPos, LLVector3 &outNorm) | ||
4150 | { | ||
4151 | LLVector3d zVec(0.0f, 0.0f, 0.5f); | ||
4152 | LLVector3d p0 = inPos + zVec; | ||
4153 | LLVector3d p1 = inPos - zVec; | ||
4154 | LLViewerObject *obj; | ||
4155 | gWorldPointer->resolveStepHeightGlobal(this, p0, p1, outPos, outNorm, &obj); | ||
4156 | if (!obj) | ||
4157 | { | ||
4158 | mStepOnLand = TRUE; | ||
4159 | mStepMaterial = 0; | ||
4160 | mStepObjectVelocity.setVec(0.0f, 0.0f, 0.0f); | ||
4161 | } | ||
4162 | else | ||
4163 | { | ||
4164 | mStepOnLand = FALSE; | ||
4165 | mStepMaterial = obj->getMaterial(); | ||
4166 | |||
4167 | // We want the primitive velocity, not our velocity... (which actually subtracts the | ||
4168 | // step object velocity) | ||
4169 | LLVector3 angularVelocity = obj->getAngularVelocity(); | ||
4170 | LLVector3 relativePos = gAgent.getPosAgentFromGlobal(outPos) - obj->getPositionAgent(); | ||
4171 | |||
4172 | LLVector3 linearComponent = angularVelocity % relativePos; | ||
4173 | // llinfos << "Linear Component of Rotation Velocity " << linearComponent << llendl; | ||
4174 | mStepObjectVelocity = obj->getVelocity() + linearComponent; | ||
4175 | } | ||
4176 | } | ||
4177 | |||
4178 | |||
4179 | //----------------------------------------------------------------------------- | ||
4180 | // getStepSound() | ||
4181 | //----------------------------------------------------------------------------- | ||
4182 | LLUUID& LLVOAvatar::getStepSound() | ||
4183 | { | ||
4184 | if ( mStepOnLand ) | ||
4185 | { | ||
4186 | return sStepSoundOnLand; | ||
4187 | } | ||
4188 | |||
4189 | return sStepSounds[mStepMaterial]; | ||
4190 | } | ||
4191 | |||
4192 | |||
4193 | //----------------------------------------------------------------------------- | ||
4194 | // processAnimationStateChanges() | ||
4195 | //----------------------------------------------------------------------------- | ||
4196 | void LLVOAvatar::processAnimationStateChanges() | ||
4197 | { | ||
4198 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
4199 | |||
4200 | if (gNoRender) | ||
4201 | { | ||
4202 | return; | ||
4203 | } | ||
4204 | |||
4205 | if ( isAnyAnimationSignaled(AGENT_WALK_ANIMS, NUM_AGENT_WALK_ANIMS) ) | ||
4206 | { | ||
4207 | startMotion(ANIM_AGENT_WALK_ADJUST); | ||
4208 | stopMotion(ANIM_AGENT_FLY_ADJUST); | ||
4209 | } | ||
4210 | else if (mInAir && !mIsSitting) | ||
4211 | { | ||
4212 | stopMotion(ANIM_AGENT_WALK_ADJUST); | ||
4213 | startMotion(ANIM_AGENT_FLY_ADJUST); | ||
4214 | } | ||
4215 | else | ||
4216 | { | ||
4217 | stopMotion(ANIM_AGENT_WALK_ADJUST); | ||
4218 | stopMotion(ANIM_AGENT_FLY_ADJUST); | ||
4219 | } | ||
4220 | |||
4221 | if ( isAnyAnimationSignaled(AGENT_GUN_AIM_ANIMS, NUM_AGENT_GUN_AIM_ANIMS) ) | ||
4222 | { | ||
4223 | startMotion(ANIM_AGENT_TARGET); | ||
4224 | stopMotion(ANIM_AGENT_BODY_NOISE); | ||
4225 | } | ||
4226 | else | ||
4227 | { | ||
4228 | stopMotion(ANIM_AGENT_TARGET); | ||
4229 | startMotion(ANIM_AGENT_BODY_NOISE); | ||
4230 | } | ||
4231 | |||
4232 | // clear all current animations | ||
4233 | AnimIterator anim_it; | ||
4234 | for (anim_it = mPlayingAnimations.begin(); anim_it != mPlayingAnimations.end();) | ||
4235 | { | ||
4236 | AnimIterator found_anim = mSignaledAnimations.find(anim_it->first); | ||
4237 | |||
4238 | // playing, but not signaled, so stop | ||
4239 | if (found_anim == mSignaledAnimations.end()) | ||
4240 | { | ||
4241 | processSingleAnimationStateChange(anim_it->first, FALSE); | ||
4242 | mPlayingAnimations.erase(anim_it++); | ||
4243 | continue; | ||
4244 | } | ||
4245 | |||
4246 | ++anim_it; | ||
4247 | } | ||
4248 | |||
4249 | // start up all new anims | ||
4250 | for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();) | ||
4251 | { | ||
4252 | AnimIterator found_anim = mPlayingAnimations.find(anim_it->first); | ||
4253 | |||
4254 | // signaled but not playing, or different sequence id, start motion | ||
4255 | if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second) | ||
4256 | { | ||
4257 | if (processSingleAnimationStateChange(anim_it->first, TRUE)) | ||
4258 | { | ||
4259 | mPlayingAnimations[anim_it->first] = anim_it->second; | ||
4260 | ++anim_it; | ||
4261 | continue; | ||
4262 | } | ||
4263 | } | ||
4264 | |||
4265 | ++anim_it; | ||
4266 | } | ||
4267 | |||
4268 | // clear source information for animations which have been stopped | ||
4269 | if (mIsSelf) | ||
4270 | { | ||
4271 | AnimSourceIterator source_it = mAnimationSources.begin(); | ||
4272 | |||
4273 | for (source_it = mAnimationSources.begin(); source_it != mAnimationSources.end();) | ||
4274 | { | ||
4275 | if (mSignaledAnimations.find(source_it->second) == mSignaledAnimations.end()) | ||
4276 | { | ||
4277 | mAnimationSources.erase(source_it++); | ||
4278 | } | ||
4279 | else | ||
4280 | { | ||
4281 | ++source_it; | ||
4282 | } | ||
4283 | } | ||
4284 | } | ||
4285 | |||
4286 | stop_glerror(); | ||
4287 | } | ||
4288 | |||
4289 | |||
4290 | //----------------------------------------------------------------------------- | ||
4291 | // processSingleAnimationStateChange(); | ||
4292 | //----------------------------------------------------------------------------- | ||
4293 | BOOL LLVOAvatar::processSingleAnimationStateChange( const LLUUID& anim_id, BOOL start ) | ||
4294 | { | ||
4295 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
4296 | |||
4297 | BOOL result = FALSE; | ||
4298 | |||
4299 | if ( start ) // start animation | ||
4300 | { | ||
4301 | if (anim_id == ANIM_AGENT_TYPE) | ||
4302 | { | ||
4303 | if (gAudiop) | ||
4304 | { | ||
4305 | LLVector3d char_pos_global = gAgent.getPosGlobalFromAgent(getCharacterPosition()); | ||
4306 | if (gParcelMgr && gParcelMgr->canHearSound(char_pos_global) | ||
4307 | && gMuteListp && !gMuteListp->isMuted(getID())) | ||
4308 | { | ||
4309 | // RN: uncomment this to play on typing sound at fixed volume once sound engine is fixed | ||
4310 | // to support both spatialized and non-spatialized instances of the same sound | ||
4311 | //if (mIsSelf) | ||
4312 | //{ | ||
4313 | // gAudiop->triggerSound(LLUUID(gSavedSettings.getString("UISndTyping")), 0.8f); | ||
4314 | //} | ||
4315 | //else | ||
4316 | { | ||
4317 | LLUUID sound_id = LLUUID(gSavedSettings.getString("UISndTyping")); | ||
4318 | gAudiop->triggerSound(sound_id, getID(), 1.f, char_pos_global); | ||
4319 | } | ||
4320 | } | ||
4321 | } | ||
4322 | } | ||
4323 | else if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED) | ||
4324 | { | ||
4325 | mIsSitting = TRUE; | ||
4326 | } | ||
4327 | |||
4328 | |||
4329 | if (startMotion(anim_id)) | ||
4330 | { | ||
4331 | result = TRUE; | ||
4332 | } | ||
4333 | else | ||
4334 | { | ||
4335 | llwarns << "Failed to start motion!" << llendl; | ||
4336 | } | ||
4337 | } | ||
4338 | else //stop animation | ||
4339 | { | ||
4340 | if (anim_id == ANIM_AGENT_SIT_GROUND_CONSTRAINED) | ||
4341 | { | ||
4342 | mIsSitting = FALSE; | ||
4343 | } | ||
4344 | stopMotion(anim_id); | ||
4345 | result = TRUE; | ||
4346 | } | ||
4347 | |||
4348 | return result; | ||
4349 | } | ||
4350 | |||
4351 | //----------------------------------------------------------------------------- | ||
4352 | // isAnyAnimationSignaled() | ||
4353 | //----------------------------------------------------------------------------- | ||
4354 | BOOL LLVOAvatar::isAnyAnimationSignaled(const LLUUID *anim_array, const S32 num_anims) | ||
4355 | { | ||
4356 | for (S32 i = 0; i < num_anims; i++) | ||
4357 | { | ||
4358 | if(mSignaledAnimations.find(anim_array[i]) != mSignaledAnimations.end()) | ||
4359 | { | ||
4360 | return TRUE; | ||
4361 | } | ||
4362 | } | ||
4363 | return FALSE; | ||
4364 | } | ||
4365 | |||
4366 | //----------------------------------------------------------------------------- | ||
4367 | // resetAnimations() | ||
4368 | //----------------------------------------------------------------------------- | ||
4369 | void LLVOAvatar::resetAnimations() | ||
4370 | { | ||
4371 | LLKeyframeMotion::flushKeyframeCache(); | ||
4372 | flushAllMotions(); | ||
4373 | } | ||
4374 | |||
4375 | //----------------------------------------------------------------------------- | ||
4376 | // startMotion() | ||
4377 | // id is the asset if of the animation to start | ||
4378 | // time_offset is the offset into the animation at which to start playing | ||
4379 | //----------------------------------------------------------------------------- | ||
4380 | BOOL LLVOAvatar::startMotion(const LLUUID& id, F32 time_offset) | ||
4381 | { | ||
4382 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
4383 | |||
4384 | // start special case female walk for female avatars | ||
4385 | if (getSex() == SEX_FEMALE) | ||
4386 | { | ||
4387 | if (id == ANIM_AGENT_WALK) | ||
4388 | { | ||
4389 | return LLCharacter::startMotion(ANIM_AGENT_FEMALE_WALK, time_offset); | ||
4390 | } | ||
4391 | else if (id == ANIM_AGENT_SIT) | ||
4392 | { | ||
4393 | return LLCharacter::startMotion(ANIM_AGENT_SIT_FEMALE, time_offset); | ||
4394 | } | ||
4395 | } | ||
4396 | |||
4397 | if (mIsSelf && id == ANIM_AGENT_AWAY) | ||
4398 | { | ||
4399 | gAgent.setAFK(); | ||
4400 | } | ||
4401 | |||
4402 | return LLCharacter::startMotion(id, time_offset); | ||
4403 | } | ||
4404 | |||
4405 | //----------------------------------------------------------------------------- | ||
4406 | // stopMotion() | ||
4407 | //----------------------------------------------------------------------------- | ||
4408 | BOOL LLVOAvatar::stopMotion(const LLUUID& id, BOOL stop_immediate) | ||
4409 | { | ||
4410 | if (mIsSelf) | ||
4411 | { | ||
4412 | if (id == ANIM_AGENT_STAND) | ||
4413 | { | ||
4414 | LLAgent::stopFidget(); | ||
4415 | } | ||
4416 | else if (id == ANIM_AGENT_AWAY) | ||
4417 | { | ||
4418 | gAgent.clearAFK(); | ||
4419 | } | ||
4420 | } | ||
4421 | |||
4422 | if (id == ANIM_AGENT_WALK) | ||
4423 | { | ||
4424 | LLCharacter::stopMotion(ANIM_AGENT_FEMALE_WALK, stop_immediate); | ||
4425 | } | ||
4426 | else if (id == ANIM_AGENT_SIT) | ||
4427 | { | ||
4428 | LLCharacter::stopMotion(ANIM_AGENT_SIT_FEMALE, stop_immediate); | ||
4429 | } | ||
4430 | |||
4431 | return LLCharacter::stopMotion(id, stop_immediate); | ||
4432 | } | ||
4433 | |||
4434 | //----------------------------------------------------------------------------- | ||
4435 | // stopMotionFromSource() | ||
4436 | //----------------------------------------------------------------------------- | ||
4437 | void LLVOAvatar::stopMotionFromSource(const LLUUID& source_id) | ||
4438 | { | ||
4439 | if (!mIsSelf) | ||
4440 | { | ||
4441 | return; | ||
4442 | } | ||
4443 | AnimSourceIterator motion_it; | ||
4444 | |||
4445 | for(motion_it = mAnimationSources.find(source_id); motion_it != mAnimationSources.end();) | ||
4446 | { | ||
4447 | gAgent.sendAnimationRequest( motion_it->second, ANIM_REQUEST_STOP ); | ||
4448 | mAnimationSources.erase(motion_it++); | ||
4449 | } | ||
4450 | |||
4451 | LLViewerObject* object = gObjectList.findObject(source_id); | ||
4452 | if (object) | ||
4453 | { | ||
4454 | object->mFlags &= ~FLAGS_ANIM_SOURCE; | ||
4455 | } | ||
4456 | } | ||
4457 | |||
4458 | //----------------------------------------------------------------------------- | ||
4459 | // getVolumePos() | ||
4460 | //----------------------------------------------------------------------------- | ||
4461 | LLVector3 LLVOAvatar::getVolumePos(S32 joint_index, LLVector3& volume_offset) | ||
4462 | { | ||
4463 | if (joint_index > mNumCollisionVolumes) | ||
4464 | { | ||
4465 | return LLVector3::zero; | ||
4466 | } | ||
4467 | |||
4468 | return mCollisionVolumes[joint_index].getVolumePos(volume_offset); | ||
4469 | } | ||
4470 | |||
4471 | //----------------------------------------------------------------------------- | ||
4472 | // findCollisionVolume() | ||
4473 | //----------------------------------------------------------------------------- | ||
4474 | LLJoint* LLVOAvatar::findCollisionVolume(U32 volume_id) | ||
4475 | { | ||
4476 | if ((S32)volume_id > mNumCollisionVolumes) | ||
4477 | { | ||
4478 | return NULL; | ||
4479 | } | ||
4480 | |||
4481 | return &mCollisionVolumes[volume_id]; | ||
4482 | } | ||
4483 | |||
4484 | //----------------------------------------------------------------------------- | ||
4485 | // findCollisionVolume() | ||
4486 | //----------------------------------------------------------------------------- | ||
4487 | S32 LLVOAvatar::getCollisionVolumeID(std::string &name) | ||
4488 | { | ||
4489 | for (S32 i = 0; i < mNumCollisionVolumes; i++) | ||
4490 | { | ||
4491 | if (mCollisionVolumes[i].getName() == name) | ||
4492 | { | ||
4493 | return i; | ||
4494 | } | ||
4495 | } | ||
4496 | |||
4497 | return -1; | ||
4498 | } | ||
4499 | |||
4500 | //----------------------------------------------------------------------------- | ||
4501 | // addDebugText() | ||
4502 | //----------------------------------------------------------------------------- | ||
4503 | void LLVOAvatar::addDebugText(const char* text) | ||
4504 | { | ||
4505 | mDebugText.append(1, '\n'); | ||
4506 | mDebugText.append(text); | ||
4507 | } | ||
4508 | |||
4509 | //----------------------------------------------------------------------------- | ||
4510 | // getID() | ||
4511 | //----------------------------------------------------------------------------- | ||
4512 | const LLUUID& LLVOAvatar::getID() | ||
4513 | { | ||
4514 | return mID; | ||
4515 | } | ||
4516 | |||
4517 | //----------------------------------------------------------------------------- | ||
4518 | // getJoint() | ||
4519 | //----------------------------------------------------------------------------- | ||
4520 | // RN: avatar joints are multi-rooted to include screen-based attachments | ||
4521 | LLJoint *LLVOAvatar::getJoint( const std::string &name ) | ||
4522 | { | ||
4523 | LLJoint* jointp = NULL; | ||
4524 | if (mScreenp) | ||
4525 | { | ||
4526 | jointp = mScreenp->findJoint(name); | ||
4527 | } | ||
4528 | if (!jointp) | ||
4529 | { | ||
4530 | jointp = mRoot.findJoint(name); | ||
4531 | } | ||
4532 | return jointp; | ||
4533 | } | ||
4534 | |||
4535 | //----------------------------------------------------------------------------- | ||
4536 | // getCharacterPosition() | ||
4537 | //----------------------------------------------------------------------------- | ||
4538 | LLVector3 LLVOAvatar::getCharacterPosition() | ||
4539 | { | ||
4540 | if (mDrawable.notNull()) | ||
4541 | { | ||
4542 | return mDrawable->getPositionAgent(); | ||
4543 | } | ||
4544 | else | ||
4545 | { | ||
4546 | return getPositionAgent(); | ||
4547 | } | ||
4548 | } | ||
4549 | |||
4550 | |||
4551 | //----------------------------------------------------------------------------- | ||
4552 | // LLVOAvatar::getCharacterRotation() | ||
4553 | //----------------------------------------------------------------------------- | ||
4554 | LLQuaternion LLVOAvatar::getCharacterRotation() | ||
4555 | { | ||
4556 | return getRotation(); | ||
4557 | } | ||
4558 | |||
4559 | |||
4560 | //----------------------------------------------------------------------------- | ||
4561 | // LLVOAvatar::getCharacterVelocity() | ||
4562 | //----------------------------------------------------------------------------- | ||
4563 | LLVector3 LLVOAvatar::getCharacterVelocity() | ||
4564 | { | ||
4565 | return getVelocity() - mStepObjectVelocity; | ||
4566 | } | ||
4567 | |||
4568 | |||
4569 | //----------------------------------------------------------------------------- | ||
4570 | // LLVOAvatar::getCharacterAngularVelocity() | ||
4571 | //----------------------------------------------------------------------------- | ||
4572 | LLVector3 LLVOAvatar::getCharacterAngularVelocity() | ||
4573 | { | ||
4574 | return getAngularVelocity(); | ||
4575 | } | ||
4576 | |||
4577 | //----------------------------------------------------------------------------- | ||
4578 | // LLVOAvatar::getGround() | ||
4579 | //----------------------------------------------------------------------------- | ||
4580 | void LLVOAvatar::getGround(const LLVector3 &in_pos_agent, LLVector3 &out_pos_agent, LLVector3 &outNorm) | ||
4581 | { | ||
4582 | LLVector3d z_vec(0.0f, 0.0f, 1.0f); | ||
4583 | LLVector3d p0_global, p1_global; | ||
4584 | |||
4585 | if (gNoRender || mIsDummy) | ||
4586 | { | ||
4587 | outNorm.setVec(z_vec); | ||
4588 | out_pos_agent = in_pos_agent; | ||
4589 | return; | ||
4590 | } | ||
4591 | |||
4592 | p0_global = gAgent.getPosGlobalFromAgent(in_pos_agent) + z_vec; | ||
4593 | p1_global = gAgent.getPosGlobalFromAgent(in_pos_agent) - z_vec; | ||
4594 | LLViewerObject *obj; | ||
4595 | LLVector3d out_pos_global; | ||
4596 | gWorldPointer->resolveStepHeightGlobal(this, p0_global, p1_global, out_pos_global, outNorm, &obj); | ||
4597 | out_pos_agent = gAgent.getPosAgentFromGlobal(out_pos_global); | ||
4598 | } | ||
4599 | |||
4600 | //----------------------------------------------------------------------------- | ||
4601 | // LLVOAvatar::getTimeDilation() | ||
4602 | //----------------------------------------------------------------------------- | ||
4603 | F32 LLVOAvatar::getTimeDilation() | ||
4604 | { | ||
4605 | return mTimeDilation; | ||
4606 | } | ||
4607 | |||
4608 | |||
4609 | //----------------------------------------------------------------------------- | ||
4610 | // LLVOAvatar::getPixelArea() | ||
4611 | //----------------------------------------------------------------------------- | ||
4612 | F32 LLVOAvatar::getPixelArea() | ||
4613 | { | ||
4614 | if (mIsDummy) | ||
4615 | { | ||
4616 | return 100000.f; | ||
4617 | } | ||
4618 | return mPixelArea; | ||
4619 | } | ||
4620 | |||
4621 | |||
4622 | //----------------------------------------------------------------------------- | ||
4623 | // LLVOAvatar::getHeadMesh() | ||
4624 | //----------------------------------------------------------------------------- | ||
4625 | LLPolyMesh* LLVOAvatar::getHeadMesh() | ||
4626 | { | ||
4627 | return mHeadMesh0.getMesh(); | ||
4628 | } | ||
4629 | |||
4630 | |||
4631 | //----------------------------------------------------------------------------- | ||
4632 | // LLVOAvatar::getUpperBodyMesh() | ||
4633 | //----------------------------------------------------------------------------- | ||
4634 | LLPolyMesh* LLVOAvatar::getUpperBodyMesh() | ||
4635 | { | ||
4636 | return mUpperBodyMesh0.getMesh(); | ||
4637 | } | ||
4638 | |||
4639 | |||
4640 | //----------------------------------------------------------------------------- | ||
4641 | // LLVOAvatar::getPosGlobalFromAgent() | ||
4642 | //----------------------------------------------------------------------------- | ||
4643 | LLVector3d LLVOAvatar::getPosGlobalFromAgent(const LLVector3 &position) | ||
4644 | { | ||
4645 | return gAgent.getPosGlobalFromAgent(position); | ||
4646 | } | ||
4647 | |||
4648 | //----------------------------------------------------------------------------- | ||
4649 | // getPosAgentFromGlobal() | ||
4650 | //----------------------------------------------------------------------------- | ||
4651 | LLVector3 LLVOAvatar::getPosAgentFromGlobal(const LLVector3d &position) | ||
4652 | { | ||
4653 | return gAgent.getPosAgentFromGlobal(position); | ||
4654 | } | ||
4655 | |||
4656 | //----------------------------------------------------------------------------- | ||
4657 | // allocateCharacterJoints() | ||
4658 | //----------------------------------------------------------------------------- | ||
4659 | BOOL LLVOAvatar::allocateCharacterJoints( U32 num ) | ||
4660 | { | ||
4661 | delete [] mSkeleton; | ||
4662 | mSkeleton = NULL; | ||
4663 | mNumJoints = 0; | ||
4664 | |||
4665 | mSkeleton = new LLViewerJoint[num]; | ||
4666 | |||
4667 | for(S32 joint_num = 0; joint_num < (S32)num; joint_num++) | ||
4668 | { | ||
4669 | mSkeleton[joint_num].setJointNum(joint_num); | ||
4670 | } | ||
4671 | |||
4672 | if (!mSkeleton) | ||
4673 | { | ||
4674 | return FALSE; | ||
4675 | } | ||
4676 | |||
4677 | mNumJoints = num; | ||
4678 | return TRUE; | ||
4679 | } | ||
4680 | |||
4681 | //----------------------------------------------------------------------------- | ||
4682 | // allocateCollisionVolumes() | ||
4683 | //----------------------------------------------------------------------------- | ||
4684 | BOOL LLVOAvatar::allocateCollisionVolumes( U32 num ) | ||
4685 | { | ||
4686 | delete [] mCollisionVolumes; | ||
4687 | mCollisionVolumes = NULL; | ||
4688 | mNumCollisionVolumes = 0; | ||
4689 | |||
4690 | mCollisionVolumes = new LLViewerJointCollisionVolume[num]; | ||
4691 | if (!mCollisionVolumes) | ||
4692 | { | ||
4693 | return FALSE; | ||
4694 | } | ||
4695 | |||
4696 | mNumCollisionVolumes = num; | ||
4697 | return TRUE; | ||
4698 | } | ||
4699 | |||
4700 | |||
4701 | //----------------------------------------------------------------------------- | ||
4702 | // getCharacterJoint() | ||
4703 | //----------------------------------------------------------------------------- | ||
4704 | LLJoint *LLVOAvatar::getCharacterJoint( U32 num ) | ||
4705 | { | ||
4706 | if ((S32)num >= mNumJoints | ||
4707 | || num < 0) | ||
4708 | { | ||
4709 | return NULL; | ||
4710 | } | ||
4711 | return (LLJoint*)&mSkeleton[num]; | ||
4712 | } | ||
4713 | |||
4714 | |||
4715 | //----------------------------------------------------------------------------- | ||
4716 | // requestStopMotion() | ||
4717 | //----------------------------------------------------------------------------- | ||
4718 | void LLVOAvatar::requestStopMotion( LLMotion* motion ) | ||
4719 | { | ||
4720 | // Only agent avatars should handle the stop motion notifications. | ||
4721 | if ( mIsSelf ) | ||
4722 | { | ||
4723 | // Notify agent that motion has stopped | ||
4724 | gAgent.requestStopMotion( motion ); | ||
4725 | } | ||
4726 | } | ||
4727 | |||
4728 | //----------------------------------------------------------------------------- | ||
4729 | // loadAvatar() | ||
4730 | //----------------------------------------------------------------------------- | ||
4731 | BOOL LLVOAvatar::loadAvatar() | ||
4732 | { | ||
4733 | // LLFastTimer t(LLFastTimer::FTM_LOAD_AVATAR); | ||
4734 | |||
4735 | // avatar_skeleton.xml | ||
4736 | if( !buildSkeleton(sSkeletonInfo) ) | ||
4737 | { | ||
4738 | llwarns << "avatar file: buildSkeleton() failed" << llendl; | ||
4739 | return FALSE; | ||
4740 | } | ||
4741 | |||
4742 | // avatar_lad.xml : <skeleton> | ||
4743 | if( !loadSkeletonNode() ) | ||
4744 | { | ||
4745 | llwarns << "avatar file: loadNodeSkeleton() failed" << llendl; | ||
4746 | return FALSE; | ||
4747 | } | ||
4748 | |||
4749 | // avatar_lad.xml : <mesh> | ||
4750 | if( !loadMeshNodes() ) | ||
4751 | { | ||
4752 | llwarns << "avatar file: loadNodeMesh() failed" << llendl; | ||
4753 | return FALSE; | ||
4754 | } | ||
4755 | |||
4756 | // avatar_lad.xml : <global_color> | ||
4757 | if( sAvatarInfo->mTexSkinColorInfo ) | ||
4758 | { | ||
4759 | mTexSkinColor = new LLTexGlobalColor( this ); | ||
4760 | if( !mTexSkinColor->setInfo( sAvatarInfo->mTexSkinColorInfo ) ) | ||
4761 | { | ||
4762 | llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl; | ||
4763 | return FALSE; | ||
4764 | } | ||
4765 | } | ||
4766 | else | ||
4767 | { | ||
4768 | llwarns << "<global_color> name=\"skin_color\" not found" << llendl; | ||
4769 | return FALSE; | ||
4770 | } | ||
4771 | if( sAvatarInfo->mTexHairColorInfo ) | ||
4772 | { | ||
4773 | mTexHairColor = new LLTexGlobalColor( this ); | ||
4774 | if( !mTexHairColor->setInfo( sAvatarInfo->mTexHairColorInfo ) ) | ||
4775 | { | ||
4776 | llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl; | ||
4777 | return FALSE; | ||
4778 | } | ||
4779 | } | ||
4780 | else | ||
4781 | { | ||
4782 | llwarns << "<global_color> name=\"hair_color\" not found" << llendl; | ||
4783 | return FALSE; | ||
4784 | } | ||
4785 | if( sAvatarInfo->mTexEyeColorInfo ) | ||
4786 | { | ||
4787 | mTexEyeColor = new LLTexGlobalColor( this ); | ||
4788 | if( !mTexEyeColor->setInfo( sAvatarInfo->mTexEyeColorInfo ) ) | ||
4789 | { | ||
4790 | llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl; | ||
4791 | return FALSE; | ||
4792 | } | ||
4793 | } | ||
4794 | else | ||
4795 | { | ||
4796 | llwarns << "<global_color> name=\"eye_color\" not found" << llendl; | ||
4797 | return FALSE; | ||
4798 | } | ||
4799 | |||
4800 | // avatar_lad.xml : <layer_set> | ||
4801 | if (sAvatarInfo->mLayerInfoList.empty()) | ||
4802 | { | ||
4803 | llwarns << "avatar file: missing <layer_set> node" << llendl; | ||
4804 | } | ||
4805 | else | ||
4806 | { | ||
4807 | LLVOAvatarInfo::layer_info_list_t::iterator iter; | ||
4808 | for (iter = sAvatarInfo->mLayerInfoList.begin(); | ||
4809 | iter != sAvatarInfo->mLayerInfoList.end(); iter++) | ||
4810 | { | ||
4811 | LLTexLayerSetInfo *info = *iter; | ||
4812 | LLTexLayerSet* layer_set = new LLTexLayerSet( this ); | ||
4813 | if (!layer_set->setInfo(info)) | ||
4814 | { | ||
4815 | stop_glerror(); | ||
4816 | delete layer_set; | ||
4817 | llwarns << "avatar file: layer_set->parseData() failed" << llendl; | ||
4818 | return FALSE; | ||
4819 | } | ||
4820 | if( layer_set->isBodyRegion( "head" ) ) | ||
4821 | { | ||
4822 | mHeadLayerSet = layer_set; | ||
4823 | } | ||
4824 | else if( layer_set->isBodyRegion( "upper_body" ) ) | ||
4825 | { | ||
4826 | mUpperBodyLayerSet = layer_set; | ||
4827 | } | ||
4828 | else if( layer_set->isBodyRegion( "lower_body" ) ) | ||
4829 | { | ||
4830 | mLowerBodyLayerSet = layer_set; | ||
4831 | } | ||
4832 | else if( layer_set->isBodyRegion( "eyes" ) ) | ||
4833 | { | ||
4834 | mEyesLayerSet = layer_set; | ||
4835 | } | ||
4836 | else if( layer_set->isBodyRegion( "skirt" ) ) | ||
4837 | { | ||
4838 | mSkirtLayerSet = layer_set; | ||
4839 | } | ||
4840 | else | ||
4841 | { | ||
4842 | llwarns << "<layer_set> has invalid body_region attribute" << llendl; | ||
4843 | delete layer_set; | ||
4844 | return FALSE; | ||
4845 | } | ||
4846 | } | ||
4847 | } | ||
4848 | |||
4849 | // avatar_lad.xml : <driver_parameters> | ||
4850 | { | ||
4851 | LLVOAvatarInfo::driver_info_list_t::iterator iter; | ||
4852 | for (iter = sAvatarInfo->mDriverInfoList.begin(); | ||
4853 | iter != sAvatarInfo->mDriverInfoList.end(); iter++) | ||
4854 | { | ||
4855 | LLDriverParamInfo *info = *iter; | ||
4856 | LLDriverParam* driver_param = new LLDriverParam( this ); | ||
4857 | if (driver_param->setInfo(info)) | ||
4858 | { | ||
4859 | addVisualParam( driver_param ); | ||
4860 | } | ||
4861 | else | ||
4862 | { | ||
4863 | delete driver_param; | ||
4864 | llwarns << "avatar file: driver_param->parseData() failed" << llendl; | ||
4865 | return FALSE; | ||
4866 | } | ||
4867 | } | ||
4868 | } | ||
4869 | |||
4870 | return TRUE; | ||
4871 | } | ||
4872 | |||
4873 | //----------------------------------------------------------------------------- | ||
4874 | // loadSkeletonNode(): loads <skeleton> node from XML tree | ||
4875 | //----------------------------------------------------------------------------- | ||
4876 | BOOL LLVOAvatar::loadSkeletonNode () | ||
4877 | { | ||
4878 | mRoot.addChild( &mSkeleton[0] ); | ||
4879 | |||
4880 | mRoot.addChild( &mHeadLOD ); | ||
4881 | mHeadLOD.mUpdateXform = FALSE; | ||
4882 | mHeadLOD.addChild( &mHeadMesh0 ); | ||
4883 | mHeadLOD.addChild( &mHeadMesh1 ); | ||
4884 | mHeadLOD.addChild( &mHeadMesh2 ); | ||
4885 | mHeadLOD.addChild( &mHeadMesh3 ); | ||
4886 | mHeadLOD.addChild( &mHeadMesh4 ); | ||
4887 | |||
4888 | mRoot.addChild( &mEyeLashLOD ); | ||
4889 | mEyeLashLOD.mUpdateXform = FALSE; | ||
4890 | mEyeLashLOD.addChild( &mEyeLashMesh0 ); | ||
4891 | |||
4892 | mRoot.addChild( &mUpperBodyLOD ); | ||
4893 | mUpperBodyLOD.mUpdateXform = FALSE; | ||
4894 | mUpperBodyLOD.addChild( &mUpperBodyMesh0 ); | ||
4895 | mUpperBodyLOD.addChild( &mUpperBodyMesh1 ); | ||
4896 | mUpperBodyLOD.addChild( &mUpperBodyMesh2 ); | ||
4897 | mUpperBodyLOD.addChild( &mUpperBodyMesh3 ); | ||
4898 | mUpperBodyLOD.addChild( &mUpperBodyMesh4 ); | ||
4899 | |||
4900 | mRoot.addChild( &mLowerBodyLOD ); | ||
4901 | mLowerBodyLOD.mUpdateXform = FALSE; | ||
4902 | mLowerBodyLOD.addChild( &mLowerBodyMesh0 ); | ||
4903 | mLowerBodyLOD.addChild( &mLowerBodyMesh1 ); | ||
4904 | mLowerBodyLOD.addChild( &mLowerBodyMesh2 ); | ||
4905 | mLowerBodyLOD.addChild( &mLowerBodyMesh3 ); | ||
4906 | mLowerBodyLOD.addChild( &mLowerBodyMesh4 ); | ||
4907 | |||
4908 | mRoot.addChild( &mSkirtLOD ); | ||
4909 | mSkirtLOD.mUpdateXform = FALSE; | ||
4910 | mSkirtLOD.addChild( &mSkirtMesh0 ); | ||
4911 | mSkirtLOD.addChild( &mSkirtMesh1 ); | ||
4912 | mSkirtLOD.addChild( &mSkirtMesh2 ); | ||
4913 | mSkirtLOD.addChild( &mSkirtMesh3 ); | ||
4914 | mSkirtLOD.addChild( &mSkirtMesh4 ); | ||
4915 | |||
4916 | LLViewerJoint *skull = (LLViewerJoint*)mRoot.findJoint("mSkull"); | ||
4917 | if (skull) | ||
4918 | { | ||
4919 | skull->addChild( &mHairLOD ); | ||
4920 | mHairLOD.mUpdateXform = FALSE; | ||
4921 | mHairLOD.addChild( &mHairMesh0 ); | ||
4922 | mHairLOD.addChild( &mHairMesh1 ); | ||
4923 | mHairLOD.addChild( &mHairMesh2 ); | ||
4924 | mHairLOD.addChild( &mHairMesh3 ); | ||
4925 | mHairLOD.addChild( &mHairMesh4 ); | ||
4926 | mHairLOD.addChild( &mHairMesh5 ); | ||
4927 | } | ||
4928 | |||
4929 | LLViewerJoint *eyeL = (LLViewerJoint*)mRoot.findJoint("mEyeLeft"); | ||
4930 | if (eyeL) | ||
4931 | { | ||
4932 | eyeL->addChild( &mEyeBallLeftLOD ); | ||
4933 | mEyeBallLeftLOD.mUpdateXform = FALSE; | ||
4934 | mEyeBallLeftLOD.addChild( &mEyeBallLeftMesh0 ); | ||
4935 | mEyeBallLeftLOD.addChild( &mEyeBallLeftMesh1 ); | ||
4936 | } | ||
4937 | |||
4938 | LLViewerJoint *eyeR = (LLViewerJoint*)mRoot.findJoint("mEyeRight"); | ||
4939 | if (eyeR) | ||
4940 | { | ||
4941 | eyeR->addChild( &mEyeBallRightLOD ); | ||
4942 | mEyeBallRightLOD.mUpdateXform = FALSE; | ||
4943 | mEyeBallRightLOD.addChild( &mEyeBallRightMesh0 ); | ||
4944 | mEyeBallRightLOD.addChild( &mEyeBallRightMesh1 ); | ||
4945 | } | ||
4946 | |||
4947 | // SKELETAL DISTORTIONS | ||
4948 | { | ||
4949 | LLVOAvatarInfo::skeletal_distortion_info_list_t::iterator iter; | ||
4950 | for (iter = sAvatarInfo->mSkeletalDistortionInfoList.begin(); | ||
4951 | iter != sAvatarInfo->mSkeletalDistortionInfoList.end(); iter++) | ||
4952 | { | ||
4953 | LLPolySkeletalDistortionInfo *info = *iter; | ||
4954 | LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this); | ||
4955 | if (!param->setInfo(info)) | ||
4956 | { | ||
4957 | delete param; | ||
4958 | return FALSE; | ||
4959 | } | ||
4960 | else | ||
4961 | { | ||
4962 | addVisualParam(param); | ||
4963 | } | ||
4964 | } | ||
4965 | } | ||
4966 | |||
4967 | // ATTACHMENTS | ||
4968 | { | ||
4969 | LLVOAvatarInfo::attachment_info_list_t::iterator iter; | ||
4970 | for (iter = sAvatarInfo->mAttachmentInfoList.begin(); | ||
4971 | iter != sAvatarInfo->mAttachmentInfoList.end(); iter++) | ||
4972 | { | ||
4973 | LLVOAvatarInfo::LLVOAvatarAttachmentInfo *info = *iter; | ||
4974 | LLViewerJointAttachment* attachment = new LLViewerJointAttachment(); | ||
4975 | |||
4976 | attachment->setName(info->mName); | ||
4977 | LLJoint *parentJoint = getJoint(info->mJointName); | ||
4978 | if (!parentJoint) | ||
4979 | { | ||
4980 | llwarns << "No parent joint by name " << info->mJointName << " found for attachment point " << info->mName << llendl; | ||
4981 | delete attachment; | ||
4982 | continue; | ||
4983 | } | ||
4984 | |||
4985 | if (info->mHasPosition) | ||
4986 | { | ||
4987 | attachment->setOriginalPosition(info->mPosition); | ||
4988 | } | ||
4989 | |||
4990 | if (info->mHasRotation) | ||
4991 | { | ||
4992 | LLQuaternion rotation; | ||
4993 | rotation.setQuat(info->mRotationEuler.mV[VX] * DEG_TO_RAD, | ||
4994 | info->mRotationEuler.mV[VY] * DEG_TO_RAD, | ||
4995 | info->mRotationEuler.mV[VZ] * DEG_TO_RAD); | ||
4996 | attachment->setRotation(rotation); | ||
4997 | } | ||
4998 | |||
4999 | int group = info->mGroup; | ||
5000 | if (group >= 0) | ||
5001 | { | ||
5002 | if (group < 0 || group >= 9) | ||
5003 | { | ||
5004 | llwarns << "Invalid group number (" << group << ") for attachment point " << info->mName << llendl; | ||
5005 | } | ||
5006 | else | ||
5007 | { | ||
5008 | attachment->setGroup(group); | ||
5009 | } | ||
5010 | } | ||
5011 | |||
5012 | S32 attachmentID = info->mAttachmentID; | ||
5013 | if (attachmentID < 1 || attachmentID > 255) | ||
5014 | { | ||
5015 | llwarns << "Attachment point out of range [1-255]: " << attachmentID << " on attachment point " << info->mName << llendl; | ||
5016 | delete attachment; | ||
5017 | continue; | ||
5018 | } | ||
5019 | if (mAttachmentPoints.checkData(attachmentID)) | ||
5020 | { | ||
5021 | llwarns << "Attachment point redefined with id " << attachmentID << " on attachment point " << info->mName << llendl; | ||
5022 | delete attachment; | ||
5023 | continue; | ||
5024 | } | ||
5025 | |||
5026 | attachment->setPieSlice(info->mPieMenuSlice); | ||
5027 | attachment->setVisibleInFirstPerson(info->mVisibleFirstPerson); | ||
5028 | attachment->setIsHUDAttachment(info->mIsHUDAttachment); | ||
5029 | |||
5030 | mAttachmentPoints[attachmentID] = attachment; | ||
5031 | |||
5032 | // now add attachment joint | ||
5033 | parentJoint->addChild(attachment); | ||
5034 | } | ||
5035 | } | ||
5036 | |||
5037 | return TRUE; | ||
5038 | } | ||
5039 | |||
5040 | //----------------------------------------------------------------------------- | ||
5041 | // loadMeshNodes(): loads <mesh> nodes from XML tree | ||
5042 | //----------------------------------------------------------------------------- | ||
5043 | BOOL LLVOAvatar::loadMeshNodes() | ||
5044 | { | ||
5045 | LLVOAvatarInfo::mesh_info_list_t::iterator iter; | ||
5046 | for (iter = sAvatarInfo->mMeshInfoList.begin(); | ||
5047 | iter != sAvatarInfo->mMeshInfoList.end(); iter++) | ||
5048 | { | ||
5049 | LLVOAvatarInfo::LLVOAvatarMeshInfo *info = *iter; | ||
5050 | LLString &type = info->mType; | ||
5051 | S32 lod = info->mLOD; | ||
5052 | |||
5053 | LLViewerJointMesh* mesh = NULL; | ||
5054 | if (type == "hairMesh") | ||
5055 | { | ||
5056 | switch (lod) | ||
5057 | { | ||
5058 | case 0: | ||
5059 | mesh = &mHairMesh0; | ||
5060 | break; | ||
5061 | case 1: | ||
5062 | mesh = &mHairMesh1; | ||
5063 | break; | ||
5064 | case 2: | ||
5065 | mesh = &mHairMesh2; | ||
5066 | break; | ||
5067 | case 3: | ||
5068 | mesh = &mHairMesh3; | ||
5069 | break; | ||
5070 | case 4: | ||
5071 | mesh = &mHairMesh4; | ||
5072 | break; | ||
5073 | case 5: | ||
5074 | mesh = &mHairMesh5; | ||
5075 | break; | ||
5076 | default: | ||
5077 | llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; | ||
5078 | return FALSE; | ||
5079 | } | ||
5080 | } | ||
5081 | else if (type == "headMesh") | ||
5082 | { | ||
5083 | switch (lod) | ||
5084 | { | ||
5085 | case 0: | ||
5086 | mesh = &mHeadMesh0; | ||
5087 | break; | ||
5088 | case 1: | ||
5089 | mesh = &mHeadMesh1; | ||
5090 | break; | ||
5091 | case 2: | ||
5092 | mesh = &mHeadMesh2; | ||
5093 | break; | ||
5094 | case 3: | ||
5095 | mesh = &mHeadMesh3; | ||
5096 | break; | ||
5097 | case 4: | ||
5098 | mesh = &mHeadMesh4; | ||
5099 | break; | ||
5100 | default: | ||
5101 | llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; | ||
5102 | return FALSE; | ||
5103 | } | ||
5104 | } | ||
5105 | else if (type == "upperBodyMesh") | ||
5106 | { | ||
5107 | switch (lod) | ||
5108 | { | ||
5109 | case 0: | ||
5110 | mesh = &mUpperBodyMesh0; | ||
5111 | break; | ||
5112 | case 1: | ||
5113 | mesh = &mUpperBodyMesh1; | ||
5114 | break; | ||
5115 | case 2: | ||
5116 | mesh = &mUpperBodyMesh2; | ||
5117 | break; | ||
5118 | case 3: | ||
5119 | mesh = &mUpperBodyMesh3; | ||
5120 | break; | ||
5121 | case 4: | ||
5122 | mesh = &mUpperBodyMesh4; | ||
5123 | break; | ||
5124 | default: | ||
5125 | llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; | ||
5126 | return FALSE; | ||
5127 | } | ||
5128 | } | ||
5129 | else if (type == "lowerBodyMesh") | ||
5130 | { | ||
5131 | switch (lod) | ||
5132 | { | ||
5133 | case 0: | ||
5134 | mesh = &mLowerBodyMesh0; | ||
5135 | break; | ||
5136 | case 1: | ||
5137 | mesh = &mLowerBodyMesh1; | ||
5138 | break; | ||
5139 | case 2: | ||
5140 | mesh = &mLowerBodyMesh2; | ||
5141 | break; | ||
5142 | case 3: | ||
5143 | mesh = &mLowerBodyMesh3; | ||
5144 | break; | ||
5145 | case 4: | ||
5146 | mesh = &mLowerBodyMesh4; | ||
5147 | break; | ||
5148 | default: | ||
5149 | llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; | ||
5150 | return FALSE; | ||
5151 | } | ||
5152 | } | ||
5153 | else if (type == "skirtMesh") | ||
5154 | { | ||
5155 | switch (lod) | ||
5156 | { | ||
5157 | case 0: | ||
5158 | mesh = &mSkirtMesh0; | ||
5159 | break; | ||
5160 | case 1: | ||
5161 | mesh = &mSkirtMesh1; | ||
5162 | break; | ||
5163 | case 2: | ||
5164 | mesh = &mSkirtMesh2; | ||
5165 | break; | ||
5166 | case 3: | ||
5167 | mesh = &mSkirtMesh3; | ||
5168 | break; | ||
5169 | case 4: | ||
5170 | mesh = &mSkirtMesh4; | ||
5171 | break; | ||
5172 | default: | ||
5173 | llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; | ||
5174 | return FALSE; | ||
5175 | } | ||
5176 | } | ||
5177 | else if (type == "eyelashMesh") | ||
5178 | { | ||
5179 | mesh = &mEyeLashMesh0; | ||
5180 | } | ||
5181 | else if (type == "eyeBallLeftMesh") | ||
5182 | { | ||
5183 | switch (lod) | ||
5184 | { | ||
5185 | case 0: | ||
5186 | mesh = &mEyeBallLeftMesh0; | ||
5187 | break; | ||
5188 | case 1: | ||
5189 | mesh = &mEyeBallLeftMesh1; | ||
5190 | break; | ||
5191 | default: | ||
5192 | llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; | ||
5193 | return FALSE; | ||
5194 | } | ||
5195 | } | ||
5196 | else if (type == "eyeBallRightMesh") | ||
5197 | { | ||
5198 | switch (lod) | ||
5199 | { | ||
5200 | case 0: | ||
5201 | mesh = &mEyeBallRightMesh0; | ||
5202 | break; | ||
5203 | case 1: | ||
5204 | mesh = &mEyeBallRightMesh1; | ||
5205 | break; | ||
5206 | default: | ||
5207 | llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl; | ||
5208 | return FALSE; | ||
5209 | } | ||
5210 | } | ||
5211 | |||
5212 | if( !mesh ) | ||
5213 | { | ||
5214 | llwarns << "Ignoring unrecognized mesh type: " << type << llendl; | ||
5215 | return FALSE; | ||
5216 | } | ||
5217 | |||
5218 | // llinfos << "Parsing mesh data for " << type << "..." << llendl; | ||
5219 | |||
5220 | mesh->setColor( 0.8f, 0.8f, 0.8f, 1.0f ); | ||
5221 | |||
5222 | LLPolyMesh *poly_mesh = NULL; | ||
5223 | |||
5224 | if (!info->mReferenceMeshName.empty()) | ||
5225 | { | ||
5226 | mesh_map_t::iterator iter = mMeshes.find(info->mReferenceMeshName); | ||
5227 | if (iter != mMeshes.end()) | ||
5228 | { | ||
5229 | poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, iter->second); | ||
5230 | poly_mesh->setAvatar(this); | ||
5231 | } | ||
5232 | else | ||
5233 | { | ||
5234 | // This should never happen | ||
5235 | } | ||
5236 | } | ||
5237 | else | ||
5238 | { | ||
5239 | poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName); | ||
5240 | poly_mesh->setAvatar(this); | ||
5241 | } | ||
5242 | |||
5243 | if( !poly_mesh ) | ||
5244 | { | ||
5245 | llwarns << "Failed to load mesh of type " << type << llendl; | ||
5246 | return FALSE; | ||
5247 | } | ||
5248 | |||
5249 | // Multimap insert | ||
5250 | mMeshes.insert(std::pair<LLString, LLPolyMesh*>(info->mMeshFileName, poly_mesh)); | ||
5251 | |||
5252 | mesh->setMesh( poly_mesh ); | ||
5253 | |||
5254 | mesh->setLOD( info->mMinPixelArea ); | ||
5255 | |||
5256 | LLVOAvatarInfo::LLVOAvatarMeshInfo::morph_info_list_t::iterator iter; | ||
5257 | for (iter = info->mPolyMorphTargetInfoList.begin(); | ||
5258 | iter != info->mPolyMorphTargetInfoList.end(); iter++) | ||
5259 | { | ||
5260 | LLVOAvatarInfo::LLVOAvatarMeshInfo::morph_info_pair_t *info_pair = &(*iter); | ||
5261 | LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh()); | ||
5262 | if (!param->setInfo(info_pair->first)) | ||
5263 | { | ||
5264 | delete param; | ||
5265 | return FALSE; | ||
5266 | } | ||
5267 | else | ||
5268 | { | ||
5269 | if (info_pair->second) | ||
5270 | { | ||
5271 | addSharedVisualParam(param); | ||
5272 | } | ||
5273 | else | ||
5274 | { | ||
5275 | addVisualParam(param); | ||
5276 | } | ||
5277 | } | ||
5278 | } | ||
5279 | } | ||
5280 | |||
5281 | return TRUE; | ||
5282 | } | ||
5283 | |||
5284 | //----------------------------------------------------------------------------- | ||
5285 | // updateVisualParams() | ||
5286 | //----------------------------------------------------------------------------- | ||
5287 | void LLVOAvatar::updateVisualParams() | ||
5288 | { | ||
5289 | if (gNoRender) | ||
5290 | { | ||
5291 | return; | ||
5292 | } | ||
5293 | |||
5294 | setSex( (getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE ); | ||
5295 | |||
5296 | LLCharacter::updateVisualParams(); | ||
5297 | |||
5298 | if (mLastSkeletonSerialNum != mSkeletonSerialNum) | ||
5299 | { | ||
5300 | computeBodySize(); | ||
5301 | mLastSkeletonSerialNum = mSkeletonSerialNum; | ||
5302 | mRoot.updateWorldMatrixChildren(); | ||
5303 | } | ||
5304 | |||
5305 | dirtyMesh(); | ||
5306 | updateHeadOffset(); | ||
5307 | } | ||
5308 | |||
5309 | //----------------------------------------------------------------------------- | ||
5310 | // isActive() | ||
5311 | //----------------------------------------------------------------------------- | ||
5312 | BOOL LLVOAvatar::isActive() const | ||
5313 | { | ||
5314 | return TRUE; | ||
5315 | } | ||
5316 | |||
5317 | //----------------------------------------------------------------------------- | ||
5318 | // setPixelAreaAndAngle() | ||
5319 | //----------------------------------------------------------------------------- | ||
5320 | void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent) | ||
5321 | { | ||
5322 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
5323 | |||
5324 | LLVector3 viewer_pos_agent = agent.getCameraPositionAgent(); | ||
5325 | LLVector3 pos_agent; | ||
5326 | |||
5327 | pos_agent = getRenderPosition(); | ||
5328 | |||
5329 | F32 dx = viewer_pos_agent.mV[VX] - pos_agent.mV[VX]; | ||
5330 | F32 dy = viewer_pos_agent.mV[VY] - pos_agent.mV[VY]; | ||
5331 | F32 dz = viewer_pos_agent.mV[VZ] - pos_agent.mV[VZ]; | ||
5332 | |||
5333 | F32 max_scale = getMaxScale(); | ||
5334 | F32 mid_scale = getMidScale(); | ||
5335 | F32 min_scale = llmin( getScale().mV[VX], llmin( getScale().mV[VY], getScale().mV[VZ] ) ); | ||
5336 | |||
5337 | // IW: esitmate - when close to large objects, computing range based on distance from center is no good | ||
5338 | // to try to get a min distance from face, subtract min_scale/2 from the range. | ||
5339 | // This means we'll load too much detail sometimes, but that's better than not enough | ||
5340 | // I don't think there's a better way to do this without calculating distance per-poly | ||
5341 | F32 range = sqrt(dx*dx + dy*dy + dz*dz) - min_scale/2; | ||
5342 | |||
5343 | if (range < 0.001f) // range == zero | ||
5344 | { | ||
5345 | mAppAngle = 180.f; | ||
5346 | mPixelArea = gCamera->getViewHeightInPixels() * | ||
5347 | gCamera->getViewHeightInPixels() * | ||
5348 | gCamera->getAspect(); | ||
5349 | } | ||
5350 | else | ||
5351 | { | ||
5352 | mAppAngle = (F32) atan2( max_scale, range) * RAD_TO_DEG; | ||
5353 | |||
5354 | F32 pixels_per_meter = gCamera->getPixelMeterRatio() / range; | ||
5355 | |||
5356 | mPixelArea = (pixels_per_meter * max_scale) * (pixels_per_meter * mid_scale); | ||
5357 | // if( !mIsSelf ) | ||
5358 | // { | ||
5359 | // llinfos << "range " << range << llendl; | ||
5360 | // llinfos << "pixels_per_meter " << pixels_per_meter << llendl; | ||
5361 | // llinfos << "scale " << max_scale << "x" << mid_scale << llendl; | ||
5362 | // llinfos << "pixel area " << mPixelArea << llendl; | ||
5363 | // } | ||
5364 | } | ||
5365 | |||
5366 | // We always want to look good to ourselves | ||
5367 | if( mIsSelf ) | ||
5368 | { | ||
5369 | mPixelArea = llmax( mPixelArea, F32(LOCTEX_IMAGE_SIZE_SELF / 16) ); | ||
5370 | } | ||
5371 | } | ||
5372 | |||
5373 | //----------------------------------------------------------------------------- | ||
5374 | // updateJointLODs() | ||
5375 | //----------------------------------------------------------------------------- | ||
5376 | void LLVOAvatar::updateJointLODs() | ||
5377 | { | ||
5378 | if (!mMeshValid) | ||
5379 | { | ||
5380 | return; | ||
5381 | } | ||
5382 | |||
5383 | F32 lod_factor = (sLODFactor * AVATAR_LOD_TWEAK_RANGE + (1.f - AVATAR_LOD_TWEAK_RANGE)); | ||
5384 | F32 avatar_num_min_factor = clamp_rescale(sLODFactor, 0.f, 1.f, 0.25f, 0.6f); | ||
5385 | F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor); | ||
5386 | |||
5387 | { | ||
5388 | if (mIsSelf) | ||
5389 | { | ||
5390 | if(gAgent.cameraCustomizeAvatar() || gAgent.cameraMouselook()) | ||
5391 | { | ||
5392 | mAdjustedPixelArea = 1000000; | ||
5393 | } | ||
5394 | else | ||
5395 | { | ||
5396 | mAdjustedPixelArea = mPixelArea; | ||
5397 | } | ||
5398 | } | ||
5399 | else if (mIsDummy) | ||
5400 | { | ||
5401 | mAdjustedPixelArea = 1000000; | ||
5402 | } | ||
5403 | else | ||
5404 | { | ||
5405 | // reported avatar pixel area is dependent on avatar render load, based on number of visible avatars | ||
5406 | mAdjustedPixelArea = (F32)mPixelArea * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor; | ||
5407 | } | ||
5408 | |||
5409 | // now select meshes to render based on adjusted pixel area, and perform AGP data push as necessary | ||
5410 | BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE); | ||
5411 | if (res) | ||
5412 | { | ||
5413 | sNumLODChangesThisFrame++; | ||
5414 | updateMeshData(); | ||
5415 | } | ||
5416 | } | ||
5417 | |||
5418 | return; | ||
5419 | } | ||
5420 | |||
5421 | //----------------------------------------------------------------------------- | ||
5422 | // createDrawable() | ||
5423 | //----------------------------------------------------------------------------- | ||
5424 | LLDrawable *LLVOAvatar::createDrawable(LLPipeline *pipeline) | ||
5425 | { | ||
5426 | pipeline->allocDrawable(this); | ||
5427 | mDrawable->setLit(FALSE); | ||
5428 | |||
5429 | LLDrawPool *poolp = gPipeline.getPool(LLDrawPool::POOL_AVATAR); | ||
5430 | |||
5431 | // Only a single face (one per avatar) | ||
5432 | mDrawable->setState(LLDrawable::ACTIVE); | ||
5433 | mDrawable->addFace(poolp, NULL); | ||
5434 | |||
5435 | poolp = gPipeline.getPool(LLDrawPool::POOL_ALPHA); | ||
5436 | |||
5437 | LLFace *facep; | ||
5438 | |||
5439 | // Add faces for the foot shadows | ||
5440 | facep = mDrawable->addFace(poolp, mShadowImagep); | ||
5441 | mShadow0Facep = facep; | ||
5442 | |||
5443 | facep = mDrawable->addFace(poolp, mShadowImagep); | ||
5444 | mShadow1Facep = facep; | ||
5445 | |||
5446 | gPipeline.markMaterialed(mDrawable); | ||
5447 | dirtyMesh(); | ||
5448 | return mDrawable; | ||
5449 | } | ||
5450 | |||
5451 | |||
5452 | //----------------------------------------------------------------------------- | ||
5453 | // updateGeometry() | ||
5454 | //----------------------------------------------------------------------------- | ||
5455 | BOOL LLVOAvatar::updateGeometry(LLDrawable *drawable) | ||
5456 | { | ||
5457 | if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))) | ||
5458 | { | ||
5459 | return TRUE; | ||
5460 | } | ||
5461 | |||
5462 | if (!mMeshValid) | ||
5463 | { | ||
5464 | return TRUE; | ||
5465 | } | ||
5466 | |||
5467 | if (!drawable) | ||
5468 | { | ||
5469 | llerrs << "LLVOAvatar::updateGeometry() called with NULL drawable" << llendl; | ||
5470 | } | ||
5471 | |||
5472 | // Update the shadow, tractor, and text label geometry. | ||
5473 | |||
5474 | updateShadowFaces(); | ||
5475 | |||
5476 | if (!drawable->isVisible()) | ||
5477 | { | ||
5478 | return TRUE; | ||
5479 | } | ||
5480 | |||
5481 | LLFace* facep = drawable->getFace(0); | ||
5482 | if (!mDirtyMesh && !facep->getDirty()) | ||
5483 | { | ||
5484 | return TRUE; | ||
5485 | } | ||
5486 | |||
5487 | // U32 num_vertices = 0; | ||
5488 | |||
5489 | updateMeshData(); | ||
5490 | |||
5491 | mDirtyMesh = FALSE; | ||
5492 | return TRUE; | ||
5493 | } | ||
5494 | |||
5495 | |||
5496 | //----------------------------------------------------------------------------- | ||
5497 | // updateShadowFaces() | ||
5498 | //----------------------------------------------------------------------------- | ||
5499 | void LLVOAvatar::updateShadowFaces() | ||
5500 | { | ||
5501 | LLFace *face0p = mShadow0Facep; | ||
5502 | LLFace *face1p = mShadow1Facep; | ||
5503 | // | ||
5504 | // render avatar shadows | ||
5505 | // | ||
5506 | if (mInAir) | ||
5507 | { | ||
5508 | face0p->setSize(0, 0); | ||
5509 | face1p->setSize(0, 0); | ||
5510 | return; | ||
5511 | } | ||
5512 | |||
5513 | LLSprite sprite(mShadowImageID); | ||
5514 | sprite.setFollow(FALSE); | ||
5515 | const F32 cos_angle = gSky.getSunDirection().mV[2]; | ||
5516 | F32 cos_elev = sqrt(1 - cos_angle * cos_angle); | ||
5517 | if (cos_angle < 0) cos_elev = -cos_elev; | ||
5518 | sprite.setSize(0.4f + cos_elev * 0.8f, 0.3f); | ||
5519 | LLVector3 sun_vec = gSky.mVOSkyp->getToSun(); | ||
5520 | |||
5521 | if (mShadowImagep->getHasGLTexture()) | ||
5522 | { | ||
5523 | LLVector3 normal; | ||
5524 | LLVector3d shadow_pos; | ||
5525 | LLVector3 shadow_pos_agent; | ||
5526 | F32 foot_height; | ||
5527 | |||
5528 | if (mFootLeftp) | ||
5529 | { | ||
5530 | LLVector3 joint_world_pos = mFootLeftp->getWorldPosition(); | ||
5531 | // this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now | ||
5532 | // but we make an explicit ray trace call in expectation of future improvements | ||
5533 | resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos), | ||
5534 | gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal); | ||
5535 | shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos); | ||
5536 | foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ]; | ||
5537 | |||
5538 | // Pull sprite in direction of surface normal | ||
5539 | shadow_pos_agent += normal * SHADOW_OFFSET_AMT; | ||
5540 | |||
5541 | // Render sprite | ||
5542 | sprite.setNormal(normal); | ||
5543 | if (mIsSelf && gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK) | ||
5544 | { | ||
5545 | sprite.setColor(0.f, 0.f, 0.f, 0.f); | ||
5546 | } | ||
5547 | else | ||
5548 | { | ||
5549 | sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f)); | ||
5550 | } | ||
5551 | sprite.setPosition(shadow_pos_agent); | ||
5552 | |||
5553 | LLVector3 foot_to_knee = mKneeLeftp->getWorldPosition() - joint_world_pos; | ||
5554 | //foot_to_knee.normVec(); | ||
5555 | foot_to_knee -= projected_vec(foot_to_knee, sun_vec); | ||
5556 | sprite.setYaw(azimuth(sun_vec - foot_to_knee)); | ||
5557 | |||
5558 | sprite.updateFace(*face0p); | ||
5559 | } | ||
5560 | |||
5561 | if (mFootRightp) | ||
5562 | { | ||
5563 | LLVector3 joint_world_pos = mFootRightp->getWorldPosition(); | ||
5564 | // this only does a ray straight down from the foot, as our client-side ray-tracing is very limited now | ||
5565 | // but we make an explicit ray trace call in expectation of future improvements | ||
5566 | resolveRayCollisionAgent(gAgent.getPosGlobalFromAgent(joint_world_pos), | ||
5567 | gAgent.getPosGlobalFromAgent(gSky.getSunDirection() + joint_world_pos), shadow_pos, normal); | ||
5568 | shadow_pos_agent = gAgent.getPosAgentFromGlobal(shadow_pos); | ||
5569 | foot_height = joint_world_pos.mV[VZ] - shadow_pos_agent.mV[VZ]; | ||
5570 | |||
5571 | // Pull sprite in direction of surface normal | ||
5572 | shadow_pos_agent += normal * SHADOW_OFFSET_AMT; | ||
5573 | |||
5574 | // Render sprite | ||
5575 | sprite.setNormal(normal); | ||
5576 | if (mIsSelf && gAgent.getCameraMode() == CAMERA_MODE_MOUSELOOK) | ||
5577 | { | ||
5578 | sprite.setColor(0.f, 0.f, 0.f, 0.f); | ||
5579 | } | ||
5580 | else | ||
5581 | { | ||
5582 | sprite.setColor(0.f, 0.f, 0.f, clamp_rescale(foot_height, MIN_SHADOW_HEIGHT, MAX_SHADOW_HEIGHT, 0.5f, 0.f)); | ||
5583 | } | ||
5584 | sprite.setPosition(shadow_pos_agent); | ||
5585 | |||
5586 | LLVector3 foot_to_knee = mKneeRightp->getWorldPosition() - joint_world_pos; | ||
5587 | //foot_to_knee.normVec(); | ||
5588 | foot_to_knee -= projected_vec(foot_to_knee, sun_vec); | ||
5589 | sprite.setYaw(azimuth(sun_vec - foot_to_knee)); | ||
5590 | |||
5591 | sprite.updateFace(*face1p); | ||
5592 | } | ||
5593 | } | ||
5594 | } | ||
5595 | |||
5596 | //----------------------------------------------------------------------------- | ||
5597 | // updateSexDependentLayerSets() | ||
5598 | //----------------------------------------------------------------------------- | ||
5599 | void LLVOAvatar::updateSexDependentLayerSets( BOOL set_by_user ) | ||
5600 | { | ||
5601 | invalidateComposite( mHeadLayerSet, set_by_user ); | ||
5602 | invalidateComposite( mLowerBodyLayerSet, set_by_user ); | ||
5603 | invalidateComposite( mUpperBodyLayerSet, set_by_user ); | ||
5604 | updateMeshTextures(); | ||
5605 | } | ||
5606 | |||
5607 | //----------------------------------------------------------------------------- | ||
5608 | // dirtyMesh() | ||
5609 | //----------------------------------------------------------------------------- | ||
5610 | void LLVOAvatar::dirtyMesh() | ||
5611 | { | ||
5612 | mDirtyMesh = TRUE; | ||
5613 | } | ||
5614 | |||
5615 | //----------------------------------------------------------------------------- | ||
5616 | // requestLayerSetUpdate() | ||
5617 | //----------------------------------------------------------------------------- | ||
5618 | void LLVOAvatar::requestLayerSetUpdate( LLVOAvatar::ELocTexIndex i ) | ||
5619 | { | ||
5620 | switch( i ) | ||
5621 | { | ||
5622 | case LOCTEX_HEAD_BODYPAINT: | ||
5623 | if( mHeadLayerSet ) | ||
5624 | { | ||
5625 | mHeadLayerSet->requestUpdate(); | ||
5626 | } | ||
5627 | break; | ||
5628 | |||
5629 | case LOCTEX_UPPER_BODYPAINT: | ||
5630 | case LOCTEX_UPPER_SHIRT: | ||
5631 | case LOCTEX_UPPER_GLOVES: | ||
5632 | case LOCTEX_UPPER_UNDERSHIRT: | ||
5633 | if( mUpperBodyLayerSet ) | ||
5634 | { | ||
5635 | mUpperBodyLayerSet->requestUpdate(); | ||
5636 | } | ||
5637 | break; | ||
5638 | |||
5639 | case LOCTEX_LOWER_BODYPAINT: | ||
5640 | case LOCTEX_LOWER_PANTS: | ||
5641 | case LOCTEX_LOWER_SHOES: | ||
5642 | case LOCTEX_LOWER_SOCKS: | ||
5643 | case LOCTEX_LOWER_UNDERPANTS: | ||
5644 | if( mLowerBodyLayerSet ) | ||
5645 | { | ||
5646 | mLowerBodyLayerSet->requestUpdate(); | ||
5647 | } | ||
5648 | break; | ||
5649 | |||
5650 | case LOCTEX_EYES_IRIS: | ||
5651 | if( mEyesLayerSet ) | ||
5652 | { | ||
5653 | mEyesLayerSet->requestUpdate(); | ||
5654 | } | ||
5655 | break; | ||
5656 | |||
5657 | |||
5658 | case LOCTEX_SKIRT: | ||
5659 | if( mSkirtLayerSet ) | ||
5660 | { | ||
5661 | mSkirtLayerSet->requestUpdate(); | ||
5662 | } | ||
5663 | break; | ||
5664 | |||
5665 | |||
5666 | case LOCTEX_LOWER_JACKET: | ||
5667 | if( mUpperBodyLayerSet ) | ||
5668 | { | ||
5669 | mUpperBodyLayerSet->requestUpdate(); | ||
5670 | } | ||
5671 | |||
5672 | if( mLowerBodyLayerSet ) | ||
5673 | { | ||
5674 | mLowerBodyLayerSet->requestUpdate(); | ||
5675 | } | ||
5676 | break; | ||
5677 | } | ||
5678 | |||
5679 | } | ||
5680 | |||
5681 | void LLVOAvatar::setParent(LLViewerObject* parent) | ||
5682 | { | ||
5683 | if (parent == NULL) | ||
5684 | { | ||
5685 | getOffObject(); | ||
5686 | LLViewerObject::setParent(parent); | ||
5687 | if (isSelf()) | ||
5688 | { | ||
5689 | gAgent.resetCamera(); | ||
5690 | } | ||
5691 | } | ||
5692 | else | ||
5693 | { | ||
5694 | LLViewerObject::setParent(parent); | ||
5695 | sitOnObject(parent); | ||
5696 | } | ||
5697 | } | ||
5698 | |||
5699 | void LLVOAvatar::addChild(LLViewerObject *childp) | ||
5700 | { | ||
5701 | LLViewerObject::addChild(childp); | ||
5702 | attachObject(childp); | ||
5703 | } | ||
5704 | |||
5705 | void LLVOAvatar::removeChild(LLViewerObject *childp) | ||
5706 | { | ||
5707 | LLViewerObject::removeChild(childp); | ||
5708 | detachObject(childp); | ||
5709 | } | ||
5710 | |||
5711 | //----------------------------------------------------------------------------- | ||
5712 | // attachObject() | ||
5713 | //----------------------------------------------------------------------------- | ||
5714 | BOOL LLVOAvatar::attachObject(LLViewerObject *viewer_object) | ||
5715 | { | ||
5716 | S32 attachmentID = ATTACHMENT_ID_FROM_STATE(viewer_object->getState()); | ||
5717 | //clamp((S32)(viewer_object->getState() & AGENT_ATTACH_MASK) >> AGENT_ATTACH_OFFSET, 1, 0xff); | ||
5718 | |||
5719 | //if (mIsSelf) | ||
5720 | //{ | ||
5721 | // gSelectMgr->deselectObjectAndFamily(viewer_object); | ||
5722 | //} | ||
5723 | |||
5724 | LLViewerJointAttachment* attachment = mAttachmentPoints.getIfThere(attachmentID); | ||
5725 | |||
5726 | if (!attachment) | ||
5727 | { | ||
5728 | llwarns << "Tried to attach object to invalid attachment point: " << attachmentID << llendl; | ||
5729 | return FALSE; | ||
5730 | } | ||
5731 | |||
5732 | // LLQuaternion object_world_rot = viewer_object->getWorldRotation(); | ||
5733 | |||
5734 | if (!attachment->addObject(viewer_object)) | ||
5735 | { | ||
5736 | return FALSE; | ||
5737 | } | ||
5738 | |||
5739 | if (viewer_object->isSelected()) | ||
5740 | { | ||
5741 | gSelectMgr->updateSelectionCenter(); | ||
5742 | gSelectMgr->updatePointAt(); | ||
5743 | } | ||
5744 | |||
5745 | // LLQuaternion desired_rot = (object_world_rot * ~attachment->getWorldRotation()); | ||
5746 | |||
5747 | lldebugs << "Attaching object (" << attachmentID << ") item_id=" << attachment->getItemID() << " task_id=" << viewer_object->getID() << "to " << attachment->getName() << llendl; | ||
5748 | |||
5749 | if (mIsSelf) | ||
5750 | { | ||
5751 | updateAttachmentVisibility(gAgent.getCameraMode()); | ||
5752 | |||
5753 | // Then make sure the inventory is in sync with the avatar. | ||
5754 | gInventory.addChangedMask( LLInventoryObserver::LABEL, attachment->getItemID() ); | ||
5755 | gInventory.notifyObservers(); | ||
5756 | } | ||
5757 | |||
5758 | return TRUE; | ||
5759 | } | ||
5760 | |||
5761 | //----------------------------------------------------------------------------- | ||
5762 | // lazyAttach() | ||
5763 | //----------------------------------------------------------------------------- | ||
5764 | void LLVOAvatar::lazyAttach() | ||
5765 | { | ||
5766 | for(LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); | ||
5767 | attachment; | ||
5768 | attachment = mAttachmentPoints.getNextData()) | ||
5769 | { | ||
5770 | if (attachment->getAttachmentDirty()) | ||
5771 | { | ||
5772 | attachment->lazyAttach(); | ||
5773 | if (mIsSelf) | ||
5774 | { | ||
5775 | updateAttachmentVisibility(gAgent.getCameraMode()); | ||
5776 | } | ||
5777 | } | ||
5778 | } | ||
5779 | } | ||
5780 | |||
5781 | //----------------------------------------------------------------------------- | ||
5782 | // detachObject() | ||
5783 | //----------------------------------------------------------------------------- | ||
5784 | BOOL LLVOAvatar::detachObject(LLViewerObject *viewer_object) | ||
5785 | { | ||
5786 | for(LLViewerJointAttachment* attachment = mAttachmentPoints.getFirstData(); | ||
5787 | attachment; | ||
5788 | attachment = mAttachmentPoints.getNextData()) | ||
5789 | { | ||
5790 | // only one object per attachment point for now | ||
5791 | if (attachment->getObject(0) == viewer_object) | ||
5792 | { | ||
5793 | LLUUID item_id = attachment->getItemID(); | ||
5794 | attachment->removeObject(viewer_object); | ||
5795 | if (mIsSelf) | ||
5796 | { | ||
5797 | // the simulator should automatically handle | ||
5798 | // permissiosn revokation | ||
5799 | |||
5800 | stopMotionFromSource(viewer_object->getID()); | ||
5801 | LLFollowCamMgr::setCameraActive(viewer_object->getID(), FALSE); | ||
5802 | |||
5803 | for (S32 i = 0; i < (S32)viewer_object->mChildList.size(); i++) | ||
5804 | { | ||
5805 | LLViewerObject* child_objectp = viewer_object->mChildList[i]; | ||
5806 | // the simulator should automatically handle | ||
5807 | // permissions revokation | ||
5808 | |||
5809 | stopMotionFromSource(child_objectp->getID()); | ||
5810 | LLFollowCamMgr::setCameraActive(child_objectp->getID(), FALSE); | ||
5811 | } | ||
5812 | |||
5813 | } | ||
5814 | lldebugs << "Detaching object " << viewer_object->mID << " from " << attachment->getName() << llendl; | ||
5815 | if (mIsSelf) | ||
5816 | { | ||
5817 | // Then make sure the inventory is in sync with the avatar. | ||
5818 | gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id); | ||
5819 | gInventory.notifyObservers(); | ||
5820 | } | ||
5821 | return TRUE; | ||
5822 | } | ||
5823 | } | ||
5824 | |||
5825 | |||
5826 | return FALSE; | ||
5827 | } | ||
5828 | |||
5829 | //----------------------------------------------------------------------------- | ||
5830 | // sitOnObject() | ||
5831 | //----------------------------------------------------------------------------- | ||
5832 | void LLVOAvatar::sitOnObject(LLViewerObject *sit_object) | ||
5833 | { | ||
5834 | if (mDrawable.isNull()) | ||
5835 | { | ||
5836 | return; | ||
5837 | } | ||
5838 | LLQuaternion inv_obj_rot = ~sit_object->getRenderRotation(); | ||
5839 | LLVector3 obj_pos = sit_object->getRenderPosition(); | ||
5840 | |||
5841 | LLVector3 rel_pos = getRenderPosition() - obj_pos; | ||
5842 | rel_pos.rotVec(inv_obj_rot); | ||
5843 | |||
5844 | mDrawable->mXform.setPosition(rel_pos); | ||
5845 | mDrawable->mXform.setRotation(mDrawable->getWorldRotation() * inv_obj_rot); | ||
5846 | |||
5847 | gPipeline.markMoved(mDrawable, TRUE); | ||
5848 | mIsSitting = TRUE; | ||
5849 | mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject | ||
5850 | mRoot.setPosition(getPosition()); | ||
5851 | mRoot.updateWorldMatrixChildren(); | ||
5852 | |||
5853 | stopMotion(ANIM_AGENT_BODY_NOISE); | ||
5854 | |||
5855 | if (mIsSelf) | ||
5856 | { | ||
5857 | // Might be first sit | ||
5858 | LLFirstUse::useSit(); | ||
5859 | |||
5860 | gAgent.setFlying(FALSE); | ||
5861 | gAgent.setThirdPersonHeadOffset(LLVector3::zero); | ||
5862 | //interpolate to new camera position | ||
5863 | gAgent.startCameraAnimation(); | ||
5864 | // make sure we are not trying to autopilot | ||
5865 | gAgent.stopAutoPilot(); | ||
5866 | gAgent.setupSitCamera(); | ||
5867 | if (gAgent.mForceMouselook) gAgent.changeCameraToMouselook(); | ||
5868 | } | ||
5869 | } | ||
5870 | |||
5871 | //----------------------------------------------------------------------------- | ||
5872 | // getOffObject() | ||
5873 | //----------------------------------------------------------------------------- | ||
5874 | void LLVOAvatar::getOffObject() | ||
5875 | { | ||
5876 | if (mDrawable.isNull()) | ||
5877 | { | ||
5878 | return; | ||
5879 | } | ||
5880 | |||
5881 | LLViewerObject* sit_object = (LLViewerObject*)getParent(); | ||
5882 | |||
5883 | if (sit_object) | ||
5884 | { | ||
5885 | stopMotionFromSource(sit_object->getID()); | ||
5886 | LLFollowCamMgr::setCameraActive(sit_object->getID(), FALSE); | ||
5887 | |||
5888 | for (S32 i = 0; i < (S32)sit_object->mChildList.size(); i++) | ||
5889 | { | ||
5890 | LLViewerObject* child_objectp = sit_object->mChildList[i]; | ||
5891 | |||
5892 | stopMotionFromSource(child_objectp->getID()); | ||
5893 | LLFollowCamMgr::setCameraActive(child_objectp->getID(), FALSE); | ||
5894 | } | ||
5895 | } | ||
5896 | |||
5897 | // assumes that transform will not be updated with drawable still having a parent | ||
5898 | LLVector3 cur_position_world = mDrawable->getWorldPosition(); | ||
5899 | LLQuaternion cur_rotation_world = mDrawable->getWorldRotation(); | ||
5900 | |||
5901 | // set *local* position based on last *world* position, since we're unparenting the avatar | ||
5902 | mDrawable->mXform.setPosition(cur_position_world); | ||
5903 | mDrawable->mXform.setRotation(cur_rotation_world); | ||
5904 | |||
5905 | gPipeline.markMoved(mDrawable, TRUE); | ||
5906 | |||
5907 | mIsSitting = FALSE; | ||
5908 | mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject | ||
5909 | mRoot.setPosition(cur_position_world); | ||
5910 | mRoot.setRotation(cur_rotation_world); | ||
5911 | mRoot.getXform()->update(); | ||
5912 | |||
5913 | startMotion(ANIM_AGENT_BODY_NOISE); | ||
5914 | |||
5915 | if (mIsSelf) | ||
5916 | { | ||
5917 | LLQuaternion av_rot = gAgent.getFrameAgent().getQuaternion(); | ||
5918 | LLQuaternion obj_rot = sit_object ? sit_object->getRenderRotation() : LLQuaternion::DEFAULT; | ||
5919 | av_rot = av_rot * obj_rot; | ||
5920 | LLVector3 at_axis = LLVector3::x_axis; | ||
5921 | at_axis = at_axis * av_rot; | ||
5922 | at_axis.mV[VZ] = 0.f; | ||
5923 | at_axis.normVec(); | ||
5924 | gAgent.resetAxes(at_axis); | ||
5925 | |||
5926 | //reset orientation | ||
5927 | // mRoot.setRotation(avWorldRot); | ||
5928 | gAgent.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f)); | ||
5929 | |||
5930 | gAgent.setSitCamera(LLUUID::null); | ||
5931 | } | ||
5932 | } | ||
5933 | |||
5934 | //----------------------------------------------------------------------------- | ||
5935 | // findAvatarFromAttachment() | ||
5936 | //----------------------------------------------------------------------------- | ||
5937 | // static | ||
5938 | LLVOAvatar* LLVOAvatar::findAvatarFromAttachment( LLViewerObject* obj ) | ||
5939 | { | ||
5940 | if( obj->isAttachment() ) | ||
5941 | { | ||
5942 | do | ||
5943 | { | ||
5944 | obj = (LLViewerObject*) obj->getParent(); | ||
5945 | } | ||
5946 | while( obj && !obj->isAvatar() ); | ||
5947 | |||
5948 | if( obj && !obj->isDead() ) | ||
5949 | { | ||
5950 | return (LLVOAvatar*)obj; | ||
5951 | } | ||
5952 | } | ||
5953 | return NULL; | ||
5954 | } | ||
5955 | |||
5956 | //----------------------------------------------------------------------------- | ||
5957 | // isWearingAttachment() | ||
5958 | //----------------------------------------------------------------------------- | ||
5959 | BOOL LLVOAvatar::isWearingAttachment( const LLUUID& inv_item_id ) | ||
5960 | { | ||
5961 | for (LLViewerJointAttachment *attachment_point = mAttachmentPoints.getFirstData(); | ||
5962 | attachment_point; | ||
5963 | attachment_point = mAttachmentPoints.getNextData()) | ||
5964 | { | ||
5965 | if( attachment_point->getItemID() == inv_item_id ) | ||
5966 | { | ||
5967 | return TRUE; | ||
5968 | } | ||
5969 | } | ||
5970 | return FALSE; | ||
5971 | } | ||
5972 | |||
5973 | //----------------------------------------------------------------------------- | ||
5974 | // getWornAttachment() | ||
5975 | //----------------------------------------------------------------------------- | ||
5976 | LLViewerObject* LLVOAvatar::getWornAttachment( const LLUUID& inv_item_id ) | ||
5977 | { | ||
5978 | for (LLViewerJointAttachment *attachment_point = mAttachmentPoints.getFirstData(); | ||
5979 | attachment_point; | ||
5980 | attachment_point = mAttachmentPoints.getNextData()) | ||
5981 | { | ||
5982 | if( attachment_point->getItemID() == inv_item_id ) | ||
5983 | { | ||
5984 | return attachment_point->getObject(0); | ||
5985 | } | ||
5986 | } | ||
5987 | return NULL; | ||
5988 | } | ||
5989 | |||
5990 | const LLString LLVOAvatar::getAttachedPointName(const LLUUID& inv_item_id) | ||
5991 | { | ||
5992 | for (LLViewerJointAttachment *attachment_point = mAttachmentPoints.getFirstData(); | ||
5993 | attachment_point; | ||
5994 | attachment_point = mAttachmentPoints.getNextData()) | ||
5995 | { | ||
5996 | if( attachment_point->getItemID() == inv_item_id ) | ||
5997 | { | ||
5998 | return (LLString)attachment_point->getName(); | ||
5999 | } | ||
6000 | } | ||
6001 | |||
6002 | return LLString::null; | ||
6003 | } | ||
6004 | |||
6005 | |||
6006 | //----------------------------------------------------------------------------- | ||
6007 | // static | ||
6008 | // onLocalTextureLoaded() | ||
6009 | //----------------------------------------------------------------------------- | ||
6010 | void LLVOAvatar::onLocalTextureLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src_raw, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) | ||
6011 | { | ||
6012 | //llinfos << "onLocalTextureLoaded: " << src_vi->getID() << llendl; | ||
6013 | |||
6014 | const LLUUID& src_id = src_vi->getID(); | ||
6015 | LLAvatarTexData *data = (LLAvatarTexData *)userdata; | ||
6016 | if (success) | ||
6017 | { | ||
6018 | LLVOAvatar *self = (LLVOAvatar *)gObjectList.findObject(data->mAvatarID); | ||
6019 | LLVOAvatar::ELocTexIndex idx = data->mIndex; | ||
6020 | if( self && | ||
6021 | (!self->mLocalTextureBaked[ idx ]) && | ||
6022 | (self->mLocalTexture[ idx ].notNull()) && | ||
6023 | (self->mLocalTexture[ idx ]->getID() == src_id) && | ||
6024 | (discard_level < self->mLocalTextureDiscard[idx])) | ||
6025 | { | ||
6026 | self->mLocalTextureDiscard[idx] = discard_level; | ||
6027 | self->requestLayerSetUpdate( idx ); | ||
6028 | if( self->mIsSelf && gAgent.cameraCustomizeAvatar() ) | ||
6029 | { | ||
6030 | LLVisualParamHint::requestHintUpdates(); | ||
6031 | } | ||
6032 | self->updateMeshTextures(); | ||
6033 | } | ||
6034 | } | ||
6035 | |||
6036 | if( final || !success ) | ||
6037 | { | ||
6038 | delete data; | ||
6039 | } | ||
6040 | } | ||
6041 | |||
6042 | void LLVOAvatar::updateComposites() | ||
6043 | { | ||
6044 | if( mHeadLayerSet ) | ||
6045 | { | ||
6046 | mHeadLayerSet->updateComposite(); | ||
6047 | } | ||
6048 | |||
6049 | if( mUpperBodyLayerSet ) | ||
6050 | { | ||
6051 | mUpperBodyLayerSet->updateComposite(); | ||
6052 | } | ||
6053 | |||
6054 | if( mLowerBodyLayerSet ) | ||
6055 | { | ||
6056 | mLowerBodyLayerSet->updateComposite(); | ||
6057 | } | ||
6058 | |||
6059 | if( mEyesLayerSet ) | ||
6060 | { | ||
6061 | mEyesLayerSet->updateComposite(); | ||
6062 | } | ||
6063 | |||
6064 | if( mSkirtLayerSet && isWearingWearableType( WT_SKIRT )) | ||
6065 | { | ||
6066 | mSkirtLayerSet->updateComposite(); | ||
6067 | } | ||
6068 | } | ||
6069 | |||
6070 | LLColor4 LLVOAvatar::getGlobalColor( const LLString& color_name ) | ||
6071 | { | ||
6072 | if( color_name=="skin_color" && mTexSkinColor ) | ||
6073 | { | ||
6074 | return mTexSkinColor->getColor(); | ||
6075 | } | ||
6076 | else | ||
6077 | if( color_name=="hair_color" && mTexHairColor ) | ||
6078 | { | ||
6079 | return mTexHairColor->getColor(); | ||
6080 | } | ||
6081 | if( color_name=="eye_color" && mTexEyeColor ) | ||
6082 | { | ||
6083 | return mTexEyeColor->getColor(); | ||
6084 | } | ||
6085 | else | ||
6086 | { | ||
6087 | // return LLColor4( .5f, .5f, .5f, .5f ); | ||
6088 | return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color | ||
6089 | } | ||
6090 | } | ||
6091 | |||
6092 | |||
6093 | void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_user ) | ||
6094 | { | ||
6095 | if( !layerset || !layerset->getUpdatesEnabled() ) | ||
6096 | { | ||
6097 | return; | ||
6098 | } | ||
6099 | |||
6100 | /* Debug spam. JC | ||
6101 | const char* layer_name = ""; | ||
6102 | if (layerset == mHeadLayerSet) | ||
6103 | { | ||
6104 | layer_name = "head"; | ||
6105 | } | ||
6106 | else if (layerset == mUpperBodyLayerSet) | ||
6107 | { | ||
6108 | layer_name = "upperbody"; | ||
6109 | } | ||
6110 | else if (layerset == mLowerBodyLayerSet) | ||
6111 | { | ||
6112 | layer_name = "lowerbody"; | ||
6113 | } | ||
6114 | else if (layerset == mEyesLayerSet) | ||
6115 | { | ||
6116 | layer_name = "eyes"; | ||
6117 | } | ||
6118 | else if (layerset == mSkirtLayerSet) | ||
6119 | { | ||
6120 | layer_name = "skirt"; | ||
6121 | } | ||
6122 | else | ||
6123 | { | ||
6124 | layer_name = "unknown"; | ||
6125 | } | ||
6126 | llinfos << "LLVOAvatar::invalidComposite() " << layer_name << llendl; | ||
6127 | */ | ||
6128 | |||
6129 | layerset->requestUpdate(); | ||
6130 | |||
6131 | if( set_by_user ) | ||
6132 | { | ||
6133 | llassert( mIsSelf ); | ||
6134 | |||
6135 | ETextureIndex baked_te = getBakedTE( layerset ); | ||
6136 | if( gAgent.cameraCustomizeAvatar() ) | ||
6137 | { | ||
6138 | mSavedTE[ baked_te ].setNull(); | ||
6139 | } | ||
6140 | else | ||
6141 | { | ||
6142 | setTEImage( baked_te, gImageList.getImage(IMG_DEFAULT_AVATAR) ); | ||
6143 | layerset->requestUpload(); | ||
6144 | } | ||
6145 | } | ||
6146 | } | ||
6147 | |||
6148 | |||
6149 | void LLVOAvatar::onGlobalColorChanged( LLTexGlobalColor* global_color, BOOL set_by_user ) | ||
6150 | { | ||
6151 | if( global_color == mTexSkinColor ) | ||
6152 | { | ||
6153 | // llinfos << "invalidateComposite cause: onGlobalColorChanged( skin color )" << llendl; | ||
6154 | invalidateComposite( mHeadLayerSet, set_by_user ); | ||
6155 | invalidateComposite( mUpperBodyLayerSet, set_by_user ); | ||
6156 | invalidateComposite( mLowerBodyLayerSet, set_by_user ); | ||
6157 | } | ||
6158 | else | ||
6159 | if( global_color == mTexHairColor ) | ||
6160 | { | ||
6161 | // llinfos << "invalidateComposite cause: onGlobalColorChanged( hair color )" << llendl; | ||
6162 | invalidateComposite( mHeadLayerSet, set_by_user ); | ||
6163 | |||
6164 | LLColor4 color = mTexHairColor->getColor(); | ||
6165 | mHairMesh0.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); | ||
6166 | mHairMesh1.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); | ||
6167 | mHairMesh2.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); | ||
6168 | mHairMesh3.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); | ||
6169 | mHairMesh4.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); | ||
6170 | mHairMesh5.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); | ||
6171 | } | ||
6172 | else | ||
6173 | if( global_color == mTexEyeColor ) | ||
6174 | { | ||
6175 | // llinfos << "invalidateComposite cause: onGlobalColorChanged( eyecolor )" << llendl; | ||
6176 | invalidateComposite( mEyesLayerSet, set_by_user ); | ||
6177 | } | ||
6178 | updateMeshTextures(); | ||
6179 | } | ||
6180 | |||
6181 | void LLVOAvatar::forceBakeAllTextures(bool slam_for_debug) | ||
6182 | { | ||
6183 | llinfos << "TAT: forced full rebake. " << llendl; | ||
6184 | |||
6185 | for (S32 i = 0; i < BAKED_TEXTURE_COUNT; i++) | ||
6186 | { | ||
6187 | ETextureIndex baked_index = sBakedTextureIndices[i]; | ||
6188 | LLTexLayerSet* layer_set = getLayerSet(baked_index); | ||
6189 | if (layer_set) | ||
6190 | { | ||
6191 | if (slam_for_debug) | ||
6192 | { | ||
6193 | layer_set->setUpdatesEnabled(TRUE); | ||
6194 | layer_set->cancelUpload(); | ||
6195 | } | ||
6196 | |||
6197 | BOOL set_by_user = TRUE; | ||
6198 | invalidateComposite(layer_set, set_by_user); | ||
6199 | gViewerStats->incStat(LLViewerStats::ST_TEX_REBAKES); | ||
6200 | } | ||
6201 | else | ||
6202 | { | ||
6203 | llwarns << "TAT: NO LAYER SET FOR " << (S32)baked_index << llendl; | ||
6204 | } | ||
6205 | } | ||
6206 | |||
6207 | // Don't know if this is needed | ||
6208 | updateMeshTextures(); | ||
6209 | } | ||
6210 | |||
6211 | |||
6212 | // static | ||
6213 | void LLVOAvatar::processRebakeAvatarTextures(LLMessageSystem* msg, void**) | ||
6214 | { | ||
6215 | LLUUID texture_id; | ||
6216 | msg->getUUID("TextureData", "TextureID", texture_id); | ||
6217 | |||
6218 | LLVOAvatar* self = gAgent.getAvatarObject(); | ||
6219 | if (!self) return; | ||
6220 | |||
6221 | // If this is a texture corresponding to one of our baked entries, | ||
6222 | // just rebake that layer set. | ||
6223 | BOOL found = FALSE; | ||
6224 | for (S32 i = 0; i < BAKED_TEXTURE_COUNT; i++) | ||
6225 | { | ||
6226 | ETextureIndex baked_index = sBakedTextureIndices[i]; | ||
6227 | if (texture_id == self->getTEImage(baked_index)->getID()) | ||
6228 | { | ||
6229 | LLTexLayerSet* layer_set = self->getLayerSet(baked_index); | ||
6230 | if (layer_set) | ||
6231 | { | ||
6232 | llinfos << "TAT: rebake - matched entry " << (S32)baked_index << llendl; | ||
6233 | // Apparently set_by_user == force upload | ||
6234 | BOOL set_by_user = TRUE; | ||
6235 | self->invalidateComposite(layer_set, set_by_user); | ||
6236 | found = TRUE; | ||
6237 | gViewerStats->incStat(LLViewerStats::ST_TEX_REBAKES); | ||
6238 | } | ||
6239 | } | ||
6240 | } | ||
6241 | |||
6242 | // If texture not found, rebake all entries. | ||
6243 | if (!found) | ||
6244 | { | ||
6245 | self->forceBakeAllTextures(); | ||
6246 | } | ||
6247 | else | ||
6248 | { | ||
6249 | // Not sure if this is necessary, but forceBakeAllTextures() does it. | ||
6250 | self->updateMeshTextures(); | ||
6251 | } | ||
6252 | } | ||
6253 | |||
6254 | |||
6255 | BOOL LLVOAvatar::getLocalTextureRaw(S32 index, LLImageRaw* image_raw) | ||
6256 | { | ||
6257 | BOOL success = FALSE; | ||
6258 | |||
6259 | if( (0 <= index) && (index < LOCTEX_NUM_ENTRIES) ) | ||
6260 | { | ||
6261 | if (mLocalTexture[ index ].isNull() || mLocalTexture[ index ]->getID() == IMG_DEFAULT_AVATAR ) | ||
6262 | { | ||
6263 | success = TRUE; | ||
6264 | } | ||
6265 | else | ||
6266 | { | ||
6267 | if( mLocalTexture[ index ]->readBackRaw(-1, image_raw) ) | ||
6268 | { | ||
6269 | success = TRUE; | ||
6270 | } | ||
6271 | else | ||
6272 | { | ||
6273 | // No data loaded yet | ||
6274 | setLocalTexture( (ELocTexIndex)index, getTEImage( index ), FALSE ); | ||
6275 | } | ||
6276 | } | ||
6277 | } | ||
6278 | return success; | ||
6279 | } | ||
6280 | |||
6281 | BOOL LLVOAvatar::getLocalTextureGL(S32 index, LLImageGL** image_gl_pp) | ||
6282 | { | ||
6283 | BOOL success = FALSE; | ||
6284 | *image_gl_pp = NULL; | ||
6285 | |||
6286 | if( (0 <= index) && (index < LOCTEX_NUM_ENTRIES) ) | ||
6287 | { | ||
6288 | if( mLocalTexture[ index ].isNull() || mLocalTexture[ index ]->getID() == IMG_DEFAULT_AVATAR) | ||
6289 | { | ||
6290 | success = TRUE; | ||
6291 | } | ||
6292 | else | ||
6293 | { | ||
6294 | *image_gl_pp = mLocalTexture[ index ]; | ||
6295 | success = TRUE; | ||
6296 | } | ||
6297 | } | ||
6298 | |||
6299 | if( !success ) | ||
6300 | { | ||
6301 | // llinfos << "getLocalTextureGL(" << index << ") had no data" << llendl; | ||
6302 | } | ||
6303 | return success; | ||
6304 | } | ||
6305 | |||
6306 | const LLUUID& LLVOAvatar::getLocalTextureID( S32 index ) | ||
6307 | { | ||
6308 | if (index >= 0 && mLocalTexture[index].notNull()) | ||
6309 | { | ||
6310 | return mLocalTexture[index]->getID(); | ||
6311 | } | ||
6312 | else | ||
6313 | { | ||
6314 | return IMG_DEFAULT_AVATAR; | ||
6315 | } | ||
6316 | } | ||
6317 | |||
6318 | // static | ||
6319 | void LLVOAvatar::dumpTotalLocalTextureByteCount() | ||
6320 | { | ||
6321 | S32 total_gl_bytes = 0; | ||
6322 | for( LLVOAvatar* cur = (LLVOAvatar*)LLCharacter::sInstances.getFirstData(); | ||
6323 | cur; | ||
6324 | cur = (LLVOAvatar*)LLCharacter::sInstances.getNextData() ) | ||
6325 | { | ||
6326 | S32 gl_bytes = 0; | ||
6327 | cur->getLocalTextureByteCount(&gl_bytes ); | ||
6328 | total_gl_bytes += gl_bytes; | ||
6329 | } | ||
6330 | llinfos << "Total Avatar LocTex GL:" << (total_gl_bytes/1024) << "KB" << llendl; | ||
6331 | } | ||
6332 | |||
6333 | BOOL LLVOAvatar::isVisible() | ||
6334 | { | ||
6335 | return mDrawable.notNull() && mDrawable->isVisible(); | ||
6336 | } | ||
6337 | |||
6338 | |||
6339 | //----------------------------------------------------------------------------- | ||
6340 | // findMotion() | ||
6341 | //----------------------------------------------------------------------------- | ||
6342 | LLMotion* LLVOAvatar::findMotion(const LLUUID& id) | ||
6343 | { | ||
6344 | return mMotionController.findMotion(id); | ||
6345 | } | ||
6346 | |||
6347 | // Counts the memory footprint of local textures. | ||
6348 | void LLVOAvatar::getLocalTextureByteCount( S32* gl_bytes ) | ||
6349 | { | ||
6350 | *gl_bytes = 0; | ||
6351 | for( S32 i = 0; i < LOCTEX_NUM_ENTRIES; i++ ) | ||
6352 | { | ||
6353 | LLViewerImage* image_gl = mLocalTexture[i]; | ||
6354 | if( image_gl ) | ||
6355 | { | ||
6356 | S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents(); | ||
6357 | |||
6358 | if( image_gl->getHasGLTexture() ) | ||
6359 | { | ||
6360 | *gl_bytes += bytes; | ||
6361 | } | ||
6362 | } | ||
6363 | } | ||
6364 | } | ||
6365 | |||
6366 | |||
6367 | BOOL LLVOAvatar::bindScratchTexture( LLGLenum format ) | ||
6368 | { | ||
6369 | U32 texture_bytes = 0; | ||
6370 | GLuint gl_name = getScratchTexName( format, &texture_bytes ); | ||
6371 | if( gl_name ) | ||
6372 | { | ||
6373 | LLImageGL::bindExternalTexture( gl_name, 0, GL_TEXTURE_2D ); | ||
6374 | stop_glerror(); | ||
6375 | |||
6376 | F32* last_bind_time = LLVOAvatar::sScratchTexLastBindTime.getIfThere( format ); | ||
6377 | if( last_bind_time ) | ||
6378 | { | ||
6379 | if( *last_bind_time != LLImageGL::sLastFrameTime ) | ||
6380 | { | ||
6381 | *last_bind_time = LLImageGL::sLastFrameTime; | ||
6382 | LLImageGL::updateBoundTexMem(texture_bytes); | ||
6383 | } | ||
6384 | } | ||
6385 | else | ||
6386 | { | ||
6387 | LLImageGL::updateBoundTexMem(texture_bytes); | ||
6388 | LLVOAvatar::sScratchTexLastBindTime.addData( format, new F32(LLImageGL::sLastFrameTime) ); | ||
6389 | } | ||
6390 | |||
6391 | |||
6392 | return TRUE; | ||
6393 | } | ||
6394 | else | ||
6395 | { | ||
6396 | return FALSE; | ||
6397 | } | ||
6398 | } | ||
6399 | |||
6400 | |||
6401 | LLGLuint LLVOAvatar::getScratchTexName( LLGLenum format, U32* texture_bytes ) | ||
6402 | { | ||
6403 | S32 components; | ||
6404 | GLenum internal_format; | ||
6405 | switch( format ) | ||
6406 | { | ||
6407 | case GL_LUMINANCE: components = 1; internal_format = GL_LUMINANCE8; break; | ||
6408 | case GL_ALPHA: components = 1; internal_format = GL_ALPHA8; break; | ||
6409 | case GL_COLOR_INDEX: components = 1; internal_format = GL_COLOR_INDEX8_EXT; break; | ||
6410 | case GL_LUMINANCE_ALPHA: components = 2; internal_format = GL_LUMINANCE8_ALPHA8; break; | ||
6411 | case GL_RGB: components = 3; internal_format = GL_RGB8; break; | ||
6412 | case GL_RGBA: components = 4; internal_format = GL_RGBA8; break; | ||
6413 | default: llassert(0); components = 4; internal_format = GL_RGBA8; break; | ||
6414 | } | ||
6415 | |||
6416 | *texture_bytes = components * VOAVATAR_SCRATCH_TEX_WIDTH * VOAVATAR_SCRATCH_TEX_HEIGHT; | ||
6417 | |||
6418 | if( LLVOAvatar::sScratchTexNames.checkData( format ) ) | ||
6419 | { | ||
6420 | return *( LLVOAvatar::sScratchTexNames.getData( format ) ); | ||
6421 | } | ||
6422 | else | ||
6423 | { | ||
6424 | |||
6425 | LLGLSUIDefault gls_ui; | ||
6426 | |||
6427 | GLuint name = 0; | ||
6428 | glGenTextures(1, &name ); | ||
6429 | stop_glerror(); | ||
6430 | |||
6431 | LLImageGL::bindExternalTexture( name, 0, GL_TEXTURE_2D ); | ||
6432 | stop_glerror(); | ||
6433 | |||
6434 | glTexImage2D( | ||
6435 | GL_TEXTURE_2D, 0, internal_format, | ||
6436 | VOAVATAR_SCRATCH_TEX_WIDTH, VOAVATAR_SCRATCH_TEX_HEIGHT, | ||
6437 | 0, format, GL_UNSIGNED_BYTE, NULL ); | ||
6438 | stop_glerror(); | ||
6439 | |||
6440 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
6441 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
6442 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); | ||
6443 | glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); | ||
6444 | stop_glerror(); | ||
6445 | |||
6446 | LLImageGL::unbindTexture(0, GL_TEXTURE_2D); | ||
6447 | stop_glerror(); | ||
6448 | |||
6449 | LLVOAvatar::sScratchTexNames.addData( format, new LLGLuint( name ) ); | ||
6450 | |||
6451 | LLVOAvatar::sScratchTexBytes += *texture_bytes; | ||
6452 | LLImageGL::sGlobalTextureMemory += *texture_bytes; | ||
6453 | return name; | ||
6454 | } | ||
6455 | } | ||
6456 | |||
6457 | |||
6458 | |||
6459 | //----------------------------------------------------------------------------- | ||
6460 | // setLocalTextureTE() | ||
6461 | //----------------------------------------------------------------------------- | ||
6462 | void LLVOAvatar::setLocTexTE( U8 te, LLViewerImage* image, BOOL set_by_user ) | ||
6463 | { | ||
6464 | if( !mIsSelf ) | ||
6465 | { | ||
6466 | llassert( 0 ); | ||
6467 | return; | ||
6468 | } | ||
6469 | |||
6470 | if( te >= TEX_NUM_ENTRIES ) | ||
6471 | { | ||
6472 | llassert(0); | ||
6473 | return; | ||
6474 | } | ||
6475 | |||
6476 | if( getTEImage( te )->getID() == image->getID() ) | ||
6477 | { | ||
6478 | return; | ||
6479 | } | ||
6480 | |||
6481 | if (isTextureIndexBaked(te)) | ||
6482 | { | ||
6483 | llassert(0); | ||
6484 | return; | ||
6485 | } | ||
6486 | |||
6487 | LLTexLayerSet* layer_set = getLayerSet((ETextureIndex)te); | ||
6488 | if (layer_set) | ||
6489 | { | ||
6490 | invalidateComposite(layer_set, set_by_user); | ||
6491 | } | ||
6492 | |||
6493 | setTEImage( te, image ); | ||
6494 | updateMeshTextures(); | ||
6495 | |||
6496 | if( gAgent.cameraCustomizeAvatar() ) | ||
6497 | { | ||
6498 | LLVisualParamHint::requestHintUpdates(); | ||
6499 | } | ||
6500 | } | ||
6501 | |||
6502 | void LLVOAvatar::setupComposites() | ||
6503 | { | ||
6504 | // Don't invalidate the baked textures we had on start-up. | ||
6505 | BOOL head_baked = ( getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6506 | BOOL upper_baked = ( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6507 | BOOL lower_baked = ( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6508 | BOOL eyes_baked = ( getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6509 | BOOL skirt_baked = ( getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6510 | |||
6511 | if (mHeadLayerSet) | ||
6512 | { | ||
6513 | mHeadLayerSet->setUpdatesEnabled( !head_baked ); | ||
6514 | } | ||
6515 | if (mUpperBodyLayerSet) | ||
6516 | { | ||
6517 | mUpperBodyLayerSet->setUpdatesEnabled( !upper_baked ); | ||
6518 | } | ||
6519 | if (mLowerBodyLayerSet) | ||
6520 | { | ||
6521 | mLowerBodyLayerSet->setUpdatesEnabled( !lower_baked ); | ||
6522 | } | ||
6523 | if (mEyesLayerSet) | ||
6524 | { | ||
6525 | mEyesLayerSet->setUpdatesEnabled( !eyes_baked ); | ||
6526 | } | ||
6527 | if (mSkirtLayerSet) | ||
6528 | { | ||
6529 | mSkirtLayerSet->setUpdatesEnabled( !skirt_baked ); | ||
6530 | } | ||
6531 | } | ||
6532 | |||
6533 | //----------------------------------------------------------------------------- | ||
6534 | // updateMeshTextures() | ||
6535 | // Uses the current TE values to set the meshes' and layersets' textures. | ||
6536 | //----------------------------------------------------------------------------- | ||
6537 | void LLVOAvatar::updateMeshTextures() | ||
6538 | { | ||
6539 | // llinfos << "updateMeshTextures" << llendl; | ||
6540 | if (gNoRender) | ||
6541 | { | ||
6542 | return; | ||
6543 | } | ||
6544 | // if user has never specified a texture, assign the default | ||
6545 | LLViewerImage* default_tex = gImageList.getImage(IMG_DEFAULT); | ||
6546 | U8 num_TEs = getNumTEs(); | ||
6547 | for (U32 i=0; i<num_TEs; i++) | ||
6548 | { | ||
6549 | LLViewerImage* te_image = getTEImage(i); | ||
6550 | if( (NULL == te_image) || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT) ) | ||
6551 | { | ||
6552 | if( TEX_HAIR == i ) | ||
6553 | { | ||
6554 | setTEImage(i, default_tex ); | ||
6555 | } | ||
6556 | else | ||
6557 | { | ||
6558 | setTEImage(i, gImageList.getImage(IMG_DEFAULT_AVATAR)); // a special texture that's never rendered. | ||
6559 | } | ||
6560 | } | ||
6561 | } | ||
6562 | |||
6563 | // During face edit mode, we don't use baked textures | ||
6564 | BOOL self_customize = mIsSelf && gAgent.cameraCustomizeAvatar(); | ||
6565 | |||
6566 | BOOL head_baked = (getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6567 | BOOL upper_baked = (getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6568 | BOOL lower_baked = (getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6569 | BOOL eyes_baked = (getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6570 | BOOL skirt_baked = (getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6571 | |||
6572 | // Nothing should be baked if we're in customize avatar mode. | ||
6573 | llassert( !( self_customize && | ||
6574 | ( head_baked || upper_baked || lower_baked || eyes_baked ) ) ); | ||
6575 | |||
6576 | BOOL use_lkg_head_baked = FALSE; | ||
6577 | BOOL use_lkg_upper_baked = FALSE; | ||
6578 | BOOL use_lkg_lower_baked = FALSE; | ||
6579 | BOOL use_lkg_eyes_baked = FALSE; | ||
6580 | BOOL use_lkg_skirt_baked = FALSE; | ||
6581 | |||
6582 | BOOL other_culled = !mIsSelf && mCulled; | ||
6583 | if( other_culled ) | ||
6584 | { | ||
6585 | use_lkg_head_baked = !head_baked && (mLastHeadBakedID != IMG_DEFAULT_AVATAR); | ||
6586 | use_lkg_upper_baked = !upper_baked && (mLastUpperBodyBakedID != IMG_DEFAULT_AVATAR); | ||
6587 | use_lkg_lower_baked = !lower_baked && (mLastLowerBodyBakedID != IMG_DEFAULT_AVATAR); | ||
6588 | use_lkg_eyes_baked = !eyes_baked && (mLastEyesBakedID != IMG_DEFAULT_AVATAR); | ||
6589 | use_lkg_skirt_baked = !skirt_baked && (mLastSkirtBakedID != IMG_DEFAULT_AVATAR); | ||
6590 | |||
6591 | if( mHeadLayerSet ) | ||
6592 | { | ||
6593 | mHeadLayerSet->destroyComposite(); | ||
6594 | } | ||
6595 | |||
6596 | if( mUpperBodyLayerSet ) | ||
6597 | { | ||
6598 | mUpperBodyLayerSet->destroyComposite(); | ||
6599 | } | ||
6600 | |||
6601 | if( mLowerBodyLayerSet ) | ||
6602 | { | ||
6603 | mLowerBodyLayerSet->destroyComposite(); | ||
6604 | } | ||
6605 | |||
6606 | if( mEyesLayerSet ) | ||
6607 | { | ||
6608 | mEyesLayerSet->destroyComposite(); | ||
6609 | } | ||
6610 | |||
6611 | if( mSkirtLayerSet ) | ||
6612 | { | ||
6613 | mSkirtLayerSet->destroyComposite(); | ||
6614 | } | ||
6615 | |||
6616 | } | ||
6617 | else | ||
6618 | if( !self_customize ) | ||
6619 | { | ||
6620 | // When you're changing clothes and you're not in Appearance mode, | ||
6621 | // use the last-known good baked texture until you finish the first | ||
6622 | // render of the new layerset. | ||
6623 | use_lkg_head_baked = !head_baked && (mLastHeadBakedID != IMG_DEFAULT_AVATAR) && mHeadLayerSet && !mHeadLayerSet->getComposite()->isInitialized(); | ||
6624 | use_lkg_upper_baked = !upper_baked && (mLastUpperBodyBakedID != IMG_DEFAULT_AVATAR) && mUpperBodyLayerSet && !mUpperBodyLayerSet->getComposite()->isInitialized(); | ||
6625 | use_lkg_lower_baked = !lower_baked && (mLastLowerBodyBakedID != IMG_DEFAULT_AVATAR) && mLowerBodyLayerSet && !mLowerBodyLayerSet->getComposite()->isInitialized(); | ||
6626 | use_lkg_eyes_baked = !eyes_baked && (mLastEyesBakedID != IMG_DEFAULT_AVATAR) && mEyesLayerSet && !mEyesLayerSet->getComposite()->isInitialized(); | ||
6627 | use_lkg_skirt_baked = !skirt_baked && (mLastSkirtBakedID != IMG_DEFAULT_AVATAR) && mSkirtLayerSet && !mSkirtLayerSet->getComposite()->isInitialized(); | ||
6628 | |||
6629 | if( use_lkg_head_baked ) | ||
6630 | { | ||
6631 | mHeadLayerSet->setUpdatesEnabled( TRUE ); | ||
6632 | } | ||
6633 | |||
6634 | if( use_lkg_upper_baked ) | ||
6635 | { | ||
6636 | mUpperBodyLayerSet->setUpdatesEnabled( TRUE ); | ||
6637 | } | ||
6638 | |||
6639 | if( use_lkg_lower_baked ) | ||
6640 | { | ||
6641 | mLowerBodyLayerSet->setUpdatesEnabled( TRUE ); | ||
6642 | } | ||
6643 | |||
6644 | if( use_lkg_eyes_baked ) | ||
6645 | { | ||
6646 | mEyesLayerSet->setUpdatesEnabled( TRUE ); | ||
6647 | } | ||
6648 | |||
6649 | if( use_lkg_skirt_baked ) | ||
6650 | { | ||
6651 | mSkirtLayerSet->setUpdatesEnabled( TRUE ); | ||
6652 | } | ||
6653 | } | ||
6654 | |||
6655 | // Baked textures should be requested from the sim this avatar is on. JC | ||
6656 | LLHost target_host = getObjectHost(); | ||
6657 | if (!target_host.isOk()) | ||
6658 | { | ||
6659 | llwarns << "updateMeshTextures: invalid host for object: " << getID() << llendl; | ||
6660 | } | ||
6661 | |||
6662 | // Head | ||
6663 | if( use_lkg_head_baked ) | ||
6664 | { | ||
6665 | LLViewerImage* baked = gImageList.getImageFromHost( mLastHeadBakedID, target_host ); | ||
6666 | mHeadMesh0.setTexture( baked ); | ||
6667 | mHeadMesh1.setTexture( baked ); | ||
6668 | mHeadMesh2.setTexture( baked ); | ||
6669 | mHeadMesh3.setTexture( baked ); | ||
6670 | mHeadMesh4.setTexture( baked ); | ||
6671 | mEyeLashMesh0.setTexture( baked ); | ||
6672 | } | ||
6673 | else | ||
6674 | if( !self_customize && head_baked ) | ||
6675 | { | ||
6676 | LLViewerImage* baked = getTEImage( TEX_HEAD_BAKED ); | ||
6677 | if( baked->getID() == mLastHeadBakedID ) | ||
6678 | { | ||
6679 | // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). | ||
6680 | useBakedTexture( baked->getID() ); | ||
6681 | } | ||
6682 | else | ||
6683 | { | ||
6684 | mHeadBakedLoaded = FALSE; | ||
6685 | mHeadMaskDiscard = -1; | ||
6686 | baked->setNeedsAux(TRUE); | ||
6687 | baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID )); | ||
6688 | baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) ); | ||
6689 | } | ||
6690 | } | ||
6691 | else | ||
6692 | if( mHeadLayerSet && !other_culled ) | ||
6693 | { | ||
6694 | mHeadLayerSet->createComposite(); | ||
6695 | mHeadLayerSet->setUpdatesEnabled( TRUE ); | ||
6696 | mHeadMesh0.setLayerSet( mHeadLayerSet ); | ||
6697 | mHeadMesh1.setLayerSet( mHeadLayerSet ); | ||
6698 | mHeadMesh2.setLayerSet( mHeadLayerSet ); | ||
6699 | mHeadMesh3.setLayerSet( mHeadLayerSet ); | ||
6700 | mHeadMesh4.setLayerSet( mHeadLayerSet ); | ||
6701 | mEyeLashMesh0.setLayerSet( mHeadLayerSet ); | ||
6702 | } | ||
6703 | else | ||
6704 | { | ||
6705 | mHeadMesh0.setTexture( default_tex ); | ||
6706 | mHeadMesh1.setTexture( default_tex ); | ||
6707 | mHeadMesh2.setTexture( default_tex ); | ||
6708 | mHeadMesh3.setTexture( default_tex ); | ||
6709 | mHeadMesh4.setTexture( default_tex ); | ||
6710 | mEyeLashMesh0.setTexture( default_tex ); | ||
6711 | } | ||
6712 | |||
6713 | // Upper body | ||
6714 | if( use_lkg_upper_baked ) | ||
6715 | { | ||
6716 | LLViewerImage* baked = gImageList.getImageFromHost( mLastUpperBodyBakedID, target_host ); | ||
6717 | mUpperBodyMesh0.setTexture( baked ); | ||
6718 | mUpperBodyMesh1.setTexture( baked ); | ||
6719 | mUpperBodyMesh2.setTexture( baked ); | ||
6720 | mUpperBodyMesh3.setTexture( baked ); | ||
6721 | mUpperBodyMesh4.setTexture( baked ); | ||
6722 | } | ||
6723 | else | ||
6724 | if( !self_customize && upper_baked ) | ||
6725 | { | ||
6726 | LLViewerImage* baked = getTEImage( TEX_UPPER_BAKED ); | ||
6727 | |||
6728 | if( baked->getID() == mLastUpperBodyBakedID ) | ||
6729 | { | ||
6730 | // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). | ||
6731 | useBakedTexture( baked->getID() ); | ||
6732 | } | ||
6733 | else | ||
6734 | { | ||
6735 | mUpperBakedLoaded = FALSE; | ||
6736 | mUpperMaskDiscard = -1; | ||
6737 | baked->setNeedsAux(TRUE); | ||
6738 | baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID )); | ||
6739 | baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) ); | ||
6740 | } | ||
6741 | } | ||
6742 | else | ||
6743 | if( mUpperBodyLayerSet && !other_culled ) | ||
6744 | { | ||
6745 | mUpperBodyLayerSet->createComposite(); | ||
6746 | mUpperBodyLayerSet->setUpdatesEnabled( TRUE ); | ||
6747 | mUpperBodyMesh0.setLayerSet( mUpperBodyLayerSet ); | ||
6748 | mUpperBodyMesh1.setLayerSet( mUpperBodyLayerSet ); | ||
6749 | mUpperBodyMesh2.setLayerSet( mUpperBodyLayerSet ); | ||
6750 | mUpperBodyMesh3.setLayerSet( mUpperBodyLayerSet ); | ||
6751 | mUpperBodyMesh4.setLayerSet( mUpperBodyLayerSet ); | ||
6752 | } | ||
6753 | else | ||
6754 | { | ||
6755 | mUpperBodyMesh0.setTexture( default_tex ); | ||
6756 | mUpperBodyMesh1.setTexture( default_tex ); | ||
6757 | mUpperBodyMesh2.setTexture( default_tex ); | ||
6758 | mUpperBodyMesh3.setTexture( default_tex ); | ||
6759 | mUpperBodyMesh4.setTexture( default_tex ); | ||
6760 | } | ||
6761 | |||
6762 | // Lower body | ||
6763 | if( use_lkg_lower_baked ) | ||
6764 | { | ||
6765 | LLViewerImage* baked = gImageList.getImageFromHost( mLastLowerBodyBakedID, target_host ); | ||
6766 | mLowerBodyMesh0.setTexture( baked ); | ||
6767 | mLowerBodyMesh1.setTexture( baked ); | ||
6768 | mLowerBodyMesh2.setTexture( baked ); | ||
6769 | mLowerBodyMesh3.setTexture( baked ); | ||
6770 | mLowerBodyMesh4.setTexture( baked ); | ||
6771 | } | ||
6772 | else | ||
6773 | if( !self_customize && lower_baked ) | ||
6774 | { | ||
6775 | LLViewerImage* baked = getTEImage( TEX_LOWER_BAKED ); | ||
6776 | if( baked->getID() == mLastLowerBodyBakedID ) | ||
6777 | { | ||
6778 | // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). | ||
6779 | useBakedTexture( baked->getID() ); | ||
6780 | } | ||
6781 | else | ||
6782 | { | ||
6783 | mLowerBakedLoaded = FALSE; | ||
6784 | mLowerMaskDiscard = -1; | ||
6785 | baked->setNeedsAux(TRUE); | ||
6786 | baked->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID )); | ||
6787 | baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) ); | ||
6788 | } | ||
6789 | } | ||
6790 | else | ||
6791 | if( mLowerBodyLayerSet && !other_culled ) | ||
6792 | { | ||
6793 | mLowerBodyLayerSet->createComposite(); | ||
6794 | mLowerBodyLayerSet->setUpdatesEnabled( TRUE ); | ||
6795 | mLowerBodyMesh0.setLayerSet( mLowerBodyLayerSet ); | ||
6796 | mLowerBodyMesh1.setLayerSet( mLowerBodyLayerSet ); | ||
6797 | mLowerBodyMesh2.setLayerSet( mLowerBodyLayerSet ); | ||
6798 | mLowerBodyMesh3.setLayerSet( mLowerBodyLayerSet ); | ||
6799 | mLowerBodyMesh4.setLayerSet( mLowerBodyLayerSet ); | ||
6800 | } | ||
6801 | else | ||
6802 | { | ||
6803 | mLowerBodyMesh0.setTexture( default_tex ); | ||
6804 | mLowerBodyMesh1.setTexture( default_tex ); | ||
6805 | mLowerBodyMesh2.setTexture( default_tex ); | ||
6806 | mLowerBodyMesh3.setTexture( default_tex ); | ||
6807 | mLowerBodyMesh4.setTexture( default_tex ); | ||
6808 | } | ||
6809 | |||
6810 | // Eyes | ||
6811 | if( use_lkg_eyes_baked ) | ||
6812 | { | ||
6813 | LLViewerImage* baked = gImageList.getImageFromHost( mLastEyesBakedID, target_host ); | ||
6814 | mEyeBallLeftMesh0.setTexture( baked ); | ||
6815 | mEyeBallLeftMesh1.setTexture( baked ); | ||
6816 | mEyeBallRightMesh0.setTexture( baked ); | ||
6817 | mEyeBallRightMesh1.setTexture( baked ); | ||
6818 | } | ||
6819 | else | ||
6820 | if( !self_customize && eyes_baked ) | ||
6821 | { | ||
6822 | LLViewerImage* baked = getTEImage( TEX_EYES_BAKED ); | ||
6823 | if( baked->getID() == mLastEyesBakedID ) | ||
6824 | { | ||
6825 | // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). | ||
6826 | useBakedTexture( baked->getID() ); | ||
6827 | } | ||
6828 | else | ||
6829 | { | ||
6830 | mEyesBakedLoaded = FALSE; | ||
6831 | baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) ); | ||
6832 | } | ||
6833 | } | ||
6834 | else | ||
6835 | if( mEyesLayerSet && !other_culled ) | ||
6836 | { | ||
6837 | mEyesLayerSet->createComposite(); | ||
6838 | mEyesLayerSet->setUpdatesEnabled( TRUE ); | ||
6839 | mEyeBallLeftMesh0.setLayerSet( mEyesLayerSet ); | ||
6840 | mEyeBallLeftMesh1.setLayerSet( mEyesLayerSet ); | ||
6841 | mEyeBallRightMesh0.setLayerSet( mEyesLayerSet ); | ||
6842 | mEyeBallRightMesh1.setLayerSet( mEyesLayerSet ); | ||
6843 | } | ||
6844 | else | ||
6845 | { | ||
6846 | mEyeBallLeftMesh0.setTexture( default_tex ); | ||
6847 | mEyeBallLeftMesh1.setTexture( default_tex ); | ||
6848 | mEyeBallRightMesh0.setTexture( default_tex ); | ||
6849 | mEyeBallRightMesh1.setTexture( default_tex ); | ||
6850 | } | ||
6851 | |||
6852 | // Skirt | ||
6853 | if( use_lkg_skirt_baked ) | ||
6854 | { | ||
6855 | LLViewerImage* baked = gImageList.getImageFromHost( mLastSkirtBakedID, target_host ); | ||
6856 | mSkirtMesh0.setTexture( baked ); | ||
6857 | mSkirtMesh1.setTexture( baked ); | ||
6858 | mSkirtMesh2.setTexture( baked ); | ||
6859 | mSkirtMesh3.setTexture( baked ); | ||
6860 | mSkirtMesh4.setTexture( baked ); | ||
6861 | } | ||
6862 | else | ||
6863 | if( !self_customize && skirt_baked ) | ||
6864 | { | ||
6865 | LLViewerImage* baked = getTEImage( TEX_SKIRT_BAKED ); | ||
6866 | if( baked->getID() == mLastSkirtBakedID ) | ||
6867 | { | ||
6868 | // Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing). | ||
6869 | useBakedTexture( baked->getID() ); | ||
6870 | } | ||
6871 | else | ||
6872 | { | ||
6873 | mSkirtBakedLoaded = FALSE; | ||
6874 | baked->setLoadedCallback(onBakedTextureLoaded, SWITCH_TO_BAKED_DISCARD, FALSE, new LLUUID( mID ) ); | ||
6875 | } | ||
6876 | } | ||
6877 | else | ||
6878 | if( mSkirtLayerSet && !other_culled) | ||
6879 | { | ||
6880 | mSkirtLayerSet->createComposite(); | ||
6881 | mSkirtLayerSet->setUpdatesEnabled( TRUE ); | ||
6882 | mSkirtMesh0.setLayerSet( mSkirtLayerSet ); | ||
6883 | mSkirtMesh1.setLayerSet( mSkirtLayerSet ); | ||
6884 | mSkirtMesh2.setLayerSet( mSkirtLayerSet ); | ||
6885 | mSkirtMesh3.setLayerSet( mSkirtLayerSet ); | ||
6886 | mSkirtMesh4.setLayerSet( mSkirtLayerSet ); | ||
6887 | } | ||
6888 | else | ||
6889 | { | ||
6890 | mSkirtMesh0.setTexture( default_tex ); | ||
6891 | mSkirtMesh1.setTexture( default_tex ); | ||
6892 | mSkirtMesh2.setTexture( default_tex ); | ||
6893 | mSkirtMesh3.setTexture( default_tex ); | ||
6894 | mSkirtMesh4.setTexture( default_tex ); | ||
6895 | } | ||
6896 | |||
6897 | mHairMesh0.setTexture( getTEImage( TEX_HAIR ) ); | ||
6898 | mHairMesh1.setTexture( getTEImage( TEX_HAIR ) ); | ||
6899 | mHairMesh2.setTexture( getTEImage( TEX_HAIR ) ); | ||
6900 | mHairMesh3.setTexture( getTEImage( TEX_HAIR ) ); | ||
6901 | mHairMesh4.setTexture( getTEImage( TEX_HAIR ) ); | ||
6902 | mHairMesh5.setTexture( getTEImage( TEX_HAIR ) ); | ||
6903 | |||
6904 | if( mTexHairColor ) | ||
6905 | { | ||
6906 | LLColor4 color = mTexHairColor->getColor(); | ||
6907 | mHairMesh0.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); | ||
6908 | mHairMesh1.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); | ||
6909 | mHairMesh2.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); | ||
6910 | mHairMesh3.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); | ||
6911 | mHairMesh4.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); | ||
6912 | mHairMesh5.setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] ); | ||
6913 | } | ||
6914 | |||
6915 | // Head | ||
6916 | BOOL head_baked_ready = (head_baked && mHeadBakedLoaded) || other_culled; | ||
6917 | setLocalTexture( LOCTEX_HEAD_BODYPAINT, getTEImage( TEX_HEAD_BODYPAINT ), head_baked_ready ); | ||
6918 | |||
6919 | // Upper body | ||
6920 | BOOL upper_baked_ready = (upper_baked && mUpperBakedLoaded) || other_culled; | ||
6921 | setLocalTexture( LOCTEX_UPPER_SHIRT, getTEImage( TEX_UPPER_SHIRT ), upper_baked_ready ); | ||
6922 | setLocalTexture( LOCTEX_UPPER_BODYPAINT, getTEImage( TEX_UPPER_BODYPAINT ), upper_baked_ready ); | ||
6923 | setLocalTexture( LOCTEX_UPPER_JACKET, getTEImage( TEX_UPPER_JACKET ), upper_baked_ready ); | ||
6924 | setLocalTexture( LOCTEX_UPPER_GLOVES, getTEImage( TEX_UPPER_GLOVES ), upper_baked_ready ); | ||
6925 | setLocalTexture( LOCTEX_UPPER_UNDERSHIRT, getTEImage( TEX_UPPER_UNDERSHIRT ), upper_baked_ready ); | ||
6926 | |||
6927 | // Lower body | ||
6928 | BOOL lower_baked_ready = (lower_baked && mLowerBakedLoaded) || other_culled; | ||
6929 | setLocalTexture( LOCTEX_LOWER_PANTS, getTEImage( TEX_LOWER_PANTS ), lower_baked_ready ); | ||
6930 | setLocalTexture( LOCTEX_LOWER_BODYPAINT, getTEImage( TEX_LOWER_BODYPAINT ), lower_baked_ready ); | ||
6931 | setLocalTexture( LOCTEX_LOWER_SHOES, getTEImage( TEX_LOWER_SHOES ), lower_baked_ready ); | ||
6932 | setLocalTexture( LOCTEX_LOWER_SOCKS, getTEImage( TEX_LOWER_SOCKS ), lower_baked_ready ); | ||
6933 | setLocalTexture( LOCTEX_LOWER_JACKET, getTEImage( TEX_LOWER_JACKET ), lower_baked_ready ); | ||
6934 | setLocalTexture( LOCTEX_LOWER_UNDERPANTS, getTEImage( TEX_LOWER_UNDERPANTS ), lower_baked_ready ); | ||
6935 | |||
6936 | // Eyes | ||
6937 | BOOL eyes_baked_ready = (eyes_baked && mEyesBakedLoaded) || other_culled; | ||
6938 | setLocalTexture( LOCTEX_EYES_IRIS, getTEImage( TEX_EYES_IRIS ), eyes_baked_ready ); | ||
6939 | |||
6940 | // Skirt | ||
6941 | BOOL skirt_baked_ready = (skirt_baked && mSkirtBakedLoaded) || other_culled; | ||
6942 | setLocalTexture( LOCTEX_SKIRT, getTEImage( TEX_SKIRT ), skirt_baked_ready ); | ||
6943 | |||
6944 | removeMissingBakedTextures(); | ||
6945 | } | ||
6946 | |||
6947 | //----------------------------------------------------------------------------- | ||
6948 | // setLocalTexture() | ||
6949 | //----------------------------------------------------------------------------- | ||
6950 | void LLVOAvatar::setLocalTexture( ELocTexIndex idx, LLViewerImage* tex, BOOL baked_version_ready ) | ||
6951 | { | ||
6952 | S32 desired_discard = mIsSelf ? 0 : 2; | ||
6953 | if (!baked_version_ready) | ||
6954 | { | ||
6955 | if (tex != mLocalTexture[idx] || mLocalTextureBaked[idx]) | ||
6956 | { | ||
6957 | mLocalTextureDiscard[idx] = MAX_DISCARD_LEVEL+1; | ||
6958 | } | ||
6959 | if (tex->getID() != IMG_DEFAULT_AVATAR) | ||
6960 | { | ||
6961 | if (mLocalTextureDiscard[idx] > desired_discard) | ||
6962 | { | ||
6963 | S32 tex_discard = tex->getDiscardLevel(); | ||
6964 | if (tex_discard >= 0 && tex_discard <= desired_discard) | ||
6965 | { | ||
6966 | mLocalTextureDiscard[idx] = tex_discard; | ||
6967 | requestLayerSetUpdate( idx ); | ||
6968 | if( mIsSelf && gAgent.cameraCustomizeAvatar() ) | ||
6969 | { | ||
6970 | LLVisualParamHint::requestHintUpdates(); | ||
6971 | } | ||
6972 | } | ||
6973 | else | ||
6974 | { | ||
6975 | tex->setLoadedCallback( onLocalTextureLoaded, desired_discard, TRUE, new LLAvatarTexData(getID(), idx) ); | ||
6976 | } | ||
6977 | } | ||
6978 | tex->setMinDiscardLevel(desired_discard); | ||
6979 | } | ||
6980 | } | ||
6981 | mLocalTextureBaked[idx] = baked_version_ready; | ||
6982 | mLocalTexture[idx] = tex; | ||
6983 | } | ||
6984 | |||
6985 | //----------------------------------------------------------------------------- | ||
6986 | // requestLayerSetUploads() | ||
6987 | //----------------------------------------------------------------------------- | ||
6988 | void LLVOAvatar::requestLayerSetUploads() | ||
6989 | { | ||
6990 | BOOL upper_baked = (getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6991 | BOOL lower_baked = (getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6992 | BOOL head_baked = (getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6993 | BOOL eyes_baked = (getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6994 | BOOL skirt_baked = (getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
6995 | |||
6996 | if( !head_baked && mHeadLayerSet ) | ||
6997 | { | ||
6998 | mHeadLayerSet->requestUpload(); | ||
6999 | } | ||
7000 | |||
7001 | if( !upper_baked && mUpperBodyLayerSet ) | ||
7002 | { | ||
7003 | mUpperBodyLayerSet->requestUpload(); | ||
7004 | } | ||
7005 | |||
7006 | if( !lower_baked && mLowerBodyLayerSet ) | ||
7007 | { | ||
7008 | mLowerBodyLayerSet->requestUpload(); | ||
7009 | } | ||
7010 | |||
7011 | if( !eyes_baked && mEyesLayerSet ) | ||
7012 | { | ||
7013 | mEyesLayerSet->requestUpload(); | ||
7014 | } | ||
7015 | |||
7016 | if( !skirt_baked && mSkirtLayerSet ) | ||
7017 | { | ||
7018 | mSkirtLayerSet->requestUpload(); | ||
7019 | } | ||
7020 | } | ||
7021 | |||
7022 | |||
7023 | //----------------------------------------------------------------------------- | ||
7024 | // setCompositeUpdatesEnabled() | ||
7025 | //----------------------------------------------------------------------------- | ||
7026 | void LLVOAvatar::setCompositeUpdatesEnabled( BOOL b ) | ||
7027 | { | ||
7028 | if( mHeadLayerSet ) | ||
7029 | { | ||
7030 | mHeadLayerSet->setUpdatesEnabled( b ); | ||
7031 | } | ||
7032 | |||
7033 | if( mUpperBodyLayerSet ) | ||
7034 | { | ||
7035 | mUpperBodyLayerSet->setUpdatesEnabled( b ); | ||
7036 | } | ||
7037 | |||
7038 | if( mLowerBodyLayerSet ) | ||
7039 | { | ||
7040 | mLowerBodyLayerSet->setUpdatesEnabled( b ); | ||
7041 | } | ||
7042 | |||
7043 | if( mEyesLayerSet ) | ||
7044 | { | ||
7045 | mEyesLayerSet->setUpdatesEnabled( b ); | ||
7046 | } | ||
7047 | |||
7048 | if( mSkirtLayerSet ) | ||
7049 | { | ||
7050 | mSkirtLayerSet->setUpdatesEnabled( b ); | ||
7051 | } | ||
7052 | |||
7053 | } | ||
7054 | |||
7055 | void LLVOAvatar::addChat(const LLChat& chat) | ||
7056 | { | ||
7057 | std::deque<LLChat>::iterator chat_iter; | ||
7058 | |||
7059 | mChats.push_back(chat); | ||
7060 | |||
7061 | S32 chat_length = 0; | ||
7062 | for( chat_iter = mChats.begin(); chat_iter != mChats.end(); ++chat_iter) | ||
7063 | { | ||
7064 | chat_length += chat_iter->mText.size(); | ||
7065 | } | ||
7066 | |||
7067 | // remove any excess chat | ||
7068 | chat_iter = mChats.begin(); | ||
7069 | while ((chat_length > MAX_BUBBLE_CHAT_LENGTH || mChats.size() > MAX_BUBBLE_CHAT_UTTERANCES) && chat_iter != mChats.end()) | ||
7070 | { | ||
7071 | chat_length -= chat_iter->mText.size(); | ||
7072 | mChats.pop_front(); | ||
7073 | chat_iter = mChats.begin(); | ||
7074 | } | ||
7075 | |||
7076 | mChatTimer.reset(); | ||
7077 | } | ||
7078 | |||
7079 | void LLVOAvatar::clearChat() | ||
7080 | { | ||
7081 | mChats.clear(); | ||
7082 | } | ||
7083 | |||
7084 | S32 LLVOAvatar::getLocalDiscardLevel( S32 index ) | ||
7085 | { | ||
7086 | if (index >= 0 && mLocalTexture[index].notNull() && mLocalTexture[index]->getID() != IMG_DEFAULT_AVATAR) | ||
7087 | { | ||
7088 | return mLocalTexture[index]->getDiscardLevel(); | ||
7089 | } | ||
7090 | else | ||
7091 | { | ||
7092 | // We don't care about this (no image associated with the layer) treat as fully loaded. | ||
7093 | return 0; | ||
7094 | } | ||
7095 | } | ||
7096 | |||
7097 | //----------------------------------------------------------------------------- | ||
7098 | // isLocalTextureDataFinal() | ||
7099 | // Returns true is the highest quality discard level exists for every texture | ||
7100 | // in the layerset. | ||
7101 | //----------------------------------------------------------------------------- | ||
7102 | BOOL LLVOAvatar::isLocalTextureDataFinal( LLTexLayerSet* layerset ) | ||
7103 | { | ||
7104 | if( layerset == mHeadLayerSet ) | ||
7105 | { | ||
7106 | return getLocalDiscardLevel( LOCTEX_HEAD_BODYPAINT ) == 0; | ||
7107 | } | ||
7108 | else if( layerset == mUpperBodyLayerSet ) | ||
7109 | { | ||
7110 | return getLocalDiscardLevel( LOCTEX_UPPER_SHIRT ) == 0 && | ||
7111 | getLocalDiscardLevel( LOCTEX_UPPER_BODYPAINT ) == 0 && | ||
7112 | getLocalDiscardLevel( LOCTEX_UPPER_JACKET ) == 0 && | ||
7113 | getLocalDiscardLevel( LOCTEX_UPPER_GLOVES ) == 0 && | ||
7114 | getLocalDiscardLevel( LOCTEX_UPPER_UNDERSHIRT ) == 0; | ||
7115 | } | ||
7116 | else if( layerset == mLowerBodyLayerSet ) | ||
7117 | { | ||
7118 | return getLocalDiscardLevel( LOCTEX_LOWER_PANTS ) == 0 && | ||
7119 | getLocalDiscardLevel( LOCTEX_LOWER_BODYPAINT ) == 0 && | ||
7120 | getLocalDiscardLevel( LOCTEX_LOWER_SHOES ) == 0 && | ||
7121 | getLocalDiscardLevel( LOCTEX_LOWER_SOCKS ) == 0 && | ||
7122 | getLocalDiscardLevel( LOCTEX_LOWER_JACKET ) == 0 && | ||
7123 | getLocalDiscardLevel( LOCTEX_LOWER_UNDERPANTS ) == 0; | ||
7124 | } | ||
7125 | else if( layerset == mEyesLayerSet ) | ||
7126 | { | ||
7127 | return getLocalDiscardLevel( LOCTEX_EYES_IRIS ) == 0; | ||
7128 | } | ||
7129 | else if( layerset == mSkirtLayerSet ) | ||
7130 | { | ||
7131 | return getLocalDiscardLevel( LOCTEX_SKIRT ) == 0; | ||
7132 | } | ||
7133 | |||
7134 | llassert(0); | ||
7135 | return FALSE; | ||
7136 | } | ||
7137 | |||
7138 | //----------------------------------------------------------------------------- | ||
7139 | // isLocalTextureDataAvailable() | ||
7140 | // Returns true is at least the lowest quality discard level exists for every texture | ||
7141 | // in the layerset. | ||
7142 | //----------------------------------------------------------------------------- | ||
7143 | BOOL LLVOAvatar::isLocalTextureDataAvailable( LLTexLayerSet* layerset ) | ||
7144 | { | ||
7145 | if( layerset == mHeadLayerSet ) | ||
7146 | { | ||
7147 | return getLocalDiscardLevel( LOCTEX_HEAD_BODYPAINT ) >= 0; | ||
7148 | } | ||
7149 | else if( layerset == mUpperBodyLayerSet ) | ||
7150 | { | ||
7151 | return getLocalDiscardLevel( LOCTEX_UPPER_SHIRT ) >= 0 && | ||
7152 | getLocalDiscardLevel( LOCTEX_UPPER_BODYPAINT ) >= 0 && | ||
7153 | getLocalDiscardLevel( LOCTEX_UPPER_JACKET ) >= 0 && | ||
7154 | getLocalDiscardLevel( LOCTEX_UPPER_GLOVES ) >= 0 && | ||
7155 | getLocalDiscardLevel( LOCTEX_UPPER_UNDERSHIRT ) >= 0; | ||
7156 | } | ||
7157 | else if( layerset == mLowerBodyLayerSet ) | ||
7158 | { | ||
7159 | return getLocalDiscardLevel( LOCTEX_LOWER_PANTS ) >= 0 && | ||
7160 | getLocalDiscardLevel( LOCTEX_LOWER_BODYPAINT ) >= 0 && | ||
7161 | getLocalDiscardLevel( LOCTEX_LOWER_SHOES ) >= 0 && | ||
7162 | getLocalDiscardLevel( LOCTEX_LOWER_SOCKS ) >= 0 && | ||
7163 | getLocalDiscardLevel( LOCTEX_LOWER_JACKET ) >= 0 && | ||
7164 | getLocalDiscardLevel( LOCTEX_LOWER_UNDERPANTS ) >= 0; | ||
7165 | } | ||
7166 | else if( layerset == mEyesLayerSet ) | ||
7167 | { | ||
7168 | return getLocalDiscardLevel( LOCTEX_EYES_IRIS ) >= 0; | ||
7169 | } | ||
7170 | else if( layerset == mSkirtLayerSet ) | ||
7171 | { | ||
7172 | return getLocalDiscardLevel( LOCTEX_SKIRT ) >= 0; | ||
7173 | } | ||
7174 | |||
7175 | llassert(0); | ||
7176 | return FALSE; | ||
7177 | } | ||
7178 | |||
7179 | |||
7180 | //----------------------------------------------------------------------------- | ||
7181 | // getBakedTE() | ||
7182 | // Used by the LayerSet. (Layer sets don't in general know what textures depend on them.) | ||
7183 | //----------------------------------------------------------------------------- | ||
7184 | LLVOAvatar::ETextureIndex LLVOAvatar::getBakedTE( LLTexLayerSet* layerset ) | ||
7185 | { | ||
7186 | if( layerset == mHeadLayerSet ) | ||
7187 | { | ||
7188 | return TEX_HEAD_BAKED; | ||
7189 | } | ||
7190 | else | ||
7191 | if( layerset == mUpperBodyLayerSet ) | ||
7192 | { | ||
7193 | return TEX_UPPER_BAKED; | ||
7194 | } | ||
7195 | else | ||
7196 | if( layerset == mLowerBodyLayerSet ) | ||
7197 | { | ||
7198 | return TEX_LOWER_BAKED; | ||
7199 | } | ||
7200 | else | ||
7201 | if( layerset == mEyesLayerSet ) | ||
7202 | { | ||
7203 | return TEX_EYES_BAKED; | ||
7204 | } | ||
7205 | else | ||
7206 | if( layerset == mSkirtLayerSet ) | ||
7207 | { | ||
7208 | return TEX_SKIRT_BAKED; | ||
7209 | } | ||
7210 | |||
7211 | llassert(0); | ||
7212 | return TEX_HEAD_BAKED; | ||
7213 | } | ||
7214 | |||
7215 | //----------------------------------------------------------------------------- | ||
7216 | // setNewBakedTexture() | ||
7217 | // A new baked texture has been successfully uploaded and we can start using it now. | ||
7218 | //----------------------------------------------------------------------------- | ||
7219 | void LLVOAvatar::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid ) | ||
7220 | { | ||
7221 | // Baked textures live on other sims. | ||
7222 | LLHost target_host = getObjectHost(); | ||
7223 | setTEImage( te, gImageList.getImageFromHost( uuid, target_host ) ); | ||
7224 | updateMeshTextures(); | ||
7225 | dirtyMesh(); | ||
7226 | |||
7227 | LLVOAvatar::cullAvatarsByPixelArea(); | ||
7228 | |||
7229 | switch( te ) | ||
7230 | { | ||
7231 | case TEX_HEAD_BAKED: | ||
7232 | llinfos << "New baked texture: HEAD" << llendl; | ||
7233 | break; | ||
7234 | case TEX_UPPER_BAKED: | ||
7235 | llinfos << "New baked texture: UPPER" << llendl; | ||
7236 | break; | ||
7237 | case TEX_LOWER_BAKED: | ||
7238 | llinfos << "New baked texture: LOWER" << llendl; | ||
7239 | break; | ||
7240 | case TEX_EYES_BAKED: | ||
7241 | llinfos << "New baked texture: EYES" << llendl; | ||
7242 | break; | ||
7243 | case TEX_SKIRT_BAKED: | ||
7244 | llinfos << "New baked texture: SKIRT" << llendl; | ||
7245 | break; | ||
7246 | default: | ||
7247 | llwarns << "New baked texture: unknown te " << te << llendl; | ||
7248 | break; | ||
7249 | } | ||
7250 | |||
7251 | // dumpAvatarTEs( "setNewBakedTexture() send" ); | ||
7252 | // RN: throttle uploads | ||
7253 | if (!hasPendingBakedUploads()) | ||
7254 | { | ||
7255 | gAgent.sendAgentSetAppearance(); | ||
7256 | } | ||
7257 | } | ||
7258 | |||
7259 | bool LLVOAvatar::hasPendingBakedUploads() | ||
7260 | { | ||
7261 | bool head_pending = (mHeadLayerSet && mHeadLayerSet->getComposite()->uploadPending()); | ||
7262 | bool upper_pending = (mUpperBodyLayerSet && mUpperBodyLayerSet->getComposite()->uploadPending()); | ||
7263 | bool lower_pending = (mLowerBodyLayerSet && mLowerBodyLayerSet->getComposite()->uploadPending()); | ||
7264 | bool eyes_pending = (mEyesLayerSet && mEyesLayerSet->getComposite()->uploadPending()); | ||
7265 | bool skirt_pending = (mSkirtLayerSet && mSkirtLayerSet->getComposite()->uploadPending()); | ||
7266 | |||
7267 | //llinfos << "TAT: LLVOAvatar::hasPendingBakedUploads()" | ||
7268 | // << " head_pending " << head_pending | ||
7269 | // << " upper_pending " << upper_pending | ||
7270 | // << " lower_pending " << lower_pending | ||
7271 | // << " eyes_pending " << eyes_pending | ||
7272 | // << " skirt_pending " << skirt_pending | ||
7273 | // << llendl; | ||
7274 | |||
7275 | if (head_pending || upper_pending || lower_pending || eyes_pending || skirt_pending) | ||
7276 | { | ||
7277 | return true; | ||
7278 | } | ||
7279 | else | ||
7280 | { | ||
7281 | return false; | ||
7282 | } | ||
7283 | } | ||
7284 | |||
7285 | //----------------------------------------------------------------------------- | ||
7286 | // setCachedBakedTexture() | ||
7287 | // A baked texture id was received from a cache query, make it active | ||
7288 | //----------------------------------------------------------------------------- | ||
7289 | void LLVOAvatar::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid ) | ||
7290 | { | ||
7291 | setTETexture( te, uuid ); | ||
7292 | |||
7293 | switch(te) | ||
7294 | { | ||
7295 | case TEX_HEAD_BAKED: | ||
7296 | if( mHeadLayerSet ) | ||
7297 | { | ||
7298 | mHeadLayerSet->cancelUpload(); | ||
7299 | } | ||
7300 | break; | ||
7301 | case TEX_UPPER_BAKED: | ||
7302 | if( mUpperBodyLayerSet ) | ||
7303 | { | ||
7304 | mUpperBodyLayerSet->cancelUpload(); | ||
7305 | } | ||
7306 | break; | ||
7307 | case TEX_LOWER_BAKED: | ||
7308 | if( mLowerBodyLayerSet ) | ||
7309 | { | ||
7310 | mLowerBodyLayerSet->cancelUpload(); | ||
7311 | } | ||
7312 | break; | ||
7313 | case TEX_EYES_BAKED: | ||
7314 | if( mEyesLayerSet ) | ||
7315 | { | ||
7316 | mEyesLayerSet->cancelUpload(); | ||
7317 | } | ||
7318 | break; | ||
7319 | case TEX_SKIRT_BAKED: | ||
7320 | if( mSkirtLayerSet ) | ||
7321 | { | ||
7322 | mSkirtLayerSet->cancelUpload(); | ||
7323 | } | ||
7324 | break; | ||
7325 | } | ||
7326 | } | ||
7327 | |||
7328 | //----------------------------------------------------------------------------- | ||
7329 | // static | ||
7330 | // onCustomizeStart() | ||
7331 | //----------------------------------------------------------------------------- | ||
7332 | void LLVOAvatar::onCustomizeStart() | ||
7333 | { | ||
7334 | LLVOAvatar* avatar = gAgent.getAvatarObject(); | ||
7335 | if( avatar ) | ||
7336 | { | ||
7337 | for( S32 i = 0; i < BAKED_TEXTURE_COUNT; i++ ) | ||
7338 | { | ||
7339 | S32 tex_index = sBakedTextureIndices[i]; | ||
7340 | avatar->mSavedTE[ tex_index ] = avatar->getTEImage(tex_index)->getID(); | ||
7341 | avatar->setTEImage( tex_index, gImageList.getImage(IMG_DEFAULT_AVATAR) ); | ||
7342 | } | ||
7343 | |||
7344 | avatar->updateMeshTextures(); | ||
7345 | |||
7346 | // avatar->dumpAvatarTEs( "onCustomizeStart() send" ); | ||
7347 | gAgent.sendAgentSetAppearance(); | ||
7348 | } | ||
7349 | } | ||
7350 | |||
7351 | //----------------------------------------------------------------------------- | ||
7352 | // static | ||
7353 | // onCustomizeEnd() | ||
7354 | //----------------------------------------------------------------------------- | ||
7355 | void LLVOAvatar::onCustomizeEnd() | ||
7356 | { | ||
7357 | LLVOAvatar* avatar = gAgent.getAvatarObject(); | ||
7358 | if( !avatar ) return; | ||
7359 | |||
7360 | LLHost target_host = avatar->getObjectHost(); | ||
7361 | for( S32 i = 0; i < BAKED_TEXTURE_COUNT; i++ ) | ||
7362 | { | ||
7363 | S32 tex_index = sBakedTextureIndices[i]; | ||
7364 | const LLUUID& saved = avatar->mSavedTE[ tex_index ]; | ||
7365 | if( !saved.isNull() ) | ||
7366 | { | ||
7367 | avatar->setTEImage( tex_index, gImageList.getImageFromHost( saved, target_host ) ); | ||
7368 | } | ||
7369 | } | ||
7370 | |||
7371 | avatar->updateMeshTextures(); | ||
7372 | |||
7373 | if( !gQuit ) | ||
7374 | { | ||
7375 | avatar->requestLayerSetUploads(); | ||
7376 | } | ||
7377 | |||
7378 | gAgent.sendAgentSetAppearance(); | ||
7379 | } | ||
7380 | |||
7381 | BOOL LLVOAvatar::teToColorParams( ETextureIndex te, const char* param_name[3] ) | ||
7382 | { | ||
7383 | switch( te ) | ||
7384 | { | ||
7385 | case TEX_UPPER_SHIRT: | ||
7386 | param_name[0] = "shirt_red"; | ||
7387 | param_name[1] = "shirt_green"; | ||
7388 | param_name[2] = "shirt_blue"; | ||
7389 | break; | ||
7390 | |||
7391 | case TEX_LOWER_PANTS: | ||
7392 | param_name[0] = "pants_red"; | ||
7393 | param_name[1] = "pants_green"; | ||
7394 | param_name[2] = "pants_blue"; | ||
7395 | break; | ||
7396 | |||
7397 | case TEX_LOWER_SHOES: | ||
7398 | param_name[0] = "shoes_red"; | ||
7399 | param_name[1] = "shoes_green"; | ||
7400 | param_name[2] = "shoes_blue"; | ||
7401 | break; | ||
7402 | |||
7403 | case TEX_LOWER_SOCKS: | ||
7404 | param_name[0] = "socks_red"; | ||
7405 | param_name[1] = "socks_green"; | ||
7406 | param_name[2] = "socks_blue"; | ||
7407 | break; | ||
7408 | |||
7409 | case TEX_UPPER_JACKET: | ||
7410 | case TEX_LOWER_JACKET: | ||
7411 | param_name[0] = "jacket_red"; | ||
7412 | param_name[1] = "jacket_green"; | ||
7413 | param_name[2] = "jacket_blue"; | ||
7414 | break; | ||
7415 | |||
7416 | case TEX_UPPER_GLOVES: | ||
7417 | param_name[0] = "gloves_red"; | ||
7418 | param_name[1] = "gloves_green"; | ||
7419 | param_name[2] = "gloves_blue"; | ||
7420 | break; | ||
7421 | |||
7422 | case TEX_UPPER_UNDERSHIRT: | ||
7423 | param_name[0] = "undershirt_red"; | ||
7424 | param_name[1] = "undershirt_green"; | ||
7425 | param_name[2] = "undershirt_blue"; | ||
7426 | break; | ||
7427 | |||
7428 | case TEX_LOWER_UNDERPANTS: | ||
7429 | param_name[0] = "underpants_red"; | ||
7430 | param_name[1] = "underpants_green"; | ||
7431 | param_name[2] = "underpants_blue"; | ||
7432 | break; | ||
7433 | |||
7434 | case TEX_SKIRT: | ||
7435 | param_name[0] = "skirt_red"; | ||
7436 | param_name[1] = "skirt_green"; | ||
7437 | param_name[2] = "skirt_blue"; | ||
7438 | break; | ||
7439 | |||
7440 | default: | ||
7441 | llassert(0); | ||
7442 | return FALSE; | ||
7443 | } | ||
7444 | |||
7445 | return TRUE; | ||
7446 | } | ||
7447 | |||
7448 | void LLVOAvatar::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL set_by_user ) | ||
7449 | { | ||
7450 | const char* param_name[3]; | ||
7451 | if( teToColorParams( te, param_name ) ) | ||
7452 | { | ||
7453 | setVisualParamWeight( param_name[0], new_color.mV[VX], set_by_user ); | ||
7454 | setVisualParamWeight( param_name[1], new_color.mV[VY], set_by_user ); | ||
7455 | setVisualParamWeight( param_name[2], new_color.mV[VZ], set_by_user ); | ||
7456 | } | ||
7457 | } | ||
7458 | |||
7459 | LLColor4 LLVOAvatar::getClothesColor( ETextureIndex te ) | ||
7460 | { | ||
7461 | LLColor4 color; | ||
7462 | const char* param_name[3]; | ||
7463 | if( teToColorParams( te, param_name ) ) | ||
7464 | { | ||
7465 | color.mV[VX] = getVisualParamWeight( param_name[0] ); | ||
7466 | color.mV[VY] = getVisualParamWeight( param_name[1] ); | ||
7467 | color.mV[VZ] = getVisualParamWeight( param_name[2] ); | ||
7468 | } | ||
7469 | return color; | ||
7470 | } | ||
7471 | |||
7472 | |||
7473 | |||
7474 | |||
7475 | void LLVOAvatar::dumpAvatarTEs( const char* context ) | ||
7476 | { | ||
7477 | llinfos << (mIsSelf ? "Self: " : "Other: ") << context << llendl; | ||
7478 | for( S32 i=0; i<TEX_NUM_ENTRIES; i++ ) | ||
7479 | { | ||
7480 | const char* te_name[] = { | ||
7481 | "TEX_HEAD_BODYPAINT ", | ||
7482 | "TEX_UPPER_SHIRT ", | ||
7483 | "TEX_LOWER_PANTS ", | ||
7484 | "TEX_EYES_IRIS ", | ||
7485 | "TEX_HAIR ", | ||
7486 | "TEX_UPPER_BODYPAINT ", | ||
7487 | "TEX_LOWER_BODYPAINT ", | ||
7488 | "TEX_LOWER_SHOES ", | ||
7489 | "TEX_HEAD_BAKED ", | ||
7490 | "TEX_UPPER_BAKED ", | ||
7491 | "TEX_LOWER_BAKED ", | ||
7492 | "TEX_EYES_BAKED ", | ||
7493 | "TEX_LOWER_SOCKS ", | ||
7494 | "TEX_UPPER_JACKET ", | ||
7495 | "TEX_LOWER_JACKET ", | ||
7496 | "TEX_UPPER_GLOVES ", | ||
7497 | "TEX_UPPER_UNDERSHIRT ", | ||
7498 | "TEX_LOWER_UNDERPANTS ", | ||
7499 | "TEX_SKIRT ", | ||
7500 | "TEX_SKIRT_BAKED " | ||
7501 | }; | ||
7502 | |||
7503 | LLViewerImage* te_image = getTEImage(i); | ||
7504 | if( !te_image ) | ||
7505 | { | ||
7506 | llinfos << " " << te_name[i] << ": null ptr" << llendl; | ||
7507 | } | ||
7508 | else | ||
7509 | if( te_image->getID().isNull() ) | ||
7510 | { | ||
7511 | llinfos << " " << te_name[i] << ": null UUID" << llendl; | ||
7512 | } | ||
7513 | else | ||
7514 | if( te_image->getID() == IMG_DEFAULT ) | ||
7515 | { | ||
7516 | llinfos << " " << te_name[i] << ": IMG_DEFAULT" << llendl; | ||
7517 | } | ||
7518 | else | ||
7519 | if( te_image->getID() == IMG_DEFAULT_AVATAR ) | ||
7520 | { | ||
7521 | llinfos << " " << te_name[i] << ": IMG_DEFAULT_AVATAR" << llendl; | ||
7522 | } | ||
7523 | else | ||
7524 | { | ||
7525 | llinfos << " " << te_name[i] << ": " << te_image->getID() << llendl; | ||
7526 | } | ||
7527 | } | ||
7528 | } | ||
7529 | |||
7530 | //----------------------------------------------------------------------------- | ||
7531 | // updateAttachmentVisibility() | ||
7532 | //----------------------------------------------------------------------------- | ||
7533 | void LLVOAvatar::updateAttachmentVisibility(U32 camera_mode) | ||
7534 | { | ||
7535 | for (LLViewerJointAttachment *attachmentPoint = mAttachmentPoints.getFirstData(); | ||
7536 | attachmentPoint; | ||
7537 | attachmentPoint = mAttachmentPoints.getNextData()) | ||
7538 | { | ||
7539 | if (attachmentPoint->getIsHUDAttachment()) | ||
7540 | { | ||
7541 | attachmentPoint->setAttachmentVisibility(TRUE); | ||
7542 | } | ||
7543 | else | ||
7544 | { | ||
7545 | switch (camera_mode) | ||
7546 | { | ||
7547 | case CAMERA_MODE_MOUSELOOK: | ||
7548 | if (LLVOAvatar::sVisibleInFirstPerson && attachmentPoint->getVisibleInFirstPerson()) | ||
7549 | { | ||
7550 | attachmentPoint->setAttachmentVisibility(TRUE); | ||
7551 | } | ||
7552 | else | ||
7553 | { | ||
7554 | attachmentPoint->setAttachmentVisibility(FALSE); | ||
7555 | } | ||
7556 | break; | ||
7557 | default: | ||
7558 | attachmentPoint->setAttachmentVisibility(TRUE); | ||
7559 | break; | ||
7560 | } | ||
7561 | } | ||
7562 | } | ||
7563 | } | ||
7564 | |||
7565 | // Given a texture entry, determine which wearable type owns it. | ||
7566 | // static | ||
7567 | LLUUID LLVOAvatar::getDefaultTEImageID( S32 te ) | ||
7568 | { | ||
7569 | switch( te ) | ||
7570 | { | ||
7571 | case TEX_UPPER_SHIRT: return LLUUID( gSavedSettings.getString("UIImgDefaultShirtUUID") ); | ||
7572 | case TEX_LOWER_PANTS: return LLUUID( gSavedSettings.getString("UIImgDefaultPantsUUID") ); | ||
7573 | case TEX_EYES_IRIS: return LLUUID( gSavedSettings.getString("UIImgDefaultEyesUUID") ); | ||
7574 | case TEX_HAIR: return LLUUID( gSavedSettings.getString("UIImgDefaultHairUUID") ); | ||
7575 | case TEX_LOWER_SHOES: return LLUUID( gSavedSettings.getString("UIImgDefaultShoesUUID") ); | ||
7576 | case TEX_LOWER_SOCKS: return LLUUID( gSavedSettings.getString("UIImgDefaultSocksUUID") ); | ||
7577 | case TEX_UPPER_GLOVES: return LLUUID( gSavedSettings.getString("UIImgDefaultGlovesUUID") ); | ||
7578 | |||
7579 | case TEX_UPPER_JACKET: | ||
7580 | case TEX_LOWER_JACKET: return LLUUID( gSavedSettings.getString("UIImgDefaultJacketUUID") ); | ||
7581 | |||
7582 | case TEX_UPPER_UNDERSHIRT: | ||
7583 | case TEX_LOWER_UNDERPANTS: return LLUUID( gSavedSettings.getString("UIImgDefaultUnderwearUUID") ); | ||
7584 | |||
7585 | case TEX_SKIRT: return LLUUID( gSavedSettings.getString("UIImgDefaultSkirtUUID") ); | ||
7586 | |||
7587 | default: return IMG_DEFAULT_AVATAR; | ||
7588 | } | ||
7589 | } | ||
7590 | |||
7591 | |||
7592 | |||
7593 | // Given a texture entry, determine which wearable type owns it. | ||
7594 | // static | ||
7595 | EWearableType LLVOAvatar::getTEWearableType( S32 te ) | ||
7596 | { | ||
7597 | switch( te ) | ||
7598 | { | ||
7599 | case TEX_UPPER_SHIRT: | ||
7600 | return WT_SHIRT; | ||
7601 | |||
7602 | case TEX_LOWER_PANTS: | ||
7603 | return WT_PANTS; | ||
7604 | |||
7605 | case TEX_EYES_IRIS: | ||
7606 | return WT_EYES; | ||
7607 | |||
7608 | case TEX_HAIR: | ||
7609 | return WT_HAIR; | ||
7610 | |||
7611 | case TEX_HEAD_BODYPAINT: | ||
7612 | case TEX_UPPER_BODYPAINT: | ||
7613 | case TEX_LOWER_BODYPAINT: | ||
7614 | return WT_SKIN; | ||
7615 | |||
7616 | case TEX_LOWER_SHOES: | ||
7617 | return WT_SHOES; | ||
7618 | |||
7619 | case TEX_LOWER_SOCKS: | ||
7620 | return WT_SOCKS; | ||
7621 | |||
7622 | case TEX_UPPER_JACKET: | ||
7623 | case TEX_LOWER_JACKET: | ||
7624 | return WT_JACKET; | ||
7625 | |||
7626 | case TEX_UPPER_GLOVES: | ||
7627 | return WT_GLOVES; | ||
7628 | |||
7629 | case TEX_UPPER_UNDERSHIRT: | ||
7630 | return WT_UNDERSHIRT; | ||
7631 | |||
7632 | case TEX_LOWER_UNDERPANTS: | ||
7633 | return WT_UNDERPANTS; | ||
7634 | |||
7635 | case TEX_SKIRT: | ||
7636 | return WT_SKIRT; | ||
7637 | |||
7638 | default: | ||
7639 | return WT_INVALID; | ||
7640 | } | ||
7641 | } | ||
7642 | |||
7643 | // Unlike most wearable functions, this works for both self and other. | ||
7644 | BOOL LLVOAvatar::isWearingWearableType( EWearableType type ) | ||
7645 | { | ||
7646 | if (mIsDummy) return TRUE; | ||
7647 | |||
7648 | ETextureIndex indicator_te; | ||
7649 | switch( type ) | ||
7650 | { | ||
7651 | case WT_SHIRT: | ||
7652 | indicator_te = TEX_UPPER_SHIRT; | ||
7653 | break; | ||
7654 | |||
7655 | case WT_PANTS: | ||
7656 | indicator_te = TEX_LOWER_PANTS; | ||
7657 | break; | ||
7658 | |||
7659 | case WT_SHOES: | ||
7660 | indicator_te = TEX_LOWER_SHOES; | ||
7661 | break; | ||
7662 | |||
7663 | case WT_SOCKS: | ||
7664 | indicator_te = TEX_LOWER_SOCKS; | ||
7665 | break; | ||
7666 | |||
7667 | case WT_JACKET: | ||
7668 | indicator_te = TEX_UPPER_JACKET; | ||
7669 | // Note: no need to test both upper and lower jacket | ||
7670 | break; | ||
7671 | |||
7672 | case WT_GLOVES: | ||
7673 | indicator_te = TEX_UPPER_GLOVES; | ||
7674 | break; | ||
7675 | |||
7676 | case WT_UNDERSHIRT: | ||
7677 | indicator_te = TEX_UPPER_UNDERSHIRT; | ||
7678 | break; | ||
7679 | |||
7680 | case WT_UNDERPANTS: | ||
7681 | indicator_te = TEX_LOWER_UNDERPANTS; | ||
7682 | break; | ||
7683 | |||
7684 | case WT_SKIRT: | ||
7685 | indicator_te = TEX_SKIRT; | ||
7686 | break; | ||
7687 | |||
7688 | case WT_SHAPE: | ||
7689 | case WT_SKIN: | ||
7690 | case WT_HAIR: | ||
7691 | case WT_EYES: | ||
7692 | return TRUE; // everyone has all bodyparts | ||
7693 | |||
7694 | default: | ||
7695 | return FALSE; | ||
7696 | } | ||
7697 | |||
7698 | return ( getTEImage(indicator_te)->getID() != IMG_DEFAULT_AVATAR ); | ||
7699 | } | ||
7700 | |||
7701 | |||
7702 | //----------------------------------------------------------------------------- | ||
7703 | // clampAttachmentPositions() | ||
7704 | //----------------------------------------------------------------------------- | ||
7705 | void LLVOAvatar::clampAttachmentPositions() | ||
7706 | { | ||
7707 | if (isDead()) return; | ||
7708 | for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData(); | ||
7709 | attachment; | ||
7710 | attachment = mAttachmentPoints.getNextData()) | ||
7711 | { | ||
7712 | if (attachment) | ||
7713 | { | ||
7714 | attachment->clampObjectPosition(); | ||
7715 | } | ||
7716 | } | ||
7717 | } | ||
7718 | |||
7719 | BOOL LLVOAvatar::hasHUDAttachment() | ||
7720 | { | ||
7721 | for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData(); | ||
7722 | attachment; | ||
7723 | attachment = mAttachmentPoints.getNextData()) | ||
7724 | { | ||
7725 | if (attachment->getIsHUDAttachment() && attachment->getObject(0)) | ||
7726 | { | ||
7727 | return TRUE; | ||
7728 | } | ||
7729 | } | ||
7730 | return FALSE; | ||
7731 | } | ||
7732 | |||
7733 | LLBBox LLVOAvatar::getHUDBBox() | ||
7734 | { | ||
7735 | LLBBox bbox; | ||
7736 | for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData(); | ||
7737 | attachment; | ||
7738 | attachment = mAttachmentPoints.getNextData()) | ||
7739 | { | ||
7740 | if (attachment->getIsHUDAttachment() && attachment->getObject(0)) | ||
7741 | { | ||
7742 | LLViewerObject* hud_object = attachment->getObject(0); | ||
7743 | |||
7744 | // initialize bounding box to contain identity orientation and center point for attached object | ||
7745 | bbox.addPointLocal(hud_object->getPosition()); | ||
7746 | // add rotated bounding box for attached object | ||
7747 | bbox.addBBoxAgent(hud_object->getBoundingBoxAgent()); | ||
7748 | for (U32 i = 0; i < hud_object->mChildList.size(); i++) | ||
7749 | { | ||
7750 | bbox.addBBoxAgent(hud_object->mChildList[i]->getBoundingBoxAgent()); | ||
7751 | } | ||
7752 | } | ||
7753 | } | ||
7754 | |||
7755 | return bbox; | ||
7756 | } | ||
7757 | |||
7758 | void LLVOAvatar::rebuildHUD() | ||
7759 | { | ||
7760 | if (!mIsSelf) | ||
7761 | { | ||
7762 | return; | ||
7763 | } | ||
7764 | |||
7765 | for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData(); | ||
7766 | attachment; | ||
7767 | attachment = mAttachmentPoints.getNextData()) | ||
7768 | { | ||
7769 | if (attachment->getIsHUDAttachment() && attachment->getObject(0)) | ||
7770 | { | ||
7771 | LLViewerObject* hud_object = attachment->getObject(0); | ||
7772 | LLDrawable* hud_drawable = hud_object->mDrawable; | ||
7773 | |||
7774 | if (hud_drawable) | ||
7775 | { | ||
7776 | // this assumes that an AGP sync will happen because face has been backlisted, | ||
7777 | // so that pool has been rebuilt this frame and is scheduled for a sync | ||
7778 | for(S32 face_index = 0; face_index < hud_drawable->getNumFaces(); ++face_index) | ||
7779 | { | ||
7780 | LLFace* facep = hud_drawable->getFace(face_index); | ||
7781 | if (facep->isState(LLFace::BACKLIST)) | ||
7782 | { | ||
7783 | facep->restore(); | ||
7784 | } | ||
7785 | } | ||
7786 | } | ||
7787 | for (U32 child_num = 0; child_num < hud_object->mChildList.size(); ++child_num) | ||
7788 | { | ||
7789 | LLViewerObject* childp = hud_object->mChildList[child_num]; | ||
7790 | LLDrawable* child_drawable = childp->mDrawable; | ||
7791 | |||
7792 | if (child_drawable) | ||
7793 | { | ||
7794 | for(S32 face_index = 0; face_index < child_drawable->getNumFaces(); ++face_index) | ||
7795 | { | ||
7796 | LLFace* facep = child_drawable->getFace(face_index); | ||
7797 | if (facep->isState(LLFace::BACKLIST)) | ||
7798 | { | ||
7799 | facep->restore(); | ||
7800 | } | ||
7801 | } | ||
7802 | } | ||
7803 | } | ||
7804 | } | ||
7805 | } | ||
7806 | } | ||
7807 | |||
7808 | //----------------------------------------------------------------------------- | ||
7809 | // onFirstTEMessageReceived() | ||
7810 | //----------------------------------------------------------------------------- | ||
7811 | void LLVOAvatar::onFirstTEMessageReceived() | ||
7812 | { | ||
7813 | if( !mFirstTEMessageReceived ) | ||
7814 | { | ||
7815 | mFirstTEMessageReceived = TRUE; | ||
7816 | |||
7817 | BOOL head_baked = ( getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
7818 | BOOL upper_baked = ( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
7819 | BOOL lower_baked = ( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
7820 | BOOL eyes_baked = ( getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
7821 | BOOL skirt_baked = ( getTEImage( TEX_SKIRT_BAKED )->getID() != IMG_DEFAULT_AVATAR ); | ||
7822 | |||
7823 | // Use any baked textures that we have even if they haven't downloaded yet. | ||
7824 | // (That is, don't do a transition from unbaked to baked.) | ||
7825 | if( head_baked ) | ||
7826 | { | ||
7827 | mLastHeadBakedID = getTEImage( TEX_HEAD_BAKED )->getID(); | ||
7828 | LLViewerImage* image = getTEImage( TEX_HEAD_BAKED ); | ||
7829 | image->setNeedsAux(TRUE); | ||
7830 | image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID )); | ||
7831 | image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) ); | ||
7832 | } | ||
7833 | |||
7834 | if( upper_baked ) | ||
7835 | { | ||
7836 | mLastUpperBodyBakedID = getTEImage( TEX_UPPER_BAKED )->getID(); | ||
7837 | LLViewerImage* image = getTEImage( TEX_UPPER_BAKED ); | ||
7838 | image->setNeedsAux(TRUE); | ||
7839 | image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID )); | ||
7840 | image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) ); | ||
7841 | } | ||
7842 | |||
7843 | if( lower_baked ) | ||
7844 | { | ||
7845 | mLastLowerBodyBakedID = getTEImage( TEX_LOWER_BAKED )->getID(); | ||
7846 | LLViewerImage* image = getTEImage( TEX_LOWER_BAKED ); | ||
7847 | image->setNeedsAux(TRUE); | ||
7848 | image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, new LLTextureMaskData( mID )); | ||
7849 | image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) ); | ||
7850 | } | ||
7851 | |||
7852 | if( eyes_baked ) | ||
7853 | { | ||
7854 | mLastEyesBakedID = getTEImage( TEX_EYES_BAKED )->getID(); | ||
7855 | LLViewerImage* image = getTEImage( TEX_EYES_BAKED ); | ||
7856 | image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) ); | ||
7857 | } | ||
7858 | |||
7859 | if( skirt_baked ) | ||
7860 | { | ||
7861 | mLastSkirtBakedID = getTEImage( TEX_SKIRT_BAKED )->getID(); | ||
7862 | LLViewerImage* image = getTEImage( TEX_SKIRT_BAKED ); | ||
7863 | image->setLoadedCallback( onInitialBakedTextureLoaded, MAX_DISCARD_LEVEL, FALSE, new LLUUID( mID ) ); | ||
7864 | } | ||
7865 | |||
7866 | updateMeshTextures(); | ||
7867 | } | ||
7868 | } | ||
7869 | |||
7870 | //----------------------------------------------------------------------------- | ||
7871 | // processAvatarAppearance() | ||
7872 | //----------------------------------------------------------------------------- | ||
7873 | void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys ) | ||
7874 | { | ||
7875 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
7876 | |||
7877 | // llinfos << "processAvatarAppearance start " << mID << llendl; | ||
7878 | BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived; | ||
7879 | |||
7880 | mFirstAppearanceMessageReceived = TRUE; | ||
7881 | |||
7882 | if( mIsSelf ) | ||
7883 | { | ||
7884 | llwarns << "Received AvatarAppearance for self" << llendl; | ||
7885 | if( mFirstTEMessageReceived ) | ||
7886 | { | ||
7887 | // llinfos << "processAvatarAppearance end " << mID << llendl; | ||
7888 | return; | ||
7889 | } | ||
7890 | } | ||
7891 | |||
7892 | if (gNoRender) | ||
7893 | { | ||
7894 | return; | ||
7895 | } | ||
7896 | |||
7897 | ESex old_sex = getSex(); | ||
7898 | |||
7899 | // llinfos << "ady LLVOAvatar::processAvatarAppearance()" << llendl; | ||
7900 | // dumpAvatarTEs( "PRE processAvatarAppearance()" ); | ||
7901 | unpackTEMessage(mesgsys, _PREHASH_ObjectData); | ||
7902 | // dumpAvatarTEs( "POST processAvatarAppearance()" ); | ||
7903 | |||
7904 | // llinfos << "Received AvatarAppearance: " << (mIsSelf ? "(self): " : "(other): " ) << | ||
7905 | // (( getTEImage( TEX_HEAD_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "HEAD " : "head " ) << | ||
7906 | // (( getTEImage( TEX_UPPER_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "UPPER " : "upper " ) << | ||
7907 | // (( getTEImage( TEX_LOWER_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "LOWER " : "lower " ) << | ||
7908 | // (( getTEImage( TEX_EYES_BAKED )->getID() != IMG_DEFAULT_AVATAR ) ? "EYES" : "eyes" ) << llendl; | ||
7909 | |||
7910 | if( !mFirstTEMessageReceived ) | ||
7911 | { | ||
7912 | onFirstTEMessageReceived(); | ||
7913 | } | ||
7914 | |||
7915 | setCompositeUpdatesEnabled( FALSE ); | ||
7916 | updateMeshTextures(); // enables updates for laysets without baked textures. | ||
7917 | |||
7918 | // parse visual params | ||
7919 | S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam); | ||
7920 | if( num_blocks > 1 ) | ||
7921 | { | ||
7922 | BOOL params_changed = FALSE; | ||
7923 | BOOL interp_params = FALSE; | ||
7924 | |||
7925 | LLVisualParam* param = getFirstVisualParam(); | ||
7926 | if (!param) | ||
7927 | { | ||
7928 | llwarns << "No visual params!" << llendl; | ||
7929 | } | ||
7930 | else | ||
7931 | { | ||
7932 | for( S32 i = 0; i < num_blocks; i++ ) | ||
7933 | { | ||
7934 | while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) | ||
7935 | { | ||
7936 | param = getNextVisualParam(); | ||
7937 | } | ||
7938 | |||
7939 | if( !param ) | ||
7940 | { | ||
7941 | llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file." << llendl; | ||
7942 | return; | ||
7943 | } | ||
7944 | |||
7945 | U8 value; | ||
7946 | mesgsys->getU8Fast(_PREHASH_VisualParam, _PREHASH_ParamValue, value, i); | ||
7947 | F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight()); | ||
7948 | |||
7949 | if (is_first_appearance_message || (param->getWeight() != newWeight)) | ||
7950 | { | ||
7951 | //llinfos << "Received update for param " << param->getDisplayName() << " at value " << newWeight << llendl; | ||
7952 | params_changed = TRUE; | ||
7953 | if(is_first_appearance_message) | ||
7954 | { | ||
7955 | param->setWeight(newWeight, FALSE); | ||
7956 | } | ||
7957 | else | ||
7958 | { | ||
7959 | interp_params = TRUE; | ||
7960 | param->setAnimationTarget(newWeight, FALSE); | ||
7961 | } | ||
7962 | } | ||
7963 | |||
7964 | param = getNextVisualParam(); | ||
7965 | } | ||
7966 | } | ||
7967 | |||
7968 | while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) | ||
7969 | { | ||
7970 | param = getNextVisualParam(); | ||
7971 | } | ||
7972 | if( param ) | ||
7973 | { | ||
7974 | llwarns << "Number of params in AvatarAppearance msg does not match number of params in avatar xml file." << llendl; | ||
7975 | return; | ||
7976 | } | ||
7977 | |||
7978 | if (params_changed) | ||
7979 | { | ||
7980 | if (interp_params) | ||
7981 | { | ||
7982 | startAppearanceAnimation(FALSE, FALSE); | ||
7983 | } | ||
7984 | updateVisualParams(); | ||
7985 | |||
7986 | ESex new_sex = getSex(); | ||
7987 | if( old_sex != new_sex ) | ||
7988 | { | ||
7989 | updateSexDependentLayerSets( FALSE ); | ||
7990 | } | ||
7991 | } | ||
7992 | } | ||
7993 | else | ||
7994 | { | ||
7995 | llwarns << "AvatarAppearance msg received without any parameters" << llendl; | ||
7996 | } | ||
7997 | |||
7998 | setCompositeUpdatesEnabled( TRUE ); | ||
7999 | |||
8000 | llassert( getSex() == ((getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE) ); | ||
8001 | |||
8002 | // If all of the avatars are completely baked, release the global image caches to conserve memory. | ||
8003 | LLVOAvatar::cullAvatarsByPixelArea(); | ||
8004 | |||
8005 | // llinfos << "processAvatarAppearance end " << mID << llendl; | ||
8006 | } | ||
8007 | |||
8008 | // static | ||
8009 | void LLVOAvatar::getAnimLabels( LLDynamicArray<const char*>* labels ) | ||
8010 | { | ||
8011 | S32 i; | ||
8012 | for( i = 0; i < gUserAnimStatesCount; i++ ) | ||
8013 | { | ||
8014 | labels->put( gUserAnimStates[i].mLabel ); | ||
8015 | } | ||
8016 | |||
8017 | // Special case to trigger away (AFK) state | ||
8018 | labels->put( "Away From Keyboard" ); | ||
8019 | } | ||
8020 | |||
8021 | // static | ||
8022 | void LLVOAvatar::getAnimNames( LLDynamicArray<const char*>* names ) | ||
8023 | { | ||
8024 | S32 i; | ||
8025 | |||
8026 | for( i = 0; i < gUserAnimStatesCount; i++ ) | ||
8027 | { | ||
8028 | names->put( gUserAnimStates[i].mName ); | ||
8029 | } | ||
8030 | |||
8031 | // Special case to trigger away (AFK) state | ||
8032 | names->put( "enter_away_from_keyboard_state" ); | ||
8033 | } | ||
8034 | |||
8035 | void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) | ||
8036 | { | ||
8037 | //llinfos << "onBakedTextureMasksLoaded: " << src_vi->getID() << llendl; | ||
8038 | LLMemType mt(LLMemType::MTYPE_AVATAR); | ||
8039 | |||
8040 | LLUUID id = src_vi->getID(); | ||
8041 | |||
8042 | if (!userdata) | ||
8043 | { | ||
8044 | return; | ||
8045 | } | ||
8046 | |||
8047 | LLTextureMaskData* maskData = (LLTextureMaskData*) userdata; | ||
8048 | LLVOAvatar* self = (LLVOAvatar*) gObjectList.findObject( maskData->mAvatarID ); | ||
8049 | |||
8050 | // if discard level is 2 less than last discard level we processed, or we hit 0, | ||
8051 | // then generate morph masks | ||
8052 | if( self && success && (discard_level < maskData->mLastDiscardLevel - 2 || discard_level == 0) ) | ||
8053 | { | ||
8054 | LLViewerImage* head_baked = self->getTEImage( TEX_HEAD_BAKED ); | ||
8055 | LLViewerImage* upper_baked = self->getTEImage( TEX_UPPER_BAKED ); | ||
8056 | LLViewerImage* lower_baked = self->getTEImage( TEX_LOWER_BAKED ); | ||
8057 | |||
8058 | if( aux_src && aux_src->getComponents() == 1 ) | ||
8059 | { | ||
8060 | if (!aux_src->getData()) | ||
8061 | { | ||
8062 | llwarns << "No auxiliary source data for onBakedTextureMasksLoaded" << llendl; | ||
8063 | src_vi->startImageDecode(); | ||
8064 | return; | ||
8065 | } | ||
8066 | |||
8067 | U32 gl_name; | ||
8068 | glGenTextures(1, (GLuint*) &gl_name ); | ||
8069 | stop_glerror(); | ||
8070 | |||
8071 | LLImageGL::bindExternalTexture( gl_name, 0, GL_TEXTURE_2D ); | ||
8072 | stop_glerror(); | ||
8073 | |||
8074 | glTexImage2D( | ||
8075 | GL_TEXTURE_2D, 0, GL_ALPHA8, | ||
8076 | aux_src->getWidth(), aux_src->getHeight(), | ||
8077 | 0, GL_ALPHA, GL_UNSIGNED_BYTE, aux_src->getData()); | ||
8078 | stop_glerror(); | ||
8079 | |||
8080 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); | ||
8081 | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); | ||
8082 | |||
8083 | if( id == head_baked->getID() ) | ||
8084 | { | ||
8085 | if (self->mHeadLayerSet) | ||
8086 | { | ||
8087 | //llinfos << "onBakedTextureMasksLoaded for head " << id << " discard = " << discard_level << llendl; | ||
8088 | self->mHeadLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1); | ||
8089 | maskData->mLastDiscardLevel = discard_level; | ||
8090 | self->mHeadMaskDiscard = discard_level; | ||
8091 | if (self->mHeadMaskTexName) | ||
8092 | { | ||
8093 | glDeleteTextures(1, (GLuint*) &self->mHeadMaskTexName); | ||
8094 | } | ||
8095 | self->mHeadMaskTexName = gl_name; | ||
8096 | } | ||
8097 | else | ||
8098 | { | ||
8099 | llwarns << "onBakedTextureMasksLoaded: no mHeadLayerSet." << llendl; | ||
8100 | } | ||
8101 | } | ||
8102 | else | ||
8103 | if( id == upper_baked->getID() ) | ||
8104 | { | ||
8105 | if ( self->mUpperBodyLayerSet) | ||
8106 | { | ||
8107 | //llinfos << "onBakedTextureMasksLoaded for upper body " << id << " discard = " << discard_level << llendl; | ||
8108 | self->mUpperBodyLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1); | ||
8109 | maskData->mLastDiscardLevel = discard_level; | ||
8110 | self->mUpperMaskDiscard = discard_level; | ||
8111 | if (self->mUpperMaskTexName) | ||
8112 | { | ||
8113 | glDeleteTextures(1, (GLuint*) &self->mUpperMaskTexName); | ||
8114 | } | ||
8115 | self->mUpperMaskTexName = gl_name; | ||
8116 | } | ||
8117 | else | ||
8118 | { | ||
8119 | llwarns << "onBakedTextureMasksLoaded: no mHeadLayerSet." << llendl; | ||
8120 | } | ||
8121 | } | ||
8122 | else | ||
8123 | if( id == lower_baked->getID() ) | ||
8124 | { | ||
8125 | if ( self->mLowerBodyLayerSet ) | ||
8126 | { | ||
8127 | //llinfos << "onBakedTextureMasksLoaded for lower body " << id << " discard = " << discard_level << llendl; | ||
8128 | self->mLowerBodyLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1); | ||
8129 | maskData->mLastDiscardLevel = discard_level; | ||
8130 | self->mLowerMaskDiscard = discard_level; | ||
8131 | if (self->mLowerMaskTexName) | ||
8132 | { | ||
8133 | glDeleteTextures(1, (GLuint*) &self->mLowerMaskTexName); | ||
8134 | } | ||
8135 | self->mLowerMaskTexName = gl_name; | ||
8136 | } | ||
8137 | else | ||
8138 | { | ||
8139 | llwarns << "onBakedTextureMasksLoaded: no mHeadLayerSet." << llendl; | ||
8140 | } | ||
8141 | } | ||
8142 | else | ||
8143 | { | ||
8144 | llinfos << "onBakedTextureMasksLoaded(): unexpected image id: " << id << llendl; | ||
8145 | } | ||
8146 | |||
8147 | self->dirtyMesh(); | ||
8148 | } | ||
8149 | else | ||
8150 | { | ||
8151 | // this can happen when someone uses an old baked texture possibly provided by | ||
8152 | // viewer-side baked texture caching | ||
8153 | llwarns << "Masks loaded callback but NO aux source!" << llendl; | ||
8154 | } | ||
8155 | } | ||
8156 | |||
8157 | if (final || !success) | ||
8158 | { | ||
8159 | delete maskData; | ||
8160 | } | ||
8161 | |||
8162 | } | ||
8163 | |||
8164 | // static | ||
8165 | void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata ) | ||
8166 | { | ||
8167 | LLUUID *avatar_idp = (LLUUID *)userdata; | ||
8168 | LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); | ||
8169 | |||
8170 | if (!success && selfp) | ||
8171 | { | ||
8172 | selfp->removeMissingBakedTextures(); | ||
8173 | } | ||
8174 | if (final || !success ) | ||
8175 | { | ||
8176 | delete avatar_idp; | ||
8177 | } | ||
8178 | } | ||
8179 | |||
8180 | void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerImage *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata) | ||
8181 | { | ||
8182 | //llinfos << "onBakedTextureLoaded: " << src_vi->getID() << llendl; | ||
8183 | |||
8184 | LLUUID id = src_vi->getID(); | ||
8185 | LLUUID *avatar_idp = (LLUUID *)userdata; | ||
8186 | LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp); | ||
8187 | |||
8188 | if (selfp && !success) | ||
8189 | { | ||
8190 | selfp->removeMissingBakedTextures(); | ||
8191 | } | ||
8192 | |||
8193 | if( final || !success ) | ||
8194 | { | ||
8195 | delete avatar_idp; | ||
8196 | } | ||
8197 | |||
8198 | if( selfp && success && final ) | ||
8199 | { | ||
8200 | selfp->useBakedTexture( id ); | ||
8201 | } | ||
8202 | } | ||
8203 | |||
8204 | |||
8205 | // Called when baked texture is loaded and also when we start up with a baked texture | ||
8206 | void LLVOAvatar::useBakedTexture( const LLUUID& id ) | ||
8207 | { | ||
8208 | // llinfos << "useBakedTexture" << llendl; | ||
8209 | LLViewerImage* head_baked = getTEImage( TEX_HEAD_BAKED ); | ||
8210 | LLViewerImage* upper_baked = getTEImage( TEX_UPPER_BAKED ); | ||
8211 | LLViewerImage* lower_baked = getTEImage( TEX_LOWER_BAKED ); | ||
8212 | LLViewerImage* eyes_baked = getTEImage( TEX_EYES_BAKED ); | ||
8213 | LLViewerImage* skirt_baked = getTEImage( TEX_SKIRT_BAKED ); | ||
8214 | |||
8215 | if( id == head_baked->getID() ) | ||
8216 | { | ||
8217 | mHeadBakedLoaded = TRUE; | ||
8218 | |||
8219 | mLastHeadBakedID = id; | ||
8220 | mHeadMesh0.setTexture( head_baked ); | ||
8221 | mHeadMesh1.setTexture( head_baked ); | ||
8222 | mHeadMesh2.setTexture( head_baked ); | ||
8223 | mHeadMesh3.setTexture( head_baked ); | ||
8224 | mHeadMesh4.setTexture( head_baked ); | ||
8225 | mEyeLashMesh0.setTexture( head_baked ); | ||
8226 | if( mHeadLayerSet ) | ||
8227 | { | ||
8228 | mHeadLayerSet->destroyComposite(); | ||
8229 | } | ||
8230 | setLocalTexture( LOCTEX_HEAD_BODYPAINT, getTEImage( TEX_HEAD_BODYPAINT ), TRUE ); | ||
8231 | } | ||
8232 | else | ||
8233 | if( id == upper_baked->getID() ) | ||
8234 | { | ||
8235 | mUpperBakedLoaded = TRUE; | ||
8236 | |||
8237 | mLastUpperBodyBakedID = id; | ||
8238 | mUpperBodyMesh0.setTexture( upper_baked ); | ||
8239 | mUpperBodyMesh1.setTexture( upper_baked ); | ||
8240 | mUpperBodyMesh2.setTexture( upper_baked ); | ||
8241 | mUpperBodyMesh3.setTexture( upper_baked ); | ||
8242 | mUpperBodyMesh4.setTexture( upper_baked ); | ||
8243 | if( mUpperBodyLayerSet ) | ||
8244 | { | ||
8245 | mUpperBodyLayerSet->destroyComposite(); | ||
8246 | } | ||
8247 | |||
8248 | setLocalTexture( LOCTEX_UPPER_SHIRT, getTEImage( TEX_UPPER_SHIRT ), TRUE ); | ||
8249 | setLocalTexture( LOCTEX_UPPER_BODYPAINT, getTEImage( TEX_UPPER_BODYPAINT ), TRUE ); | ||
8250 | setLocalTexture( LOCTEX_UPPER_JACKET, getTEImage( TEX_UPPER_JACKET ), TRUE ); | ||
8251 | setLocalTexture( LOCTEX_UPPER_GLOVES, getTEImage( TEX_UPPER_GLOVES ), TRUE ); | ||
8252 | setLocalTexture( LOCTEX_UPPER_UNDERSHIRT, getTEImage( TEX_UPPER_UNDERSHIRT ), TRUE ); | ||
8253 | } | ||
8254 | else | ||
8255 | if( id == lower_baked->getID() ) | ||
8256 | { | ||
8257 | mLowerBakedLoaded = TRUE; | ||
8258 | |||
8259 | mLastLowerBodyBakedID = id; | ||
8260 | mLowerBodyMesh0.setTexture( lower_baked ); | ||
8261 | mLowerBodyMesh1.setTexture( lower_baked ); | ||
8262 | mLowerBodyMesh2.setTexture( lower_baked ); | ||
8263 | mLowerBodyMesh3.setTexture( lower_baked ); | ||
8264 | mLowerBodyMesh4.setTexture( lower_baked ); | ||
8265 | if( mLowerBodyLayerSet ) | ||
8266 | { | ||
8267 | mLowerBodyLayerSet->destroyComposite(); | ||
8268 | } | ||
8269 | |||
8270 | setLocalTexture( LOCTEX_LOWER_PANTS, getTEImage( TEX_LOWER_PANTS ), TRUE ); | ||
8271 | setLocalTexture( LOCTEX_LOWER_BODYPAINT, getTEImage( TEX_LOWER_BODYPAINT ), TRUE ); | ||
8272 | setLocalTexture( LOCTEX_LOWER_SHOES, getTEImage( TEX_LOWER_SHOES ), TRUE ); | ||
8273 | setLocalTexture( LOCTEX_LOWER_SOCKS, getTEImage( TEX_LOWER_SOCKS ), TRUE ); | ||
8274 | setLocalTexture( LOCTEX_LOWER_JACKET, getTEImage( TEX_LOWER_JACKET ), TRUE ); | ||
8275 | setLocalTexture( LOCTEX_LOWER_UNDERPANTS, getTEImage( TEX_LOWER_UNDERPANTS ), TRUE ); | ||
8276 | } | ||
8277 | else | ||
8278 | if( id == eyes_baked->getID() ) | ||
8279 | { | ||
8280 | mEyesBakedLoaded = TRUE; | ||
8281 | |||
8282 | mLastEyesBakedID = id; | ||
8283 | mEyeBallLeftMesh0.setTexture( eyes_baked ); | ||
8284 | mEyeBallLeftMesh1.setTexture( eyes_baked ); | ||
8285 | mEyeBallRightMesh0.setTexture( eyes_baked ); | ||
8286 | mEyeBallRightMesh1.setTexture( eyes_baked ); | ||
8287 | if( mEyesLayerSet ) | ||
8288 | { | ||
8289 | mEyesLayerSet->destroyComposite(); | ||
8290 | } | ||
8291 | |||
8292 | setLocalTexture( LOCTEX_EYES_IRIS, getTEImage( TEX_EYES_IRIS ), TRUE ); | ||
8293 | } | ||
8294 | else | ||
8295 | if( id == skirt_baked->getID() ) | ||
8296 | { | ||
8297 | mSkirtBakedLoaded = TRUE; | ||
8298 | |||
8299 | mLastSkirtBakedID = id; | ||
8300 | mSkirtMesh0.setTexture( skirt_baked ); | ||
8301 | mSkirtMesh1.setTexture( skirt_baked ); | ||
8302 | mSkirtMesh2.setTexture( skirt_baked ); | ||
8303 | mSkirtMesh3.setTexture( skirt_baked ); | ||
8304 | mSkirtMesh4.setTexture( skirt_baked ); | ||
8305 | if( mSkirtLayerSet ) | ||
8306 | { | ||
8307 | mSkirtLayerSet->destroyComposite(); | ||
8308 | } | ||
8309 | |||
8310 | setLocalTexture( LOCTEX_SKIRT, getTEImage( TEX_SKIRT ), TRUE ); | ||
8311 | } | ||
8312 | |||
8313 | dirtyMesh(); | ||
8314 | } | ||
8315 | |||
8316 | // static | ||
8317 | void LLVOAvatar::dumpArchetypeXML( void* ) | ||
8318 | { | ||
8319 | LLVOAvatar* avatar = gAgent.getAvatarObject(); | ||
8320 | apr_file_t* file = ll_apr_file_open(gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"new archetype.xml"), LL_APR_WB ); | ||
8321 | if( !file ) | ||
8322 | { | ||
8323 | return; | ||
8324 | } | ||
8325 | |||
8326 | apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" ); | ||
8327 | apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" ); | ||
8328 | apr_file_printf( file, "\n\t<archetype name=\"???\">\n" ); | ||
8329 | |||
8330 | // only body parts, not clothing. | ||
8331 | for( S32 type = WT_SHAPE; type <= WT_EYES; type++ ) | ||
8332 | { | ||
8333 | const char* wearable_name = LLWearable::typeToTypeName( (EWearableType) type ); | ||
8334 | apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name ); | ||
8335 | |||
8336 | for( LLVisualParam* param = avatar->getFirstVisualParam(); param; param = avatar->getNextVisualParam() ) | ||
8337 | { | ||
8338 | LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param; | ||
8339 | if( (viewer_param->getWearableType() == type) && | ||
8340 | (viewer_param->getGroup() == VISUAL_PARAM_GROUP_TWEAKABLE) ) | ||
8341 | { | ||
8342 | apr_file_printf( file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\"/>\n", | ||
8343 | viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getWeight() ); | ||
8344 | } | ||
8345 | } | ||
8346 | |||
8347 | for( S32 te = 0; te < TEX_NUM_ENTRIES; te++ ) | ||
8348 | { | ||
8349 | if( LLVOAvatar::getTEWearableType( te ) == type ) | ||
8350 | { | ||
8351 | LLViewerImage* te_image = avatar->getTEImage( te ); | ||
8352 | if( te_image ) | ||
8353 | { | ||
8354 | char uuid_str[UUID_STR_LENGTH]; | ||
8355 | te_image->getID().toString( uuid_str ); | ||
8356 | apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str); | ||
8357 | } | ||
8358 | } | ||
8359 | } | ||
8360 | } | ||
8361 | apr_file_printf( file, "\t</archetype>\n" ); | ||
8362 | apr_file_printf( file, "\n</linden_genepool>\n" ); | ||
8363 | apr_file_close( file ); | ||
8364 | } | ||
8365 | |||
8366 | |||
8367 | // Assumes LLVOAvatar::sInstances has already been sorted. | ||
8368 | S32 LLVOAvatar::getUnbakedPixelAreaRank() | ||
8369 | { | ||
8370 | S32 rank = 1; | ||
8371 | for( LLVOAvatar* inst = (LLVOAvatar*)LLCharacter::sInstances.getFirstData(); | ||
8372 | inst; | ||
8373 | inst = (LLVOAvatar*)LLCharacter::sInstances.getNextData() ) | ||
8374 | { | ||
8375 | if( inst == this ) | ||
8376 | { | ||
8377 | return rank; | ||
8378 | } | ||
8379 | else | ||
8380 | if( !inst->isDead() && !inst->isFullyBaked() ) | ||
8381 | { | ||
8382 | rank++; | ||
8383 | } | ||
8384 | } | ||
8385 | |||
8386 | llassert(0); | ||
8387 | return 0; | ||
8388 | } | ||
8389 | |||
8390 | // static | ||
8391 | void LLVOAvatar::cullAvatarsByPixelArea() | ||
8392 | { | ||
8393 | LLVOAvatar::sInstances.bubbleSortList(); | ||
8394 | |||
8395 | |||
8396 | // Update the avatars that have changed status | ||
8397 | S32 rank = 1; | ||
8398 | |||
8399 | for( LLVOAvatar* inst = (LLVOAvatar*)LLCharacter::sInstances.getFirstData(); | ||
8400 | inst; | ||
8401 | inst = (LLVOAvatar*)LLCharacter::sInstances.getNextData() ) | ||
8402 | { | ||
8403 | BOOL culled; | ||
8404 | if( inst->isDead() ) | ||
8405 | { | ||
8406 | culled = TRUE; | ||
8407 | } | ||
8408 | else if( inst->isSelf() || inst->isFullyBaked() ) | ||
8409 | { | ||
8410 | culled = FALSE; | ||
8411 | } | ||
8412 | else | ||
8413 | { | ||
8414 | culled = (rank > LLVOAvatar::sMaxOtherAvatarsToComposite) || (inst->mPixelArea < MIN_PIXEL_AREA_FOR_COMPOSITE); | ||
8415 | rank++; | ||
8416 | } | ||
8417 | |||
8418 | if( inst->mCulled != culled ) | ||
8419 | { | ||
8420 | inst->mCulled = culled; | ||
8421 | |||
8422 | lldebugs << "avatar " << inst->getID() << (culled ? " start culled" : " start not culled" ) << llendl; | ||
8423 | |||
8424 | inst->updateMeshTextures(); | ||
8425 | } | ||
8426 | } | ||
8427 | |||
8428 | if( LLVOAvatar::areAllNearbyInstancesBaked() ) | ||
8429 | { | ||
8430 | LLVOAvatar::deleteCachedImages(); | ||
8431 | } | ||
8432 | } | ||
8433 | |||
8434 | const LLUUID& LLVOAvatar::grabLocalTexture(ETextureIndex index) | ||
8435 | { | ||
8436 | if (canGrabLocalTexture(index)) | ||
8437 | { | ||
8438 | return getTEImage( index )->getID(); | ||
8439 | } | ||
8440 | return LLUUID::null; | ||
8441 | } | ||
8442 | |||
8443 | BOOL LLVOAvatar::canGrabLocalTexture(ETextureIndex index) | ||
8444 | { | ||
8445 | // Check if the texture hasn't been baked yet. | ||
8446 | if ( getTEImage( index )->getID() == IMG_DEFAULT_AVATAR ) | ||
8447 | { | ||
8448 | lldebugs << "getTEImage( " << (U32) index << " )->getID() == IMG_DEFAULT_AVATAR" << llendl; | ||
8449 | return FALSE; | ||
8450 | } | ||
8451 | |||
8452 | // Check permissions of textures that show up in the | ||
8453 | // baked texture. We don't want people copying people's | ||
8454 | // work via baked textures. | ||
8455 | std::vector<ETextureIndex> textures; | ||
8456 | switch (index) | ||
8457 | { | ||
8458 | case TEX_EYES_BAKED: | ||
8459 | textures.push_back(TEX_EYES_IRIS); | ||
8460 | break; | ||
8461 | case TEX_HEAD_BAKED: | ||
8462 | textures.push_back(TEX_HEAD_BODYPAINT); | ||
8463 | break; | ||
8464 | case TEX_UPPER_BAKED: | ||
8465 | textures.push_back(TEX_UPPER_BODYPAINT); | ||
8466 | textures.push_back(TEX_UPPER_UNDERSHIRT); | ||
8467 | textures.push_back(TEX_UPPER_SHIRT); | ||
8468 | textures.push_back(TEX_UPPER_JACKET); | ||
8469 | textures.push_back(TEX_UPPER_GLOVES); | ||
8470 | break; | ||
8471 | case TEX_LOWER_BAKED: | ||
8472 | textures.push_back(TEX_LOWER_BODYPAINT); | ||
8473 | textures.push_back(TEX_LOWER_UNDERPANTS); | ||
8474 | textures.push_back(TEX_LOWER_PANTS); | ||
8475 | textures.push_back(TEX_LOWER_JACKET); | ||
8476 | textures.push_back(TEX_LOWER_SOCKS); | ||
8477 | textures.push_back(TEX_LOWER_SHOES); | ||
8478 | break; | ||
8479 | case TEX_SKIRT_BAKED: | ||
8480 | textures.push_back(TEX_SKIRT); | ||
8481 | break; | ||
8482 | default: | ||
8483 | return FALSE; | ||
8484 | break; | ||
8485 | } | ||
8486 | |||
8487 | std::vector<ETextureIndex>::iterator iter = textures.begin(); | ||
8488 | std::vector<ETextureIndex>::iterator end = textures.end(); | ||
8489 | for (; iter != end; ++iter) | ||
8490 | { | ||
8491 | ETextureIndex t_index = (*iter); | ||
8492 | lldebugs << "Checking index " << (U32) t_index << llendl; | ||
8493 | const LLUUID& texture_id = getTEImage( t_index )->getID(); | ||
8494 | if (texture_id != IMG_DEFAULT_AVATAR) | ||
8495 | { | ||
8496 | // Search inventory for this texture. | ||
8497 | LLViewerInventoryCategory::cat_array_t cats; | ||
8498 | LLViewerInventoryItem::item_array_t items; | ||
8499 | LLAssetIDMatches asset_id_matches(texture_id); | ||
8500 | gInventory.collectDescendentsIf(LLUUID::null, | ||
8501 | cats, | ||
8502 | items, | ||
8503 | LLInventoryModel::INCLUDE_TRASH, | ||
8504 | asset_id_matches); | ||
8505 | |||
8506 | BOOL can_grab = FALSE; | ||
8507 | lldebugs << "item count for asset " << texture_id << ": " << items.count() << llendl; | ||
8508 | if (items.count()) | ||
8509 | { | ||
8510 | // search for full permissions version | ||
8511 | for (S32 i = 0; i < items.count(); i++) | ||
8512 | { | ||
8513 | LLInventoryItem* itemp = items[i]; | ||
8514 | LLPermissions item_permissions = itemp->getPermissions(); | ||
8515 | if ( item_permissions.allowOperationBy( | ||
8516 | PERM_MODIFY, gAgent.getID(), gAgent.getGroupID()) && | ||
8517 | item_permissions.allowOperationBy( | ||
8518 | PERM_COPY, gAgent.getID(), gAgent.getGroupID()) && | ||
8519 | item_permissions.allowOperationBy( | ||
8520 | PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID()) ) | ||
8521 | { | ||
8522 | can_grab = TRUE; | ||
8523 | break; | ||
8524 | } | ||
8525 | } | ||
8526 | } | ||
8527 | if (!can_grab) return FALSE; | ||
8528 | } | ||
8529 | } | ||
8530 | |||
8531 | return TRUE; | ||
8532 | } | ||
8533 | |||
8534 | void LLVOAvatar::dumpLocalTextures() | ||
8535 | { | ||
8536 | llinfos << "Local Textures:" << llendl; | ||
8537 | |||
8538 | char* names[] = { | ||
8539 | "Shirt ", | ||
8540 | "UpperTatoo", | ||
8541 | "Pants ", | ||
8542 | "LowerTatoo", | ||
8543 | "Head Tatoo", | ||
8544 | "Shoes ", | ||
8545 | "Socks ", | ||
8546 | "Upper Jckt", | ||
8547 | "Lower Jckt", | ||
8548 | "Gloves ", | ||
8549 | "Undershirt", | ||
8550 | "Underpants", | ||
8551 | "Iris ", | ||
8552 | "Skirt "}; | ||
8553 | |||
8554 | ETextureIndex baked_equiv[] = { | ||
8555 | TEX_UPPER_BAKED, | ||
8556 | TEX_UPPER_BAKED, | ||
8557 | TEX_LOWER_BAKED, | ||
8558 | TEX_LOWER_BAKED, | ||
8559 | TEX_HEAD_BAKED, | ||
8560 | TEX_LOWER_BAKED, | ||
8561 | TEX_LOWER_BAKED, | ||
8562 | TEX_UPPER_BAKED, | ||
8563 | TEX_LOWER_BAKED, | ||
8564 | TEX_UPPER_BAKED, | ||
8565 | TEX_UPPER_BAKED, | ||
8566 | TEX_LOWER_BAKED, | ||
8567 | TEX_EYES_BAKED, | ||
8568 | TEX_SKIRT_BAKED }; | ||
8569 | |||
8570 | |||
8571 | for( S32 i = 0; i < LOCTEX_NUM_ENTRIES; i++ ) | ||
8572 | { | ||
8573 | if( getTEImage( baked_equiv[i] )->getID() != IMG_DEFAULT_AVATAR ) | ||
8574 | { | ||
8575 | #if LL_RELEASE_FOR_DOWNLOAD | ||
8576 | // End users don't get to trivially see avatar texture IDs, makes textures | ||
8577 | // easier to steal. JC | ||
8578 | llinfos << "LocTex " << names[i] << ": Baked " << llendl; | ||
8579 | #else | ||
8580 | llinfos << "LocTex " << names[i] << ": Baked " << getTEImage( baked_equiv[i] )->getID() << llendl; | ||
8581 | #endif | ||
8582 | } | ||
8583 | else if (mLocalTexture[i].notNull()) | ||
8584 | { | ||
8585 | if( mLocalTexture[i]->getID() == IMG_DEFAULT_AVATAR ) | ||
8586 | { | ||
8587 | llinfos << "LocTex " << names[i] << ": None" << llendl; | ||
8588 | } | ||
8589 | else | ||
8590 | { | ||
8591 | LLViewerImage* image = mLocalTexture[i]; | ||
8592 | F32 data_progress = 0.0f; | ||
8593 | F32 decode_progress = image->getDecodeProgress(&data_progress); | ||
8594 | |||
8595 | llinfos << "LocTex " << names[i] << ": " | ||
8596 | << "Discard " << image->getDiscardLevel() << ", " | ||
8597 | << "(" << image->getWidth() << ", " << image->getHeight() << ") " | ||
8598 | #if !LL_RELEASE_FOR_DOWNLOAD | ||
8599 | // End users don't get to trivially see avatar texture IDs, | ||
8600 | // makes textures easier to steal | ||
8601 | << image->getID() << " " | ||
8602 | #endif | ||
8603 | << "Data: " << (data_progress * 100) << "% " | ||
8604 | << "Decode: " << (decode_progress * 100) << "% " | ||
8605 | << "Priority: " << image->getDecodePriority() << " " | ||
8606 | << (image->needsDecode() ? "pending decode" : "not pending decode") | ||
8607 | << llendl; | ||
8608 | } | ||
8609 | } | ||
8610 | else | ||
8611 | { | ||
8612 | llinfos << "LocTex " << names[i] << ": No LLViewerImage" << llendl; | ||
8613 | } | ||
8614 | } | ||
8615 | } | ||
8616 | |||
8617 | void LLVOAvatar::startAppearanceAnimation(BOOL set_by_user, BOOL play_sound) | ||
8618 | { | ||
8619 | if(!mAppearanceAnimating) | ||
8620 | { | ||
8621 | mAppearanceAnimSetByUser = set_by_user; | ||
8622 | mAppearanceAnimating = TRUE; | ||
8623 | mAppearanceMorphTimer.reset(); | ||
8624 | mLastAppearanceBlendTime = 0.f; | ||
8625 | } | ||
8626 | } | ||
8627 | |||
8628 | |||
8629 | void LLVOAvatar::removeMissingBakedTextures() | ||
8630 | { | ||
8631 | if (!mIsSelf) | ||
8632 | { | ||
8633 | return; | ||
8634 | } | ||
8635 | BOOL removed = FALSE; | ||
8636 | |||
8637 | for( S32 i = 0; i < BAKED_TEXTURE_COUNT; i++ ) | ||
8638 | { | ||
8639 | S32 te = sBakedTextureIndices[i]; | ||
8640 | |||
8641 | if( getTEImage( te )->isMissingAsset() ) | ||
8642 | { | ||
8643 | setTEImage( te, gImageList.getImage(IMG_DEFAULT_AVATAR) ); | ||
8644 | removed = TRUE; | ||
8645 | } | ||
8646 | } | ||
8647 | |||
8648 | if( removed ) | ||
8649 | { | ||
8650 | invalidateComposite( mEyesLayerSet, FALSE ); | ||
8651 | invalidateComposite( mHeadLayerSet, FALSE ); | ||
8652 | invalidateComposite( mUpperBodyLayerSet, FALSE ); | ||
8653 | invalidateComposite( mLowerBodyLayerSet, FALSE ); | ||
8654 | invalidateComposite( mSkirtLayerSet, FALSE ); | ||
8655 | updateMeshTextures(); | ||
8656 | requestLayerSetUploads(); | ||
8657 | } | ||
8658 | } | ||
8659 | |||
8660 | |||
8661 | //----------------------------------------------------------------------------- | ||
8662 | // LLVOAvatarInfo | ||
8663 | //----------------------------------------------------------------------------- | ||
8664 | |||
8665 | LLVOAvatarInfo::LLVOAvatarInfo() | ||
8666 | : mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0) | ||
8667 | { | ||
8668 | } | ||
8669 | |||
8670 | LLVOAvatarInfo::~LLVOAvatarInfo() | ||
8671 | { | ||
8672 | std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer()); | ||
8673 | std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer()); | ||
8674 | std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer()); | ||
8675 | delete mTexSkinColorInfo; | ||
8676 | delete mTexHairColorInfo; | ||
8677 | delete mTexEyeColorInfo; | ||
8678 | std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer()); | ||
8679 | std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer()); | ||
8680 | } | ||
8681 | |||
8682 | //----------------------------------------------------------------------------- | ||
8683 | // LLVOAvatarBoneInfo::parseXml() | ||
8684 | //----------------------------------------------------------------------------- | ||
8685 | BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node) | ||
8686 | { | ||
8687 | if (node->hasName("bone")) | ||
8688 | { | ||
8689 | mIsJoint = TRUE; | ||
8690 | static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); | ||
8691 | if (!node->getFastAttributeString(name_string, mName)) | ||
8692 | { | ||
8693 | llwarns << "Bone without name" << llendl; | ||
8694 | return FALSE; | ||
8695 | } | ||
8696 | } | ||
8697 | else if (node->hasName("collision_volume")) | ||
8698 | { | ||
8699 | mIsJoint = FALSE; | ||
8700 | static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); | ||
8701 | if (!node->getFastAttributeString(name_string, mName)) | ||
8702 | { | ||
8703 | mName = "Collision Volume"; | ||
8704 | } | ||
8705 | } | ||
8706 | else | ||
8707 | { | ||
8708 | llerrs << "Invalid node " << node->getName() << llendl; | ||
8709 | return FALSE; | ||
8710 | } | ||
8711 | |||
8712 | static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos"); | ||
8713 | if (!node->getFastAttributeVector3(pos_string, mPos)) | ||
8714 | { | ||
8715 | llwarns << "Bone without position" << llendl; | ||
8716 | return FALSE; | ||
8717 | } | ||
8718 | |||
8719 | static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot"); | ||
8720 | if (!node->getFastAttributeVector3(rot_string, mRot)) | ||
8721 | { | ||
8722 | llwarns << "Bone without rotation" << llendl; | ||
8723 | return FALSE; | ||
8724 | } | ||
8725 | |||
8726 | static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale"); | ||
8727 | if (!node->getFastAttributeVector3(scale_string, mScale)) | ||
8728 | { | ||
8729 | llwarns << "Bone without scale" << llendl; | ||
8730 | return FALSE; | ||
8731 | } | ||
8732 | |||
8733 | if (mIsJoint) | ||
8734 | { | ||
8735 | static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot"); | ||
8736 | if (!node->getFastAttributeVector3(pivot_string, mPivot)) | ||
8737 | { | ||
8738 | llwarns << "Bone without pivot" << llendl; | ||
8739 | return FALSE; | ||
8740 | } | ||
8741 | } | ||
8742 | |||
8743 | // parse children | ||
8744 | LLXmlTreeNode* child; | ||
8745 | for( child = node->getFirstChild(); child; child = node->getNextChild() ) | ||
8746 | { | ||
8747 | LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo; | ||
8748 | if (!child_info->parseXml(child)) | ||
8749 | { | ||
8750 | delete child_info; | ||
8751 | return FALSE; | ||
8752 | } | ||
8753 | mChildList.push_back(child_info); | ||
8754 | } | ||
8755 | return TRUE; | ||
8756 | } | ||
8757 | |||
8758 | //----------------------------------------------------------------------------- | ||
8759 | // LLVOAvatarSkeletonInfo::parseXml() | ||
8760 | //----------------------------------------------------------------------------- | ||
8761 | BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node) | ||
8762 | { | ||
8763 | static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones"); | ||
8764 | if (!node->getFastAttributeS32(num_bones_string, mNumBones)) | ||
8765 | { | ||
8766 | llerrs << "Couldn't find number of bones." << llendl; | ||
8767 | return FALSE; | ||
8768 | } | ||
8769 | |||
8770 | static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes"); | ||
8771 | node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes); | ||
8772 | |||
8773 | LLXmlTreeNode* child; | ||
8774 | for( child = node->getFirstChild(); child; child = node->getNextChild() ) | ||
8775 | { | ||
8776 | LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo; | ||
8777 | if (!info->parseXml(child)) | ||
8778 | { | ||
8779 | delete info; | ||
8780 | llerrs << "Error parsing bone in skeleton file" << llendl; | ||
8781 | } | ||
8782 | mBoneInfoList.push_back(info); | ||
8783 | } | ||
8784 | return TRUE; | ||
8785 | } | ||
8786 | |||
8787 | //----------------------------------------------------------------------------- | ||
8788 | // parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree | ||
8789 | //----------------------------------------------------------------------------- | ||
8790 | BOOL LLVOAvatarInfo::parseXmlSkeletonNode(LLXmlTreeNode* root) | ||
8791 | { | ||
8792 | LLXmlTreeNode* node = root->getChildByName( "skeleton" ); | ||
8793 | if( !node ) | ||
8794 | { | ||
8795 | llwarns << "avatar file: missing <skeleton>" << llendl; | ||
8796 | return FALSE; | ||
8797 | } | ||
8798 | |||
8799 | LLXmlTreeNode* child; | ||
8800 | |||
8801 | // SKELETON DISTORTIONS | ||
8802 | for (child = node->getChildByName( "param" ); | ||
8803 | child; | ||
8804 | child = node->getNextNamedChild()) | ||
8805 | { | ||
8806 | if (!child->getChildByName("param_skeleton")) | ||
8807 | { | ||
8808 | if (child->getChildByName("param_morph")) | ||
8809 | { | ||
8810 | llwarns << "Can't specify morph param in skeleton definition." << llendl; | ||
8811 | } | ||
8812 | else | ||
8813 | { | ||
8814 | llwarns << "Unknown param type." << llendl; | ||
8815 | } | ||
8816 | continue; | ||
8817 | } | ||
8818 | |||
8819 | LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo; | ||
8820 | if (!info->parseXml(child)) | ||
8821 | { | ||
8822 | delete info; | ||
8823 | return FALSE; | ||
8824 | } | ||
8825 | |||
8826 | mSkeletalDistortionInfoList.push_back(info); | ||
8827 | } | ||
8828 | |||
8829 | // ATTACHMENT POINTS | ||
8830 | for (child = node->getChildByName( "attachment_point" ); | ||
8831 | child; | ||
8832 | child = node->getNextNamedChild()) | ||
8833 | { | ||
8834 | LLVOAvatarAttachmentInfo* info = new LLVOAvatarAttachmentInfo(); | ||
8835 | |||
8836 | static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); | ||
8837 | if (!child->getFastAttributeString(name_string, info->mName)) | ||
8838 | { | ||
8839 | llwarns << "No name supplied for attachment point." << llendl; | ||
8840 | delete info; | ||
8841 | continue; | ||
8842 | } | ||
8843 | |||
8844 | static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint"); | ||
8845 | if (!child->getFastAttributeString(joint_string, info->mJointName)) | ||
8846 | { | ||
8847 | llwarns << "No bone declared in attachment point " << info->mName << llendl; | ||
8848 | delete info; | ||
8849 | continue; | ||
8850 | } | ||
8851 | |||
8852 | static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position"); | ||
8853 | if (child->getFastAttributeVector3(position_string, info->mPosition)) | ||
8854 | { | ||
8855 | info->mHasPosition = TRUE; | ||
8856 | } | ||
8857 | |||
8858 | static LLStdStringHandle rotation_string = LLXmlTree::addAttributeString("rotation"); | ||
8859 | if (child->getFastAttributeVector3(rotation_string, info->mRotationEuler)) | ||
8860 | { | ||
8861 | info->mHasRotation = TRUE; | ||
8862 | } | ||
8863 | static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group"); | ||
8864 | if (child->getFastAttributeS32(group_string, info->mGroup)) | ||
8865 | { | ||
8866 | if (info->mGroup == -1) | ||
8867 | info->mGroup = -1111; // -1 = none parsed, < -1 = bad value | ||
8868 | } | ||
8869 | |||
8870 | static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id"); | ||
8871 | if (!child->getFastAttributeS32(id_string, info->mAttachmentID)) | ||
8872 | { | ||
8873 | llwarns << "No id supplied for attachment point " << info->mName << llendl; | ||
8874 | delete info; | ||
8875 | continue; | ||
8876 | } | ||
8877 | |||
8878 | static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice"); | ||
8879 | child->getFastAttributeS32(slot_string, info->mPieMenuSlice); | ||
8880 | |||
8881 | static LLStdStringHandle visible_in_first_person_string = LLXmlTree::addAttributeString("visible_in_first_person"); | ||
8882 | child->getFastAttributeBOOL(visible_in_first_person_string, info->mVisibleFirstPerson); | ||
8883 | |||
8884 | static LLStdStringHandle hud_attachment_string = LLXmlTree::addAttributeString("hud"); | ||
8885 | child->getFastAttributeBOOL(hud_attachment_string, info->mIsHUDAttachment); | ||
8886 | |||
8887 | mAttachmentInfoList.push_back(info); | ||
8888 | } | ||
8889 | |||
8890 | return TRUE; | ||
8891 | } | ||
8892 | |||
8893 | //----------------------------------------------------------------------------- | ||
8894 | // parseXmlMeshNodes(): parses <mesh> nodes from XML tree | ||
8895 | //----------------------------------------------------------------------------- | ||
8896 | BOOL LLVOAvatarInfo::parseXmlMeshNodes(LLXmlTreeNode* root) | ||
8897 | { | ||
8898 | for (LLXmlTreeNode* node = root->getChildByName( "mesh" ); | ||
8899 | node; | ||
8900 | node = root->getNextNamedChild()) | ||
8901 | { | ||
8902 | LLVOAvatarMeshInfo *info = new LLVOAvatarMeshInfo; | ||
8903 | |||
8904 | // attribute: type | ||
8905 | static LLStdStringHandle type_string = LLXmlTree::addAttributeString("type"); | ||
8906 | if( !node->getFastAttributeString( type_string, info->mType ) ) | ||
8907 | { | ||
8908 | llwarns << "Avatar file: <mesh> is missing type attribute. Ignoring element. " << llendl; | ||
8909 | delete info; | ||
8910 | return FALSE; // Ignore this element | ||
8911 | } | ||
8912 | |||
8913 | static LLStdStringHandle lod_string = LLXmlTree::addAttributeString("lod"); | ||
8914 | if (!node->getFastAttributeS32( lod_string, info->mLOD )) | ||
8915 | { | ||
8916 | llwarns << "Avatar file: <mesh> is missing lod attribute. Ignoring element. " << llendl; | ||
8917 | delete info; | ||
8918 | return FALSE; // Ignore this element | ||
8919 | } | ||
8920 | |||
8921 | static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name"); | ||
8922 | if( !node->getFastAttributeString( file_name_string, info->mMeshFileName ) ) | ||
8923 | { | ||
8924 | llwarns << "Avatar file: <mesh> is missing file_name attribute. Ignoring: " << info->mType << llendl; | ||
8925 | delete info; | ||
8926 | return FALSE; // Ignore this element | ||
8927 | } | ||
8928 | |||
8929 | static LLStdStringHandle reference_string = LLXmlTree::addAttributeString("reference"); | ||
8930 | node->getFastAttributeString( reference_string, info->mReferenceMeshName ); | ||
8931 | |||
8932 | // attribute: min_pixel_area | ||
8933 | static LLStdStringHandle min_pixel_area_string = LLXmlTree::addAttributeString("min_pixel_area"); | ||
8934 | static LLStdStringHandle min_pixel_width_string = LLXmlTree::addAttributeString("min_pixel_width"); | ||
8935 | if (!node->getFastAttributeF32( min_pixel_area_string, info->mMinPixelArea )) | ||
8936 | { | ||
8937 | F32 min_pixel_area = 0.1f; | ||
8938 | if (node->getFastAttributeF32( min_pixel_width_string, min_pixel_area )) | ||
8939 | { | ||
8940 | // this is square root of pixel area (sensible to use linear space in defining lods) | ||
8941 | min_pixel_area = min_pixel_area * min_pixel_area; | ||
8942 | } | ||
8943 | info->mMinPixelArea = min_pixel_area; | ||
8944 | } | ||
8945 | |||
8946 | // Parse visual params for this node only if we haven't already | ||
8947 | for (LLXmlTreeNode* child = node->getChildByName( "param" ); | ||
8948 | child; | ||
8949 | child = node->getNextNamedChild()) | ||
8950 | { | ||
8951 | if (!child->getChildByName("param_morph")) | ||
8952 | { | ||
8953 | if (child->getChildByName("param_skeleton")) | ||
8954 | { | ||
8955 | llwarns << "Can't specify skeleton param in a mesh definition." << llendl; | ||
8956 | } | ||
8957 | else | ||
8958 | { | ||
8959 | llwarns << "Unknown param type." << llendl; | ||
8960 | } | ||
8961 | continue; | ||
8962 | } | ||
8963 | |||
8964 | LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo(); | ||
8965 | if (!morphinfo->parseXml(child)) | ||
8966 | { | ||
8967 | delete morphinfo; | ||
8968 | delete info; | ||
8969 | return -1; | ||
8970 | } | ||
8971 | BOOL shared = FALSE; | ||
8972 | static LLStdStringHandle shared_string = LLXmlTree::addAttributeString("shared"); | ||
8973 | child->getFastAttributeBOOL(shared_string, shared); | ||
8974 | |||
8975 | info->mPolyMorphTargetInfoList.push_back(LLVOAvatarMeshInfo::morph_info_pair_t(morphinfo, shared)); | ||
8976 | } | ||
8977 | |||
8978 | mMeshInfoList.push_back(info); | ||
8979 | } | ||
8980 | return TRUE; | ||
8981 | } | ||
8982 | |||
8983 | //----------------------------------------------------------------------------- | ||
8984 | // parseXmlColorNodes(): parses <global_color> nodes from XML tree | ||
8985 | //----------------------------------------------------------------------------- | ||
8986 | BOOL LLVOAvatarInfo::parseXmlColorNodes(LLXmlTreeNode* root) | ||
8987 | { | ||
8988 | for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" ); | ||
8989 | color_node; | ||
8990 | color_node = root->getNextNamedChild()) | ||
8991 | { | ||
8992 | LLString global_color_name; | ||
8993 | static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name"); | ||
8994 | if (color_node->getFastAttributeString( name_string, global_color_name ) ) | ||
8995 | { | ||
8996 | if( global_color_name == "skin_color" ) | ||
8997 | { | ||
8998 | if (mTexSkinColorInfo) | ||
8999 | { | ||
9000 | llwarns << "avatar file: multiple instances of skin_color" << llendl; | ||
9001 | return FALSE; | ||
9002 | } | ||
9003 | mTexSkinColorInfo = new LLTexGlobalColorInfo; | ||
9004 | if( !mTexSkinColorInfo->parseXml( color_node ) ) | ||
9005 | { | ||
9006 | delete mTexSkinColorInfo; mTexSkinColorInfo = 0; | ||
9007 | llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl; | ||
9008 | return FALSE; | ||
9009 | } | ||
9010 | } | ||
9011 | else if( global_color_name == "hair_color" ) | ||
9012 | { | ||
9013 | if (mTexHairColorInfo) | ||
9014 | { | ||
9015 | llwarns << "avatar file: multiple instances of hair_color" << llendl; | ||
9016 | return FALSE; | ||
9017 | } | ||
9018 | mTexHairColorInfo = new LLTexGlobalColorInfo; | ||
9019 | if( !mTexHairColorInfo->parseXml( color_node ) ) | ||
9020 | { | ||
9021 | delete mTexHairColorInfo; mTexHairColorInfo = 0; | ||
9022 | llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl; | ||
9023 | return FALSE; | ||
9024 | } | ||
9025 | } | ||
9026 | else if( global_color_name == "eye_color" ) | ||
9027 | { | ||
9028 | if (mTexEyeColorInfo) | ||
9029 | { | ||
9030 | llwarns << "avatar file: multiple instances of eye_color" << llendl; | ||
9031 | return FALSE; | ||
9032 | } | ||
9033 | mTexEyeColorInfo = new LLTexGlobalColorInfo; | ||
9034 | if( !mTexEyeColorInfo->parseXml( color_node ) ) | ||
9035 | { | ||
9036 | llwarns << "avatar file: mTexEyeColor->parseXml() failed" << llendl; | ||
9037 | return FALSE; | ||
9038 | } | ||
9039 | } | ||
9040 | } | ||
9041 | } | ||
9042 | return TRUE; | ||
9043 | } | ||
9044 | |||
9045 | //----------------------------------------------------------------------------- | ||
9046 | // parseXmlLayerNodes(): parses <layer_set> nodes from XML tree | ||
9047 | //----------------------------------------------------------------------------- | ||
9048 | BOOL LLVOAvatarInfo::parseXmlLayerNodes(LLXmlTreeNode* root) | ||
9049 | { | ||
9050 | for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" ); | ||
9051 | layer_node; | ||
9052 | layer_node = root->getNextNamedChild()) | ||
9053 | { | ||
9054 | LLTexLayerSetInfo* layer_info = new LLTexLayerSetInfo(); | ||
9055 | if( layer_info->parseXml( layer_node ) ) | ||
9056 | { | ||
9057 | mLayerInfoList.push_back(layer_info); | ||
9058 | } | ||
9059 | else | ||
9060 | { | ||
9061 | delete layer_info; | ||
9062 | llwarns << "avatar file: layer_set->parseXml() failed" << llendl; | ||
9063 | return FALSE; | ||
9064 | } | ||
9065 | } | ||
9066 | return TRUE; | ||
9067 | } | ||
9068 | |||
9069 | //----------------------------------------------------------------------------- | ||
9070 | // parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree | ||
9071 | //----------------------------------------------------------------------------- | ||
9072 | BOOL LLVOAvatarInfo::parseXmlDriverNodes(LLXmlTreeNode* root) | ||
9073 | { | ||
9074 | LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" ); | ||
9075 | if( driver ) | ||
9076 | { | ||
9077 | for (LLXmlTreeNode* grand_child = driver->getChildByName( "param" ); | ||
9078 | grand_child; | ||
9079 | grand_child = driver->getNextNamedChild()) | ||
9080 | { | ||
9081 | if( grand_child->getChildByName( "param_driver" ) ) | ||
9082 | { | ||
9083 | LLDriverParamInfo* driver_info = new LLDriverParamInfo(); | ||
9084 | if( driver_info->parseXml( grand_child ) ) | ||
9085 | { | ||
9086 | mDriverInfoList.push_back(driver_info); | ||
9087 | } | ||
9088 | else | ||
9089 | { | ||
9090 | delete driver_info; | ||
9091 | llwarns << "avatar file: driver_param->parseXml() failed" << llendl; | ||
9092 | return FALSE; | ||
9093 | } | ||
9094 | } | ||
9095 | } | ||
9096 | } | ||
9097 | return TRUE; | ||
9098 | } | ||
9099 | |||
9100 | void LLVOAvatar::writeCAL3D(std::string& path, std::string& file_base) | ||
9101 | { | ||
9102 | char filename[MAX_PATH]; | ||
9103 | |||
9104 | // reset animated morphs | ||
9105 | setVisualParamWeight("Blink_Left", 0.f); | ||
9106 | setVisualParamWeight("Blink_Right", 0.f); | ||
9107 | setVisualParamWeight("Hands_Relaxed", 1.f); | ||
9108 | setVisualParamWeight("Hands_Point", 0.f); | ||
9109 | setVisualParamWeight("Hands_Fist", 0.f); | ||
9110 | setVisualParamWeight("Hands_Relaxed_L", 0.f); | ||
9111 | setVisualParamWeight("Hands_Point_L", 0.f); | ||
9112 | setVisualParamWeight("Hands_Fist_L", 0.f); | ||
9113 | setVisualParamWeight("Hands_Relaxed_R", 0.f); | ||
9114 | setVisualParamWeight("Hands_Point_R", 0.f); | ||
9115 | setVisualParamWeight("Hands_Fist_R", 0.f); | ||
9116 | setVisualParamWeight("Hands_Salute_R", 0.f); | ||
9117 | setVisualParamWeight("Hands_Typing", 0.f); | ||
9118 | setVisualParamWeight("Hands_Peace_R", 0.f); | ||
9119 | setVisualParamWeight("Hands_Spread_R", 0.f); | ||
9120 | updateVisualParams(); | ||
9121 | |||
9122 | sprintf(filename, "%s\\%s_skeleton.xsf", path.c_str(), file_base.c_str()); | ||
9123 | apr_file_t* fp = ll_apr_file_open(filename, LL_APR_W); | ||
9124 | if (!fp) | ||
9125 | { | ||
9126 | llwarns << "Unable to write avatar file " << filename << llendl; | ||
9127 | return; | ||
9128 | } | ||
9129 | apr_file_printf(fp, "<SKELETON VERSION=\"1000\" NUMBONES=\"%d\">\n", sSkeletonInfo->getNumBones() - sSkeletonInfo->getNumCollisionVolumes()); | ||
9130 | mRoot.writeCAL3D(fp); | ||
9131 | apr_file_printf(fp, "</SKELETON>\n"); | ||
9132 | apr_file_close(fp); | ||
9133 | |||
9134 | sprintf(filename, "%s\\%s_mesh_body.xmf", path.c_str(), file_base.c_str()); | ||
9135 | //gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"avatar.cal").c_str() | ||
9136 | fp = ll_apr_file_open(filename, LL_APR_W); | ||
9137 | if (!fp) | ||
9138 | { | ||
9139 | llwarns << "Unable to write avatar file " << filename << llendl; | ||
9140 | return; | ||
9141 | } | ||
9142 | |||
9143 | BOOL has_skirt = isWearingWearableType(WT_SKIRT); | ||
9144 | |||
9145 | apr_file_printf(fp, "<MESH VERSION=\"1000\" NUMSUBMESH=\"%d\">\n", has_skirt ? 8 : 7); | ||
9146 | mHairMesh0.writeCAL3D(fp, 5, this); | ||
9147 | mHeadMesh0.writeCAL3D(fp, 0, this); | ||
9148 | mEyeLashMesh0.writeCAL3D(fp, 0, this); | ||
9149 | mUpperBodyMesh0.writeCAL3D(fp, 1, this); | ||
9150 | mLowerBodyMesh0.writeCAL3D(fp, 2, this); | ||
9151 | mEyeBallLeftMesh0.writeCAL3D(fp, 3, this); | ||
9152 | mEyeBallRightMesh0.writeCAL3D(fp, 3, this); | ||
9153 | if (has_skirt) | ||
9154 | { | ||
9155 | mSkirtMesh0.writeCAL3D(fp, 4, this); | ||
9156 | } | ||
9157 | apr_file_printf(fp, "</MESH>\n"); | ||
9158 | apr_file_close(fp); | ||
9159 | |||
9160 | // write out material files | ||
9161 | LLPointer<LLImageTGA> tga_image = new LLImageTGA; | ||
9162 | |||
9163 | for (S32 i = 0; i < (has_skirt ? BAKED_TEXTURE_COUNT : BAKED_TEXTURE_COUNT - 1); i++) | ||
9164 | { | ||
9165 | sprintf(filename, "%s\\%s_material_tex_%d.tga", path.c_str(), file_base.c_str(), i); | ||
9166 | |||
9167 | LLViewerImage* viewer_imagep = mTEImages[sBakedTextureIndices[i]]; | ||
9168 | if (!viewer_imagep->getHasGLTexture()) | ||
9169 | { | ||
9170 | llinfos << "No image data available for " << filename << llendl; | ||
9171 | continue; | ||
9172 | } | ||
9173 | LLPointer<LLImageRaw> raw_image = new LLImageRaw; | ||
9174 | viewer_imagep->readBackRaw(-1, raw_image); | ||
9175 | BOOL success = tga_image->encode(raw_image); | ||
9176 | success = tga_image->save(filename); | ||
9177 | } | ||
9178 | |||
9179 | // output image for hair | ||
9180 | sprintf(filename, "%s\\%s_material_tex_5.tga", path.c_str(), file_base.c_str()); | ||
9181 | LLViewerImage* viewer_imagep = mTEImages[TEX_HAIR]; | ||
9182 | if (!viewer_imagep->getHasGLTexture()) | ||
9183 | { | ||
9184 | llinfos << "No image data available for " << filename << llendl; | ||
9185 | } | ||
9186 | else | ||
9187 | { | ||
9188 | LLPointer<LLImageRaw> raw_image = new LLImageRaw; | ||
9189 | viewer_imagep->readBackRaw(-1, raw_image); | ||
9190 | BOOL success = tga_image->encode(raw_image); | ||
9191 | success = tga_image->save(filename); | ||
9192 | } | ||
9193 | |||
9194 | // save out attachments | ||
9195 | sprintf(filename, "%s\\%s_mesh_attachments.xmf", path.c_str(), file_base.c_str()); | ||
9196 | fp = ll_apr_file_open(filename, LL_APR_W); | ||
9197 | if (!fp) | ||
9198 | { | ||
9199 | llwarns << "Unable to write attachments file " << filename << llendl; | ||
9200 | return; | ||
9201 | } | ||
9202 | |||
9203 | typedef std::multimap<LLUUID, LLMaterialExportInfo*>::iterator material_it_t; | ||
9204 | std::multimap<LLUUID, LLMaterialExportInfo*> material_map; | ||
9205 | |||
9206 | S32 num_attachment_objects = 0; | ||
9207 | for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData(); | ||
9208 | attachment; | ||
9209 | attachment = mAttachmentPoints.getNextData()) | ||
9210 | { | ||
9211 | LLViewerObject *attached_object = attachment->getObject(0); | ||
9212 | if (attached_object && !attached_object->isDead() && attached_object->mDrawable.notNull() && | ||
9213 | attached_object->getPCode() == LL_PCODE_VOLUME) | ||
9214 | { | ||
9215 | num_attachment_objects += attached_object->mDrawable->getNumFaces(); | ||
9216 | for (U32 i = 0; i < attached_object->mChildList.size(); i++) | ||
9217 | { | ||
9218 | LLViewerObject* child_object = attached_object->mChildList[i]; | ||
9219 | num_attachment_objects += child_object->mDrawable->getNumFaces(); | ||
9220 | } | ||
9221 | } | ||
9222 | } | ||
9223 | |||
9224 | apr_file_printf(fp, "<MESH VERSION=\"1000\" NUMSUBMESH=\"%d\">\n", num_attachment_objects); | ||
9225 | |||
9226 | S32 material_index = 6; | ||
9227 | S32 texture_index = 6; | ||
9228 | for(LLViewerJointAttachment *attachment = mAttachmentPoints.getFirstData(); | ||
9229 | attachment; | ||
9230 | attachment = mAttachmentPoints.getNextData()) | ||
9231 | { | ||
9232 | LLViewerObject *attached_object = attachment->getObject(0); | ||
9233 | if (attached_object && !attached_object->isDead() && attached_object->getPCode() == LL_PCODE_VOLUME) | ||
9234 | { | ||
9235 | LLVOVolume* attached_volume = (LLVOVolume*)attached_object; | ||
9236 | LLVector3 pos = attachment->getPosition(); | ||
9237 | LLJoint* cur_joint = attachment->getParent(); | ||
9238 | while (cur_joint) | ||
9239 | { | ||
9240 | pos += cur_joint->getSkinOffset(); | ||
9241 | cur_joint = (LLViewerJoint*)cur_joint->getParent(); | ||
9242 | } | ||
9243 | pos *= 100.f; | ||
9244 | S32 attached_joint_num = attachment->getParent()->mJointNum; | ||
9245 | LLQuaternion rot = attachment->getRotation(); | ||
9246 | attached_volume->writeCAL3D(fp, path, file_base, attached_joint_num, pos, rot, material_index, texture_index, material_map); | ||
9247 | } | ||
9248 | } | ||
9249 | apr_file_printf(fp, "</MESH>\n"); | ||
9250 | apr_file_close(fp); | ||
9251 | |||
9252 | // now dump sample animation | ||
9253 | LLKeyframeMotion* walk_motion = | ||
9254 | getSex() == SEX_MALE ? (LLKeyframeMotion*)findMotion(ANIM_AGENT_WALK) : (LLKeyframeMotion*)findMotion(ANIM_AGENT_FEMALE_WALK); | ||
9255 | if (FALSE)//(walk_motion) | ||
9256 | { | ||
9257 | sprintf(filename, "%s\\%s_anim.xaf", path.c_str(), file_base.c_str()); | ||
9258 | apr_file_t* fp = ll_apr_file_open(filename, LL_APR_W); | ||
9259 | if (!fp) | ||
9260 | { | ||
9261 | llwarns << "Unable to write avatar animation file " << filename << llendl; | ||
9262 | return; | ||
9263 | } | ||
9264 | |||
9265 | walk_motion->writeCAL3D(fp); | ||
9266 | |||
9267 | apr_file_close(fp); | ||
9268 | } | ||
9269 | |||
9270 | // finally, write out .cfg file | ||
9271 | sprintf(filename, "%s\\%s_avatar.cfg", path.c_str(), file_base.c_str()); | ||
9272 | fp = ll_apr_file_open(filename, LL_APR_W); | ||
9273 | if (!fp) | ||
9274 | { | ||
9275 | llwarns << "Unable to write avatar config file " << filename << llendl; | ||
9276 | return; | ||
9277 | } | ||
9278 | |||
9279 | // this version exports animation | ||
9280 | //apr_file_printf(fp, "#\n# cal3d model configuration file\n#\n# model: %s_avatar\n#\n\nscale=1.0\n\nskeleton=%s_skeleton.xsf\n\nanimation=%s_anim.xaf\n\n", file_base.c_str(), file_base.c_str(), file_base.c_str()); | ||
9281 | apr_file_printf(fp, "#\n# cal3d model configuration file\n#\n# model: %s_avatar\n#\n\nscale=1.0\n\nskeleton=%s_skeleton.xsf\n\n", file_base.c_str(), file_base.c_str()); | ||
9282 | apr_file_printf(fp, "mesh=%s_mesh_body.xmf\nmesh=%s_mesh_attachments.xmf\n", file_base.c_str(), file_base.c_str()); | ||
9283 | |||
9284 | for (S32 i = 0; i < material_index; i++) | ||
9285 | { | ||
9286 | apr_file_printf(fp, "material=%s_material_%d.xrf\n", file_base.c_str(), i); | ||
9287 | } | ||
9288 | apr_file_close(fp); | ||
9289 | |||
9290 | for(S32 i = 0; i < 6; i++) | ||
9291 | { | ||
9292 | sprintf(filename, "%s\\%s_material_%d.xrf", path.c_str(), file_base.c_str(), i); | ||
9293 | apr_file_t* fp = ll_apr_file_open(filename, LL_APR_W); | ||
9294 | if (!fp) | ||
9295 | { | ||
9296 | llwarns << "Unable to write material definition file " << filename << llendl; | ||
9297 | return; | ||
9298 | } | ||
9299 | |||
9300 | // for hair material, use hair color...otherwise use white for entire body | ||
9301 | LLColor4U material_color = (i == 5) ? mTexHairColor->getColor() : LLColor4U::white; | ||
9302 | |||
9303 | apr_file_printf(fp, "<HEADER MAGIC=\"XRF\" VERSION=\"900\" />\n<MATERIAL NUMMAPS=\"1\">\n"); | ||
9304 | apr_file_printf(fp, " <AMBIENT>%d %d %d %d</AMBIENT>\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]); | ||
9305 | apr_file_printf(fp, " <DIFFUSE>%d %d %d %d</DIFFUSE>\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]); | ||
9306 | apr_file_printf(fp, " <SPECULAR>0 0 0 0</SPECULAR>\n"); | ||
9307 | apr_file_printf(fp, " <SHININESS>1.0</SHININESS>\n"); | ||
9308 | apr_file_printf(fp, " <MAP>%s_material_tex_%d.tga</MAP>\n", file_base.c_str(), i); | ||
9309 | apr_file_printf(fp, "</MATERIAL>\n"); | ||
9310 | |||
9311 | apr_file_close(fp); | ||
9312 | } | ||
9313 | |||
9314 | // write out material files | ||
9315 | for(material_it_t material_it = material_map.begin(); material_it != material_map.end(); ++material_it) | ||
9316 | { | ||
9317 | LLMaterialExportInfo* export_info = material_it->second; | ||
9318 | |||
9319 | sprintf(filename, "%s\\%s_material_%d.xrf", path.c_str(), file_base.c_str(), export_info->mMaterialIndex); | ||
9320 | apr_file_t* fp = ll_apr_file_open(filename, LL_APR_W); | ||
9321 | if (!fp) | ||
9322 | { | ||
9323 | llwarns << "Unable to write material definition file " << filename << llendl; | ||
9324 | return; | ||
9325 | } | ||
9326 | |||
9327 | LLColor4U material_color = export_info->mColor; | ||
9328 | |||
9329 | apr_file_printf(fp, "<HEADER MAGIC=\"XRF\" VERSION=\"900\" />\n<MATERIAL NUMMAPS=\"1\">\n"); | ||
9330 | apr_file_printf(fp, " <AMBIENT>%d %d %d %d</AMBIENT>\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]); | ||
9331 | apr_file_printf(fp, " <DIFFUSE>%d %d %d %d</DIFFUSE>\n", material_color.mV[VX], material_color.mV[VY], material_color.mV[VZ], material_color.mV[VW]); | ||
9332 | apr_file_printf(fp, " <SPECULAR>0 0 0 0</SPECULAR>\n"); | ||
9333 | apr_file_printf(fp, " <SHININESS>1.0</SHININESS>\n"); | ||
9334 | apr_file_printf(fp, " <MAP>%s_material_tex_%d.tga</MAP>\n", file_base.c_str(), export_info->mTextureIndex); | ||
9335 | apr_file_printf(fp, "</MATERIAL>\n"); | ||
9336 | |||
9337 | apr_file_close(fp); | ||
9338 | } | ||
9339 | |||
9340 | |||
9341 | std::for_each(material_map.begin(), material_map.end(), DeletePairedPointer()); | ||
9342 | material_map.clear(); | ||
9343 | } | ||
9344 | |||
9345 | // warning: order(N) not order(1) | ||
9346 | S32 LLVOAvatar::getAttachmentCount() | ||
9347 | { | ||
9348 | S32 count = mAttachmentPoints.getLength(); | ||
9349 | return count; | ||
9350 | } | ||
9351 | |||
9352 | //virtual | ||
9353 | void LLVOAvatar::updateRegion(LLViewerRegion *regionp) | ||
9354 | { | ||
9355 | if (mIsSelf) | ||
9356 | { | ||
9357 | if (regionp->getHandle() != mLastRegionHandle) | ||
9358 | { | ||
9359 | if (mLastRegionHandle != 0) | ||
9360 | { | ||
9361 | ++mRegionCrossingCount; | ||
9362 | F64 delta = (F64)mRegionCrossingTimer.getElapsedTimeF32(); | ||
9363 | F64 avg = (mRegionCrossingCount == 1) ? 0 : gViewerStats->getStat(LLViewerStats::ST_CROSSING_AVG); | ||
9364 | F64 delta_avg = (delta + avg*(mRegionCrossingCount-1)) / mRegionCrossingCount; | ||
9365 | gViewerStats->setStat(LLViewerStats::ST_CROSSING_AVG, delta_avg); | ||
9366 | |||
9367 | F64 max = (mRegionCrossingCount == 1) ? 0 : gViewerStats->getStat(LLViewerStats::ST_CROSSING_MAX); | ||
9368 | max = llmax(delta, max); | ||
9369 | gViewerStats->setStat(LLViewerStats::ST_CROSSING_MAX, max); | ||
9370 | } | ||
9371 | mLastRegionHandle = regionp->getHandle(); | ||
9372 | } | ||
9373 | mRegionCrossingTimer.reset(); | ||
9374 | } | ||
9375 | } | ||
9376 | |||
9377 | LLString LLVOAvatar::getFullname() const | ||
9378 | { | ||
9379 | LLString name; | ||
9380 | |||
9381 | LLNameValue* first = getNVPair("FirstName"); | ||
9382 | LLNameValue* last = getNVPair("LastName"); | ||
9383 | if (first && last) | ||
9384 | { | ||
9385 | name += first->getString(); | ||
9386 | name += " "; | ||
9387 | name += last->getString(); | ||
9388 | } | ||
9389 | |||
9390 | return name; | ||
9391 | } | ||
9392 | |||
9393 | LLTexLayerSet* LLVOAvatar::getLayerSet(ETextureIndex index) const | ||
9394 | { | ||
9395 | switch( index ) | ||
9396 | { | ||
9397 | case TEX_HEAD_BAKED: | ||
9398 | case TEX_HEAD_BODYPAINT: | ||
9399 | return mHeadLayerSet; | ||
9400 | |||
9401 | case TEX_UPPER_BAKED: | ||
9402 | case TEX_UPPER_SHIRT: | ||
9403 | case TEX_UPPER_BODYPAINT: | ||
9404 | case TEX_UPPER_JACKET: | ||
9405 | case TEX_UPPER_GLOVES: | ||
9406 | case TEX_UPPER_UNDERSHIRT: | ||
9407 | return mUpperBodyLayerSet; | ||
9408 | |||
9409 | case TEX_LOWER_BAKED: | ||
9410 | case TEX_LOWER_PANTS: | ||
9411 | case TEX_LOWER_BODYPAINT: | ||
9412 | case TEX_LOWER_SHOES: | ||
9413 | case TEX_LOWER_SOCKS: | ||
9414 | case TEX_LOWER_JACKET: | ||
9415 | case TEX_LOWER_UNDERPANTS: | ||
9416 | return mLowerBodyLayerSet; | ||
9417 | |||
9418 | case TEX_EYES_BAKED: | ||
9419 | case TEX_EYES_IRIS: | ||
9420 | return mEyesLayerSet; | ||
9421 | |||
9422 | case TEX_SKIRT_BAKED: | ||
9423 | case TEX_SKIRT: | ||
9424 | return mSkirtLayerSet; | ||
9425 | |||
9426 | case TEX_HAIR: | ||
9427 | default: | ||
9428 | return NULL; | ||
9429 | } | ||
9430 | } | ||
9431 | |||
9432 | LLHost LLVOAvatar::getObjectHost() const | ||
9433 | { | ||
9434 | LLViewerRegion* region = getRegion(); | ||
9435 | if (region && !isDead()) | ||
9436 | { | ||
9437 | return region->getHost(); | ||
9438 | } | ||
9439 | else | ||
9440 | { | ||
9441 | return LLHost::invalid; | ||
9442 | } | ||
9443 | } | ||