aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/lldrawable.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:44:50 -0500
committerJacek Antonelli2008-08-15 23:44:50 -0500
commit89fe5dab825a62a0e3fd8d248cbc91c65eb2a426 (patch)
treebcff14b7888d04a2fec799c59369f6095224bd08 /linden/indra/newview/lldrawable.cpp
parentSecond Life viewer sources 1.13.3.2 (diff)
downloadmeta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.zip
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.gz
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.bz2
meta-impy-89fe5dab825a62a0e3fd8d248cbc91c65eb2a426.tar.xz
Second Life viewer sources 1.14.0.0
Diffstat (limited to 'linden/indra/newview/lldrawable.cpp')
-rw-r--r--linden/indra/newview/lldrawable.cpp633
1 files changed, 422 insertions, 211 deletions
diff --git a/linden/indra/newview/lldrawable.cpp b/linden/indra/newview/lldrawable.cpp
index af4f205..4d9083e 100644
--- a/linden/indra/newview/lldrawable.cpp
+++ b/linden/indra/newview/lldrawable.cpp
@@ -33,8 +33,6 @@
33#include "material_codes.h" 33#include "material_codes.h"
34 34
35// viewer includes 35// viewer includes
36#include "llagparray.h"
37#include "llagparray.inl"
38#include "llcriticaldamp.h" 36#include "llcriticaldamp.h"
39#include "llface.h" 37#include "llface.h"
40#include "lllightconstants.h" 38#include "lllightconstants.h"
@@ -77,6 +75,8 @@ U32 LLDrawable::sNumZombieDrawables = 0;
77F32 LLDrawable::sCurPixelAngle = 0; 75F32 LLDrawable::sCurPixelAngle = 0;
78LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList; 76LLDynamicArrayPtr<LLPointer<LLDrawable> > LLDrawable::sDeadList;
79 77
78#define FORCE_INVISIBLE_AREA 16.f
79
80// static 80// static
81void LLDrawable::incrementVisible() 81void LLDrawable::incrementVisible()
82{ 82{
@@ -127,12 +127,11 @@ void LLDrawable::destroy()
127 std::for_each(mFaces.begin(), mFaces.end(), DeletePointer()); 127 std::for_each(mFaces.begin(), mFaces.end(), DeletePointer());
128 mFaces.clear(); 128 mFaces.clear();
129 129
130 /* 130
131 if (!(sNumZombieDrawables % 10)) 131 /*if (!(sNumZombieDrawables % 10))
132 { 132 {
133 llinfos << "- Zombie drawables: " << sNumZombieDrawables << llendl; 133 llinfos << "- Zombie drawables: " << sNumZombieDrawables << llendl;
134 } 134 }*/
135 */
136} 135}
137 136
138void LLDrawable::markDead() 137void LLDrawable::markDead()
@@ -269,7 +268,7 @@ void LLDrawable::removeFace(const S32 i)
269} 268}
270#endif 269#endif
271 270
272LLFace* LLDrawable::addFace(LLDrawPool *poolp, LLViewerImage *texturep, const BOOL shared_geom) 271LLFace* LLDrawable::addFace(LLFacePool *poolp, LLViewerImage *texturep)
273{ 272{
274 LLMemType mt(LLMemType::MTYPE_DRAWABLE); 273 LLMemType mt(LLMemType::MTYPE_DRAWABLE);
275 274
@@ -278,16 +277,12 @@ LLFace* LLDrawable::addFace(LLDrawPool *poolp, LLViewerImage *texturep, const BO
278 if (face) 277 if (face)
279 { 278 {
280 mFaces.push_back(face); 279 mFaces.push_back(face);
281 face->setPool(poolp, texturep);
282 280
283 if (shared_geom) 281 if (poolp)
284 { 282 {
285 face->setState(LLFace::SHARED_GEOM); 283 face->setPool(poolp, texturep);
286 }
287 else if (!isVisible())
288 {
289 face->setState(LLFace::BACKLIST);
290 } 284 }
285
291 if (isState(UNLIT)) 286 if (isState(UNLIT))
292 { 287 {
293 face->setState(LLFace::FULLBRIGHT); 288 face->setState(LLFace::FULLBRIGHT);
@@ -296,7 +291,27 @@ LLFace* LLDrawable::addFace(LLDrawPool *poolp, LLViewerImage *texturep, const BO
296 return face; 291 return face;
297} 292}
298 293
299void LLDrawable::setNumFaces(const S32 newFaces, LLDrawPool *poolp, LLViewerImage *texturep) 294LLFace* LLDrawable::addFace(const LLTextureEntry *te, LLViewerImage *texturep)
295{
296 LLMemType mt(LLMemType::MTYPE_DRAWABLE);
297
298 LLFace *face = new LLFace(this, mVObjp);
299
300 face->setTEOffset(mFaces.size());
301 face->setTexture(texturep);
302 face->setPoolType(gPipeline.getPoolTypeFromTE(te, texturep));
303 mFaces.push_back(face);
304
305 if (isState(UNLIT))
306 {
307 face->setState(LLFace::FULLBRIGHT);
308 }
309
310 return face;
311
312}
313
314void LLDrawable::setNumFaces(const S32 newFaces, LLFacePool *poolp, LLViewerImage *texturep)
300{ 315{
301 if (newFaces == (S32)mFaces.size()) 316 if (newFaces == (S32)mFaces.size())
302 { 317 {
@@ -317,7 +332,7 @@ void LLDrawable::setNumFaces(const S32 newFaces, LLDrawPool *poolp, LLViewerImag
317 } 332 }
318} 333}
319 334
320void LLDrawable::setNumFacesFast(const S32 newFaces, LLDrawPool *poolp, LLViewerImage *texturep) 335void LLDrawable::setNumFacesFast(const S32 newFaces, LLFacePool *poolp, LLViewerImage *texturep)
321{ 336{
322 if (newFaces <= (S32)mFaces.size() && newFaces >= (S32)mFaces.size()/2) 337 if (newFaces <= (S32)mFaces.size() && newFaces >= (S32)mFaces.size()/2)
323 { 338 {
@@ -372,21 +387,43 @@ void LLDrawable::updateMaterial()
372 387
373void LLDrawable::makeActive() 388void LLDrawable::makeActive()
374{ 389{
390#if !LL_RELEASE_FOR_DOWNLOAD
391 if (mVObjp.notNull())
392 {
393 U32 pcode = mVObjp->getPCode();
394 if (pcode == LLViewerObject::LL_VO_WATER ||
395 pcode == LLViewerObject::LL_VO_SURFACE_PATCH ||
396 pcode == LLViewerObject::LL_VO_PART_GROUP ||
397 pcode == LLViewerObject::LL_VO_CLOUDS ||
398 pcode == LLViewerObject::LL_VO_STARS ||
399 pcode == LLViewerObject::LL_VO_GROUND ||
400 pcode == LLViewerObject::LL_VO_SKY)
401 {
402 llerrs << "Static viewer object has active drawable!" << llendl;
403 }
404 }
405#endif
406
375 if (!isState(ACTIVE)) // && mGeneration > 0) 407 if (!isState(ACTIVE)) // && mGeneration > 0)
376 { 408 {
377 setState(ACTIVE); 409 setState(ACTIVE);
378 410
411 //parent must be made active first
379 if (!isRoot() && !mParent->isActive()) 412 if (!isRoot() && !mParent->isActive())
380 { 413 {
381 mParent->makeActive(); 414 mParent->makeActive();
382 } 415 }
383 416
384 gPipeline.setActive(this, TRUE); 417 gPipeline.setActive(this, TRUE);
385 418
386 //all child objects must also be active 419 //all child objects must also be active
387 for (U32 i = 0; i < getChildCount(); i++) 420 for (U32 i = 0; i < getChildCount(); i++)
388 { 421 {
389 getChild(i)->makeActive(); 422 LLDrawable* drawable = getChild(i);
423 if (drawable)
424 {
425 drawable->makeActive();
426 }
390 } 427 }
391 428
392 if (mVObjp->getPCode() == LL_PCODE_VOLUME) 429 if (mVObjp->getPCode() == LL_PCODE_VOLUME)
@@ -403,7 +440,15 @@ void LLDrawable::makeActive()
403 gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE); 440 gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE);
404 } 441 }
405 } 442 }
406 mQuietCount = 0; 443 updatePartition();
444 if (isRoot())
445 {
446 mQuietCount = 0;
447 }
448 else
449 {
450 getParent()->mQuietCount = 0;
451 }
407} 452}
408 453
409 454
@@ -416,7 +461,7 @@ void LLDrawable::makeStatic()
416 461
417 if (mParent.notNull() && mParent->isActive()) 462 if (mParent.notNull() && mParent->isActive())
418 { 463 {
419 llerrs << "Drawable became static with active parent!" << llendl; 464 llwarns << "Drawable becamse static with active parent!" << llendl;
420 } 465 }
421 466
422 S32 child_count = mVObjp->mChildList.size(); 467 S32 child_count = mVObjp->mChildList.size();
@@ -425,6 +470,10 @@ void LLDrawable::makeStatic()
425 LLDrawable* child_drawable = mVObjp->mChildList[child_num]->mDrawable; 470 LLDrawable* child_drawable = mVObjp->mChildList[child_num]->mDrawable;
426 if (child_drawable) 471 if (child_drawable)
427 { 472 {
473 if (child_drawable->getParent() != this)
474 {
475 llwarns << "Child drawable has unknown parent." << llendl;
476 }
428 child_drawable->makeStatic(); 477 child_drawable->makeStatic();
429 } 478 }
430 } 479 }
@@ -441,6 +490,7 @@ void LLDrawable::makeStatic()
441 setSpatialBridge(NULL); 490 setSpatialBridge(NULL);
442 } 491 }
443 } 492 }
493 updatePartition();
444} 494}
445 495
446// Returns "distance" between target destination and resulting xfrom 496// Returns "distance" between target destination and resulting xfrom
@@ -499,9 +549,8 @@ F32 LLDrawable::updateXform(BOOL undamped)
499 if (scaled >= MIN_INTERPOLATE_DISTANCE_SQUARED) 549 if (scaled >= MIN_INTERPOLATE_DISTANCE_SQUARED)
500 { 550 {
501 //scaling requires an immediate rebuild 551 //scaling requires an immediate rebuild
502 gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE); 552 gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
503 } 553 }
504
505 } 554 }
506 else 555 else
507 { 556 {
@@ -517,20 +566,6 @@ F32 LLDrawable::updateXform(BOOL undamped)
517 mXform.updateMatrix(); 566 mXform.updateMatrix();
518 567
519 mCurrentScale = target_scale; 568 mCurrentScale = target_scale;
520
521 if (!getVOVolume())
522 {
523 movePartition();
524 }
525 else if (mSpatialBridge)
526 {
527 gPipeline.markMoved(mSpatialBridge, FALSE);
528 }
529 else
530 {
531 //a child prim moved and needs its verts regenerated
532 gPipeline.markRebuild(this, LLDrawable::REBUILD_VOLUME, TRUE);
533 }
534 569
535 return dist_squared; 570 return dist_squared;
536} 571}
@@ -540,11 +575,6 @@ void LLDrawable::setRadius(F32 radius)
540 if (mRadius != radius) 575 if (mRadius != radius)
541 { 576 {
542 mRadius = radius; 577 mRadius = radius;
543 updateBinRadius();
544 if (!getVOVolume())
545 {
546 movePartition();
547 }
548 } 578 }
549} 579}
550 580
@@ -573,13 +603,10 @@ void LLDrawable::moveUpdatePipeline(BOOL moved)
573 603
574void LLDrawable::movePartition() 604void LLDrawable::movePartition()
575{ 605{
576 if (getSpatialGroup() || getVOVolume()) 606 LLSpatialPartition* part = getSpatialPartition();
607 if (part)
577 { 608 {
578 LLSpatialPartition* part = getSpatialPartition(); 609 part->move(this, getSpatialGroup());
579 if (part)
580 {
581 part->move(this, getSpatialGroup());
582 }
583 } 610 }
584} 611}
585 612
@@ -625,10 +652,27 @@ BOOL LLDrawable::updateMoveUndamped()
625 } 652 }
626 653
627 mVObjp->clearChanged(LLXform::MOVED); 654 mVObjp->clearChanged(LLXform::MOVED);
628 655
629 return TRUE; 656 return TRUE;
630} 657}
631 658
659void LLDrawable::updatePartition()
660{
661 if (!getVOVolume())
662 {
663 movePartition();
664 }
665 else if (mSpatialBridge)
666 {
667 gPipeline.markMoved(mSpatialBridge, FALSE);
668 }
669 else
670 {
671 //a child prim moved and needs its verts regenerated
672 gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
673 }
674}
675
632BOOL LLDrawable::updateMoveDamped() 676BOOL LLDrawable::updateMoveDamped()
633{ 677{
634 F32 dist_squared = updateXform(FALSE); 678 F32 dist_squared = updateXform(FALSE);
@@ -654,25 +698,42 @@ BOOL LLDrawable::updateMoveDamped()
654 698
655void LLDrawable::updateDistance(LLCamera& camera) 699void LLDrawable::updateDistance(LLCamera& camera)
656{ 700{
657 if (mVObjp->isHUDAttachment())
658 {
659 mDistanceWRTCamera = 1.0f;
660 if (sCurVisible % 16 == 0)
661 {
662 mVObjp->updateLOD();
663 }
664 return;
665 }
666
667 LLVector3 pos(getPositionGroup());
668
669 pos -= camera.getOrigin();
670 mDistanceWRTCamera = pos.magVec();
671
672 //switch LOD with the spatial group to avoid artifacts 701 //switch LOD with the spatial group to avoid artifacts
673 LLSpatialGroup* sg = getSpatialGroup(); 702 LLSpatialGroup* sg = getSpatialGroup();
703
704 LLVector3 pos;
705
674 if (!sg || sg->changeLOD()) 706 if (!sg || sg->changeLOD())
675 { 707 {
708 LLVOVolume* volume = getVOVolume();
709 if (volume)
710 {
711 volume->updateRelativeXform();
712 pos = LLVector3(0,0,0) * volume->getRelativeXform();
713
714 for (S32 i = 0; i < getNumFaces(); i++)
715 {
716 LLFace* facep = getFace(i);
717 if (facep->getPoolType() == LLDrawPool::POOL_ALPHA)
718 {
719 LLVector3 box = (facep->mExtents[1] - facep->mExtents[0]) * 0.25f;
720 LLVector3 v = (facep->mCenterLocal-camera.getOrigin());
721 LLVector3 at = camera.getAtAxis();
722 for (U32 j = 0; j < 3; j++)
723 {
724 v.mV[j] -= box.mV[j] * at.mV[j];
725 }
726 facep->mDistance = v * camera.getAtAxis();
727 }
728 }
729 }
730 else
731 {
732 pos = LLVector3(getPositionGroup());
733 }
734
735 pos -= camera.getOrigin();
736 mDistanceWRTCamera = llround(pos.magVec(), 0.01f);
676 mVObjp->updateLOD(); 737 mVObjp->updateLOD();
677 } 738 }
678} 739}
@@ -687,67 +748,33 @@ void LLDrawable::updateTexture()
687 return; 748 return;
688 } 749 }
689 750
690 // *FIX: this updates textures on all faces in this drawable, not 751 if (getNumFaces() != mVObjp->getNumTEs())
691 // just the viewer object we care about 752 { //drawable is transitioning its face count
692 if (mVObjp->getNumTEs()) 753 return;
754 }
755
756 if (getVOVolume())
693 { 757 {
694 // For each face in this drawable, change the drawpool if necessary. 758 if (!isActive())
695 for (S32 i = 0; i < getNumFaces(); i++) 759 {
760 gPipeline.markMoved(this);
761 }
762 else
696 { 763 {
697 LLFace *facep = mFaces[i]; 764 if (isRoot())
698 U32 pool_type = facep->getPool()->getType();
699
700 if ((pool_type == LLDrawPool::POOL_SIMPLE) ||
701 (pool_type == LLDrawPool::POOL_ALPHA) ||
702 (pool_type == LLDrawPool::POOL_HUD) ||
703 (pool_type == LLDrawPool::POOL_MEDIA) ||
704 (pool_type == LLDrawPool::POOL_BUMP))
705 { 765 {
706 LLViewerObject* objp = facep->getViewerObject(); 766 mQuietCount = 0;
707 S32 te_offset = facep->getTEOffset(); 767 }
708 768 else
709 if (te_offset >= objp->getNumTEs()) // Shouldn't happen 769 {
710 { 770 getParent()->mQuietCount = 0;
711 llwarns << "TE offsets don't match!" << llendl;
712 facep->setTEOffset(-1);
713 continue;
714 }
715
716 LLDrawPool* poolp = NULL;
717 LLViewerImage* imagep = (te_offset >= 0) ? objp->getTEImage(te_offset) : facep->getTexture();
718 if (facep->isState(LLFace::HUD_RENDER))
719 {
720 poolp = gPipeline.getPool(LLDrawPool::POOL_HUD);
721 }
722 else if (te_offset >= 0)
723 {
724 // This face actually uses texture entries...
725 const LLTextureEntry* te = facep->getTextureEntry();
726 poolp = LLPipeline::getPoolFromTE(te, imagep);
727 }
728 else
729 {
730 // No texture entry for this face.
731 if (!imagep)
732 {
733 poolp = gPipeline.getPool(LLDrawPool::POOL_SIMPLE, NULL);
734 }
735 else if ((imagep->getComponents() == 4) || (imagep->getComponents() == 2))
736 {
737 poolp = gPipeline.getPool(LLDrawPool::POOL_ALPHA);
738 }
739 else
740 {
741 poolp = gPipeline.getPool(LLDrawPool::POOL_SIMPLE, imagep);
742 }
743 }
744 facep->setPool(poolp, imagep);
745 } 771 }
746 } 772 }
773
774 gPipeline.markRebuild(this, LLDrawable::REBUILD_MATERIAL, TRUE);
747 } 775 }
748} 776}
749 777
750
751BOOL LLDrawable::updateGeometry(BOOL priority) 778BOOL LLDrawable::updateGeometry(BOOL priority)
752{ 779{
753 llassert(mVObjp.notNull()); 780 llassert(mVObjp.notNull());
@@ -788,12 +815,9 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector)
788 mXform.setScale(1,1,1); 815 mXform.setScale(1,1,1);
789 mXform.updateMatrix(); 816 mXform.updateMatrix();
790 817
791 if (isStatic() || // *FIX: don't know why this is happening, but 818 if (isStatic())
792 // some terrain patches are becoming active
793 // (earth quake, maybe?) DP
794 getRenderType() == LLPipeline::RENDER_TYPE_TERRAIN)
795 { 819 {
796 LLStrider<LLVector3> verticesp; 820 gPipeline.markRebuild(this, LLDrawable::REBUILD_GEOMETRY, TRUE);
797 821
798 for (S32 i = 0; i < getNumFaces(); i++) 822 for (S32 i = 0; i < getNumFaces(); i++)
799 { 823 {
@@ -802,34 +826,13 @@ void LLDrawable::shiftPos(const LLVector3 &shift_vector)
802 facep->mExtents[0] += shift_vector; 826 facep->mExtents[0] += shift_vector;
803 facep->mExtents[1] += shift_vector; 827 facep->mExtents[1] += shift_vector;
804 828
805 if (facep->hasGeometry() && !facep->isState(LLFace::SHARED_GEOM)) 829 if (facep->hasGeometry())
806 { 830 {
807 S32 index = facep->getVertices(verticesp); 831 facep->mVertexBuffer = NULL;
808 if (index >= 0) 832 facep->mLastVertexBuffer = NULL;
809 {
810 S32 vertex_count = facep->getGeomCount();
811 for (S32 j = 0; j < vertex_count; j++)
812 {
813 *verticesp += shift_vector;
814 verticesp++;
815 }
816 }
817 } 833 }
818 } 834 }
819 } 835
820 else
821 {
822 // Update the face centers.
823 for (S32 i = 0; i < getNumFaces(); i++)
824 {
825 LLFace *facep = getFace(i);
826 facep->mCenterAgent += shift_vector;
827 }
828 }
829
830 //update spatial extents
831 if (!getVOVolume() || isStatic())
832 {
833 mExtents[0] += shift_vector; 836 mExtents[0] += shift_vector;
834 mExtents[1] += shift_vector; 837 mExtents[1] += shift_vector;
835 mPositionGroup += LLVector3d(shift_vector); 838 mPositionGroup += LLVector3d(shift_vector);
@@ -874,6 +877,8 @@ void LLDrawable::updateSpatialExtents()
874 mVObjp->updateSpatialExtents(mExtents[0], mExtents[1]); 877 mVObjp->updateSpatialExtents(mExtents[0], mExtents[1]);
875 } 878 }
876 879
880 updateBinRadius();
881
877 if (mSpatialBridge.notNull()) 882 if (mSpatialBridge.notNull())
878 { 883 {
879 mPositionGroup.setVec(0,0,0); 884 mPositionGroup.setVec(0,0,0);
@@ -883,11 +888,14 @@ void LLDrawable::updateSpatialExtents()
883 888
884void LLDrawable::updateBinRadius() 889void LLDrawable::updateBinRadius()
885{ 890{
886 S32 binLOD = mVObjp ? mVObjp->getLOD() : 2; 891 if (mVObjp.notNull())
887 static F64 detail_bins[] = { 8, 4, 2, 1 }; 892 {
888 F32 radius = getVOVolume() && isStatic() ? 893 mBinRadius = mVObjp->getBinRadius();
889 (mExtents[1]-mExtents[0]).magVec() : getRadius(); 894 }
890 mBinRadius = detail_bins[binLOD] * llmax((F64) radius, (3-binLOD)*0.25); 895 else
896 {
897 mBinRadius = getRadius()*4.f;
898 }
891} 899}
892 900
893void LLDrawable::updateLightSet() 901void LLDrawable::updateLightSet()
@@ -898,6 +906,7 @@ void LLDrawable::updateLightSet()
898 return; 906 return;
899 } 907 }
900 908
909 LLSpatialPartition* part = gPipeline.getSpatialPartition(LLPipeline::PARTITION_VOLUME);
901 LLVOVolume* light = getVOVolume(); 910 LLVOVolume* light = getVOVolume();
902 if (isLight() && light) 911 if (isLight() && light)
903 { 912 {
@@ -907,7 +916,7 @@ void LLDrawable::updateLightSet()
907 gPipeline.markRelight(*iter); 916 gPipeline.markRelight(*iter);
908 } 917 }
909 mLightSet.clear(); 918 mLightSet.clear();
910 gPipeline.mObjectPartition->getObjects(getPositionAgent(), light->getLightRadius(), mLightSet); 919 part->getObjects(getPositionAgent(), light->getLightRadius(), mLightSet);
911 for (drawable_set_t::iterator iter = mLightSet.begin(); iter != mLightSet.end(); iter++) 920 for (drawable_set_t::iterator iter = mLightSet.begin(); iter != mLightSet.end(); iter++)
912 { 921 {
913 gPipeline.markRelight(*iter); 922 gPipeline.markRelight(*iter);
@@ -917,9 +926,9 @@ void LLDrawable::updateLightSet()
917 { 926 {
918 // mLightSet points to nearby lights 927 // mLightSet points to nearby lights
919 mLightSet.clear(); 928 mLightSet.clear();
920 gPipeline.mObjectPartition->getLights(getPositionAgent(), getRadius(), mLightSet); 929 part->getLights(getPositionAgent(), getRadius(), mLightSet);
921 const U32 max_lights = 16; 930 const drawable_set_t::size_type MAX_LIGHTS = 16;
922 if (mLightSet.size() > max_lights) 931 if (mLightSet.size() > MAX_LIGHTS)
923 { 932 {
924 typedef std::set<std::pair<F32,LLPointer<LLDrawable> > > sorted_pair_set_t; 933 typedef std::set<std::pair<F32,LLPointer<LLDrawable> > > sorted_pair_set_t;
925 sorted_pair_set_t sorted_set; 934 sorted_pair_set_t sorted_set;
@@ -1053,28 +1062,28 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
1053{ 1062{
1054 LLSpatialPartition* retval = NULL; 1063 LLSpatialPartition* retval = NULL;
1055 1064
1056 if (mVObjp->isHUDAttachment())
1057 { //HUD attachments don't get space partitioned
1058 return NULL;
1059 }
1060
1061 if (!mVObjp || 1065 if (!mVObjp ||
1062 !getVOVolume() || 1066 !getVOVolume() ||
1063 isStatic()) 1067 isStatic())
1064 { 1068 {
1065 retval = gPipeline.mObjectPartition; 1069 retval = gPipeline.getSpatialPartition((LLViewerObject*) mVObjp);
1066 } 1070 }
1067 1071 else if (isRoot())
1068 //must be an active volume 1072 { //must be an active volume
1069 if (!retval && isRoot())
1070 {
1071 if (!mSpatialBridge) 1073 if (!mSpatialBridge)
1072 { 1074 {
1073 setSpatialBridge(new LLSpatialBridge(this)); 1075 if (mVObjp->isHUDAttachment())
1076 {
1077 setSpatialBridge(new LLHUDBridge(this));
1078 }
1079 else
1080 {
1081 setSpatialBridge(new LLVolumeBridge(this));
1082 }
1074 } 1083 }
1075 return mSpatialBridge->asPartition(); 1084 return mSpatialBridge->asPartition();
1076 } 1085 }
1077 else if (!retval) 1086 else
1078 { 1087 {
1079 retval = getParent()->getSpatialPartition(); 1088 retval = getParent()->getSpatialPartition();
1080 } 1089 }
@@ -1088,27 +1097,73 @@ LLSpatialPartition* LLDrawable::getSpatialPartition()
1088 return retval; 1097 return retval;
1089} 1098}
1090 1099
1100
1101BOOL LLDrawable::isVisible() const
1102{
1103 if (mVisible == sCurVisible)
1104 {
1105 return TRUE;
1106 }
1107
1108 if (isActive())
1109 {
1110 if (isRoot())
1111 {
1112 LLSpatialGroup* group = mSpatialBridge.notNull() ? mSpatialBridge->getSpatialGroup() :
1113 getSpatialGroup();
1114 if (!group || group->isVisible())
1115 {
1116 mVisible = sCurVisible;
1117 return TRUE;
1118 }
1119 }
1120 else
1121 {
1122 if (getParent()->isVisible())
1123 {
1124 mVisible = sCurVisible;
1125 return TRUE;
1126 }
1127 }
1128 }
1129 else
1130 {
1131 LLSpatialGroup* group = getSpatialGroup();
1132 if (!group || group->isVisible())
1133 {
1134 mVisible = sCurVisible;
1135 return TRUE;
1136 }
1137 }
1138
1139 return FALSE;
1140}
1141
1091//======================================= 1142//=======================================
1092// Spatial Partition Bridging Drawable 1143// Spatial Partition Bridging Drawable
1093//======================================= 1144//=======================================
1094 1145
1095LLSpatialBridge::LLSpatialBridge(LLDrawable* root) 1146LLSpatialBridge::LLSpatialBridge(LLDrawable* root, U32 data_mask)
1147: LLSpatialPartition(data_mask, FALSE)
1096{ 1148{
1097 mDrawable = root; 1149 mDrawable = root;
1098 root->setSpatialBridge(this); 1150 root->setSpatialBridge(this);
1099 1151
1100 mRenderType = mDrawable->mRenderType; //w00! magic! 1152 mRenderType = mDrawable->mRenderType;
1101 1153 mDrawableType = mDrawable->mRenderType;
1154
1155 mPartitionType = LLPipeline::PARTITION_VOLUME;
1156
1102 mOctree->balance(); 1157 mOctree->balance();
1103 1158
1104 gPipeline.mObjectPartition->put(this); 1159 gPipeline.getSpatialPartition(mPartitionType)->put(this);
1105} 1160}
1106 1161
1107LLSpatialBridge::~LLSpatialBridge() 1162LLSpatialBridge::~LLSpatialBridge()
1108{ 1163{
1109 if (getSpatialGroup()) 1164 if (getSpatialGroup())
1110 { 1165 {
1111 gPipeline.mObjectPartition->remove(this, getSpatialGroup()); 1166 gPipeline.getSpatialPartition(mPartitionType)->remove(this, getSpatialGroup());
1112 } 1167 }
1113} 1168}
1114 1169
@@ -1116,7 +1171,6 @@ void LLSpatialBridge::updateSpatialExtents()
1116{ 1171{
1117 LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0); 1172 LLSpatialGroup* root = (LLSpatialGroup*) mOctree->getListener(0);
1118 1173
1119 if (mOctree->getChildCount() > 0)
1120 { 1174 {
1121 LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND); 1175 LLFastTimer ftm(LLFastTimer::FTM_CULL_REBOUND);
1122 root->rebound(); 1176 root->rebound();
@@ -1164,6 +1218,9 @@ void LLSpatialBridge::updateSpatialExtents()
1164 } 1218 }
1165 } 1219 }
1166 } 1220 }
1221
1222 LLVector3 diagonal = newMax - newMin;
1223 mRadius = diagonal.magVec() * 0.5f;
1167 1224
1168 mPositionGroup.setVec((newMin + newMax) * 0.5f); 1225 mPositionGroup.setVec((newMin + newMax) * 0.5f);
1169 updateBinRadius(); 1226 updateBinRadius();
@@ -1171,9 +1228,7 @@ void LLSpatialBridge::updateSpatialExtents()
1171 1228
1172void LLSpatialBridge::updateBinRadius() 1229void LLSpatialBridge::updateBinRadius()
1173{ 1230{
1174 F32 rad = ((mExtents[1]-mExtents[0])*0.5f).magVec(); 1231 mBinRadius = llmin((F32) mOctree->getSize().mdV[0]*0.5f, 256.f);
1175 mBinRadius = llmax(rad, 2.f);
1176 mRadius = rad;
1177} 1232}
1178 1233
1179LLCamera LLSpatialBridge::transformCamera(LLCamera& camera) 1234LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
@@ -1181,39 +1236,123 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
1181 LLCamera ret = camera; 1236 LLCamera ret = camera;
1182 LLXformMatrix* mat = mDrawable->getXform(); 1237 LLXformMatrix* mat = mDrawable->getXform();
1183 LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix(); 1238 LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix();
1184 //LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix()); 1239 LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix());
1185 1240
1186 //ret.rotate(~mat->getRotation());
1187 LLVector3 delta = ret.getOrigin() - center; 1241 LLVector3 delta = ret.getOrigin() - center;
1188 delta *= ~mat->getRotation(); 1242 LLQuaternion rot = ~mat->getRotation();
1189 ret.setOrigin(delta); 1243
1244 delta *= rot;
1245 LLVector3 lookAt = ret.getAtAxis();
1246 LLVector3 up_axis = ret.getUpAxis();
1247 LLVector3 left_axis = ret.getLeftAxis();
1190 1248
1249 lookAt *= rot;
1250 up_axis *= rot;
1251 left_axis *= rot;
1252
1253 ret.setOrigin(delta);
1254 ret.setAxes(lookAt, left_axis, up_axis);
1255
1191 return ret; 1256 return ret;
1192} 1257}
1193 1258
1194void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, BOOL for_select) 1259void LLDrawable::setVisible(LLCamera& camera, std::vector<LLDrawable*>* results, BOOL for_select)
1195{ 1260{
1196 mVisible = sCurVisible; 1261 mVisible = sCurVisible;
1262
1263#if 0 && !LL_RELEASE_FOR_DOWNLOAD
1264 //crazy paranoid rules checking
1265 if (getVOVolume())
1266 {
1267 if (!isRoot())
1268 {
1269 if (isActive() && !mParent->isActive())
1270 {
1271 llerrs << "Active drawable has static parent!" << llendl;
1272 }
1273
1274 if (isStatic() && !mParent->isStatic())
1275 {
1276 llerrs << "Static drawable has active parent!" << llendl;
1277 }
1278
1279 if (mSpatialBridge)
1280 {
1281 llerrs << "Child drawable has spatial bridge!" << llendl;
1282 }
1283 }
1284 else if (isActive() && !mSpatialBridge)
1285 {
1286 llerrs << "Active root drawable has no spatial bridge!" << llendl;
1287 }
1288 else if (isStatic() && mSpatialBridge.notNull())
1289 {
1290 llerrs << "Static drawable has spatial bridge!" << llendl;
1291 }
1292 }
1293#endif
1197} 1294}
1198 1295
1296class LLOctreeMarkNotCulled: public LLOctreeTraveler<LLDrawable>
1297{
1298public:
1299 LLCamera* mCamera;
1300
1301 LLOctreeMarkNotCulled(LLCamera* camera_in) : mCamera(camera_in) { }
1302
1303 virtual void traverse(const LLOctreeNode<LLDrawable>* node)
1304 {
1305 LLSpatialGroup* group = (LLSpatialGroup*) node->getListener(0);
1306 group->clearState(LLSpatialGroup::OCCLUDED | LLSpatialGroup::CULLED);
1307 LLOctreeTraveler<LLDrawable>::traverse(node);
1308 }
1309
1310 void visit(const LLOctreeState<LLDrawable>* branch)
1311 {
1312 gPipeline.markNotCulled((LLSpatialGroup*) branch->getListener(0), *mCamera, TRUE);
1313 }
1314};
1315
1199void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results, BOOL for_select) 1316void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>* results, BOOL for_select)
1200{ 1317{
1318 if (!gPipeline.hasRenderType(mDrawableType))
1319 {
1320 return;
1321 }
1322
1323 LLViewerObject *vobj = mDrawable->getVObj();
1324 if (vobj && vobj->isAttachment() && !vobj->isHUDAttachment())
1325 {
1326 LLVOAvatar* av;
1327 LLDrawable* parent = mDrawable->getParent();
1328
1329 if (parent)
1330 {
1331 av = (LLVOAvatar*) parent->getVObj();
1332
1333 if (!av->isVisible())
1334 {
1335 return;
1336 }
1337 }
1338 }
1339
1340
1341 LLSpatialGroup* group = (LLSpatialGroup*) mOctree->getListener(0);
1342 group->rebound();
1343
1201 LLVector3 center = (mExtents[0] + mExtents[1]) * 0.5f; 1344 LLVector3 center = (mExtents[0] + mExtents[1]) * 0.5f;
1202 LLVector3 size = (mExtents[1]-mExtents[0]) * 0.5f; 1345 LLVector3 size = (mExtents[1]-mExtents[0]) * 0.5f;
1203 1346
1204 if (camera_in.AABBInFrustum(center, size)) 1347 if (camera_in.AABBInFrustum(center, size))
1205 { 1348 {
1206 LLVector3 lookAt = center - camera_in.getOrigin(); 1349 if (LLPipeline::calcPixelArea(center, size, camera_in) < FORCE_INVISIBLE_AREA)
1207 F32 distSqr = lookAt.magVecSquared();
1208 F32 objRad = size.magVecSquared();
1209
1210 if (objRad/distSqr < SG_MIN_DIST_RATIO*4)
1211 { 1350 {
1212 return; 1351 return;
1213 } 1352 }
1214 1353
1215 LLDrawable::setVisible(camera_in); 1354 LLDrawable::setVisible(camera_in);
1216 1355
1217 if (for_select) 1356 if (for_select)
1218 { 1357 {
1219 results->push_back(mDrawable); 1358 results->push_back(mDrawable);
@@ -1222,42 +1361,36 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
1222 results->push_back(mDrawable->getChild(i)); 1361 results->push_back(mDrawable->getChild(i));
1223 } 1362 }
1224 } 1363 }
1225 else 1364 else
1226 { 1365 {
1227 const LLVector3* extents = mDrawable->getSpatialExtents(); 1366 LLCamera trans_camera = transformCamera(camera_in);
1228 objRad = mDrawable->getRadius(); 1367 LLOctreeMarkNotCulled culler(&trans_camera);
1229 objRad *= objRad; 1368 culler.traverse(mOctree);
1230 1369 }
1231 if (objRad/distSqr > SG_MIN_DIST_RATIO)
1232 {
1233 gPipeline.markNotCulled(mDrawable, camera_in);
1234 }
1235
1236 for (U32 i = 0; i < mDrawable->getChildCount(); i++)
1237 {
1238 LLDrawable* child = mDrawable->getChild(i);
1239 extents = child->getSpatialExtents();
1240 objRad = child->getRadius();
1241 objRad *= objRad;
1242
1243 if (objRad/distSqr > SG_MIN_DIST_RATIO)
1244 {
1245 gPipeline.markNotCulled(mDrawable->getChild(i), camera_in);
1246 }
1247 }
1248 }
1249 } 1370 }
1250} 1371}
1251 1372
1252void LLSpatialBridge::updateDistance(LLCamera& camera_in) 1373void LLSpatialBridge::updateDistance(LLCamera& camera_in)
1253{ 1374{
1375 if (mDrawable == NULL)
1376 {
1377 markDead();
1378 return;
1379 }
1380
1254 LLCamera camera = transformCamera(camera_in); 1381 LLCamera camera = transformCamera(camera_in);
1255 1382
1256 mDrawable->updateDistance(camera); 1383 mDrawable->updateDistance(camera);
1257 1384
1258 for (U32 i = 0; i < mDrawable->getChildCount(); ++i) 1385 for (U32 i = 0; i < mDrawable->getChildCount(); ++i)
1259 { 1386 {
1260 mDrawable->getChild(i)->updateDistance(camera); 1387 LLDrawable* child = mDrawable->getChild(i);
1388 if (!child)
1389 {
1390 llwarns << "Corrupt drawable found while updating spatial bridge distance." << llendl;
1391 continue;
1392 }
1393 child->updateDistance(camera);
1261 } 1394 }
1262} 1395}
1263 1396
@@ -1280,7 +1413,7 @@ void LLSpatialBridge::move(LLDrawable *drawablep, LLSpatialGroup *curp, BOOL imm
1280BOOL LLSpatialBridge::updateMove() 1413BOOL LLSpatialBridge::updateMove()
1281{ 1414{
1282 mOctree->balance(); 1415 mOctree->balance();
1283 gPipeline.mObjectPartition->move(this, getSpatialGroup(), TRUE); 1416 gPipeline.getSpatialPartition(mPartitionType)->move(this, getSpatialGroup(), TRUE);
1284 return TRUE; 1417 return TRUE;
1285} 1418}
1286 1419
@@ -1338,3 +1471,81 @@ const LLVector3 LLDrawable::getPositionAgent() const
1338 } 1471 }
1339} 1472}
1340 1473
1474BOOL LLDrawable::isAnimating() const
1475{
1476 if (!getVObj())
1477 {
1478 return TRUE;
1479 }
1480
1481 if (getScale() != mVObjp->getScale())
1482 {
1483 return TRUE;
1484 }
1485
1486 if (mVObjp->isFlexible())
1487 {
1488 return TRUE;
1489 }
1490
1491 if (mVObjp->getPCode() == LLViewerObject::LL_VO_PART_GROUP)
1492 {
1493 return TRUE;
1494 }
1495
1496 if (mVObjp->getPCode() == LLViewerObject::LL_VO_CLOUDS)
1497 {
1498 return TRUE;
1499 }
1500
1501 LLVOVolume* vol = getVOVolume();
1502 if (vol && vol->mTextureAnimp)
1503 {
1504 return TRUE;
1505 }
1506
1507 if (!isRoot() && !mVObjp->getAngularVelocity().isExactlyZero())
1508 {
1509 return TRUE;
1510 }
1511
1512 return FALSE;
1513}
1514
1515void LLDrawable::updateFaceSize(S32 idx)
1516{
1517 if (mVObjp.notNull())
1518 {
1519 mVObjp->updateFaceSize(idx);
1520 }
1521}
1522
1523LLBridgePartition::LLBridgePartition()
1524: LLSpatialPartition(0, TRUE)
1525{
1526 mRenderByGroup = FALSE;
1527 mDrawableType = LLPipeline::RENDER_TYPE_AVATAR;
1528 mPartitionType = LLPipeline::PARTITION_BRIDGE;
1529 mLODPeriod = 1;
1530 mSlopRatio = 0.f;
1531}
1532
1533LLHUDBridge::LLHUDBridge(LLDrawable* drawablep)
1534: LLVolumeBridge(drawablep)
1535{
1536 mDrawableType = LLPipeline::RENDER_TYPE_HUD;
1537 mPartitionType = LLPipeline::PARTITION_HUD;
1538 mSlopRatio = 0.0f;
1539}
1540
1541F32 LLHUDBridge::calcPixelArea(LLSpatialGroup* group, LLCamera& camera)
1542{
1543 return 1024.f;
1544}
1545
1546
1547void LLHUDBridge::shiftPos(const LLVector3& vec)
1548{
1549 //don't shift hud bridges on region crossing
1550}
1551