aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/llprimitive/llprimitive.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-x[-rw-r--r--]linden/indra/llprimitive/llprimitive.cpp667
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;
111const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE; 112const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE;
112const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE; 113const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE;
113 114
115const S32 MAX_FACE_BITS = 9;
114 116
115const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e"; 117const 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//===============================================================
152LLPrimitive::LLPrimitive() 154LLPrimitive::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//===============================================================
176LLPrimitive::~LLPrimitive() 177LLPrimitive::~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
188void LLPrimitive::clearTextureList()
189{
190}
191
192//=============================================================== 192//===============================================================
193// static 193// static
194LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code) 194LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code)
@@ -212,15 +212,7 @@ LLPrimitive *LLPrimitive::createPrimitive(LLPCode p_code)
212void LLPrimitive::init_primitive(LLPCode p_code) 212void 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//===============================================================
233const LLTextureEntry * LLPrimitive::getTE(const U8 te_num) const 225LLTextureEntry* 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//===============================================================
247void LLPrimitive::setNumTEs(const U8 num_tes) 231void 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//===============================================================
292void LLPrimitive::setAllTETextures(const LLUUID &tex_id) 237void 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//===============================================================
303void LLPrimitive::setTE(const U8 index, const LLTextureEntry &te) 243void LLPrimitive::setTE(const U8 index, const LLTextureEntry& te)
304{ 244{
305 mTextureList[index] = te; 245 mTextureList.copyTexture(index, te);
306} 246}
307 247
308S32 LLPrimitive::setTETexture(const U8 te, const LLUUID &tex_id) 248S32 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
320S32 LLPrimitive::setTEColor(const U8 te, const LLColor4 &color) 253S32 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
332S32 LLPrimitive::setTEColor(const U8 te, const LLColor3 &color) 259S32 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
344S32 LLPrimitive::setTEAlpha(const U8 te, const F32 alpha) 264S32 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//===============================================================
357S32 LLPrimitive::setTEScale(const U8 te, const F32 s, const F32 t) 270S32 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
372S32 LLPrimitive::setTEScaleS(const U8 te, const F32 s) 278S32 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
388S32 LLPrimitive::setTEScaleT(const U8 te, const F32 t) 286S32 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//===============================================================
403S32 LLPrimitive::setTEOffset(const U8 te, const F32 s, const F32 t) 293S32 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
418S32 LLPrimitive::setTEOffsetS(const U8 te, const F32 s) 301S32 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
434S32 LLPrimitive::setTEOffsetT(const U8 te, const F32 t) 309S32 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//===============================================================
449S32 LLPrimitive::setTERotation(const U8 te, const F32 r) 316S32 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//===============================================================
463S32 LLPrimitive::setTEBumpShinyFullbright(const U8 te, const U8 bump) 323S32 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
475S32 LLPrimitive::setTEMediaTexGen(const U8 te, const U8 media) 328S32 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
487S32 LLPrimitive::setTEBumpmap(const U8 te, const U8 bump) 333S32 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
499S32 LLPrimitive::setTEBumpShiny(const U8 te, const U8 bump_shiny) 338S32 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
511S32 LLPrimitive::setTETexGen(const U8 te, const U8 texgen) 343S32 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
523S32 LLPrimitive::setTEShiny(const U8 te, const U8 shiny) 348S32 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
535S32 LLPrimitive::setTEFullbright(const U8 te, const U8 fullbright) 353S32 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
547S32 LLPrimitive::setTEMediaFlags(const U8 te, const U8 media_flags) 358S32 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
559S32 LLPrimitive::setTEGlow(const U8 te, const F32 glow) 363S32 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)
877void LLPrimitive::copyTEs(const LLPrimitive *primitivep) 674void 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
973BOOL 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
986void 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
942BOOL 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
1504void LLPrimitive::setTextureList(LLTextureEntry *listp) 1431U8 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
1441void LLPrimitive::copyTextureList(const LLPrimTextureList& other_list)
1442{
1443 mTextureList.copy(other_list);
1444}
1445
1446void 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
1848LLLightImageParams::LLLightImageParams()
1849{
1850 mType = PARAMS_LIGHT_IMAGE;
1851 mParams.setVec(F_PI*0.5f, 0.f, 0.f);
1852}
1853
1854BOOL LLLightImageParams::pack(LLDataPacker &dp) const
1855{
1856 dp.packUUID(mLightTexture, "texture");
1857 dp.packVector3(mParams, "params");
1858
1859 return TRUE;
1860}
1861
1862BOOL LLLightImageParams::unpack(LLDataPacker &dp)
1863{
1864 dp.unpackUUID(mLightTexture, "texture");
1865 dp.unpackVector3(mParams, "params");
1866
1867 return TRUE;
1868}
1869
1870bool 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
1891void LLLightImageParams::copy(const LLNetworkData& data)
1892{
1893 const LLLightImageParams *param = (LLLightImageParams*)&data;
1894 mLightTexture = param->mLightTexture;
1895 mParams = param->mParams;
1896}
1897
1898
1899
1900LLSD LLLightImageParams::asLLSD() const
1901{
1902 LLSD sd;
1903
1904 sd["texture"] = mLightTexture;
1905 sd["params"] = mParams.getValue();
1906
1907 return sd;
1908}
1909
1910bool 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}