diff options
Diffstat (limited to '')
-rwxr-xr-x[-rw-r--r--] | linden/indra/llprimitive/llprimitive.cpp | 667 |
1 files changed, 342 insertions, 325 deletions
diff --git a/linden/indra/llprimitive/llprimitive.cpp b/linden/indra/llprimitive/llprimitive.cpp index f1b7522..0ad9f79 100644..100755 --- a/linden/indra/llprimitive/llprimitive.cpp +++ b/linden/indra/llprimitive/llprimitive.cpp | |||
@@ -4,7 +4,7 @@ | |||
4 | * | 4 | * |
5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ | 5 | * $LicenseInfo:firstyear=2001&license=viewergpl$ |
6 | * | 6 | * |
7 | * Copyright (c) 2001-2009, Linden Research, Inc. | 7 | * Copyright (c) 2001-2010, Linden Research, Inc. |
8 | * | 8 | * |
9 | * Second Life Viewer Source Code | 9 | * Second Life Viewer Source Code |
10 | * The source code in this file ("Source Code") is provided by Linden Lab | 10 | * The source code in this file ("Source Code") is provided by Linden Lab |
@@ -43,7 +43,8 @@ | |||
43 | #include "llvolumemgr.h" | 43 | #include "llvolumemgr.h" |
44 | #include "llstring.h" | 44 | #include "llstring.h" |
45 | #include "lldatapacker.h" | 45 | #include "lldatapacker.h" |
46 | #include "llsdutil.h" | 46 | #include "llsdutil.h"//_math.h" |
47 | #include "llprimtexturelist.h" | ||
47 | 48 | ||
48 | /** | 49 | /** |
49 | * exported constants | 50 | * exported constants |
@@ -111,6 +112,7 @@ const F32 FLEXIBLE_OBJECT_DEFAULT_LENGTH = 1.0f; | |||
111 | const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE; | 112 | const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE; |
112 | const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE; | 113 | const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE; |
113 | 114 | ||
115 | const S32 MAX_FACE_BITS = 9; | ||
114 | 116 | ||
115 | const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e"; | 117 | const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e"; |
116 | 118 | ||
@@ -129,7 +131,7 @@ void LLPrimitive::setVolumeManager( LLVolumeMgr* volume_manager ) | |||
129 | { | 131 | { |
130 | if ( !volume_manager || sVolumeManager ) | 132 | if ( !volume_manager || sVolumeManager ) |
131 | { | 133 | { |
132 | llerrs << "Unable to set LLPrimitive::sVolumeManager to NULL" << llendl; | 134 | llerrs << "LLPrimitive::sVolumeManager attempting to be set to NULL or it already has been set." << llendl; |
133 | } | 135 | } |
134 | sVolumeManager = volume_manager; | 136 | sVolumeManager = volume_manager; |
135 | } | 137 | } |
@@ -150,7 +152,9 @@ bool LLPrimitive::cleanupVolumeManager() | |||
150 | 152 | ||
151 | //=============================================================== | 153 | //=============================================================== |
152 | LLPrimitive::LLPrimitive() | 154 | LLPrimitive::LLPrimitive() |
153 | : mMiscFlags(0) | 155 | : mTextureList(), |
156 | mNumTEs(0), | ||
157 | mMiscFlags(0) | ||
154 | { | 158 | { |
155 | mPrimitiveCode = 0; | 159 | mPrimitiveCode = 0; |
156 | 160 | ||
@@ -167,20 +171,12 @@ LLPrimitive::LLPrimitive() | |||
167 | mAngularVelocity.setVec(0.f,0.f,0.f); | 171 | mAngularVelocity.setVec(0.f,0.f,0.f); |
168 | 172 | ||
169 | mScale.setVec(1.f,1.f,1.f); | 173 | mScale.setVec(1.f,1.f,1.f); |
170 | |||
171 | mNumTEs = 0; | ||
172 | mTextureList = NULL; | ||
173 | } | 174 | } |
174 | 175 | ||
175 | //=============================================================== | 176 | //=============================================================== |
176 | LLPrimitive::~LLPrimitive() | 177 | LLPrimitive::~LLPrimitive() |
177 | { | 178 | { |
178 | if (mTextureList) | 179 | clearTextureList(); |
179 | { | ||
180 | delete [] mTextureList; | ||
181 | mTextureList = NULL; | ||
182 | } | ||
183 | |||
184 | // Cleanup handled by volume manager | 180 | // Cleanup handled by volume manager |
185 | if (mVolumep) | 181 | if (mVolumep) |
186 | { | 182 | { |
@@ -189,6 +185,10 @@ LLPrimitive::~LLPrimitive() | |||
189 | mVolumep = NULL; | 185 | mVolumep = NULL; |
190 | } | 186 | } |
191 | 187 | ||
188 | void LLPrimitive::clearTextureList() | ||
189 | { | ||
190 | } | ||
191 | |||
192 | //=============================================================== | 192 | //=============================================================== |
193 | // static | 193 | // static |
194 | LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) | 194 | LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) |
@@ -212,15 +212,7 @@ LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) | |||
212 | void LLPrimitive::init_primitive(LLPCode p_code) | 212 | void LLPrimitive::init_primitive(LLPCode p_code) |
213 | { | 213 | { |
214 | LLMemType m1(LLMemType::MTYPE_PRIMITIVE); | 214 | LLMemType m1(LLMemType::MTYPE_PRIMITIVE); |
215 | if (mNumTEs) | 215 | clearTextureList(); |
216 | { | ||
217 | if (mTextureList) | ||
218 | { | ||
219 | delete [] mTextureList; | ||
220 | } | ||
221 | mTextureList = new LLTextureEntry[mNumTEs]; | ||
222 | } | ||
223 | |||
224 | mPrimitiveCode = p_code; | 216 | mPrimitiveCode = p_code; |
225 | } | 217 | } |
226 | 218 | ||
@@ -230,342 +222,147 @@ void LLPrimitive::setPCode(const U8 p_code) | |||
230 | } | 222 | } |
231 | 223 | ||
232 | //=============================================================== | 224 | //=============================================================== |
233 | const LLTextureEntry * LLPrimitive::getTE(const U8 te_num) const | 225 | LLTextureEntry* LLPrimitive::getTE(const U8 index) const |
234 | { | 226 | { |
235 | // if we're asking for a non-existent face, return null | 227 | return mTextureList.getTexture(index); |
236 | if (mNumTEs && (te_num< mNumTEs)) | ||
237 | { | ||
238 | return(&mTextureList[te_num]); | ||
239 | } | ||
240 | else | ||
241 | { | ||
242 | return(NULL); | ||
243 | } | ||
244 | } | 228 | } |
245 | 229 | ||
246 | //=============================================================== | 230 | //=============================================================== |
247 | void LLPrimitive::setNumTEs(const U8 num_tes) | 231 | void LLPrimitive::setNumTEs(const U8 num_tes) |
248 | { | 232 | { |
249 | if (num_tes == mNumTEs) | 233 | mTextureList.setSize(num_tes); |
250 | { | ||
251 | return; | ||
252 | } | ||
253 | |||
254 | // Right now, we don't try and preserve entries when the number of faces | ||
255 | // changes. | ||
256 | |||
257 | LLMemType m1(LLMemType::MTYPE_PRIMITIVE); | ||
258 | if (num_tes) | ||
259 | { | ||
260 | LLTextureEntry *new_tes; | ||
261 | new_tes = new LLTextureEntry[num_tes]; | ||
262 | U32 i; | ||
263 | for (i = 0; i < num_tes; i++) | ||
264 | { | ||
265 | if (i < mNumTEs) | ||
266 | { | ||
267 | new_tes[i] = mTextureList[i]; | ||
268 | } | ||
269 | else if (mNumTEs) | ||
270 | { | ||
271 | new_tes[i] = mTextureList[mNumTEs - 1]; | ||
272 | } | ||
273 | else | ||
274 | { | ||
275 | new_tes[i] = LLTextureEntry(); | ||
276 | } | ||
277 | } | ||
278 | delete[] mTextureList; | ||
279 | mTextureList = new_tes; | ||
280 | } | ||
281 | else | ||
282 | { | ||
283 | delete[] mTextureList; | ||
284 | mTextureList = NULL; | ||
285 | } | ||
286 | |||
287 | |||
288 | mNumTEs = num_tes; | ||
289 | } | 234 | } |
290 | 235 | ||
291 | //=============================================================== | 236 | //=============================================================== |
292 | void LLPrimitive::setAllTETextures(const LLUUID &tex_id) | 237 | void LLPrimitive::setAllTETextures(const LLUUID &tex_id) |
293 | { | 238 | { |
294 | U8 i; | 239 | mTextureList.setAllIDs(tex_id); |
295 | |||
296 | for (i = 0; i < mNumTEs; i++) | ||
297 | { | ||
298 | mTextureList[i].setID(tex_id); | ||
299 | } | ||
300 | } | 240 | } |
301 | 241 | ||
302 | //=============================================================== | 242 | //=============================================================== |
303 | void LLPrimitive::setTE(const U8 index, const LLTextureEntry &te) | 243 | void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te) |
304 | { | 244 | { |
305 | mTextureList[index] = te; | 245 | mTextureList.copyTexture(index, te); |
306 | } | 246 | } |
307 | 247 | ||
308 | S32 LLPrimitive::setTETexture(const U8 te, const LLUUID &tex_id) | 248 | S32 LLPrimitive::setTETexture(const U8 index, const LLUUID &id) |
309 | { | 249 | { |
310 | // if we're asking for a non-existent face, return null | 250 | return mTextureList.setID(index, id); |
311 | if (te >= mNumTEs) | ||
312 | { | ||
313 | llwarns << "setting non-existent te " << te << llendl; | ||
314 | return 0; | ||
315 | } | ||
316 | |||
317 | return mTextureList[te].setID(tex_id); | ||
318 | } | 251 | } |
319 | 252 | ||
320 | S32 LLPrimitive::setTEColor(const U8 te, const LLColor4 &color) | 253 | S32 LLPrimitive::setTEColor(const U8 index, const LLColor4 &color) |
321 | { | 254 | { |
322 | // if we're asking for a non-existent face, return null | ||
323 | if (te >= mNumTEs) | ||
324 | { | ||
325 | llwarns << "setting non-existent te " << te << llendl; | ||
326 | return 0; | ||
327 | } | ||
328 | 255 | ||
329 | return mTextureList[te].setColor(color); | 256 | return mTextureList.setColor(index, color); |
330 | } | 257 | } |
331 | 258 | ||
332 | S32 LLPrimitive::setTEColor(const U8 te, const LLColor3 &color) | 259 | S32 LLPrimitive::setTEColor(const U8 index, const LLColor3 &color) |
333 | { | 260 | { |
334 | // if we're asking for a non-existent face, return null | 261 | return mTextureList.setColor(index, color); |
335 | if (te >= mNumTEs) | ||
336 | { | ||
337 | llwarns << "setting non-existent te " << te << llendl; | ||
338 | return 0; | ||
339 | } | ||
340 | |||
341 | return mTextureList[te].setColor(color); | ||
342 | } | 262 | } |
343 | 263 | ||
344 | S32 LLPrimitive::setTEAlpha(const U8 te, const F32 alpha) | 264 | S32 LLPrimitive::setTEAlpha(const U8 index, const F32 alpha) |
345 | { | 265 | { |
346 | // if we're asking for a non-existent face, return null | 266 | return mTextureList.setAlpha(index, alpha); |
347 | if (te >= mNumTEs) | ||
348 | { | ||
349 | llwarns << "setting non-existent te " << te << llendl; | ||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | return mTextureList[te].setAlpha(alpha); | ||
354 | } | 267 | } |
355 | 268 | ||
356 | //=============================================================== | 269 | //=============================================================== |
357 | S32 LLPrimitive::setTEScale(const U8 te, const F32 s, const F32 t) | 270 | S32 LLPrimitive::setTEScale(const U8 index, const F32 s, const F32 t) |
358 | { | 271 | { |
359 | // if we're asking for a non-existent face, return null | 272 | return mTextureList.setScale(index, s, t); |
360 | if (te >= mNumTEs) | ||
361 | { | ||
362 | llwarns << "Setting nonexistent face" << llendl; | ||
363 | return 0; | ||
364 | } | ||
365 | |||
366 | return mTextureList[te].setScale(s,t); | ||
367 | } | 273 | } |
368 | 274 | ||
369 | 275 | ||
370 | // BUG: slow - done this way because texture entries have some | 276 | // BUG: slow - done this way because texture entries have some |
371 | // voodoo related to texture coords | 277 | // voodoo related to texture coords |
372 | S32 LLPrimitive::setTEScaleS(const U8 te, const F32 s) | 278 | S32 LLPrimitive::setTEScaleS(const U8 index, const F32 s) |
373 | { | 279 | { |
374 | if (te >= mNumTEs) | 280 | return mTextureList.setScaleS(index, s); |
375 | { | ||
376 | llwarns << "Setting nonexistent face" << llendl; | ||
377 | return 0; | ||
378 | } | ||
379 | |||
380 | F32 ignore, t; | ||
381 | mTextureList[te].getScale(&ignore, &t); | ||
382 | return mTextureList[te].setScale(s,t); | ||
383 | } | 281 | } |
384 | 282 | ||
385 | 283 | ||
386 | // BUG: slow - done this way because texture entries have some | 284 | // BUG: slow - done this way because texture entries have some |
387 | // voodoo related to texture coords | 285 | // voodoo related to texture coords |
388 | S32 LLPrimitive::setTEScaleT(const U8 te, const F32 t) | 286 | S32 LLPrimitive::setTEScaleT(const U8 index, const F32 t) |
389 | { | 287 | { |
390 | if (te >= mNumTEs) | 288 | return mTextureList.setScaleT(index, t); |
391 | { | ||
392 | llwarns << "Setting nonexistent face" << llendl; | ||
393 | return 0; | ||
394 | } | ||
395 | |||
396 | F32 s, ignore; | ||
397 | mTextureList[te].getScale(&s, &ignore); | ||
398 | return mTextureList[te].setScale(s,t); | ||
399 | } | 289 | } |
400 | 290 | ||
401 | 291 | ||
402 | //=============================================================== | 292 | //=============================================================== |
403 | S32 LLPrimitive::setTEOffset(const U8 te, const F32 s, const F32 t) | 293 | S32 LLPrimitive::setTEOffset(const U8 index, const F32 s, const F32 t) |
404 | { | 294 | { |
405 | // if we're asking for a non-existent face, return null | 295 | return mTextureList.setOffset(index, s, t); |
406 | if (te >= mNumTEs) | ||
407 | { | ||
408 | llwarns << "Setting nonexistent face" << llendl; | ||
409 | return 0; | ||
410 | } | ||
411 | |||
412 | return mTextureList[te].setOffset(s,t); | ||
413 | } | 296 | } |
414 | 297 | ||
415 | 298 | ||
416 | // BUG: slow - done this way because texture entries have some | 299 | // BUG: slow - done this way because texture entries have some |
417 | // voodoo related to texture coords | 300 | // voodoo related to texture coords |
418 | S32 LLPrimitive::setTEOffsetS(const U8 te, const F32 s) | 301 | S32 LLPrimitive::setTEOffsetS(const U8 index, const F32 s) |
419 | { | 302 | { |
420 | if (te >= mNumTEs) | 303 | return mTextureList.setOffsetS(index, s); |
421 | { | ||
422 | llwarns << "Setting nonexistent face" << llendl; | ||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | F32 ignore, t; | ||
427 | mTextureList[te].getOffset(&ignore, &t); | ||
428 | return mTextureList[te].setOffset(s,t); | ||
429 | } | 304 | } |
430 | 305 | ||
431 | 306 | ||
432 | // BUG: slow - done this way because texture entries have some | 307 | // BUG: slow - done this way because texture entries have some |
433 | // voodoo related to texture coords | 308 | // voodoo related to texture coords |
434 | S32 LLPrimitive::setTEOffsetT(const U8 te, const F32 t) | 309 | S32 LLPrimitive::setTEOffsetT(const U8 index, const F32 t) |
435 | { | 310 | { |
436 | if (te >= mNumTEs) | 311 | return mTextureList.setOffsetT(index, t); |
437 | { | ||
438 | llwarns << "Setting nonexistent face" << llendl; | ||
439 | return 0; | ||
440 | } | ||
441 | |||
442 | F32 s, ignore; | ||
443 | mTextureList[te].getOffset(&s, &ignore); | ||
444 | return mTextureList[te].setOffset(s,t); | ||
445 | } | 312 | } |
446 | 313 | ||
447 | 314 | ||
448 | //=============================================================== | 315 | //=============================================================== |
449 | S32 LLPrimitive::setTERotation(const U8 te, const F32 r) | 316 | S32 LLPrimitive::setTERotation(const U8 index, const F32 r) |
450 | { | 317 | { |
451 | // if we're asking for a non-existent face, return null | 318 | return mTextureList.setRotation(index, r); |
452 | if (te >= mNumTEs) | ||
453 | { | ||
454 | llwarns << "Setting nonexistent face" << llendl; | ||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | return mTextureList[te].setRotation(r); | ||
459 | } | 319 | } |
460 | 320 | ||
461 | 321 | ||
462 | //=============================================================== | 322 | //=============================================================== |
463 | S32 LLPrimitive::setTEBumpShinyFullbright(const U8 te, const U8 bump) | 323 | S32 LLPrimitive::setTEBumpShinyFullbright(const U8 index, const U8 bump) |
464 | { | 324 | { |
465 | // if we're asking for a non-existent face, return null | 325 | return mTextureList.setBumpShinyFullbright(index, bump); |
466 | if (te >= mNumTEs) | ||
467 | { | ||
468 | llwarns << "setting non-existent te " << te << llendl; | ||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | return mTextureList[te].setBumpShinyFullbright( bump ); | ||
473 | } | 326 | } |
474 | 327 | ||
475 | S32 LLPrimitive::setTEMediaTexGen(const U8 te, const U8 media) | 328 | S32 LLPrimitive::setTEMediaTexGen(const U8 index, const U8 media) |
476 | { | 329 | { |
477 | // if we're asking for a non-existent face, return null | 330 | return mTextureList.setMediaTexGen(index, media); |
478 | if (te >= mNumTEs) | ||
479 | { | ||
480 | llwarns << "setting non-existent te " << te << llendl; | ||
481 | return 0; | ||
482 | } | ||
483 | |||
484 | return mTextureList[te].setMediaTexGen( media ); | ||
485 | } | 331 | } |
486 | 332 | ||
487 | S32 LLPrimitive::setTEBumpmap(const U8 te, const U8 bump) | 333 | S32 LLPrimitive::setTEBumpmap(const U8 index, const U8 bump) |
488 | { | 334 | { |
489 | // if we're asking for a non-existent face, return null | 335 | return mTextureList.setBumpMap(index, bump); |
490 | if (te >= mNumTEs) | ||
491 | { | ||
492 | llwarns << "setting non-existent te " << te << llendl; | ||
493 | return 0; | ||
494 | } | ||
495 | |||
496 | return mTextureList[te].setBumpmap( bump ); | ||
497 | } | 336 | } |
498 | 337 | ||
499 | S32 LLPrimitive::setTEBumpShiny(const U8 te, const U8 bump_shiny) | 338 | S32 LLPrimitive::setTEBumpShiny(const U8 index, const U8 bump_shiny) |
500 | { | 339 | { |
501 | // if we're asking for a non-existent face, return null | 340 | return mTextureList.setBumpShiny(index, bump_shiny); |
502 | if (te >= mNumTEs) | ||
503 | { | ||
504 | llwarns << "setting non-existent te " << te << llendl; | ||
505 | return 0; | ||
506 | } | ||
507 | |||
508 | return mTextureList[te].setBumpShiny( bump_shiny ); | ||
509 | } | 341 | } |
510 | 342 | ||
511 | S32 LLPrimitive::setTETexGen(const U8 te, const U8 texgen) | 343 | S32 LLPrimitive::setTETexGen(const U8 index, const U8 texgen) |
512 | { | 344 | { |
513 | // if we're asking for a non-existent face, return null | 345 | return mTextureList.setTexGen(index, texgen); |
514 | if (te >= mNumTEs) | ||
515 | { | ||
516 | llwarns << "setting non-existent te " << te << llendl; | ||
517 | return 0; | ||
518 | } | ||
519 | |||
520 | return mTextureList[te].setTexGen( texgen ); | ||
521 | } | 346 | } |
522 | 347 | ||
523 | S32 LLPrimitive::setTEShiny(const U8 te, const U8 shiny) | 348 | S32 LLPrimitive::setTEShiny(const U8 index, const U8 shiny) |
524 | { | 349 | { |
525 | // if we're asking for a non-existent face, return null | 350 | return mTextureList.setShiny(index, shiny); |
526 | if (te >= mNumTEs) | ||
527 | { | ||
528 | llwarns << "setting non-existent te " << te << llendl; | ||
529 | return 0; | ||
530 | } | ||
531 | |||
532 | return mTextureList[te].setShiny( shiny ); | ||
533 | } | 351 | } |
534 | 352 | ||
535 | S32 LLPrimitive::setTEFullbright(const U8 te, const U8 fullbright) | 353 | S32 LLPrimitive::setTEFullbright(const U8 index, const U8 fullbright) |
536 | { | 354 | { |
537 | // if we're asking for a non-existent face, return null | 355 | return mTextureList.setFullbright(index, fullbright); |
538 | if (te >= mNumTEs) | ||
539 | { | ||
540 | llwarns << "setting non-existent te " << te << llendl; | ||
541 | return 0; | ||
542 | } | ||
543 | |||
544 | return mTextureList[te].setFullbright( fullbright ); | ||
545 | } | 356 | } |
546 | 357 | ||
547 | S32 LLPrimitive::setTEMediaFlags(const U8 te, const U8 media_flags) | 358 | S32 LLPrimitive::setTEMediaFlags(const U8 index, const U8 media_flags) |
548 | { | 359 | { |
549 | // if we're asking for a non-existent face, return null | 360 | return mTextureList.setMediaFlags(index, media_flags); |
550 | if (te >= mNumTEs) | ||
551 | { | ||
552 | llwarns << "setting non-existent te " << te << llendl; | ||
553 | return 0; | ||
554 | } | ||
555 | |||
556 | return mTextureList[te].setMediaFlags( media_flags ); | ||
557 | } | 361 | } |
558 | 362 | ||
559 | S32 LLPrimitive::setTEGlow(const U8 te, const F32 glow) | 363 | S32 LLPrimitive::setTEGlow(const U8 index, const F32 glow) |
560 | { | 364 | { |
561 | // if we're asking for a non-existent face, return null | 365 | return mTextureList.setGlow(index, glow); |
562 | if (te >= mNumTEs) | ||
563 | { | ||
564 | llwarns << "setting non-existent te " << te << llendl; | ||
565 | return 0; | ||
566 | } | ||
567 | |||
568 | return mTextureList[te].setGlow( glow ); | ||
569 | } | 366 | } |
570 | 367 | ||
571 | 368 | ||
@@ -877,25 +674,18 @@ std::string LLPrimitive::pCodeToString(const LLPCode pcode) | |||
877 | void LLPrimitive::copyTEs(const LLPrimitive *primitivep) | 674 | void LLPrimitive::copyTEs(const LLPrimitive *primitivep) |
878 | { | 675 | { |
879 | U32 i; | 676 | U32 i; |
880 | if (primitivep->getNumTEs() != getNumTEs()) | 677 | if (primitivep->getExpectedNumTEs() != getExpectedNumTEs()) |
678 | { | ||
679 | llwarns << "Primitives don't have same expected number of TE's" << llendl; | ||
680 | } | ||
681 | U32 num_tes = llmin(primitivep->getExpectedNumTEs(), getExpectedNumTEs()); | ||
682 | if (mTextureList.size() < getExpectedNumTEs()) | ||
881 | { | 683 | { |
882 | llwarns << "Primitives don't have same number of TE's" << llendl; | 684 | mTextureList.setSize(getExpectedNumTEs()); |
883 | } | 685 | } |
884 | U32 num_tes = llmin(primitivep->getNumTEs(), getNumTEs()); | ||
885 | for (i = 0; i < num_tes; i++) | 686 | for (i = 0; i < num_tes; i++) |
886 | { | 687 | { |
887 | const LLTextureEntry *tep = primitivep->getTE(i); | 688 | mTextureList.copyTexture(i, *(primitivep->getTE(i))); |
888 | F32 s, t; | ||
889 | setTETexture(i, tep->getID()); | ||
890 | setTEColor(i, tep->getColor()); | ||
891 | tep->getScale(&s, &t); | ||
892 | setTEScale(i, s, t); | ||
893 | tep->getOffset(&s, &t); | ||
894 | setTEOffset(i, s, t); | ||
895 | setTERotation(i, tep->getRotation()); | ||
896 | setTEBumpShinyFullbright(i, tep->getBumpShinyFullbright()); | ||
897 | setTEMediaTexGen(i, tep->getMediaTexGen()); | ||
898 | setTEGlow(i, tep->getGlow()); | ||
899 | } | 689 | } |
900 | } | 690 | } |
901 | 691 | ||
@@ -957,73 +747,208 @@ BOOL LLPrimitive::setVolume(const LLVolumeParams &volume_params, const S32 detai | |||
957 | 747 | ||
958 | U32 old_face_mask = mVolumep->mFaceMask; | 748 | U32 old_face_mask = mVolumep->mFaceMask; |
959 | 749 | ||
750 | |||
751 | S32 face_bit = 0; | ||
752 | S32 cur_mask = 0; | ||
753 | |||
754 | // Grab copies of the old faces from the original shape, ordered by type. | ||
755 | // We will use these to figure out what old texture info gets mapped to new | ||
756 | // faces in the new shape. | ||
757 | std::vector<LLProfile::Face> old_faces; | ||
758 | for (S32 face = 0; face < mVolumep->getNumFaces(); face++) | ||
759 | { | ||
760 | old_faces.push_back(mVolumep->getProfile().mFaces[face]); | ||
761 | } | ||
762 | |||
763 | // Copy the old texture info off to the side, but not in the order in which | ||
764 | // they live in the mTextureList, rather in order of ther "face id" which | ||
765 | // is the corresponding value of LLVolueParams::LLProfile::mFaces::mIndex. | ||
766 | // | ||
767 | // Hence, some elements of old_tes::mEntryList will be invalid. It is | ||
768 | // initialized to a size of 9 (max number of possible faces on a volume?) | ||
769 | // and only the ones with valid types are filled in. | ||
770 | LLPrimTextureList old_tes; | ||
771 | old_tes.setSize(9); | ||
772 | for (face_bit = 0; face_bit < 9; face_bit++) | ||
773 | { | ||
774 | cur_mask = 0x1 << face_bit; | ||
775 | if (old_face_mask & cur_mask) | ||
776 | { | ||
777 | S32 te_index = face_index_from_id(cur_mask, old_faces); | ||
778 | old_tes.copyTexture(face_bit, *(getTE(te_index))); | ||
779 | //llinfos << face_bit << ":" << te_index << ":" << old_tes[face_bit].getID() << llendl; | ||
780 | } | ||
781 | } | ||
782 | |||
783 | |||
960 | // build the new object | 784 | // build the new object |
961 | sVolumeManager->unrefVolume(mVolumep); | 785 | sVolumeManager->unrefVolume(mVolumep); |
962 | mVolumep = volumep; | 786 | mVolumep = volumep; |
963 | 787 | ||
964 | U32 new_face_mask = mVolumep->mFaceMask; | 788 | U32 new_face_mask = mVolumep->mFaceMask; |
965 | if (old_face_mask != new_face_mask) | 789 | S32 i; |
966 | { | ||
967 | setNumTEs(mVolumep->getNumFaces()); | ||
968 | } | ||
969 | |||
970 | return TRUE; | ||
971 | } | ||
972 | 790 | ||
973 | BOOL LLPrimitive::setMaterial(U8 material) | 791 | if (old_face_mask == new_face_mask) |
974 | { | ||
975 | if (material != mMaterial) | ||
976 | { | 792 | { |
977 | mMaterial = material; | 793 | setNumTEs(mVolumep->getNumFaces()); |
978 | return TRUE; | 794 | return TRUE; |
979 | } | 795 | } |
980 | else | ||
981 | { | ||
982 | return FALSE; | ||
983 | } | ||
984 | } | ||
985 | 796 | ||
986 | void LLPrimitive::setTEArrays(const U8 size, | 797 | // initialize face_mapping |
987 | const LLUUID* image_ids, | 798 | S32 face_mapping[9]; |
988 | const F32* scale_s, | 799 | for (face_bit = 0; face_bit < 9; face_bit++) |
989 | const F32* scale_t) | ||
990 | { | ||
991 | S32 cur_size = size; | ||
992 | if (cur_size > getNumTEs()) | ||
993 | { | 800 | { |
994 | llwarns << "Trying to set more TEs than exist!" << llendl; | 801 | face_mapping[face_bit] = face_bit; |
995 | cur_size = getNumTEs(); | ||
996 | } | 802 | } |
997 | 803 | ||
998 | S32 i; | 804 | // The new shape may have more faces than the original, but we can't just |
999 | // Copy over image information | 805 | // add them to the end -- the ordering matters and it may be that we must |
1000 | for (i = 0; i < cur_size; i++) | 806 | // insert the new faces in the middle of the list. When we add a face it |
807 | // will pick up the texture/color info of one of the old faces an so we | ||
808 | // now figure out which old face info gets mapped to each new face, and | ||
809 | // store in the face_mapping lookup table. | ||
810 | for (face_bit = 0; face_bit < 9; face_bit++) | ||
1001 | { | 811 | { |
1002 | // This is very BAD!!!!!! | 812 | cur_mask = 0x1 << face_bit; |
1003 | if (image_ids != NULL) | 813 | if (!(new_face_mask & cur_mask)) |
1004 | { | 814 | { |
1005 | setTETexture(i,image_ids[i]); | 815 | // Face doesn't exist in new map. |
816 | face_mapping[face_bit] = -1; | ||
817 | continue; | ||
1006 | } | 818 | } |
1007 | if (scale_s && scale_t) | 819 | else if (old_face_mask & cur_mask) |
1008 | { | 820 | { |
1009 | setTEScale(i, scale_s[i], scale_t[i]); | 821 | // Face exists in new and old map. |
822 | face_mapping[face_bit] = face_bit; | ||
823 | continue; | ||
1010 | } | 824 | } |
1011 | } | ||
1012 | 825 | ||
1013 | if (i < getNumTEs()) | 826 | // OK, how we've got a mismatch, where we have to fill a new face with one from |
1014 | { | 827 | // the old face. |
1015 | cur_size--; | 828 | if (cur_mask & (LL_FACE_PATH_BEGIN | LL_FACE_PATH_END | LL_FACE_INNER_SIDE)) |
1016 | for (i=i; i < getNumTEs(); i++) // the i=i removes a gcc warning | ||
1017 | { | 829 | { |
1018 | if (image_ids != NULL) | 830 | // It's a top/bottom/hollow interior face. |
831 | if (old_face_mask & LL_FACE_PATH_END) | ||
1019 | { | 832 | { |
1020 | setTETexture(i, image_ids[cur_size]); | 833 | face_mapping[face_bit] = 1; |
834 | continue; | ||
1021 | } | 835 | } |
1022 | if (scale_s && scale_t) | 836 | else |
1023 | { | 837 | { |
1024 | setTEScale(i, scale_s[cur_size], scale_t[cur_size]); | 838 | S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; |
839 | for (i = 0; i < 4; i++) | ||
840 | { | ||
841 | if (old_face_mask & cur_outer_mask) | ||
842 | { | ||
843 | face_mapping[face_bit] = 5 + i; | ||
844 | break; | ||
845 | } | ||
846 | cur_outer_mask <<= 1; | ||
847 | } | ||
848 | if (i == 4) | ||
849 | { | ||
850 | llwarns << "No path end or outer face in volume!" << llendl; | ||
851 | } | ||
852 | continue; | ||
1025 | } | 853 | } |
1026 | } | 854 | } |
855 | |||
856 | if (cur_mask & (LL_FACE_PROFILE_BEGIN | LL_FACE_PROFILE_END)) | ||
857 | { | ||
858 | // A cut slice. Use the hollow interior if we have it. | ||
859 | if (old_face_mask & LL_FACE_INNER_SIDE) | ||
860 | { | ||
861 | face_mapping[face_bit] = 2; | ||
862 | continue; | ||
863 | } | ||
864 | |||
865 | // No interior, use the bottom face. | ||
866 | // Could figure out which of the outer faces was nearest, but that would be harder. | ||
867 | if (old_face_mask & LL_FACE_PATH_END) | ||
868 | { | ||
869 | face_mapping[face_bit] = 1; | ||
870 | continue; | ||
871 | } | ||
872 | else | ||
873 | { | ||
874 | S32 cur_outer_mask = LL_FACE_OUTER_SIDE_0; | ||
875 | for (i = 0; i < 4; i++) | ||
876 | { | ||
877 | if (old_face_mask & cur_outer_mask) | ||
878 | { | ||
879 | face_mapping[face_bit] = 5 + i; | ||
880 | break; | ||
881 | } | ||
882 | cur_outer_mask <<= 1; | ||
883 | } | ||
884 | if (i == 4) | ||
885 | { | ||
886 | llwarns << "No path end or outer face in volume!" << llendl; | ||
887 | } | ||
888 | continue; | ||
889 | } | ||
890 | } | ||
891 | |||
892 | // OK, the face that's missing is an outer face... | ||
893 | // Pull from the nearest adjacent outer face (there's always guaranteed to be one... | ||
894 | S32 cur_outer = face_bit - 5; | ||
895 | S32 min_dist = 5; | ||
896 | S32 min_outer_bit = -1; | ||
897 | S32 i; | ||
898 | for (i = 0; i < 4; i++) | ||
899 | { | ||
900 | if (old_face_mask & (LL_FACE_OUTER_SIDE_0 << i)) | ||
901 | { | ||
902 | S32 dist = abs(i - cur_outer); | ||
903 | if (dist < min_dist) | ||
904 | { | ||
905 | min_dist = dist; | ||
906 | min_outer_bit = i + 5; | ||
907 | } | ||
908 | } | ||
909 | } | ||
910 | if (-1 == min_outer_bit) | ||
911 | { | ||
912 | llinfos << (LLVolume *)mVolumep << llendl; | ||
913 | llwarns << "Bad! No outer faces, impossible!" << llendl; | ||
914 | } | ||
915 | face_mapping[face_bit] = min_outer_bit; | ||
916 | } | ||
917 | |||
918 | |||
919 | setNumTEs(mVolumep->getNumFaces()); | ||
920 | for (face_bit = 0; face_bit < 9; face_bit++) | ||
921 | { | ||
922 | // For each possible face type on the new shape we check to see if that | ||
923 | // face exists and if it does we create a texture entry that is a copy | ||
924 | // of one of the originals. Since the originals might not have a | ||
925 | // matching face, we use the face_mapping lookup table to figure out | ||
926 | // which face information to copy. | ||
927 | cur_mask = 0x1 << face_bit; | ||
928 | if (new_face_mask & cur_mask) | ||
929 | { | ||
930 | if (-1 == face_mapping[face_bit]) | ||
931 | { | ||
932 | llwarns << "No mapping from old face to new face!" << llendl; | ||
933 | } | ||
934 | |||
935 | S32 te_num = face_index_from_id(cur_mask, mVolumep->getProfile().mFaces); | ||
936 | setTE(te_num, *(old_tes.getTexture(face_mapping[face_bit]))); | ||
937 | } | ||
938 | } | ||
939 | return TRUE; | ||
940 | } | ||
941 | |||
942 | BOOL LLPrimitive::setMaterial(U8 material) | ||
943 | { | ||
944 | if (material != mMaterial) | ||
945 | { | ||
946 | mMaterial = material; | ||
947 | return TRUE; | ||
948 | } | ||
949 | else | ||
950 | { | ||
951 | return FALSE; | ||
1027 | } | 952 | } |
1028 | } | 953 | } |
1029 | 954 | ||
@@ -1178,6 +1103,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys, int shield) const | |||
1178 | else memcpy(&image_ids[face_index*16],LLUUID("4934f1bf-3b1f-cf4f-dbdf-a72550d05bc6").mData,16);//grey block | 1103 | else memcpy(&image_ids[face_index*16],LLUUID("4934f1bf-3b1f-cf4f-dbdf-a72550d05bc6").mData,16);//grey block |
1179 | }else memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */ | 1104 | }else memcpy(&image_ids[face_index*16],getTE(face_index)->getID().mData,16); /* Flawfinder: ignore */ |
1180 | 1105 | ||
1106 | |||
1181 | // Cast LLColor4 to LLColor4U | 1107 | // Cast LLColor4 to LLColor4U |
1182 | coloru.setVec( getTE(face_index)->getColor() ); | 1108 | coloru.setVec( getTE(face_index)->getColor() ); |
1183 | 1109 | ||
@@ -1402,6 +1328,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con | |||
1402 | color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f; | 1328 | color.mV[VALPHA] = F32(255 - coloru.mV[VALPHA]) / 255.f; |
1403 | 1329 | ||
1404 | retval |= setTEColor(i, color); | 1330 | retval |= setTEColor(i, color); |
1331 | |||
1405 | } | 1332 | } |
1406 | 1333 | ||
1407 | return retval; | 1334 | return retval; |
@@ -1501,11 +1428,24 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp) | |||
1501 | return retval; | 1428 | return retval; |
1502 | } | 1429 | } |
1503 | 1430 | ||
1504 | void LLPrimitive::setTextureList(LLTextureEntry *listp) | 1431 | U8 LLPrimitive::getExpectedNumTEs() const |
1432 | { | ||
1433 | U8 expected_face_count = 0; | ||
1434 | if (mVolumep) | ||
1435 | { | ||
1436 | expected_face_count = mVolumep->getNumFaces(); | ||
1437 | } | ||
1438 | return expected_face_count; | ||
1439 | } | ||
1440 | |||
1441 | void LLPrimitive::copyTextureList(const LLPrimTextureList& other_list) | ||
1442 | { | ||
1443 | mTextureList.copy(other_list); | ||
1444 | } | ||
1445 | |||
1446 | void LLPrimitive::takeTextureList(LLPrimTextureList& other_list) | ||
1505 | { | 1447 | { |
1506 | LLTextureEntry* old_texture_list = mTextureList; | 1448 | mTextureList.take(other_list); |
1507 | mTextureList = listp; | ||
1508 | delete[] old_texture_list; | ||
1509 | } | 1449 | } |
1510 | 1450 | ||
1511 | //============================================================================ | 1451 | //============================================================================ |
@@ -1569,6 +1509,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size) | |||
1569 | return (size == 16); | 1509 | return (size == 16); |
1570 | case PARAMS_SCULPT: | 1510 | case PARAMS_SCULPT: |
1571 | return (size == 17); | 1511 | return (size == 17); |
1512 | case PARAMS_LIGHT_IMAGE: | ||
1513 | return (size == 28); | ||
1572 | } | 1514 | } |
1573 | 1515 | ||
1574 | return FALSE; | 1516 | return FALSE; |
@@ -1901,3 +1843,78 @@ bool LLSculptParams::fromLLSD(LLSD& sd) | |||
1901 | return false; | 1843 | return false; |
1902 | } | 1844 | } |
1903 | 1845 | ||
1846 | //============================================================================ | ||
1847 | |||
1848 | LLLightImageParams::LLLightImageParams() | ||
1849 | { | ||
1850 | mType = PARAMS_LIGHT_IMAGE; | ||
1851 | mParams.setVec(F_PI*0.5f, 0.f, 0.f); | ||
1852 | } | ||
1853 | |||
1854 | BOOL LLLightImageParams::pack(LLDataPacker &dp) const | ||
1855 | { | ||
1856 | dp.packUUID(mLightTexture, "texture"); | ||
1857 | dp.packVector3(mParams, "params"); | ||
1858 | |||
1859 | return TRUE; | ||
1860 | } | ||
1861 | |||
1862 | BOOL LLLightImageParams::unpack(LLDataPacker &dp) | ||
1863 | { | ||
1864 | dp.unpackUUID(mLightTexture, "texture"); | ||
1865 | dp.unpackVector3(mParams, "params"); | ||
1866 | |||
1867 | return TRUE; | ||
1868 | } | ||
1869 | |||
1870 | bool LLLightImageParams::operator==(const LLNetworkData& data) const | ||
1871 | { | ||
1872 | if (data.mType != PARAMS_LIGHT_IMAGE) | ||
1873 | { | ||
1874 | return false; | ||
1875 | } | ||
1876 | |||
1877 | const LLLightImageParams *param = (const LLLightImageParams*)&data; | ||
1878 | if ( (param->mLightTexture != mLightTexture) ) | ||
1879 | { | ||
1880 | return false; | ||
1881 | } | ||
1882 | |||
1883 | if ( (param->mParams != mParams ) ) | ||
1884 | { | ||
1885 | return false; | ||
1886 | } | ||
1887 | |||
1888 | return true; | ||
1889 | } | ||
1890 | |||
1891 | void LLLightImageParams::copy(const LLNetworkData& data) | ||
1892 | { | ||
1893 | const LLLightImageParams *param = (LLLightImageParams*)&data; | ||
1894 | mLightTexture = param->mLightTexture; | ||
1895 | mParams = param->mParams; | ||
1896 | } | ||
1897 | |||
1898 | |||
1899 | |||
1900 | LLSD LLLightImageParams::asLLSD() const | ||
1901 | { | ||
1902 | LLSD sd; | ||
1903 | |||
1904 | sd["texture"] = mLightTexture; | ||
1905 | sd["params"] = mParams.getValue(); | ||
1906 | |||
1907 | return sd; | ||
1908 | } | ||
1909 | |||
1910 | bool LLLightImageParams::fromLLSD(LLSD& sd) | ||
1911 | { | ||
1912 | if (sd.has("texture")) | ||
1913 | { | ||
1914 | setLightTexture( sd["texture"] ); | ||
1915 | setParams( LLVector3( sd["params"] ) ); | ||
1916 | return true; | ||
1917 | } | ||
1918 | |||
1919 | return false; | ||
1920 | } | ||