aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llvovolume.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2008-08-15 23:45:34 -0500
committerJacek Antonelli2008-08-15 23:45:34 -0500
commitcd17687f01420952712a500107e0f93e7ab8d5f8 (patch)
treece48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/newview/llvovolume.cpp
parentSecond Life viewer sources 1.19.0.5 (diff)
downloadmeta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.zip
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.gz
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.bz2
meta-impy-cd17687f01420952712a500107e0f93e7ab8d5f8.tar.xz
Second Life viewer sources 1.19.1.0
Diffstat (limited to 'linden/indra/newview/llvovolume.cpp')
-rw-r--r--linden/indra/newview/llvovolume.cpp731
1 files changed, 351 insertions, 380 deletions
diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp
index ff6c502..494e0fa 100644
--- a/linden/indra/newview/llvovolume.cpp
+++ b/linden/indra/newview/llvovolume.cpp
@@ -48,14 +48,13 @@
48#include "object_flags.h" 48#include "object_flags.h"
49#include "llagent.h" 49#include "llagent.h"
50#include "lldrawable.h" 50#include "lldrawable.h"
51#include "lldrawpoolsimple.h"
52#include "lldrawpoolbump.h" 51#include "lldrawpoolbump.h"
53#include "llface.h" 52#include "llface.h"
53#include "llspatialpartition.h"
54 54
55// TEMP HACK ventrella 55// TEMP HACK ventrella
56#include "llhudmanager.h" 56#include "llhudmanager.h"
57#include "llflexibleobject.h" 57#include "llflexibleobject.h"
58#include "llanimalcontrols.h"
59 58
60#include "llsky.h" 59#include "llsky.h"
61#include "llviewercamera.h" 60#include "llviewercamera.h"
@@ -88,9 +87,7 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
88 mRelativeXformInvTrans.identity(); 87 mRelativeXformInvTrans.identity();
89 88
90 mLOD = MIN_LOD; 89 mLOD = MIN_LOD;
91 mInited = FALSE;
92 mTextureAnimp = NULL; 90 mTextureAnimp = NULL;
93 mGlobalVolume = FALSE;
94 mVObjRadius = LLVector3(1,1,0.5f).magVec(); 91 mVObjRadius = LLVector3(1,1,0.5f).magVec();
95 mNumFaces = 0; 92 mNumFaces = 0;
96 mLODChanged = FALSE; 93 mLODChanged = FALSE;
@@ -296,6 +293,8 @@ void LLVOVolume::animateTextures()
296 for (S32 i = start; i <= end; i++) 293 for (S32 i = start; i <= end; i++)
297 { 294 {
298 LLFace* facep = mDrawable->getFace(i); 295 LLFace* facep = mDrawable->getFace(i);
296 if(facep->getVirtualSize() <= MIN_TEX_ANIM_SIZE && facep->mTextureMatrix) continue;
297
299 const LLTextureEntry* te = facep->getTextureEntry(); 298 const LLTextureEntry* te = facep->getTextureEntry();
300 299
301 if (!te) 300 if (!te)
@@ -321,7 +320,12 @@ void LLVOVolume::animateTextures()
321 LLQuaternion quat; 320 LLQuaternion quat;
322 quat.setQuat(rot, 0, 0, -1.f); 321 quat.setQuat(rot, 0, 0, -1.f);
323 322
324 LLMatrix4& tex_mat = facep->mTextureMatrix; 323 if (!facep->mTextureMatrix)
324 {
325 facep->mTextureMatrix = new LLMatrix4();
326 }
327
328 LLMatrix4& tex_mat = *facep->mTextureMatrix;
325 tex_mat.identity(); 329 tex_mat.identity();
326 tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f)); 330 tex_mat.translate(LLVector3(-0.5f, -0.5f, 0.f));
327 tex_mat.rotate(quat); 331 tex_mat.rotate(quat);
@@ -402,7 +406,6 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
402 406
403void LLVOVolume::updateTextures(LLAgent &agent) 407void LLVOVolume::updateTextures(LLAgent &agent)
404{ 408{
405// LLFastTimer t(LLFastTimer::FTM_TEMP6);
406 const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds 409 const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds
407 if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) 410 if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)
408 { 411 {
@@ -460,6 +463,29 @@ void LLVOVolume::updateTextures()
460 } 463 }
461 464
462 mPixelArea = llmax(mPixelArea, face->getPixelArea()); 465 mPixelArea = llmax(mPixelArea, face->getPixelArea());
466
467 F32 old_size = face->getVirtualSize();
468
469 if (face->getPoolType() == LLDrawPool::POOL_ALPHA)
470 {
471
472 if (LLPipeline::sFastAlpha &&
473 vsize < MIN_ALPHA_SIZE && old_size > MIN_ALPHA_SIZE ||
474 vsize > MIN_ALPHA_SIZE && old_size < MIN_ALPHA_SIZE)
475 {
476 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_COLOR, FALSE);
477 }
478 }
479
480 if (face->mTextureMatrix != NULL)
481 {
482 if (vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE ||
483 vsize > MIN_TEX_ANIM_SIZE && old_size < MIN_TEX_ANIM_SIZE)
484 {
485 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD, FALSE);
486 }
487 }
488
463 face->setVirtualSize(vsize); 489 face->setVirtualSize(vsize);
464 imagep->addTextureStats(vsize); 490 imagep->addTextureStats(vsize);
465 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA)) 491 if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
@@ -492,10 +518,12 @@ void LLVOVolume::updateTextures()
492 mSculptTexture->setBoostLevel(LLViewerImage::BOOST_SCULPTED); 518 mSculptTexture->setBoostLevel(LLViewerImage::BOOST_SCULPTED);
493 } 519 }
494 520
495 S32 desired_discard = 0; // lower discard levels have MUCH less resolution - (old=MAX_LOD - mLOD) 521 S32 texture_discard = mSculptTexture->getDiscardLevel(); //try to match the texture
496 S32 current_discard = getVolume()->getSculptLevel(); 522 S32 current_discard = getVolume()->getSculptLevel();
497 523
498 if (desired_discard != current_discard) 524 if (texture_discard >= 0 && //texture has some data available
525 (texture_discard < current_discard || //texture has more data than last rebuild
526 current_discard < 0)) //no previous rebuild
499 { 527 {
500 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE); 528 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
501 mSculptChanged = TRUE; 529 mSculptChanged = TRUE;
@@ -555,20 +583,13 @@ F32 LLVOVolume::getTextureVirtualSize(LLFace* face)
555 583
556BOOL LLVOVolume::isActive() const 584BOOL LLVOVolume::isActive() const
557{ 585{
558 return !mStatic || mTextureAnimp || isAttachment() || (mVolumeImpl && mVolumeImpl->isActive()); 586 return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive());
559} 587}
560 588
561BOOL LLVOVolume::setMaterial(const U8 material) 589BOOL LLVOVolume::setMaterial(const U8 material)
562{ 590{
563 BOOL res = LLViewerObject::setMaterial(material); 591 BOOL res = LLViewerObject::setMaterial(material);
564 if (res) 592
565 {
566 // for deprecated LL_MCODE_LIGHT
567 if (mDrawable.notNull())
568 {
569 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_LIGHTING, TRUE);
570 }
571 }
572 return res; 593 return res;
573} 594}
574 595
@@ -608,14 +629,13 @@ LLFace* LLVOVolume::addFace(S32 f)
608LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) 629LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
609{ 630{
610 pipeline->allocDrawable(this); 631 pipeline->allocDrawable(this);
632
611 mDrawable->setRenderType(LLPipeline::RENDER_TYPE_VOLUME); 633 mDrawable->setRenderType(LLPipeline::RENDER_TYPE_VOLUME);
612 634
613 S32 max_tes_to_set = getNumTEs(); 635 S32 max_tes_to_set = getNumTEs();
614 for (S32 i = 0; i < max_tes_to_set; i++) 636 for (S32 i = 0; i < max_tes_to_set; i++)
615 { 637 {
616 LLFace* face = addFace(i); 638 addFace(i);
617 // JC - should there be a setViewerObject(this) call here?
618 face->setTEOffset(i);
619 } 639 }
620 mNumFaces = max_tes_to_set; 640 mNumFaces = max_tes_to_set;
621 641
@@ -666,8 +686,6 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail
666 } 686 }
667 } 687 }
668 688
669 mGlobalVolume = (mVolumeImpl && mVolumeImpl->isVolumeGlobal());
670
671 if ((LLPrimitive::setVolume(volume_params, mLOD, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged) 689 if ((LLPrimitive::setVolume(volume_params, mLOD, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged)
672 { 690 {
673 mFaceMappingChanged = TRUE; 691 mFaceMappingChanged = TRUE;
@@ -728,13 +746,16 @@ void LLVOVolume::sculpt()
728 return; 746 return;
729 747
730 LLPointer<LLImageRaw> raw_image = new LLImageRaw(); 748 LLPointer<LLImageRaw> raw_image = new LLImageRaw();
731 mSculptTexture->readBackRaw(discard_level, raw_image, TRUE); 749 mSculptTexture->readBackRaw(discard_level, raw_image, FALSE);
732 750
733 sculpt_height = raw_image->getHeight(); 751 sculpt_height = raw_image->getHeight();
734 sculpt_width = raw_image->getWidth(); 752 sculpt_width = raw_image->getWidth();
735 753
736 sculpt_components = raw_image->getComponents(); 754 sculpt_components = raw_image->getComponents();
737 sculpt_data = raw_image->getData(); 755 sculpt_data = raw_image->getData();
756
757 llassert_always(raw_image->getDataSize() >= sculpt_height * sculpt_width * sculpt_components);
758
738 getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level); 759 getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level);
739 } 760 }
740} 761}
@@ -742,9 +763,16 @@ void LLVOVolume::sculpt()
742S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius) 763S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius)
743{ 764{
744 S32 cur_detail; 765 S32 cur_detail;
745 // We've got LOD in the profile, and in the twist. Use radius. 766 if (LLPipeline::sDynamicLOD)
746 F32 tan_angle = (LLVOVolume::sLODFactor*radius)/distance; 767 {
747 cur_detail = LLVolumeLODGroup::getDetailFromTan(llround(tan_angle, 0.01f)); 768 // We've got LOD in the profile, and in the twist. Use radius.
769 F32 tan_angle = (LLVOVolume::sLODFactor*radius)/distance;
770 cur_detail = LLVolumeLODGroup::getDetailFromTan(llround(tan_angle, 0.01f));
771 }
772 else
773 {
774 cur_detail = llclamp((S32) (sqrtf(radius)*LLVOVolume::sLODFactor*4.f), 0, 3);
775 }
748 return cur_detail; 776 return cur_detail;
749} 777}
750 778
@@ -755,6 +783,9 @@ BOOL LLVOVolume::calcLOD()
755 return FALSE; 783 return FALSE;
756 } 784 }
757 785
786 //update face texture sizes on lod calculation
787 updateTextures();
788
758 S32 cur_detail = 0; 789 S32 cur_detail = 0;
759 790
760 F32 radius = getVolume()->mLODScaleBias.scaledVec(getScale()).magVec(); 791 F32 radius = getVolume()->mLODScaleBias.scaledVec(getScale()).magVec();
@@ -860,12 +891,14 @@ void LLVOVolume::updateFaceFlags()
860 891
861void LLVOVolume::setParent(LLViewerObject* parent) 892void LLVOVolume::setParent(LLViewerObject* parent)
862{ 893{
863 LLViewerObject::setParent(parent); 894 if (parent != getParent())
864 if (mDrawable)
865 { 895 {
866 gPipeline.markMoved(mDrawable); 896 LLViewerObject::setParent(parent);
867 mVolumeChanged = TRUE; 897 if (mDrawable)
868 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE); 898 {
899 gPipeline.markMoved(mDrawable);
900 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, TRUE);
901 }
869 } 902 }
870} 903}
871 904
@@ -909,7 +942,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
909 LLFace *face = mDrawable->getFace(i); 942 LLFace *face = mDrawable->getFace(i);
910 res &= face->genVolumeBBoxes(*getVolume(), i, 943 res &= face->genVolumeBBoxes(*getVolume(), i,
911 mRelativeXform, mRelativeXformInvTrans, 944 mRelativeXform, mRelativeXformInvTrans,
912 mGlobalVolume | force_global); 945 (mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global);
913 946
914 if (rebuild) 947 if (rebuild)
915 { 948 {
@@ -939,8 +972,6 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
939 { 972 {
940 mDrawable->setSpatialExtents(min,max); 973 mDrawable->setSpatialExtents(min,max);
941 mDrawable->setPositionGroup((min+max)*0.5f); 974 mDrawable->setPositionGroup((min+max)*0.5f);
942 //bounding boxes changed, update texture priorities
943 updateTextures();
944 } 975 }
945 976
946 updateRadius(); 977 updateRadius();
@@ -949,6 +980,14 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
949 return res; 980 return res;
950} 981}
951 982
983void LLVOVolume::preRebuild()
984{
985 if (mVolumeImpl != NULL)
986 {
987 mVolumeImpl->preRebuild();
988 }
989}
990
952void LLVOVolume::updateRelativeXform() 991void LLVOVolume::updateRelativeXform()
953{ 992{
954 if (mVolumeImpl) 993 if (mVolumeImpl)
@@ -1012,8 +1051,8 @@ void LLVOVolume::updateRelativeXform()
1012 rot *= mParent->getRotation(); 1051 rot *= mParent->getRotation();
1013 } 1052 }
1014 1053
1015 LLViewerRegion* region = getRegion(); 1054 //LLViewerRegion* region = getRegion();
1016 pos += region->getOriginAgent(); 1055 //pos += region->getOriginAgent();
1017 1056
1018 LLVector3 x_axis = LLVector3(scale.mV[VX], 0.f, 0.f) * rot; 1057 LLVector3 x_axis = LLVector3(scale.mV[VX], 0.f, 0.f) * rot;
1019 LLVector3 y_axis = LLVector3(0.f, scale.mV[VY], 0.f) * rot; 1058 LLVector3 y_axis = LLVector3(0.f, scale.mV[VY], 0.f) * rot;
@@ -1045,12 +1084,17 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
1045 1084
1046 if (mVolumeImpl != NULL) 1085 if (mVolumeImpl != NULL)
1047 { 1086 {
1048 LLFastTimer t(LLFastTimer::FTM_GEN_FLEX); 1087 BOOL res;
1049 BOOL res = mVolumeImpl->doUpdateGeometry(drawable); 1088 {
1089 LLFastTimer t(LLFastTimer::FTM_GEN_FLEX);
1090 res = mVolumeImpl->doUpdateGeometry(drawable);
1091 }
1050 updateFaceFlags(); 1092 updateFaceFlags();
1051 return res; 1093 return res;
1052 } 1094 }
1053 1095
1096 dirtySpatialGroup();
1097
1054 BOOL compiled = FALSE; 1098 BOOL compiled = FALSE;
1055 1099
1056 updateRelativeXform(); 1100 updateRelativeXform();
@@ -1063,7 +1107,6 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
1063 if (mVolumeChanged || mFaceMappingChanged ) 1107 if (mVolumeChanged || mFaceMappingChanged )
1064 { 1108 {
1065 compiled = TRUE; 1109 compiled = TRUE;
1066 mInited = TRUE;
1067 1110
1068 if (mVolumeChanged) 1111 if (mVolumeChanged)
1069 { 1112 {
@@ -1248,6 +1291,17 @@ S32 LLVOVolume::setTEMediaFlags(const U8 te, const U8 media_flags)
1248 return res; 1291 return res;
1249} 1292}
1250 1293
1294S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow)
1295{
1296 S32 res = LLViewerObject::setTEGlow(te, glow);
1297 if (res)
1298 {
1299 gPipeline.markTextured(mDrawable);
1300 mFaceMappingChanged = TRUE;
1301 }
1302 return res;
1303}
1304
1251S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t) 1305S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t)
1252{ 1306{
1253 S32 res = LLViewerObject::setTEScale(te, s, t); 1307 S32 res = LLViewerObject::setTEScale(te, s, t);
@@ -1314,12 +1368,6 @@ void LLVOVolume::setIsLight(BOOL is_light)
1314 { 1368 {
1315 // Not a light. Remove it from the pipeline's light set. 1369 // Not a light. Remove it from the pipeline's light set.
1316 gPipeline.setLight(mDrawable, FALSE); 1370 gPipeline.setLight(mDrawable, FALSE);
1317
1318 // Remove this object from any object which has it as a light
1319 if (mDrawable)
1320 {
1321 mDrawable->clearLightSet();
1322 }
1323 } 1371 }
1324 } 1372 }
1325} 1373}
@@ -1476,92 +1524,6 @@ F32 LLVOVolume::getLightCutoff() const
1476 } 1524 }
1477} 1525}
1478 1526
1479//----------------------------------------------------------------------------
1480
1481// returns < 0 if inside radius
1482F32 LLVOVolume::getLightDistance(const LLVector3& pos) const
1483{
1484 LLVector3 dpos = getRenderPosition() - pos;
1485 F32 dist = dpos.magVec() - getLightRadius();
1486 return dist;
1487}
1488
1489// returns intensity, modifies color in result
1490F32 LLVOVolume::calcLightAtPoint(const LLVector3& pos, const LLVector3& norm, LLColor4& result)
1491{
1492 if (!getIsLight())
1493 {
1494 return 0.0f;
1495 }
1496 F32 light_radius = getLightRadius();
1497 LLVector3 light_pos = getRenderPosition();
1498 LLVector3 light_dir = light_pos - pos;
1499 F32 dist = light_dir.normVec();
1500 F32 dp = norm * light_dir;
1501 if ((gPipeline.getLightingDetail() > 2))
1502 {
1503 if (dp <= 0)
1504 {
1505 result *= 0;
1506 return 0;
1507 }
1508
1509 if (dist >= light_radius)
1510 {
1511 result *= 0;
1512 return 0;
1513 }
1514
1515 F32 mag = 1.0f-(dist/light_radius);
1516 mag = powf(mag, 0.75f);
1517 mag *= dp;
1518 result = getLightColor() * mag;
1519 return mag;
1520 }
1521 else
1522 {
1523 F32 light_radius = getLightRadius();
1524 LLVector3 light_pos = getRenderPosition();
1525 LLVector3 light_dir = light_pos - pos;
1526 F32 dist = light_dir.normVec();
1527 F32 dp = norm * light_dir;
1528 F32 atten = (1.f/.2f) / (light_radius); // 20% of brightness at radius
1529 F32 falloff = 1.f / (dist * atten);
1530 F32 mag = falloff * dp;
1531 mag = llmax(mag, 0.0f);
1532 result = getLightColor() * mag;
1533 return mag;
1534 }
1535}
1536
1537BOOL LLVOVolume::updateLighting(BOOL do_lighting)
1538{
1539 LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
1540#if 0
1541 if (mDrawable->isStatic())
1542 {
1543 do_lighting = FALSE;
1544 }
1545
1546 const LLMatrix4& mat_vert = mDrawable->getWorldMatrix();
1547 const LLMatrix3& mat_normal = LLMatrix3(mDrawable->getWorldRotation());
1548
1549 LLVolume* volume = getVolume();
1550
1551 for (S32 i = 0; i < volume->getNumFaces(); i++)
1552 {
1553 LLFace *face = mDrawable->getFace(i);
1554 if (face && face->getGeomCount())
1555 {
1556 face->genLighting(volume, mDrawable, i, i, mat_vert, mat_normal, do_lighting);
1557 }
1558 }
1559#endif
1560 return TRUE;
1561}
1562
1563//----------------------------------------------------------------------------
1564
1565U32 LLVOVolume::getVolumeInterfaceID() const 1527U32 LLVOVolume::getVolumeInterfaceID() const
1566{ 1528{
1567 if (mVolumeImpl) 1529 if (mVolumeImpl)
@@ -1576,7 +1538,8 @@ BOOL LLVOVolume::isFlexible() const
1576{ 1538{
1577 if (getParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE)) 1539 if (getParameterEntryInUse(LLNetworkData::PARAMS_FLEXIBLE))
1578 { 1540 {
1579 if (getVolume()->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE) 1541 LLVolume* volume = getVolume();
1542 if (volume && volume->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE)
1580 { 1543 {
1581 LLVolumeParams volume_params = getVolume()->getParams(); 1544 LLVolumeParams volume_params = getVolume()->getParams();
1582 U8 profile_and_hole = volume_params.getProfileParams().getCurveType(); 1545 U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
@@ -1684,7 +1647,13 @@ void LLVOVolume::generateSilhouette(LLSelectNode* nodep, const LLVector3& view_p
1684 } 1647 }
1685 1648
1686 updateRelativeXform(); 1649 updateRelativeXform();
1687 volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, nodep->mSilhouetteSegments, view_vector, mRelativeXform, mRelativeXformInvTrans); 1650 LLMatrix4 trans_mat = mRelativeXform;
1651 if (mDrawable->isStatic())
1652 {
1653 trans_mat.translate(getRegion()->getOriginAgent());
1654 }
1655
1656 volume->generateSilhouetteVertices(nodep->mSilhouetteVertices, nodep->mSilhouetteNormals, nodep->mSilhouetteSegments, view_vector, trans_mat, mRelativeXformInvTrans);
1688 1657
1689 nodep->mSilhouetteExists = TRUE; 1658 nodep->mSilhouetteExists = TRUE;
1690 } 1659 }
@@ -1744,137 +1713,6 @@ const LLMatrix4 LLVOVolume::getRenderMatrix() const
1744 return mDrawable->getWorldMatrix(); 1713 return mDrawable->getWorldMatrix();
1745} 1714}
1746 1715
1747void LLVOVolume::writeCAL3D(apr_file_t* fp, std::string& path, std::string& file_base, S32 joint_num, LLVector3& pos, LLQuaternion& rot, S32& material_index, S32& texture_index, std::multimap<LLUUID, LLMaterialExportInfo*>& material_map)
1748{
1749#if 0
1750 LLImageTGA tga_image;
1751
1752 if (mDrawable.isNull())
1753 {
1754 return;
1755 }
1756
1757 LLVector3 final_pos = getPosition();
1758 final_pos *= 100.f;
1759
1760 final_pos = final_pos * rot;
1761 final_pos += pos;
1762 LLQuaternion final_rot;
1763 final_rot = getRotation() * rot;
1764 LLMatrix4 transform;
1765 transform.initAll(getScale(), final_rot, final_pos);
1766
1767 LLMatrix4 int_transpose_transform;
1768 int_transpose_transform.initAll(LLVector3(1.f / getScale().mV[VX], 1.f / getScale().mV[VY], 1.f / getScale().mV[VZ]), final_rot, LLVector3::zero);
1769
1770 for (S32 i = 0; i < mDrawable->getNumFaces(); i++)
1771 {
1772 S32 vert_num = 0;
1773 LLFace* facep = mDrawable->getFace(i);
1774 LLDrawPool* poolp = facep->getPool();
1775
1776 const LLTextureEntry* tep = facep->getTextureEntry();
1777 if (!tep)
1778 {
1779 continue;
1780 }
1781
1782 S32 my_material = -1;
1783 S32 my_texture = -1;
1784 LLColor4 face_color = tep->getColor();
1785
1786 typedef std::multimap<LLUUID, LLMaterialExportInfo*>::iterator material_it_t;
1787 std::pair<material_it_t, material_it_t> found_range = material_map.equal_range(tep->getID());
1788 material_it_t material_it = found_range.first;
1789
1790 LLMaterialExportInfo* material_info = NULL;
1791
1792 while(material_it != material_map.end() && material_it != found_range.second)
1793 {
1794 // we've at least found a matching texture, so reuse it
1795 my_texture = material_it->second->mTextureIndex;
1796 if (material_it->second->mColor == face_color)
1797 {
1798 // we've found a matching material
1799 material_info = material_it->second;
1800 }
1801 ++material_it;
1802 }
1803
1804 if (material_info)
1805 {
1806 // material already exported, just reuse it
1807 my_material = material_info->mMaterialIndex;
1808 my_texture = material_info->mTextureIndex;
1809 }
1810 else
1811 {
1812 // reserve new material number
1813 my_material = material_index++;
1814
1815 // if we didn't already find a matching texture...
1816 if (my_texture == -1)
1817 {
1818 //...use the next available slot...
1819 my_texture = texture_index++;
1820
1821 //...and export texture as image file
1822 char filename[MAX_PATH]; /* Flawfinder: ignore */
1823 snprintf(filename, MAX_PATH, "%s\\%s_material_tex_%d.tga", path.c_str(), file_base.c_str(), my_texture); /* Flawfinder: ignore */
1824
1825 LLViewerImage* imagep = facep->getTexture();
1826 if (imagep->getTexName() == 0)
1827 {
1828 llinfos << "No image data available for " << filename << llendl;
1829 continue;
1830 }
1831 LLImageRaw raw_image;
1832 imagep->readBackRaw(-1, raw_image);
1833 BOOL success = tga_image.encode(raw_image);
1834 success = tga_image.save(filename);
1835 }
1836
1837 material_info = new LLMaterialExportInfo(my_material, my_texture, face_color);
1838 material_map.insert(std::make_pair<LLUUID, LLMaterialExportInfo*>(tep->getID(), material_info));
1839 }
1840
1841 apr_file_printf(fp, "\t<SUBMESH NUMVERTICES=\"%d\" NUMFACES=\"%d\" MATERIAL=\"%d\" NUMLODSTEPS=\"0\" NUMSPRINGS=\"0\" NUMTEXCOORDS=\"1\">\n",
1842 facep->getGeomCount(), facep->getIndicesCount() / 3, my_material);
1843
1844 for (S32 vert_index = 0; vert_index < facep->getGeomCount(); vert_index++)
1845 {
1846 LLVector3 vert_pos = poolp->getVertex(facep->getGeomStart() + vert_index);
1847 vert_pos *= 100.f;
1848 vert_pos = vert_pos * transform;
1849 LLVector3 vert_norm = poolp->getNormal(facep->getGeomStart() + vert_index);
1850 vert_norm = vert_norm * int_transpose_transform;
1851 LLVector2 vert_tc = poolp->getTexCoord(facep->getGeomStart() + vert_index, 0);
1852 apr_file_printf(fp, " <VERTEX ID=\"%d\" NUMINFLUENCES=\"1\">\n", vert_num++);
1853 apr_file_printf(fp, " <POS>%.4f %.4f %.4f</POS>\n", vert_pos.mV[VX], vert_pos.mV[VY], vert_pos.mV[VZ]);
1854 apr_file_printf(fp, " <NORM>%.6f %.6f %.6f</NORM>\n", vert_norm.mV[VX], vert_norm.mV[VY], vert_norm.mV[VZ]);
1855 apr_file_printf(fp, " <TEXCOORD>%.6f %.6f</TEXCOORD>\n", vert_tc.mV[VX], 1.f - vert_tc.mV[VY]);
1856 apr_file_printf(fp, " <INFLUENCE ID=\"%d\">1.0</INFLUENCE>\n", joint_num + 1);
1857 apr_file_printf(fp, " </VERTEX>\n");
1858 }
1859
1860 for (U32 index_i = 0; index_i < facep->getIndicesCount(); index_i += 3)
1861 {
1862 U32 index_a = poolp->getIndex(facep->getIndicesStart() + index_i) - facep->getGeomStart();
1863 U32 index_b = poolp->getIndex(facep->getIndicesStart() + index_i + 1) - facep->getGeomStart();
1864 U32 index_c = poolp->getIndex(facep->getIndicesStart() + index_i + 2) - facep->getGeomStart();
1865 apr_file_printf(fp, " <FACE VERTEXID=\"%d %d %d\" />\n", index_a, index_b, index_c);
1866 }
1867
1868 apr_file_printf(fp, " </SUBMESH>\n");
1869 }
1870
1871 for (U32 i = 0; i < mChildList.size(); i++)
1872 {
1873 ((LLVOVolume*)(LLViewerObject*)mChildList[i])->writeCAL3D(fp, path, file_base, joint_num, final_pos, final_rot, material_index, texture_index, material_map);
1874 }
1875#endif
1876}
1877
1878//static 1716//static
1879void LLVOVolume::preUpdateGeom() 1717void LLVOVolume::preUpdateGeom()
1880{ 1718{
@@ -1908,7 +1746,7 @@ void LLVOVolume::setSelected(BOOL sel)
1908 LLViewerObject::setSelected(sel); 1746 LLViewerObject::setSelected(sel);
1909 if (mDrawable.notNull()) 1747 if (mDrawable.notNull())
1910 { 1748 {
1911 mDrawable->movePartition(); 1749 markForUpdate(TRUE);
1912 } 1750 }
1913} 1751}
1914 1752
@@ -1929,7 +1767,9 @@ F32 LLVOVolume::getBinRadius()
1929 { 1767 {
1930 for (S32 i = 0; i < mDrawable->getNumFaces(); i++) 1768 for (S32 i = 0; i < mDrawable->getNumFaces(); i++)
1931 { 1769 {
1932 if (mDrawable->getFace(i)->getPoolType() == LLDrawPool::POOL_ALPHA) 1770 LLFace* face = mDrawable->getFace(i);
1771 if (face->getPoolType() == LLDrawPool::POOL_ALPHA &&
1772 (!LLPipeline::sFastAlpha || face->getVirtualSize() > MIN_ALPHA_SIZE))
1933 { 1773 {
1934 alpha_wrap = TRUE; 1774 alpha_wrap = TRUE;
1935 break; 1775 break;
@@ -1954,7 +1794,14 @@ F32 LLVOVolume::getBinRadius()
1954 } 1794 }
1955 else if (mDrawable->isStatic()) 1795 else if (mDrawable->isStatic())
1956 { 1796 {
1957 radius = 32.f; 1797 if (mDrawable->getRadius() < 2.0f)
1798 {
1799 radius = 16.f;
1800 }
1801 else
1802 {
1803 radius = 32.f;
1804 }
1958 } 1805 }
1959 else 1806 else
1960 { 1807 {
@@ -2049,10 +1896,10 @@ U32 LLVOVolume::getPartitionType() const
2049{ 1896{
2050 if (isHUDAttachment()) 1897 if (isHUDAttachment())
2051 { 1898 {
2052 return LLPipeline::PARTITION_HUD; 1899 return LLViewerRegion::PARTITION_HUD;
2053 } 1900 }
2054 1901
2055 return LLPipeline::PARTITION_VOLUME; 1902 return LLViewerRegion::PARTITION_VOLUME;
2056} 1903}
2057 1904
2058LLVolumePartition::LLVolumePartition() 1905LLVolumePartition::LLVolumePartition()
@@ -2061,7 +1908,7 @@ LLVolumePartition::LLVolumePartition()
2061 mLODPeriod = 16; 1908 mLODPeriod = 16;
2062 mDepthMask = FALSE; 1909 mDepthMask = FALSE;
2063 mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; 1910 mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
2064 mPartitionType = LLPipeline::PARTITION_VOLUME; 1911 mPartitionType = LLViewerRegion::PARTITION_VOLUME;
2065 mSlopRatio = 0.25f; 1912 mSlopRatio = 0.25f;
2066 mBufferUsage = GL_DYNAMIC_DRAW_ARB; 1913 mBufferUsage = GL_DYNAMIC_DRAW_ARB;
2067 mImageEnabled = TRUE; 1914 mImageEnabled = TRUE;
@@ -2073,7 +1920,7 @@ LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep)
2073 mDepthMask = FALSE; 1920 mDepthMask = FALSE;
2074 mLODPeriod = 16; 1921 mLODPeriod = 16;
2075 mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; 1922 mDrawableType = LLPipeline::RENDER_TYPE_VOLUME;
2076 mPartitionType = LLPipeline::PARTITION_BRIDGE; 1923 mPartitionType = LLViewerRegion::PARTITION_BRIDGE;
2077 1924
2078 mBufferUsage = GL_DYNAMIC_DRAW_ARB; 1925 mBufferUsage = GL_DYNAMIC_DRAW_ARB;
2079 1926
@@ -2099,50 +1946,47 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
2099 type == LLRenderPass::PASS_ALPHA) ? facep->isState(LLFace::FULLBRIGHT) : FALSE; 1946 type == LLRenderPass::PASS_ALPHA) ? facep->isState(LLFace::FULLBRIGHT) : FALSE;
2100 1947
2101 const LLMatrix4* tex_mat = NULL; 1948 const LLMatrix4* tex_mat = NULL;
2102 if (type != LLRenderPass::PASS_SHINY && facep->isState(LLFace::TEXTURE_ANIM)) 1949 if (facep->isState(LLFace::TEXTURE_ANIM) && facep->getVirtualSize() > MIN_TEX_ANIM_SIZE)
1950 {
1951 tex_mat = facep->mTextureMatrix;
1952 }
1953
1954 const LLMatrix4* model_mat = NULL;
1955
1956 LLDrawable* drawable = facep->getDrawable();
1957 if (drawable->isActive())
1958 {
1959 model_mat = &(drawable->getRenderMatrix());
1960 }
1961 else
2103 { 1962 {
2104 tex_mat = &(facep->mTextureMatrix); 1963 model_mat = &(drawable->getRegion()->mRenderMatrix);
2105 } 1964 }
2106 1965
2107 U8 bump = (type == LLRenderPass::PASS_BUMP ? facep->getTextureEntry()->getBumpmap() : 0); 1966 U8 bump = (type == LLRenderPass::PASS_BUMP ? facep->getTextureEntry()->getBumpmap() : 0);
2108 1967
2109 //LLViewerImage* tex = facep->mAppAngle < FORCE_SIMPLE_RENDER_ANGLE ? NULL : facep->getTexture();
2110 LLViewerImage* tex = facep->getTexture(); 1968 LLViewerImage* tex = facep->getTexture();
2111 1969
1970 U8 glow = 0;
1971
2112 if (type == LLRenderPass::PASS_GLOW) 1972 if (type == LLRenderPass::PASS_GLOW)
2113 { 1973 {
2114 U32 start = facep->getGeomIndex(); 1974 glow = (U8) (facep->getTextureEntry()->getGlow() * 255);
2115 U32 end = start + facep->getGeomCount()-1;
2116 U32 offset = facep->getIndicesStart();
2117 U32 count = facep->getIndicesCount();
2118 LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset,tex,
2119 facep->mVertexBuffer, fullbright, bump);
2120 draw_info->mVSize = facep->getVirtualSize();
2121 draw_vec.push_back(draw_info);
2122 LLVOVolume* volume = (LLVOVolume*) facep->getViewerObject();
2123 BOOL is_light = volume->mDrawable->isLight();
2124
2125 U8 alpha = is_light ? 196 : 160;
2126 LLColor3 col = is_light ? volume->getLightColor() : LLColor3(0,0,0);
2127 LLColor4 col2 = facep->getRenderColor();
2128 draw_info->mGlowColor.setVec((U8) (col.mV[0]*col2.mV[0]*255),
2129 (U8) (col.mV[1]*col2.mV[1]*255),
2130 (U8) (col.mV[2]*col2.mV[2]*255),
2131 alpha);
2132 draw_info->mTextureMatrix = tex_mat;
2133 validate_draw_info(*draw_info);
2134 } 1975 }
2135 else if (idx >= 0 && 1976
1977 if (idx >= 0 &&
2136 draw_vec[idx]->mVertexBuffer == facep->mVertexBuffer && 1978 draw_vec[idx]->mVertexBuffer == facep->mVertexBuffer &&
2137 draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && 1979 draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
2138 draw_vec[idx]->mTexture == tex && 1980 (LLPipeline::sTextureBindTest || draw_vec[idx]->mTexture == tex) &&
2139#if LL_DARWIN 1981#if LL_DARWIN
2140 draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && 1982 draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange &&
2141 draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && 1983 draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange &&
2142#endif 1984#endif
1985 draw_vec[idx]->mGlowColor.mV[3] == glow &&
2143 draw_vec[idx]->mFullbright == fullbright && 1986 draw_vec[idx]->mFullbright == fullbright &&
2144 draw_vec[idx]->mBump == bump && 1987 draw_vec[idx]->mBump == bump &&
2145 draw_vec[idx]->mTextureMatrix == tex_mat) 1988 draw_vec[idx]->mTextureMatrix == tex_mat &&
1989 draw_vec[idx]->mModelMatrix == model_mat)
2146 { 1990 {
2147 draw_vec[idx]->mCount += facep->getIndicesCount(); 1991 draw_vec[idx]->mCount += facep->getIndicesCount();
2148 draw_vec[idx]->mEnd += facep->getGeomCount(); 1992 draw_vec[idx]->mEnd += facep->getGeomCount();
@@ -2157,10 +2001,13 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
2157 U32 count = facep->getIndicesCount(); 2001 U32 count = facep->getIndicesCount();
2158 LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset,tex, 2002 LLPointer<LLDrawInfo> draw_info = new LLDrawInfo(start,end,count,offset,tex,
2159 facep->mVertexBuffer, fullbright, bump); 2003 facep->mVertexBuffer, fullbright, bump);
2004 draw_info->mGroup = group;
2160 draw_info->mVSize = facep->getVirtualSize(); 2005 draw_info->mVSize = facep->getVirtualSize();
2161 draw_vec.push_back(draw_info); 2006 draw_vec.push_back(draw_info);
2162 draw_info->mReflectionMap = group->mReflectionMap; 2007 draw_info->mReflectionMap = group->mReflectionMap;
2163 draw_info->mTextureMatrix = tex_mat; 2008 draw_info->mTextureMatrix = tex_mat;
2009 draw_info->mModelMatrix = model_mat;
2010 draw_info->mGlowColor.setVec(0,0,0,glow);
2164 validate_draw_info(*draw_info); 2011 validate_draw_info(*draw_info);
2165 } 2012 }
2166} 2013}
@@ -2172,6 +2019,11 @@ void LLVolumeGeometryManager::getGeometry(LLSpatialGroup* group)
2172 2019
2173void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) 2020void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2174{ 2021{
2022 if (LLPipeline::sSkipUpdate)
2023 {
2024 return;
2025 }
2026
2175 if (group->changeLOD()) 2027 if (group->changeLOD())
2176 { 2028 {
2177 group->mLastUpdateDistance = group->mDistance; 2029 group->mLastUpdateDistance = group->mDistance;
@@ -2182,6 +2034,60 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2182 if (!group->isState(LLSpatialGroup::GEOM_DIRTY | 2034 if (!group->isState(LLSpatialGroup::GEOM_DIRTY |
2183 LLSpatialGroup::ALPHA_DIRTY)) 2035 LLSpatialGroup::ALPHA_DIRTY))
2184 { 2036 {
2037 if (group->isState(LLSpatialGroup::MESH_DIRTY))
2038 {
2039 group->mBuilt = 1.f;
2040 LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO);
2041
2042 LLFastTimer ftm2(LLFastTimer::FTM_REBUILD_VOLUME_VB);
2043
2044 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
2045 {
2046 LLDrawable* drawablep = *drawable_iter;
2047 if (drawablep->isState(LLDrawable::REBUILD_ALL))
2048 {
2049 LLVOVolume* vobj = drawablep->getVOVolume();
2050 vobj->preRebuild();
2051 LLVolume* volume = vobj->getVolume();
2052 for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
2053 {
2054 LLFace* face = drawablep->getFace(i);
2055 if (face && face->mVertexBuffer.notNull())
2056 {
2057 face->getGeometryVolume(*volume, face->getTEOffset(),
2058 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex());
2059 }
2060 }
2061
2062 drawablep->clearState(LLDrawable::REBUILD_ALL);
2063 }
2064 }
2065
2066 //unmap all the buffers
2067 for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
2068 {
2069 LLSpatialGroup::buffer_list_t& list = i->second;
2070 for (LLSpatialGroup::buffer_list_t::iterator j = list.begin(); j != list.end(); ++j)
2071 {
2072 LLVertexBuffer* buffer = *j;
2073 if (buffer->isLocked())
2074 {
2075 buffer->setBuffer(0);
2076 }
2077 }
2078 }
2079
2080 // don't forget alpha
2081 if( group != NULL &&
2082 !group->mVertexBuffer.isNull() &&
2083 group->mVertexBuffer->isLocked())
2084 {
2085 group->mVertexBuffer->setBuffer(0);
2086 }
2087
2088 group->clearState(LLSpatialGroup::MESH_DIRTY);
2089 }
2090
2185 return; 2091 return;
2186 } 2092 }
2187 2093
@@ -2191,7 +2097,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2191 LLFastTimer ftm2(LLFastTimer::FTM_REBUILD_VOLUME_VB); 2097 LLFastTimer ftm2(LLFastTimer::FTM_REBUILD_VOLUME_VB);
2192 2098
2193 //find reflection map 2099 //find reflection map
2194 if (group->mSpatialPartition->mImageEnabled) 2100 if (group->mSpatialPartition->mImageEnabled && LLPipeline::sDynamicReflections)
2195 { 2101 {
2196 if (group->mReflectionMap.isNull()) 2102 if (group->mReflectionMap.isNull())
2197 { 2103 {
@@ -2213,6 +2119,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2213 U32 index_count = 0; 2119 U32 index_count = 0;
2214 U32 useage = group->mSpatialPartition->mBufferUsage; 2120 U32 useage = group->mSpatialPartition->mBufferUsage;
2215 2121
2122 U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);
2123 max_vertices = llmin(max_vertices, (U32) 65535);
2124
2216 //get all the faces into a list, putting alpha faces in their own list 2125 //get all the faces into a list, putting alpha faces in their own list
2217 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) 2126 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
2218 { 2127 {
@@ -2229,6 +2138,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2229 } 2138 }
2230 2139
2231 LLVOVolume* vobj = drawablep->getVOVolume(); 2140 LLVOVolume* vobj = drawablep->getVOVolume();
2141 vobj->updateTextures();
2142 vobj->preRebuild();
2232 2143
2233 //for each face 2144 //for each face
2234 for (S32 i = 0; i < drawablep->getNumFaces(); i++) 2145 for (S32 i = 0; i < drawablep->getNumFaces(); i++)
@@ -2272,9 +2183,38 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2272 2183
2273 if (type == LLDrawPool::POOL_ALPHA) 2184 if (type == LLDrawPool::POOL_ALPHA)
2274 { 2185 {
2275 vertex_count += facep->getGeomCount(); 2186 BOOL alpha_opt = LLPipeline::sFastAlpha && gPipeline.canUseWindLightShadersOnObjects() && facep->getVirtualSize() < MIN_ALPHA_SIZE;
2276 index_count += facep->getIndicesCount(); 2187
2277 alpha_faces.push_back(facep); 2188 const LLColor4& col = facep->getTextureEntry()->getColor();
2189
2190 if (alpha_opt)
2191 { //if we're applying the alpha optimization, only blend faces that have alpha (0.15, 0.5]
2192 //for faces with alpha (0.5, 1.0], render with an alpha mask
2193 //for faces with alpha [0.0, 0.15], don't render
2194 if (col.mV[3] > 0.5f)
2195 {
2196 mFaceList.push_back(facep);
2197 }
2198 else if (col.mV[3] > 0.15f)
2199 {
2200 vertex_count += facep->getGeomCount();
2201 index_count += facep->getIndicesCount();
2202 alpha_faces.push_back(facep);
2203 }
2204 else
2205 { //face has no renderable geometry
2206 facep->mVertexBuffer = NULL;
2207 facep->mLastVertexBuffer = NULL;
2208 //don't alpha wrap drawables that have only tiny tiny alpha faces
2209 facep->setPoolType(LLDrawPool::POOL_SIMPLE);
2210 }
2211 }
2212 else
2213 {
2214 vertex_count += facep->getGeomCount();
2215 index_count += facep->getIndicesCount();
2216 alpha_faces.push_back(facep);
2217 }
2278 } 2218 }
2279 else 2219 else
2280 { 2220 {
@@ -2291,47 +2231,60 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2291 facep->mLastVertexBuffer = NULL; 2231 facep->mLastVertexBuffer = NULL;
2292 //don't alpha wrap drawables that have only tiny tiny alpha faces 2232 //don't alpha wrap drawables that have only tiny tiny alpha faces
2293 facep->setPoolType(LLDrawPool::POOL_SIMPLE); 2233 facep->setPoolType(LLDrawPool::POOL_SIMPLE);
2294 } 2234 }
2295
2296 vobj->updateTextures();
2297 } 2235 }
2298 } 2236 }
2299 2237
2300 group->mVertexCount = vertex_count; 2238 U16 alpha_vertex_count = vertex_count > 65535 ? 65535 : vertex_count;
2301 group->mIndexCount = index_count; 2239 U32 alpha_index_count = index_count;
2302 group->mBufferUsage = useage;
2303 2240
2304 LLStrider<LLVector3> vertices; 2241 group->mBufferUsage = useage;
2305 LLStrider<LLVector3> normals;
2306 LLStrider<LLVector2> texcoords2;
2307 LLStrider<LLVector2> texcoords;
2308 LLStrider<LLColor4U> colors;
2309 LLStrider<U32> indices;
2310 2242
2311 //PROCESS NON-ALPHA FACES 2243 //PROCESS NON-ALPHA FACES
2312 { 2244 {
2313 //sort faces by texture 2245 //sort faces by things that break batches
2314 std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareTextureAndTime()); 2246 std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareBatchBreaker());
2315 2247
2316 std::vector<LLFace*>::iterator face_iter = mFaceList.begin(); 2248 std::vector<LLFace*>::iterator face_iter = mFaceList.begin();
2317 2249
2318 LLSpatialGroup::buffer_map_t buffer_map; 2250 LLSpatialGroup::buffer_map_t buffer_map;
2319 2251
2252 LLViewerImage* last_tex = NULL;
2253 U32 buffer_index = 0;
2254
2320 while (face_iter != mFaceList.end()) 2255 while (face_iter != mFaceList.end())
2321 { 2256 {
2322 //pull off next face 2257 //pull off next face
2323 LLFace* facep = *face_iter; 2258 LLFace* facep = *face_iter;
2324 LLViewerImage* tex = facep->getTexture(); 2259 LLViewerImage* tex = facep->getTexture();
2325 2260
2261 if (last_tex == tex)
2262 {
2263 buffer_index++;
2264 }
2265 else
2266 {
2267 last_tex = tex;
2268 buffer_index = 0;
2269 }
2270
2326 U32 index_count = facep->getIndicesCount(); 2271 U32 index_count = facep->getIndicesCount();
2327 U32 geom_count = facep->getGeomCount(); 2272 U32 geom_count = facep->getGeomCount();
2328 2273
2329 //sum up vertices needed for this texture 2274 //sum up vertices needed for this texture
2330 std::vector<LLFace*>::iterator i = face_iter; 2275 std::vector<LLFace*>::iterator i = face_iter;
2331 ++i; 2276 ++i;
2332 while (i != mFaceList.end() && (*i)->getTexture() == tex) 2277
2278 while (i != mFaceList.end() &&
2279 (LLPipeline::sTextureBindTest || (*i)->getTexture() == tex))
2333 { 2280 {
2334 facep = *i; 2281 facep = *i;
2282
2283 if (geom_count + facep->getGeomCount() > max_vertices)
2284 { //cut vertex buffers on geom count too big
2285 break;
2286 }
2287
2335 ++i; 2288 ++i;
2336 index_count += facep->getIndicesCount(); 2289 index_count += facep->getIndicesCount();
2337 geom_count += facep->getGeomCount(); 2290 geom_count += facep->getGeomCount();
@@ -2342,9 +2295,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2342 LLSpatialGroup::buffer_map_t::iterator found_iter = group->mBufferMap.find(tex); 2295 LLSpatialGroup::buffer_map_t::iterator found_iter = group->mBufferMap.find(tex);
2343 if (found_iter != group->mBufferMap.end()) 2296 if (found_iter != group->mBufferMap.end())
2344 { 2297 {
2345 buffer = found_iter->second; 2298 if (buffer_index < found_iter->second.size())
2299 {
2300 buffer = found_iter->second[buffer_index];
2301 }
2346 } 2302 }
2347 2303
2348 if (!buffer) 2304 if (!buffer)
2349 { //create new buffer if needed 2305 { //create new buffer if needed
2350 buffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask, 2306 buffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask,
@@ -2365,21 +2321,12 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2365 } 2321 }
2366 } 2322 }
2367 2323
2368 BOOL clean = TRUE; 2324 buffer_map[tex].push_back(buffer);
2369 buffer_map[tex] = buffer;
2370 2325
2371 //add face geometry 2326 //add face geometry
2372
2373 //get vertex buffer striders
2374 buffer->getVertexStrider(vertices);
2375 buffer->getNormalStrider(normals);
2376 buffer->getTexCoordStrider(texcoords);
2377 buffer->getTexCoord2Strider(texcoords2);
2378 buffer->getColorStrider(colors);
2379 buffer->getIndexStrider(indices);
2380 2327
2381 U32 indices_index = 0; 2328 U32 indices_index = 0;
2382 U32 index_offset = 0; 2329 U16 index_offset = 0;
2383 2330
2384 while (face_iter < i) 2331 while (face_iter < i)
2385 { 2332 {
@@ -2393,60 +2340,82 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2393 facep->mGeomIndex = index_offset; 2340 facep->mGeomIndex = index_offset;
2394 facep->mVertexBuffer = buffer; 2341 facep->mVertexBuffer = buffer;
2395 { 2342 {
2396 if (facep->getGeometryVolume(*volume, te_idx, vertices, normals, texcoords, texcoords2, colors, indices, 2343 if (facep->getGeometryVolume(*volume, te_idx,
2397 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset)) 2344 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset))
2398 { 2345 {
2399 clean = FALSE;
2400 buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(), 2346 buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(),
2401 facep->getIndicesStart(), facep->getIndicesCount()); 2347 facep->getIndicesStart(), facep->getIndicesCount());
2402 } 2348 }
2403 } 2349 }
2404 2350
2351 index_offset += facep->getGeomCount();
2405 indices_index += facep->mIndicesCount; 2352 indices_index += facep->mIndicesCount;
2406 2353
2407 BOOL force_simple = facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA; 2354 BOOL force_simple = facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA;
2408 BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); 2355 BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
2409 const LLTextureEntry* te = facep->getTextureEntry(); 2356 const LLTextureEntry* te = facep->getTextureEntry();
2410 2357
2411 if (tex->getPrimaryFormat() == GL_ALPHA) 2358 BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE;
2412 { 2359
2413 registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); 2360 if (!is_alpha
2414 } 2361 && gPipeline.canUseWindLightShadersOnObjects()
2415 else if (fullbright) 2362 && LLPipeline::sRenderBump
2363 && te->getShiny())
2416 { 2364 {
2417 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); 2365 if (tex->getPrimaryFormat() == GL_ALPHA)
2366 {
2367 registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
2368 registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
2369 }
2370 else if (fullbright)
2371 {
2372 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
2373 }
2374 else
2375 {
2376 registerFace(group, facep, LLRenderPass::PASS_SHINY);
2377 }
2418 } 2378 }
2419 else 2379 else
2420 { 2380 {
2421 registerFace(group, facep, LLRenderPass::PASS_SIMPLE); 2381 if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA)
2422 } 2382 {
2423 2383 registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
2424 facep->setPoolType(LLDrawPool::POOL_SIMPLE); 2384 }
2425 2385 else if (fullbright)
2426 if (te->getShiny()) 2386 {
2427 { 2387 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
2428 registerFace(group, facep, LLRenderPass::PASS_SHINY); 2388 }
2389 else
2390 {
2391 registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
2392 }
2393
2394 if (!is_alpha && te->getShiny())
2395 {
2396 registerFace(group, facep, LLRenderPass::PASS_SHINY);
2397 }
2429 } 2398 }
2430 2399
2431 if (!force_simple && te->getBumpmap()) 2400 if (!is_alpha)
2432 { 2401 {
2433 registerFace(group, facep, LLRenderPass::PASS_BUMP); 2402 facep->setPoolType(LLDrawPool::POOL_SIMPLE);
2403
2404 if (!force_simple && te->getBumpmap())
2405 {
2406 registerFace(group, facep, LLRenderPass::PASS_BUMP);
2407 }
2434 } 2408 }
2435 2409
2436 if (vobj->getIsLight() || 2410 if (LLPipeline::sRenderGlow && te->getGlow() > 0.f)
2437 (LLPipeline::sRenderGlow && facep->isState(LLFace::FULLBRIGHT)))
2438 { 2411 {
2439 registerFace(group, facep, LLRenderPass::PASS_GLOW); 2412 registerFace(group, facep, LLRenderPass::PASS_GLOW);
2440 } 2413 }
2441 2414
2442
2443 ++face_iter; 2415 ++face_iter;
2444 } 2416 }
2445 2417
2446 if (clean) 2418 buffer->setBuffer(0);
2447 {
2448 buffer->markClean();
2449 }
2450 } 2419 }
2451 2420
2452 group->mBufferMap.clear(); 2421 group->mBufferMap.clear();
@@ -2467,33 +2436,31 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2467 { 2436 {
2468 group->mVertexBuffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask, 2437 group->mVertexBuffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask,
2469 group->mBufferUsage); 2438 group->mBufferUsage);
2470 group->mVertexBuffer->allocateBuffer(group->mVertexCount, group->mIndexCount, true); 2439 group->mVertexBuffer->allocateBuffer(alpha_vertex_count, alpha_index_count, true);
2471 stop_glerror(); 2440 stop_glerror();
2472 } 2441 }
2473 else 2442 else
2474 { 2443 {
2475 group->mVertexBuffer->resizeBuffer(group->mVertexCount, group->mIndexCount); 2444 group->mVertexBuffer->resizeBuffer(alpha_vertex_count, alpha_index_count);
2476 stop_glerror(); 2445 stop_glerror();
2477 } 2446 }
2478 2447
2479 //get vertex buffer striders 2448 //get vertex buffer striders
2480 LLVertexBuffer* buffer = group->mVertexBuffer; 2449 LLVertexBuffer* buffer = group->mVertexBuffer;
2481 2450
2482 BOOL clean = TRUE;
2483
2484 buffer->getVertexStrider(vertices);
2485 buffer->getNormalStrider(normals);
2486 buffer->getTexCoordStrider(texcoords);
2487 buffer->getTexCoord2Strider(texcoords2);
2488 buffer->getColorStrider(colors);
2489 buffer->getIndexStrider(indices);
2490
2491 U32 index_offset = 0; 2451 U32 index_offset = 0;
2492 U32 indices_index = 0; 2452 U32 indices_index = 0;
2493 2453
2494 for (std::vector<LLFace*>::iterator i = alpha_faces.begin(); i != alpha_faces.end(); ++i) 2454 for (std::vector<LLFace*>::iterator i = alpha_faces.begin(); i != alpha_faces.end(); ++i)
2495 { 2455 {
2496 LLFace* facep = *i; 2456 LLFace* facep = *i;
2457
2458 if (facep->mGeomCount + index_offset > 65535)
2459 { //cut off alpha nodes at 64k vertices
2460 facep->mVertexBuffer = NULL ;
2461 continue ;
2462 }
2463
2497 LLDrawable* drawablep = facep->getDrawable(); 2464 LLDrawable* drawablep = facep->getDrawable();
2498 LLVOVolume* vobj = drawablep->getVOVolume(); 2465 LLVOVolume* vobj = drawablep->getVOVolume();
2499 LLVolume* volume = vobj->getVolume(); 2466 LLVolume* volume = vobj->getVolume();
@@ -2502,30 +2469,33 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2502 facep->mIndicesIndex = indices_index; 2469 facep->mIndicesIndex = indices_index;
2503 facep->mGeomIndex = index_offset; 2470 facep->mGeomIndex = index_offset;
2504 facep->mVertexBuffer = group->mVertexBuffer; 2471 facep->mVertexBuffer = group->mVertexBuffer;
2505 if (facep->getGeometryVolume(*volume, te_idx, vertices, normals, texcoords, texcoords2, colors, indices, 2472 if (facep->getGeometryVolume(*volume, te_idx,
2506 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset)) 2473 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(),
2474 index_offset))
2507 { 2475 {
2508 clean = FALSE;
2509 buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(), 2476 buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(),
2510 facep->getIndicesStart(), facep->getIndicesCount()); 2477 facep->getIndicesStart(), facep->getIndicesCount());
2511 } 2478 }
2512 2479
2480 index_offset += facep->getGeomCount();
2513 indices_index += facep->mIndicesCount; 2481 indices_index += facep->mIndicesCount;
2514 2482
2515 registerFace(group, facep, LLRenderPass::PASS_ALPHA); 2483 registerFace(group, facep, LLRenderPass::PASS_ALPHA);
2516 }
2517 2484
2518 if (clean) 2485 if (LLPipeline::sRenderGlow && facep->getTextureEntry()->getGlow() > 0.f)
2519 { 2486 {
2520 buffer->markClean(); 2487 registerFace(group, facep, LLRenderPass::PASS_GLOW);
2488 }
2521 } 2489 }
2490
2491 buffer->setBuffer(0);
2522 } 2492 }
2523 else 2493 else
2524 { 2494 {
2525 group->mVertexBuffer = NULL; 2495 group->mVertexBuffer = NULL;
2526 } 2496 }
2527 2497
2528 //get all the faces into a list, putting alpha faces in their own list 2498 //drawables have been rebuilt, clear rebuild status
2529 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) 2499 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
2530 { 2500 {
2531 LLDrawable* drawablep = *drawable_iter; 2501 LLDrawable* drawablep = *drawable_iter;
@@ -2533,8 +2503,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2533 } 2503 }
2534 2504
2535 group->mLastUpdateTime = gFrameTimeSeconds; 2505 group->mLastUpdateTime = gFrameTimeSeconds;
2536 group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::MATRIX_DIRTY | 2506 group->mBuilt = 1.f;
2537 LLSpatialGroup::ALPHA_DIRTY); 2507 group->clearState(LLSpatialGroup::GEOM_DIRTY |
2508 LLSpatialGroup::ALPHA_DIRTY | LLSpatialGroup::MESH_DIRTY);
2538 2509
2539 mFaceList.clear(); 2510 mFaceList.clear();
2540} 2511}
@@ -2589,7 +2560,7 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun
2589 2560
2590LLHUDPartition::LLHUDPartition() 2561LLHUDPartition::LLHUDPartition()
2591{ 2562{
2592 mPartitionType = LLPipeline::PARTITION_HUD; 2563 mPartitionType = LLViewerRegion::PARTITION_HUD;
2593 mDrawableType = LLPipeline::RENDER_TYPE_HUD; 2564 mDrawableType = LLPipeline::RENDER_TYPE_HUD;
2594 mSlopRatio = 0.f; 2565 mSlopRatio = 0.f;
2595 mLODPeriod = 16; 2566 mLODPeriod = 16;