diff options
author | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
---|---|---|
committer | Jacek Antonelli | 2008-08-15 23:45:34 -0500 |
commit | cd17687f01420952712a500107e0f93e7ab8d5f8 (patch) | |
tree | ce48c2b706f2c1176290e39fb555fbdf6648ce01 /linden/indra/newview/llvovolume.cpp | |
parent | Second Life viewer sources 1.19.0.5 (diff) | |
download | meta-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.cpp | 731 |
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 | ||
403 | void LLVOVolume::updateTextures(LLAgent &agent) | 407 | void 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 | ||
556 | BOOL LLVOVolume::isActive() const | 584 | BOOL LLVOVolume::isActive() const |
557 | { | 585 | { |
558 | return !mStatic || mTextureAnimp || isAttachment() || (mVolumeImpl && mVolumeImpl->isActive()); | 586 | return !mStatic || mTextureAnimp || (mVolumeImpl && mVolumeImpl->isActive()); |
559 | } | 587 | } |
560 | 588 | ||
561 | BOOL LLVOVolume::setMaterial(const U8 material) | 589 | BOOL 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) | |||
608 | LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) | 629 | LLDrawable *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() | |||
742 | S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius) | 763 | S32 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 | ||
861 | void LLVOVolume::setParent(LLViewerObject* parent) | 892 | void 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 | ||
983 | void LLVOVolume::preRebuild() | ||
984 | { | ||
985 | if (mVolumeImpl != NULL) | ||
986 | { | ||
987 | mVolumeImpl->preRebuild(); | ||
988 | } | ||
989 | } | ||
990 | |||
952 | void LLVOVolume::updateRelativeXform() | 991 | void 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 | ||
1294 | S32 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 | |||
1251 | S32 LLVOVolume::setTEScale(const U8 te, const F32 s, const F32 t) | 1305 | S32 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 | ||
1482 | F32 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 | ||
1490 | F32 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 | |||
1537 | BOOL 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 | |||
1565 | U32 LLVOVolume::getVolumeInterfaceID() const | 1527 | U32 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 | ||
1747 | void 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 |
1879 | void LLVOVolume::preUpdateGeom() | 1717 | void 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 | ||
2058 | LLVolumePartition::LLVolumePartition() | 1905 | LLVolumePartition::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 | ||
2173 | void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) | 2020 | void 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 | ||
2590 | LLHUDPartition::LLHUDPartition() | 2561 | LLHUDPartition::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; |