DRTVWR-476: Merge branch 'master' of lindenlab/viewer into DRTVWR-476-boost-1.72

master
Nat Goodspeed 2020-05-06 16:06:26 -04:00
commit ca6f092929
993 changed files with 55585 additions and 24605 deletions

View File

@ -347,6 +347,7 @@ Charles Courtois
Charlie Sazaland
Chaser Zaks
BUG-225599
BUG-227485
Cherry Cheevers
ChickyBabes Zuzu
Christopher Organiser
@ -485,6 +486,16 @@ Geenz Spad
STORM-1900
STORM-1905
NORSPEC-229
BUG-226611
BUG-226617
BUG-226618
BUG-226646
BUG-226647
BUG-226648
OPEN-339
BUG-226620
OPEN-340
OPEN-343
Gene Frostbite
GeneJ Composer
Geneko Nemeth
@ -1074,6 +1085,7 @@ Nicky Dasmijn
SL-10291
SL-10293
SL-11061
SL-11072
Nicky Perian
OPEN-1
STORM-1087
@ -1325,6 +1337,7 @@ Sovereign Engineer
STORM-2148
MAINT-7343
SL-11079
OPEN-343
SpacedOut Frye
VWR-34
VWR-45

View File

@ -0,0 +1,5 @@
# -*- cmake -*-
include(Prebuilt)
use_prebuilt_binary(libatmosphere)
set(LIBATMOSPHERE_LIBRARIES atmosphere)
set(LIBATMOSPHERE_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/atmosphere)

View File

@ -81,8 +81,8 @@ public:
LLAvatarBoneInfo() : mIsJoint(FALSE) {}
~LLAvatarBoneInfo()
{
std::for_each(mChildList.begin(), mChildList.end(), DeletePointer());
mChildList.clear();
std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
mChildren.clear();
}
BOOL parseXml(LLXmlTreeNode* node);
@ -96,8 +96,8 @@ private:
LLVector3 mRot;
LLVector3 mScale;
LLVector3 mPivot;
typedef std::vector<LLAvatarBoneInfo*> child_list_t;
child_list_t mChildList;
typedef std::vector<LLAvatarBoneInfo*> bones_t;
bones_t mChildren;
};
//------------------------------------------------------------------------
@ -679,8 +679,8 @@ BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent
// setup children
LLAvatarBoneInfo::child_list_t::const_iterator iter;
for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter)
LLAvatarBoneInfo::bones_t::const_iterator iter;
for (iter = info->mChildren.begin(); iter != info->mChildren.end(); ++iter)
{
LLAvatarBoneInfo *child_info = *iter;
if (!setupBone(child_info, joint, volume_num, joint_num))
@ -1684,7 +1684,7 @@ BOOL LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
delete child_info;
return FALSE;
}
mChildList.push_back(child_info);
mChildren.push_back(child_info);
}
return TRUE;
}
@ -1743,10 +1743,9 @@ void LLAvatarAppearance::makeJointAliases(LLAvatarBoneInfo *bone_info)
mJointAliasMap[*i] = bone_name;
}
LLAvatarBoneInfo::child_list_t::const_iterator iter;
for (iter = bone_info->mChildList.begin(); iter != bone_info->mChildList.end(); ++iter)
for (LLAvatarBoneInfo* bone : bone_info->mChildren)
{
makeJointAliases( *iter );
makeJointAliases(bone);
}
}

View File

@ -100,7 +100,7 @@ void LLAvatarJoint::setValid( BOOL valid, BOOL recursive )
//----------------------------------------------------------------
if (recursive)
{
for (child_list_t::iterator iter = mChildren.begin();
for (joints_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
@ -118,10 +118,10 @@ void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive )
mComponents = comp;
if (recursive)
{
for (child_list_t::iterator iter = mChildren.begin();
for (joints_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*iter);
joint->setSkeletonComponents(comp, recursive);
}
}
@ -133,7 +133,7 @@ void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive)
if (recursive)
{
for (child_list_t::iterator iter = mChildren.begin();
for (joints_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
@ -144,27 +144,27 @@ void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive)
void LLAvatarJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area)
{
for (child_list_t::iterator iter = mChildren.begin();
for (joints_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*iter);
joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
}
}
void LLAvatarJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
{
for (child_list_t::iterator iter = mChildren.begin();
for (joints_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*iter);
joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
}
}
void LLAvatarJoint::updateJointGeometry()
{
for (child_list_t::iterator iter = mChildren.begin();
for (joints_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
@ -178,10 +178,10 @@ BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate)
BOOL lod_changed = FALSE;
BOOL found_lod = FALSE;
for (child_list_t::iterator iter = mChildren.begin();
for (joints_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*iter);
F32 jointLOD = joint->getLOD();
if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD)
@ -207,10 +207,10 @@ BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate)
void LLAvatarJoint::dump()
{
for (child_list_t::iterator iter = mChildren.begin();
for (joints_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*iter);
joint->dump();
}
}

View File

@ -379,7 +379,7 @@ void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint)
}
// depth-first traversal
for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin();
for (LLJoint::joints_t::iterator iter = current_joint->mChildren.begin();
iter != current_joint->mChildren.end(); ++iter)
{
LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter);

View File

@ -614,7 +614,7 @@ void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight)
mAvatarAppearance->isValid() &&
driven->mParam->getCrossWearable())
{
LLWearable* wearable = dynamic_cast<LLWearable*> (mWearablep);
LLWearable* wearable = mWearablep;
if (mAvatarAppearance->getWearableData()->isOnTop(wearable))
{
use_self = true;

View File

@ -816,8 +816,8 @@ void LLPolyVertexMask::generateMask(U8 *maskTextureData, S32 width, S32 height,
U32 s = llclamp((U32)(uvCoords.mV[VX] * (F32)(width - 1)), (U32)0, (U32)width - 1);
U32 t = llclamp((U32)(uvCoords.mV[VY] * (F32)(height - 1)), (U32)0, (U32)height - 1);
mWeights[index] = ((F32) maskTextureData[((t * width + s) * num_components) + (num_components - 1)]) / 255.f;
mWeights[index] = maskTextureData ? ((F32) maskTextureData[((t * width + s) * num_components) + (num_components - 1)]) / 255.f : 0.0f;
if (invert)
{
mWeights[index] = 1.f - mWeights[index];

View File

@ -160,7 +160,7 @@ BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
mJointScales[joint] = bone_info->mScaleDeformation;
// apply to children that need to inherit it
for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
for (LLJoint::joints_t::iterator iter = joint->mChildren.begin();
iter != joint->mChildren.end(); ++iter)
{
LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter);

View File

@ -137,7 +137,7 @@ void LLTexLayerSetBuffer::postRenderTexLayerSet(BOOL success)
popProjection();
}
BOOL LLTexLayerSetBuffer::renderTexLayerSet()
BOOL LLTexLayerSetBuffer::renderTexLayerSet(LLRenderTarget* bound_target)
{
// Default color mask for tex layer render
gGL.setColorMask(true, true);
@ -161,7 +161,7 @@ BOOL LLTexLayerSetBuffer::renderTexLayerSet()
// Composite the color data
LLGLSUIDefault gls_ui;
success &= mTexLayerSet->render( getCompositeOriginX(), getCompositeOriginY(),
getCompositeWidth(), getCompositeHeight() );
getCompositeWidth(), getCompositeHeight(), bound_target );
gGL.flush();
midRenderTexLayerSet(success);
@ -375,7 +375,7 @@ void LLTexLayerSet::deleteCaches()
}
BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target )
{
BOOL success = TRUE;
mIsVisible = TRUE;
@ -427,12 +427,12 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
if (layer->getRenderPass() == LLTexLayer::RP_COLOR)
{
gGL.flush();
success &= layer->render(x, y, width, height);
success &= layer->render(x, y, width, height, bound_target);
gGL.flush();
}
}
renderAlphaMaskTextures(x, y, width, height, false);
renderAlphaMaskTextures(x, y, width, height, bound_target, false);
stop_glerror();
}
@ -523,7 +523,7 @@ const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const
}
static LLTrace::BlockTimerStatHandle FTM_GATHER_MORPH_MASK_ALPHA("gatherMorphMaskAlpha");
void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height)
void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height, LLRenderTarget* bound_target)
{
LL_RECORD_BLOCK_TIME(FTM_GATHER_MORPH_MASK_ALPHA);
memset(data, 255, width * height);
@ -531,15 +531,15 @@ void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S
for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
{
LLTexLayerInterface* layer = *iter;
layer->gatherAlphaMasks(data, origin_x, origin_y, width, height);
layer->gatherAlphaMasks(data, origin_x, origin_y, width, height, bound_target);
}
// Set alpha back to that of our alpha masks.
renderAlphaMaskTextures(origin_x, origin_y, width, height, true);
renderAlphaMaskTextures(origin_x, origin_y, width, height, bound_target, true);
}
static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_TEXTURES("renderAlphaMaskTextures");
void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear)
void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target, bool forceClear)
{
LL_RECORD_BLOCK_TIME(FTM_RENDER_ALPHA_MASK_TEXTURES);
const LLTexLayerSetInfo *info = getInfo();
@ -1065,7 +1065,7 @@ LLTexLayer::~LLTexLayer()
iter != mAlphaCache.end(); iter++ )
{
U8* alpha_data = iter->second;
delete [] alpha_data;
ll_aligned_free_32(alpha_data);
}
}
@ -1124,7 +1124,7 @@ void LLTexLayer::calculateTexLayerColor(const param_color_list_t &param_list, LL
}
}
BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target)
{
LLGLEnable color_mat(GL_COLOR_MATERIAL);
// *TODO: Is this correct?
@ -1185,7 +1185,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
}//*/
const bool force_render = true;
renderMorphMasks(x, y, width, height, net_color, force_render);
renderMorphMasks(x, y, width, height, net_color, bound_target, force_render);
alpha_mask_specified = TRUE;
gGL.flush();
gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA);
@ -1428,13 +1428,13 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
return success;
}
/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target)
{
addAlphaMask(data, originX, originY, width, height);
addAlphaMask(data, originX, originY, width, height, bound_target);
}
static LLTrace::BlockTimerStatHandle FTM_RENDER_MORPH_MASKS("renderMorphMasks");
void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render)
void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, LLRenderTarget* bound_target, bool force_render)
{
if (!force_render && !hasMorph())
{
@ -1572,17 +1572,64 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
{
alpha_cache_t::iterator iter2 = mAlphaCache.begin(); // arbitrarily grab the first entry
alpha_data = iter2->second;
delete [] alpha_data;
ll_aligned_free_32(alpha_data);
mAlphaCache.erase(iter2);
}
alpha_data = new U8[width * height];
mAlphaCache[cache_index] = alpha_data;
// nSight doesn't support use of glReadPixels
if (!LLRender::sNsightDebugSupport)
// GPUs tend to be very uptight about memory alignment as the DMA used to convey
// said data to the card works better when well-aligned so plain old default-aligned heap mem is a no-no
//new U8[width * height];
size_t bytes_per_pixel = 1; // unsigned byte alpha channel only...
size_t row_size = (width + 3) & ~0x3; // OpenGL 4-byte row align (even for things < 4 bpp...)
size_t pixels = (row_size * height);
size_t mem_size = pixels * bytes_per_pixel;
alpha_data = (U8*)ll_aligned_malloc_32(mem_size);
bool skip_readback = LLRender::sNsightDebugSupport; // nSight doesn't support use of glReadPixels
if (!skip_readback)
{
glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data);
}
if (gGLManager.mIsIntel)
{ // work-around for broken intel drivers which cannot do glReadPixels on an RGBA FBO
// returning only the alpha portion without locking up downstream
U8* temp = (U8*)ll_aligned_malloc_32(mem_size << 2); // allocate same size, but RGBA
if (bound_target)
{
gGL.getTexUnit(0)->bind(bound_target);
}
else
{
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, 0);
}
glGetTexImage(LLTexUnit::getInternalType(LLTexUnit::TT_TEXTURE), 0, GL_RGBA, GL_UNSIGNED_BYTE, temp);
U8* alpha_cursor = alpha_data;
U8* pixel = temp;
for (int i = 0; i < pixels; i++)
{
*alpha_cursor++ = pixel[3];
pixel += 4;
}
gGL.getTexUnit(0)->disable();
ll_aligned_free_32(temp);
}
else
{ // platforms with working drivers...
glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data);
}
}
else
{
ll_aligned_free_32(alpha_data);
alpha_data = nullptr;
}
mAlphaCache[cache_index] = alpha_data;
}
getTexLayerSet()->getAvatarAppearance()->dirtyMesh();
@ -1593,7 +1640,7 @@ void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
}
static LLTrace::BlockTimerStatHandle FTM_ADD_ALPHA_MASK("addAlphaMask");
void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target)
{
LL_RECORD_BLOCK_TIME(FTM_ADD_ALPHA_MASK);
S32 size = width * height;
@ -1605,7 +1652,7 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32
// TODO: eliminate need for layer morph mask valid flag
invalidateMorphMasks();
const bool force_render = false;
renderMorphMasks(originX, originY, width, height, net_color, force_render);
renderMorphMasks(originX, originY, width, height, net_color, bound_target, force_render);
alphaData = getAlphaData();
}
if (alphaData)
@ -1739,7 +1786,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const
return layer;
}
/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height)
/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target)
{
if(!mInfo)
{
@ -1766,7 +1813,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const
{
wearable->writeToAvatar(mAvatarAppearance);
layer->setLTO(lto);
success &= layer->render(x,y,width,height);
success &= layer->render(x, y, width, height, bound_target);
}
}
@ -1788,14 +1835,14 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const
return success;
}
/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target)
{
U32 num_wearables = updateWearableCache();
U32 i = num_wearables - 1; // For rendering morph masks, we only want to use the top wearable
LLTexLayer *layer = getLayer(i);
if (layer)
{
layer->addAlphaMask(data, originX, originY, width, height);
layer->addAlphaMask(data, originX, originY, width, height, bound_target);
}
}

View File

@ -65,7 +65,7 @@ public:
LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable);
virtual ~LLTexLayerInterface() {}
virtual BOOL render(S32 x, S32 y, S32 width, S32 height) = 0;
virtual BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target) = 0;
virtual void deleteCaches() = 0;
virtual BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) = 0;
virtual BOOL isInvisibleAlphaMask() const = 0;
@ -85,7 +85,7 @@ public:
BOOL isMorphValid() const { return mMorphMasksValid; }
void requestUpdate();
virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0;
virtual void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target) = 0;
BOOL hasAlphaParams() const { return !mParamAlphaList.empty(); }
ERenderPass getRenderPass() const;
@ -121,10 +121,10 @@ public:
LLTexLayerTemplate(LLTexLayerSet* const layer_set, LLAvatarAppearance* const appearance);
LLTexLayerTemplate(const LLTexLayerTemplate &layer);
/*virtual*/ ~LLTexLayerTemplate();
/*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height);
/*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target);
/*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions
/*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
/*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
/*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target);
/*virtual*/ void setHasMorph(BOOL newval);
/*virtual*/ void deleteCaches();
/*virtual*/ BOOL isInvisibleAlphaMask() const;
@ -152,16 +152,16 @@ public:
/*virtual*/ ~LLTexLayer();
/*virtual*/ BOOL setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // This sets mInfo and calls initialization functions
/*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height);
/*virtual*/ BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target);
/*virtual*/ void deleteCaches();
const U8* getAlphaData() const;
BOOL findNetColor(LLColor4* color) const;
/*virtual*/ BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
/*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
void renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render);
void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
/*virtual*/ void gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target);
void renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, LLRenderTarget* bound_target, bool force_render);
void addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, LLRenderTarget* bound_target);
/*virtual*/ BOOL isInvisibleAlphaMask() const;
void setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; }
@ -194,13 +194,13 @@ public:
const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist.
virtual void createComposite() = 0;
void destroyComposite();
void gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height);
void gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height, LLRenderTarget* bound_target);
const LLTexLayerSetInfo* getInfo() const { return mInfo; }
BOOL setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions
BOOL render(S32 x, S32 y, S32 width, S32 height);
void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false);
BOOL render(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target = nullptr);
void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, LLRenderTarget* bound_target = nullptr, bool forceClear = false);
BOOL isBodyRegion(const std::string& region) const;
void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
@ -282,7 +282,7 @@ protected:
virtual S32 getCompositeOriginY() const = 0;
virtual S32 getCompositeWidth() const = 0;
virtual S32 getCompositeHeight() const = 0;
BOOL renderTexLayerSet();
BOOL renderTexLayerSet(LLRenderTarget* bound_target);
LLTexLayerSet* const mTexLayerSet;
};

View File

@ -184,6 +184,6 @@ BOOL LLWearableType::getAllowMultiwear(LLWearableType::EType type)
// static
LLWearableType::EType LLWearableType::inventoryFlagsToWearableType(U32 flags)
{
return (LLWearableType::EType)(flags & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK);
return (LLWearableType::EType)(flags & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK);
}

View File

@ -31,16 +31,7 @@
#include "lldictionary.h"
#include "llinventorytype.h"
#include "llsingleton.h"
class LLTranslationBridge
{
public:
// clang needs this to be happy
virtual ~LLTranslationBridge() {}
virtual std::string getString(const std::string &xml_desc) = 0;
};
#include "llinvtranslationbrdg.h"
class LLWearableType : public LLParamSingleton<LLWearableType>
{

View File

@ -271,7 +271,7 @@ BOOL LLVorbisDecodeState::initDecode()
mWAVBuffer.reserve(size_guess);
mWAVBuffer.resize(WAV_HEADER_SIZE);
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
LL_WARNS("AudioEngine") << "Out of memory when trying to alloc buffer: " << size_guess << LL_ENDL;
delete mInFilep;

View File

@ -252,7 +252,7 @@ void LLCharacter::dumpCharacter( LLJoint* joint )
LL_INFOS() << "DEBUG: " << joint->getName() << " (" << (joint->getParent()?joint->getParent()->getName():std::string("ROOT")) << ")" << LL_ENDL;
// recurse
for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
for (LLJoint::joints_t::iterator iter = joint->mChildren.begin();
iter != joint->mChildren.end(); ++iter)
{
LLJoint* child_joint = *iter;

View File

@ -209,7 +209,7 @@ void LLJoint::touch(U32 flags)
child_flags |= POSITION_DIRTY;
}
for (child_list_t::iterator iter = mChildren.begin();
for (joints_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLJoint* joint = *iter;
@ -251,7 +251,7 @@ LLJoint *LLJoint::findJoint( const std::string &name )
if (name == getName())
return this;
for (child_list_t::iterator iter = mChildren.begin();
for (joints_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLJoint* joint = *iter;
@ -286,7 +286,7 @@ void LLJoint::addChild(LLJoint* joint)
//--------------------------------------------------------------------
void LLJoint::removeChild(LLJoint* joint)
{
child_list_t::iterator iter = std::find(mChildren.begin(), mChildren.end(), joint);
joints_t::iterator iter = std::find(mChildren.begin(), mChildren.end(), joint);
if (iter != mChildren.end())
{
mChildren.erase(iter);
@ -303,16 +303,17 @@ void LLJoint::removeChild(LLJoint* joint)
//--------------------------------------------------------------------
void LLJoint::removeAllChildren()
{
for (child_list_t::iterator iter = mChildren.begin();
iter != mChildren.end();)
for (LLJoint* joint : mChildren)
{
child_list_t::iterator curiter = iter++;
LLJoint* joint = *curiter;
mChildren.erase(curiter);
joint->mXform.setParent(NULL);
joint->mParent = NULL;
joint->touch();
if (joint)
{
joint->mXform.setParent(NULL);
joint->mParent = NULL;
joint->touch();
//delete joint;
}
}
mChildren.clear();
}
@ -985,7 +986,7 @@ void LLJoint::updateWorldMatrixChildren()
{
updateWorldMatrix();
}
for (child_list_t::iterator iter = mChildren.begin();
for (joints_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLJoint* joint = *iter;
@ -1031,7 +1032,7 @@ void LLJoint::clampRotation(LLQuaternion old_rot, LLQuaternion new_rot)
{
LLVector3 main_axis(1.f, 0.f, 0.f);
for (child_list_t::iterator iter = mChildren.begin();
for (joints_t::iterator iter = mChildren.begin();
iter != mChildren.end(); ++iter)
{
LLJoint* joint = *iter;

View File

@ -139,8 +139,8 @@ public:
S32 mJointNum;
// child joints
typedef std::list<LLJoint*> child_list_t;
child_list_t mChildren;
typedef std::vector<LLJoint*> joints_t;
joints_t mChildren;
// debug statics
static S32 sNumTouches;

View File

@ -2321,7 +2321,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
LLCharacter* character = *char_iter;
// look for an existing instance of this motion
LLKeyframeMotion* motionp = dynamic_cast<LLKeyframeMotion*> (character->findMotion(asset_uuid));
LLKeyframeMotion* motionp = static_cast<LLKeyframeMotion*> (character->findMotion(asset_uuid));
if (motionp)
{
if (0 == status)

View File

@ -64,7 +64,6 @@ const LLUUID IMG_ALPHA_GRAD ("e97cf410-8e61-7005-ec06-629eba4cd1fb"); // VIEW
const LLUUID IMG_ALPHA_GRAD_2D ("38b86f85-2575-52a9-a531-23108d8da837"); // VIEWER
const LLUUID IMG_TRANSPARENT ("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"); // VIEWER
const LLUUID IMG_BLOOM1 ("3c59f7fe-9dc8-47f9-8aaf-a9dd1fbc3bef"); // VIEWER
const LLUUID TERRAIN_DIRT_DETAIL ("0bc58228-74a0-7e83-89bc-5c23464bcec5"); // VIEWER
const LLUUID TERRAIN_GRASS_DETAIL ("63338ede-0037-c4fd-855b-015d77112fc8"); // VIEWER
const LLUUID TERRAIN_MOUNTAIN_DETAIL ("303cd381-8560-7579-23f1-f0a880799740"); // VIEWER

View File

@ -200,7 +200,6 @@ LL_COMMON_API extern const LLUUID IMG_ALPHA_GRAD;
LL_COMMON_API extern const LLUUID IMG_ALPHA_GRAD_2D;
LL_COMMON_API extern const LLUUID IMG_TRANSPARENT;
LL_COMMON_API extern const LLUUID IMG_BLOOM1;
LL_COMMON_API extern const LLUUID TERRAIN_DIRT_DETAIL;
LL_COMMON_API extern const LLUUID TERRAIN_GRASS_DETAIL;
LL_COMMON_API extern const LLUUID TERRAIN_MOUNTAIN_DETAIL;

View File

@ -95,11 +95,14 @@ LLAssetDictionary::LLAssetDictionary()
addEntry(LLAssetType::AT_MESH, new AssetEntry("MESH", "mesh", "mesh", false, false, false));
addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false));
addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false));
addEntry(LLAssetType::AT_SETTINGS, new AssetEntry("SETTINGS", "settings", "settings blob", true, true, true));
addEntry(LLAssetType::AT_UNKNOWN, new AssetEntry("UNKNOWN", "invalid", NULL, false, false, false));
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE));
};
const std::string LLAssetType::BADLOOKUP("llassettype_bad_lookup");
// static
LLAssetType::EType LLAssetType::getType(const std::string& desc_name)
{
@ -118,7 +121,7 @@ const std::string &LLAssetType::getDesc(LLAssetType::EType asset_type)
}
else
{
return badLookup();
return BADLOOKUP;
}
}
@ -133,7 +136,7 @@ const char *LLAssetType::lookup(LLAssetType::EType asset_type)
}
else
{
return badLookup().c_str();
return BADLOOKUP.c_str();
}
}
@ -171,7 +174,7 @@ const char *LLAssetType::lookupHumanReadable(LLAssetType::EType asset_type)
}
else
{
return badLookup().c_str();
return BADLOOKUP.c_str();
}
}
@ -221,14 +224,6 @@ bool LLAssetType::lookupIsLinkType(EType asset_type)
return false;
}
// static
const std::string &LLAssetType::badLookup()
{
static const std::string sBadLookup = "llassettype_bad_lookup";
return sBadLookup;
}
// static
bool LLAssetType::lookupIsAssetFetchByIDAllowed(EType asset_type)
{

View File

@ -116,10 +116,19 @@ public:
AT_PERSON = 45,
// A user uuid which is not an inventory asset type, used in viewer only for adding a person to a chat via drag and drop.
AT_MESH = 49,
// Mesh data in our proprietary SLM format
AT_COUNT = 50,
AT_MESH = 49,
// Mesh data in our proprietary SLM format
AT_RESERVED_1 = 50,
AT_RESERVED_2 = 51,
AT_RESERVED_3 = 52,
AT_RESERVED_4 = 53,
AT_RESERVED_5 = 54,
AT_RESERVED_6 = 55,
AT_SETTINGS = 56, // Collection of settings
AT_COUNT = 57,
// +*********************************************************+
// | TO ADD AN ELEMENT TO THIS ENUM: |
@ -153,7 +162,7 @@ public:
static bool lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download
static bool lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer
static const std::string& badLookup(); // error string when a lookup fails
static const std::string BADLOOKUP;
protected:
LLAssetType() {}

View File

@ -193,39 +193,46 @@ namespace {
return LLError::getEnabledLogTypesMask() & 0x04;
}
LL_FORCE_INLINE std::string createANSI(const std::string& color)
{
std::string ansi_code;
ansi_code += '\033';
ansi_code += "[";
ansi_code += color;
ansi_code += "m";
return ansi_code;
}
virtual void recordMessage(LLError::ELevel level,
const std::string& message) override
{
static std::string s_ansi_error = createANSI("31"); // red
static std::string s_ansi_warn = createANSI("34"); // blue
static std::string s_ansi_debug = createANSI("35"); // magenta
if (mUseANSI)
{
// Default all message levels to bold so we can distinguish our own messages from those dumped by subprocesses and libraries.
colorANSI("1"); // bold
switch (level) {
case LLError::LEVEL_ERROR:
colorANSI("31"); // red
break;
case LLError::LEVEL_WARN:
colorANSI("34"); // blue
break;
case LLError::LEVEL_DEBUG:
colorANSI("35"); // magenta
break;
default:
break;
}
writeANSI((level == LLError::LEVEL_ERROR) ? s_ansi_error :
(level == LLError::LEVEL_WARN) ? s_ansi_warn :
s_ansi_debug, message);
}
fprintf(stderr, "%s\n", message.c_str());
if (mUseANSI) colorANSI("0"); // reset
else
{
fprintf(stderr, "%s\n", message.c_str());
}
}
private:
bool mUseANSI;
void colorANSI(const std::string color)
LL_FORCE_INLINE void writeANSI(const std::string& ansi_code, const std::string& message)
{
// ANSI color code escape sequence
fprintf(stderr, "\033[%sm", color.c_str() );
};
static std::string s_ansi_bold = createANSI("1"); // bold
static std::string s_ansi_reset = createANSI("0"); // reset
// ANSI color code escape sequence, message, and reset in one fprintf call
// Default all message levels to bold so we can distinguish our own messages from those dumped by subprocesses and libraries.
fprintf(stderr, "%s%s%s\n%s", s_ansi_bold.c_str(), ansi_code.c_str(), message.c_str(), s_ansi_reset.c_str() );
}
static bool checkANSI(void)
{
@ -236,8 +243,8 @@ namespace {
return (0 != isatty(2)) &&
(NULL == getenv("LL_NO_ANSI_COLOR"));
#endif // LL_LINUX
return false;
};
return FALSE; // works in a cygwin shell... ;)
}
};
class RecordToFixedBuffer : public LLError::Recorder

View File

@ -77,7 +77,7 @@ void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
//static
void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_failure)
{
sMaxHeapSizeInKB = max_heap_size;
sMaxHeapSizeInKB = U32Kilobytes::convert(max_heap_size);
sEnableMemoryFailurePrevention = prevent_heap_failure ;
}
@ -93,9 +93,9 @@ void LLMemory::updateMemoryInfo()
return ;
}
sAllocatedMemInKB = U64Bytes(counters.WorkingSetSize) ;
sAllocatedMemInKB = U32Kilobytes::convert(U64Bytes(counters.WorkingSetSize));
sample(sAllocatedMem, sAllocatedMemInKB);
sAllocatedPageSizeInKB = U64Bytes(counters.PagefileUsage) ;
sAllocatedPageSizeInKB = U32Kilobytes::convert(U64Bytes(counters.PagefileUsage));
sample(sVirtualMem, sAllocatedPageSizeInKB);
U32Kilobytes avail_phys, avail_virtual;

View File

@ -195,6 +195,8 @@ namespace
std::string amd_CPUFamilyName(int composed_family)
{
// https://en.wikipedia.org/wiki/List_of_AMD_CPU_microarchitectures
// https://developer.amd.com/resources/developer-guides-manuals/
switch(composed_family)
{
case 4: return "AMD 80486/5x86";
@ -202,6 +204,13 @@ namespace
case 6: return "AMD K7";
case 0xF: return "AMD K8";
case 0x10: return "AMD K8L";
case 0x12: return "AMD K10";
case 0x14: return "AMD Bobcat";
case 0x15: return "AMD Bulldozer";
case 0x16: return "AMD Jaguar";
case 0x17: return "AMD Zen/Zen+/Zen2";
case 0x18: return "AMD Hygon Dhyana";
case 0x19: return "AMD Zen 3";
}
return STRINGIZE("AMD <unknown 0x" << std::hex << composed_family << ">");
}

View File

@ -132,6 +132,7 @@ public:
virtual bool has(const String&) const { return false; }
virtual LLSD get(const String&) const { return LLSD(); }
virtual LLSD getKeys() const { return LLSD::emptyArray(); }
virtual void erase(const String&) { }
virtual const LLSD& ref(const String&) const{ return undef(); }
@ -380,7 +381,8 @@ namespace
using LLSD::Impl::erase; // Unhiding erase(LLSD::Integer)
using LLSD::Impl::ref; // Unhiding ref(LLSD::Integer)
virtual LLSD get(const LLSD::String&) const;
void insert(const LLSD::String& k, const LLSD& v);
virtual LLSD getKeys() const;
void insert(const LLSD::String& k, const LLSD& v);
virtual void erase(const LLSD::String&);
LLSD& ref(const LLSD::String&);
virtual const LLSD& ref(const LLSD::String&) const;
@ -421,7 +423,19 @@ namespace
DataMap::const_iterator i = mData.find(k);
return (i != mData.end()) ? i->second : LLSD();
}
LLSD ImplMap::getKeys() const
{
LLSD keys = LLSD::emptyArray();
DataMap::const_iterator iter = mData.begin();
while (iter != mData.end())
{
keys.append((*iter).first);
iter++;
}
return keys;
}
void ImplMap::insert(const LLSD::String& k, const LLSD& v)
{
mData.insert(DataMap::value_type(k, v));
@ -502,7 +516,7 @@ namespace
virtual LLSD get(LLSD::Integer) const;
void set(LLSD::Integer, const LLSD&);
void insert(LLSD::Integer, const LLSD&);
void append(const LLSD&);
LLSD& append(const LLSD&);
virtual void erase(LLSD::Integer);
LLSD& ref(LLSD::Integer);
virtual const LLSD& ref(LLSD::Integer) const;
@ -570,9 +584,10 @@ namespace
mData.insert(mData.begin() + index, v);
}
void ImplArray::append(const LLSD& v)
LLSD& ImplArray::append(const LLSD& v)
{
mData.push_back(v);
return mData.back();
}
void ImplArray::erase(LLSD::Integer i)
@ -862,6 +877,7 @@ LLSD LLSD::emptyMap()
bool LLSD::has(const String& k) const { return safe(impl).has(k); }
LLSD LLSD::get(const String& k) const { return safe(impl).get(k); }
LLSD LLSD::getKeys() const { return safe(impl).getKeys(); }
void LLSD::insert(const String& k, const LLSD& v) { makeMap(impl).insert(k, v); }
LLSD& LLSD::with(const String& k, const LLSD& v)
@ -895,7 +911,7 @@ LLSD& LLSD::with(Integer i, const LLSD& v)
makeArray(impl).insert(i, v);
return *this;
}
void LLSD::append(const LLSD& v) { makeArray(impl).append(v); }
LLSD& LLSD::append(const LLSD& v) { return makeArray(impl).append(v); }
void LLSD::erase(Integer i) { makeArray(impl).erase(i); }
LLSD& LLSD::operator[](Integer i)

View File

@ -79,7 +79,7 @@
an LLSD array).
An array is a sequence of zero or more LLSD values.
Thread Safety
In general, these LLSD classes offer *less* safety than STL container
@ -284,6 +284,7 @@ public:
bool has(const String&) const;
LLSD get(const String&) const;
LLSD getKeys() const; // Return an LLSD array with keys as strings
void insert(const String&, const LLSD&);
void erase(const String&);
LLSD& with(const String&, const LLSD&);
@ -301,7 +302,7 @@ public:
LLSD get(Integer) const;
void set(Integer, const LLSD&);
void insert(Integer, const LLSD&);
void append(const LLSD&);
LLSD& append(const LLSD&);
void erase(Integer);
LLSD& with(Integer, const LLSD&);

View File

@ -55,6 +55,7 @@ static const S32 UNZIP_LLSD_MAX_DEPTH = 96;
static const char LEGACY_NON_HEADER[] = "<llsd>";
const std::string LLSD_BINARY_HEADER("LLSD/Binary");
const std::string LLSD_XML_HEADER("LLSD/XML");
const std::string LLSD_NOTATION_HEADER("llsd/notation");
//used to deflate a gzipped asset (currently used for navmeshes)
#define windowBits 15
@ -81,6 +82,11 @@ void LLSDSerialize::serialize(const LLSD& sd, std::ostream& str, ELLSD_Serialize
f = new LLSDXMLFormatter;
break;
case LLSD_NOTATION:
str << "<? " << LLSD_NOTATION_HEADER << " ?>\n";
f = new LLSDNotationFormatter;
break;
default:
LL_WARNS() << "serialize request for unknown ELLSD_Serialize" << LL_ENDL;
}
@ -168,6 +174,10 @@ bool LLSDSerialize::deserialize(LLSD& sd, std::istream& str, S32 max_bytes)
{
p = new LLSDXMLParser;
}
else if (header == LLSD_NOTATION_HEADER)
{
p = new LLSDNotationParser;
}
else
{
LL_WARNS() << "deserialize request for unknown ELLSD_Serialize" << LL_ENDL;
@ -2241,7 +2251,7 @@ LLUZipHelper::EZipRresult LLUZipHelper::unzip_llsd(LLSD& data, std::istream& is,
return ZR_SIZE_ERROR;
}
#endif
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
free(result);
return ZR_MEM_ERROR;

View File

@ -706,7 +706,7 @@ class LL_COMMON_API LLSDSerialize
public:
enum ELLSD_Serialize
{
LLSD_BINARY, LLSD_XML
LLSD_BINARY, LLSD_XML, LLSD_NOTATION
};
/**

View File

@ -322,6 +322,180 @@ BOOL compare_llsd_with_template(
return TRUE;
}
// filter_llsd_with_template() is a direct clone (copy-n-paste) of
// compare_llsd_with_template with the following differences:
// (1) bool vs BOOL return types
// (2) A map with the key value "*" is a special value and maps any key in the
// test llsd that doesn't have an explicitly matching key in the template.
// (3) The element of an array with exactly one element is taken as a template
// for *all* the elements of the test array. If the template array is of
// different size, compare_llsd_with_template() semantics apply.
bool filter_llsd_with_template(
const LLSD & llsd_to_test,
const LLSD & template_llsd,
LLSD & resultant_llsd)
{
if (llsd_to_test.isUndefined() && template_llsd.isDefined())
{
resultant_llsd = template_llsd;
return true;
}
else if (llsd_to_test.type() != template_llsd.type())
{
resultant_llsd = LLSD();
return false;
}
if (llsd_to_test.isArray())
{
//they are both arrays
//we loop over all the items in the template
//verifying that the to_test has a subset (in the same order)
//any shortcoming in the testing_llsd are just taken
//to be the rest of the template
LLSD data;
LLSD::array_const_iterator test_iter;
LLSD::array_const_iterator template_iter;
resultant_llsd = LLSD::emptyArray();
test_iter = llsd_to_test.beginArray();
if (1 == template_llsd.size())
{
// If the template has a single item, treat it as
// the template for *all* items in the test LLSD.
template_iter = template_llsd.beginArray();
for (; test_iter != llsd_to_test.endArray(); ++test_iter)
{
if (! filter_llsd_with_template(*test_iter, *template_iter, data))
{
resultant_llsd = LLSD();
return false;
}
else
{
resultant_llsd.append(data);
}
}
}
else
{
// Traditional compare_llsd_with_template matching
for (template_iter = template_llsd.beginArray();
template_iter != template_llsd.endArray() &&
test_iter != llsd_to_test.endArray();
++template_iter, ++test_iter)
{
if (! filter_llsd_with_template(*test_iter, *template_iter, data))
{
resultant_llsd = LLSD();
return false;
}
else
{
resultant_llsd.append(data);
}
}
//so either the test or the template ended
//we do another loop now to the end of the template
//grabbing the default values
for (;
template_iter != template_llsd.endArray();
++template_iter)
{
resultant_llsd.append(*template_iter);
}
}
}
else if (llsd_to_test.isMap())
{
resultant_llsd = LLSD::emptyMap();
//now we loop over the keys of the two maps
//any excess is taken from the template
//excess is ignored in the test
// Special tag for wildcarded LLSD map key templates
const LLSD::String wildcard_tag("*");
const bool template_has_wildcard = template_llsd.has(wildcard_tag);
LLSD wildcard_value;
LLSD value;
const LLSD::map_const_iterator template_iter_end(template_llsd.endMap());
for (LLSD::map_const_iterator template_iter(template_llsd.beginMap());
template_iter_end != template_iter;
++template_iter)
{
if (wildcard_tag == template_iter->first)
{
wildcard_value = template_iter->second;
}
else if (llsd_to_test.has(template_iter->first))
{
//the test LLSD has the same key
if (! filter_llsd_with_template(llsd_to_test[template_iter->first],
template_iter->second,
value))
{
resultant_llsd = LLSD();
return false;
}
else
{
resultant_llsd[template_iter->first] = value;
}
}
else if (! template_has_wildcard)
{
// test llsd doesn't have it...take the
// template as default value
resultant_llsd[template_iter->first] = template_iter->second;
}
}
if (template_has_wildcard)
{
LLSD sub_value;
LLSD::map_const_iterator test_iter;
for (test_iter = llsd_to_test.beginMap();
test_iter != llsd_to_test.endMap();
++test_iter)
{
if (resultant_llsd.has(test_iter->first))
{
// Final value has test key, assume more specific
// template matched and we shouldn't modify it again.
continue;
}
else if (! filter_llsd_with_template(test_iter->second,
wildcard_value,
sub_value))
{
// Test value doesn't match wildcarded template
resultant_llsd = LLSD();
return false;
}
else
{
// Test value matches template, add the actuals.
resultant_llsd[test_iter->first] = sub_value;
}
}
}
}
else
{
//of same type...take the test llsd's value
resultant_llsd = llsd_to_test;
}
return true;
}
/*****************************************************************************
* Helpers for llsd_matches()
*****************************************************************************/
@ -749,3 +923,104 @@ LLSD drill(const LLSD& blob, const LLSD& path)
}
} // namespace llsd
// Construct a deep partial clone of of an LLSD object. primitive types share
// references, however maps, arrays and binary objects are duplicated. An optional
// filter may be include to exclude/include keys in a map.
LLSD llsd_clone(LLSD value, LLSD filter)
{
LLSD clone;
bool has_filter(filter.isMap());
switch (value.type())
{
case LLSD::TypeMap:
clone = LLSD::emptyMap();
for (LLSD::map_const_iterator itm = value.beginMap(); itm != value.endMap(); ++itm)
{
if (has_filter)
{
if (filter.has((*itm).first))
{
if (!filter[(*itm).first].asBoolean())
continue;
}
else if (filter.has("*"))
{
if (!filter["*"].asBoolean())
continue;
}
else
{
continue;
}
}
clone[(*itm).first] = llsd_clone((*itm).second, filter);
}
break;
case LLSD::TypeArray:
clone = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
{
clone.append(llsd_clone(*ita, filter));
}
break;
case LLSD::TypeBinary:
{
LLSD::Binary bin(value.asBinary().begin(), value.asBinary().end());
clone = LLSD::Binary(bin);
break;
}
default:
clone = value;
}
return clone;
}
LLSD llsd_shallow(LLSD value, LLSD filter)
{
LLSD shallow;
bool has_filter(filter.isMap());
if (value.isMap())
{
shallow = LLSD::emptyMap();
for (LLSD::map_const_iterator itm = value.beginMap(); itm != value.endMap(); ++itm)
{
if (has_filter)
{
if (filter.has((*itm).first))
{
if (!filter[(*itm).first].asBoolean())
continue;
}
else if (filter.has("*"))
{
if (!filter["*"].asBoolean())
continue;
}
else
{
continue;
}
}
shallow[(*itm).first] = (*itm).second;
}
}
else if (value.isArray())
{
shallow = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
{
shallow.append(*ita);
}
}
else
{
return value;
}
return shallow;
}

View File

@ -30,6 +30,7 @@
#define LL_LLSDUTIL_H
#include "llsd.h"
#include <boost/functional/hash.hpp>
// U32
LL_COMMON_API LLSD ll_sd_from_U32(const U32);
@ -70,6 +71,19 @@ LL_COMMON_API BOOL compare_llsd_with_template(
const LLSD& template_llsd,
LLSD& resultant_llsd);
// filter_llsd_with_template() is a direct clone (copy-n-paste) of
// compare_llsd_with_template with the following differences:
// (1) bool vs BOOL return types
// (2) A map with the key value "*" is a special value and maps any key in the
// test llsd that doesn't have an explicitly matching key in the template.
// (3) The element of an array with exactly one element is taken as a template
// for *all* the elements of the test array. If the template array is of
// different size, compare_llsd_with_template() semantics apply.
bool filter_llsd_with_template(
const LLSD & llsd_to_test,
const LLSD & template_llsd,
LLSD & resultant_llsd);
/**
* Recursively determine whether a given LLSD data block "matches" another
* LLSD prototype. The returned string is empty() on success, non-empty() on
@ -516,4 +530,86 @@ private:
} // namespace llsd
// Creates a deep clone of an LLSD object. Maps, Arrays and binary objects
// are duplicated, atomic primitives (Boolean, Integer, Real, etc) simply
// use a shared reference.
// Optionally a filter may be specified to control what is duplicated. The
// map takes the form "keyname/boolean".
// If the value is true the value will be duplicated otherwise it will be skipped
// when encountered in a map. A key name of "*" can be specified as a wild card
// and will specify the default behavior. If no wild card is given and the clone
// encounters a name not in the filter, that value will be skipped.
LLSD llsd_clone(LLSD value, LLSD filter = LLSD());
// Creates a shallow copy of a map or array. If passed any other type of LLSD
// object it simply returns that value. See llsd_clone for a description of
// the filter parameter.
LLSD llsd_shallow(LLSD value, LLSD filter = LLSD());
// Specialization for generating a hash value from an LLSD block.
template <>
struct boost::hash<LLSD>
{
typedef LLSD argument_type;
typedef std::size_t result_type;
result_type operator()(argument_type const& s) const
{
result_type seed(0);
LLSD::Type stype = s.type();
boost::hash_combine(seed, (S32)stype);
switch (stype)
{
case LLSD::TypeBoolean:
boost::hash_combine(seed, s.asBoolean());
break;
case LLSD::TypeInteger:
boost::hash_combine(seed, s.asInteger());
break;
case LLSD::TypeReal:
boost::hash_combine(seed, s.asReal());
break;
case LLSD::TypeURI:
case LLSD::TypeString:
boost::hash_combine(seed, s.asString());
break;
case LLSD::TypeUUID:
boost::hash_combine(seed, s.asUUID());
break;
case LLSD::TypeDate:
boost::hash_combine(seed, s.asDate().secondsSinceEpoch());
break;
case LLSD::TypeBinary:
{
const LLSD::Binary &b(s.asBinary());
boost::hash_range(seed, b.begin(), b.end());
break;
}
case LLSD::TypeMap:
{
for (LLSD::map_const_iterator itm = s.beginMap(); itm != s.endMap(); ++itm)
{
boost::hash_combine(seed, (*itm).first);
boost::hash_combine(seed, (*itm).second);
}
break;
}
case LLSD::TypeArray:
for (LLSD::array_const_iterator ita = s.beginArray(); ita != s.endArray(); ++ita)
{
boost::hash_combine(seed, (*ita));
}
break;
case LLSD::TypeUndefined:
default:
break;
}
return seed;
}
};
#endif // LL_LLSDUTIL_H

View File

@ -805,6 +805,17 @@ private: \
friend class LLSingleton<DERIVED_CLASS>; \
DERIVED_CLASS(__VA_ARGS__)
/**
* A slight variance from the above, but includes the "override" keyword
*/
#define LLSINGLETON_C11(DERIVED_CLASS) \
private: \
/* implement LLSingleton pure virtual method whose sole purpose */ \
/* is to remind people to use this macro */ \
virtual void you_must_use_LLSINGLETON_macro() override {} \
friend class LLSingleton<DERIVED_CLASS>; \
DERIVED_CLASS()
/**
* Use LLSINGLETON_EMPTY_CTOR(Foo); at the start of an LLSingleton<Foo>
* subclass body when the constructor is trivial:
@ -823,4 +834,8 @@ private: \
/* LLSINGLETON() is carefully implemented to permit exactly this */ \
LLSINGLETON(DERIVED_CLASS) {}
#define LLSINGLETON_EMPTY_CTOR_C11(DERIVED_CLASS) \
/* LLSINGLETON() is carefully implemented to permit exactly this */ \
LLSINGLETON_C11(DERIVED_CLASS) {}
#endif

View File

@ -132,23 +132,34 @@ struct LLUnit
return mValue;
}
LL_FORCE_INLINE void value(storage_t value)
LL_FORCE_INLINE void value(const storage_t& value)
{
mValue = value;
}
template<typename NEW_UNITS>
storage_t valueInUnits()
storage_t valueInUnits() const
{
return LLUnit<storage_t, NEW_UNITS>(*this).value();
}
template<typename NEW_UNITS>
void valueInUnits(storage_t value)
void valueInUnits(const storage_t& value) const
{
*this = LLUnit<storage_t, NEW_UNITS>(value);
}
LL_FORCE_INLINE operator storage_t() const
{
return value();
}
/*LL_FORCE_INLINE self_t& operator= (storage_t v)
{
value(v);
return *this;
}*/
LL_FORCE_INLINE void operator += (self_t other)
{
mValue += convert(other).mValue;
@ -159,60 +170,60 @@ struct LLUnit
mValue -= convert(other).mValue;
}
LL_FORCE_INLINE void operator *= (storage_t multiplicand)
LL_FORCE_INLINE void operator *= (const storage_t& multiplicand)
{
mValue *= multiplicand;
}
LL_FORCE_INLINE void operator *= (self_t multiplicand)
LL_FORCE_INLINE void operator *= (const self_t& multiplicand)
{
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "Multiplication of unit types not supported.");
}
LL_FORCE_INLINE void operator /= (storage_t divisor)
LL_FORCE_INLINE void operator /= (const storage_t& divisor)
{
mValue /= divisor;
}
void operator /= (self_t divisor)
void operator /= (const self_t& divisor)
{
// spurious use of dependent type to stop gcc from triggering the static assertion before instantiating the template
LL_BAD_TEMPLATE_INSTANTIATION(STORAGE_TYPE, "Illegal in-place division of unit types.");
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator == (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
LL_FORCE_INLINE bool operator == (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue == convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator != (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
LL_FORCE_INLINE bool operator != (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue != convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator < (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
LL_FORCE_INLINE bool operator < (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue < convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator <= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
LL_FORCE_INLINE bool operator <= (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue <= convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator > (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
LL_FORCE_INLINE bool operator > (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue > convert(other).value();
}
template<typename OTHER_STORAGE_TYPE, typename OTHER_UNITS>
LL_FORCE_INLINE bool operator >= (LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS> other) const
LL_FORCE_INLINE bool operator >= (const LLUnit<OTHER_STORAGE_TYPE, OTHER_UNITS>& other) const
{
return mValue >= convert(other).value();
}

View File

@ -31,6 +31,7 @@
#include <vector>
#include "stdtypes.h"
#include "llpreprocessor.h"
#include <boost/functional/hash.hpp>
class LLMutex;
@ -164,6 +165,25 @@ public:
LLAssetID makeAssetID(const LLUUID& session) const;
};
// Generate a hash of an LLUUID object using the boost hash templates.
template <>
struct boost::hash<LLUUID>
{
typedef LLUUID argument_type;
typedef std::size_t result_type;
result_type operator()(argument_type const& s) const
{
result_type seed(0);
for (S32 i = 0; i < UUID_BYTES; ++i)
{
boost::hash_combine(seed, s.mData[i]);
}
return seed;
}
};
#endif

View File

@ -318,7 +318,7 @@ void HttpService::threadRun(LLCoreInt::HttpThread * thread)
{
LOG_UNHANDLED_EXCEPTION("");
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
LLMemory::logMemoryInfo(TRUE);

View File

@ -147,7 +147,7 @@ size_t BufferArray::append(const void * src, size_t len)
{
block = Block::alloc(BLOCK_ALLOC_SIZE);
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
LLMemory::logMemoryInfo(TRUE);

View File

@ -315,7 +315,7 @@ bool LLImageJPEG::decode(LLImageRaw* raw_image, F32 decode_time)
jpeg_destroy_decompress(&cinfo);
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
setLastError( "Out of memory");
jpeg_destroy_decompress(&cinfo);

View File

@ -210,7 +210,7 @@ BOOL LLPngWrapper::readPng(U8* src, S32 dataSize, LLImageRaw* rawImage, ImageInf
releaseResources();
return (FALSE);
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
mErrorMessage = "LLPngWrapper";
releaseResources();

View File

@ -22,12 +22,17 @@ set(llinventory_SOURCE_FILES
llfoldertype.cpp
llinventory.cpp
llinventorydefines.cpp
llinventorysettings.cpp
llinventorytype.cpp
lllandmark.cpp
llnotecard.cpp
llparcel.cpp
llpermissions.cpp
llsaleinfo.cpp
llsettingsbase.cpp
llsettingsdaycycle.cpp
llsettingssky.cpp
llsettingswater.cpp
lltransactionflags.cpp
lluserrelations.cpp
)
@ -39,7 +44,9 @@ set(llinventory_HEADER_FILES
llfoldertype.h
llinventory.h
llinventorydefines.h
llinventorysettings.h
llinventorytype.h
llinvtranslationbrdg.h
lllandmark.h
llnotecard.h
llparcel.h
@ -47,6 +54,10 @@ set(llinventory_HEADER_FILES
llpermissions.h
llpermissionsflags.h
llsaleinfo.h
llsettingsbase.h
llsettingsdaycycle.h
llsettingssky.h
llsettingswater.h
lltransactionflags.h
lltransactiontypes.h
lluserrelations.h

View File

@ -100,6 +100,8 @@ LLFolderDictionary::LLFolderDictionary()
addEntry(LLFolderType::FT_MARKETPLACE_STOCK, new FolderEntry("stock", FALSE));
addEntry(LLFolderType::FT_MARKETPLACE_VERSION, new FolderEntry("version", FALSE));
addEntry(LLFolderType::FT_SETTINGS, new FolderEntry("settings", TRUE));
addEntry(LLFolderType::FT_NONE, new FolderEntry("-1", FALSE));
};
@ -147,7 +149,7 @@ bool LLFolderType::lookupIsEnsembleType(EType folder_type)
// static
LLAssetType::EType LLFolderType::folderTypeToAssetType(LLFolderType::EType folder_type)
{
if (LLAssetType::lookup(LLAssetType::EType(folder_type)) == LLAssetType::badLookup())
if (LLAssetType::lookup(LLAssetType::EType(folder_type)) == LLAssetType::BADLOOKUP)
{
LL_WARNS() << "Converting to unknown asset type " << folder_type << LL_ENDL;
}

View File

@ -91,6 +91,8 @@ public:
FT_MARKETPLACE_STOCK = 54,
FT_MARKETPLACE_VERSION = 55, // Note: We actually *never* create folders with that type. This is used for icon override only.
FT_SETTINGS = 56,
FT_COUNT,
FT_NONE = -1

View File

@ -81,9 +81,10 @@ public:
II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS = 0x200000,
// Whether a returned object is composed of multiple items.
II_FLAGS_WEARABLES_MASK = 0xff,
// Wearables use the low order byte of flags to store the
// LLWearableType::EType enumeration found in newview/llwearable.h
II_FLAGS_SUBTYPE_MASK = 0x0000ff,
// Some items like Wearables and settings use the low order byte
// of flags to store the sub type of the inventory item.
// see LLWearableType::EType enumeration found in newview/llwearable.h
II_FLAGS_PERM_OVERWRITE_MASK = (II_FLAGS_OBJECT_SLAM_PERM |
II_FLAGS_OBJECT_SLAM_SALE |

View File

@ -0,0 +1,116 @@
/**
* @file llinventorysettings.cpp
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llinventorysettings.h"
#include "llinventorytype.h"
#include "llinventorydefines.h"
#include "lldictionary.h"
#include "llsingleton.h"
#include "llinvtranslationbrdg.h"
//=========================================================================
namespace {
LLTranslationBridge::ptr_t sTranslator;
}
//=========================================================================
struct SettingsEntry : public LLDictionaryEntry
{
SettingsEntry(const std::string &name,
const std::string& default_new_name,
LLInventoryType::EIconName iconName) :
LLDictionaryEntry(name),
mDefaultNewName(default_new_name),
mLabel(name),
mIconName(iconName)
{
std::string transdname = sTranslator->getString(mLabel);
if (!transdname.empty())
{
mLabel = transdname;
}
}
std::string mLabel;
std::string mDefaultNewName; //keep mLabel for backward compatibility
LLInventoryType::EIconName mIconName;
};
class LLSettingsDictionary : public LLSingleton<LLSettingsDictionary>,
public LLDictionary<LLSettingsType::type_e, SettingsEntry>
{
LLSINGLETON(LLSettingsDictionary);
void initSingleton();
};
LLSettingsDictionary::LLSettingsDictionary()
{
}
void LLSettingsDictionary::initSingleton()
{
addEntry(LLSettingsType::ST_SKY, new SettingsEntry("sky", "New Sky", LLInventoryType::ICONNAME_SETTINGS_SKY));
addEntry(LLSettingsType::ST_WATER, new SettingsEntry("water", "New Water", LLInventoryType::ICONNAME_SETTINGS_WATER));
addEntry(LLSettingsType::ST_DAYCYCLE, new SettingsEntry("day", "New Day", LLInventoryType::ICONNAME_SETTINGS_DAY));
addEntry(LLSettingsType::ST_NONE, new SettingsEntry("none", "New Settings", LLInventoryType::ICONNAME_SETTINGS));
addEntry(LLSettingsType::ST_INVALID, new SettingsEntry("invalid", "New Settings", LLInventoryType::ICONNAME_SETTINGS));
}
//=========================================================================
LLSettingsType::type_e LLSettingsType::fromInventoryFlags(U32 flags)
{
return (LLSettingsType::type_e)(flags & LLInventoryItemFlags::II_FLAGS_SUBTYPE_MASK);
}
LLInventoryType::EIconName LLSettingsType::getIconName(LLSettingsType::type_e type)
{
const SettingsEntry *entry = LLSettingsDictionary::instance().lookup(type);
if (!entry)
return getIconName(ST_INVALID);
return entry->mIconName;
}
std::string LLSettingsType::getDefaultName(LLSettingsType::type_e type)
{
const SettingsEntry *entry = LLSettingsDictionary::instance().lookup(type);
if (!entry)
return getDefaultName(ST_INVALID);
return entry->mDefaultNewName;
}
void LLSettingsType::initClass(LLTranslationBridge::ptr_t &trans)
{
sTranslator = trans;
}
void LLSettingsType::cleanupClass()
{
sTranslator.reset();
}

View File

@ -0,0 +1,56 @@
/**
* @file llinventorysettings.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_INVENTORY_SETTINGS_H
#define LL_INVENTORY_SETTINGS_H
#include "llinventorytype.h"
#include "llinvtranslationbrdg.h"
class LLSettingsType
{
public:
enum type_e
{
ST_SKY = 0,
ST_WATER = 1,
ST_DAYCYCLE = 2,
ST_INVALID = 255,
ST_NONE = -1
};
static type_e fromInventoryFlags(U32 flags);
static LLInventoryType::EIconName getIconName(type_e type);
static std::string getDefaultName(type_e type);
static void initClass(LLTranslationBridge::ptr_t &trans);
static void cleanupClass();
};
#endif

View File

@ -85,6 +85,7 @@ LLInventoryDictionary::LLInventoryDictionary()
addEntry(LLInventoryType::IT_MESH, new InventoryEntry("mesh", "mesh", 1, LLAssetType::AT_MESH));
addEntry(LLInventoryType::IT_WIDGET, new InventoryEntry("widget", "widget", 1, LLAssetType::AT_WIDGET));
addEntry(LLInventoryType::IT_PERSON, new InventoryEntry("person", "person", 1, LLAssetType::AT_PERSON));
addEntry(LLInventoryType::IT_SETTINGS, new InventoryEntry("settings", "settings", 1, LLAssetType::AT_SETTINGS));
}
@ -145,6 +146,14 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
LLInventoryType::IT_NONE, // 47 AT_NONE
LLInventoryType::IT_NONE, // 48 AT_NONE
LLInventoryType::IT_MESH, // 49 AT_MESH
LLInventoryType::IT_NONE, // 50 AT_RESERVED_1
LLInventoryType::IT_NONE, // 51 AT_RESERVED_2
LLInventoryType::IT_NONE, // 52 AT_RESERVED_3
LLInventoryType::IT_NONE, // 53 AT_RESERVED_4
LLInventoryType::IT_NONE, // 54 AT_RESERVED_5
LLInventoryType::IT_SETTINGS, // 55 AT_SETTINGS
};
// static
@ -200,6 +209,12 @@ bool LLInventoryType::cannotRestrictPermissions(LLInventoryType::EType type)
}
}
// Should show permissions that apply only to objects rezed in world.
bool LLInventoryType::showInWorldPermissions(LLInventoryType::EType type)
{
return (type != IT_SETTINGS);
}
bool inventory_and_asset_types_match(LLInventoryType::EType inventory_type,
LLAssetType::EType asset_type)
{

View File

@ -64,7 +64,8 @@ public:
IT_MESH = 22,
IT_WIDGET = 23,
IT_PERSON = 24,
IT_COUNT = 25,
IT_SETTINGS = 25,
IT_COUNT = 26,
IT_UNKNOWN = 255,
IT_NONE = -1
@ -112,6 +113,11 @@ public:
ICONNAME_LINKFOLDER,
ICONNAME_MESH,
ICONNAME_SETTINGS,
ICONNAME_SETTINGS_SKY,
ICONNAME_SETTINGS_WATER,
ICONNAME_SETTINGS_DAY,
ICONNAME_INVALID,
ICONNAME_UNKNOWN,
ICONNAME_COUNT,
@ -131,6 +137,8 @@ public:
// true if this type cannot have restricted permissions.
static bool cannotRestrictPermissions(EType type);
static bool showInWorldPermissions(EType type);
private:
// don't instantiate or derive one of these objects
LLInventoryType( void );

View File

@ -0,0 +1,41 @@
/**
* @file llinvtranslationbrdg.h
* @brief Translation adapter for inventory.
*
* $LicenseInfo:firstyear=2002&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_TRANSLATIONBRDG_H
#define LL_TRANSLATIONBRDG_H
class LLTranslationBridge
{
public:
typedef std::shared_ptr<LLTranslationBridge> ptr_t;
// clang needs this to be happy
virtual ~LLTranslationBridge() {}
virtual std::string getString(const std::string &xml_desc) = 0;
};
#endif

View File

@ -231,6 +231,9 @@ void LLParcel::init(const LLUUID &owner_id,
setAllowGroupAVSounds(TRUE);
setAllowAnyAVSounds(TRUE);
setHaveNewParcelLimitData(FALSE);
setRegionAllowEnvironmentOverride(FALSE);
setParcelEnvironmentVersion(INVALID_PARCEL_ENVIRONMENT_VERSION);
}
void LLParcel::overrideOwner(const LLUUID& owner_id, BOOL is_group_owned)

View File

@ -34,6 +34,7 @@
#include "llpermissions.h"
#include "lltimer.h"
#include "v3math.h"
#include "llsettingsdaycycle.h"
// Grid out of which parcels taken is stepped every 4 meters.
const F32 PARCEL_GRID_STEP_METERS = 4.f;
@ -102,6 +103,10 @@ const U32 RT_SELL = 0x1 << 5;
const S32 INVALID_PARCEL_ID = -1;
const S32 INVALID_PARCEL_ENVIRONMENT_VERSION = -2;
// if Region settings are used, parcel env. version is -1
const S32 UNSET_PARCEL_ENVIRONMENT_VERSION = -1;
// Timeouts for parcels
// default is 21 days * 24h/d * 60m/h * 60s/m *1000000 usec/s = 1814400000000
const U64 DEFAULT_USEC_CONVERSION_TIMEOUT = U64L(1814400000000);
@ -510,6 +515,10 @@ public:
{ return mRegionDenyAgeUnverifiedOverride; }
BOOL getRegionAllowAccessOverride() const
{ return mRegionAllowAccessoverride; }
BOOL getRegionAllowEnvironmentOverride() const
{ return mRegionAllowEnvironmentOverride; }
S32 getParcelEnvironmentVersion() const
{ return mCurrentEnvironmentVersion; }
BOOL getAllowGroupAVSounds() const { return mAllowGroupAVSounds; }
@ -580,6 +589,9 @@ public:
void setRegionDenyAnonymousOverride(BOOL override) { mRegionDenyAnonymousOverride = override; }
void setRegionDenyAgeUnverifiedOverride(BOOL override) { mRegionDenyAgeUnverifiedOverride = override; }
void setRegionAllowAccessOverride(BOOL override) { mRegionAllowAccessoverride = override; }
void setRegionAllowEnvironmentOverride(BOOL override) { mRegionAllowEnvironmentOverride = override; }
void setParcelEnvironmentVersion(S32 version) { mCurrentEnvironmentVersion = version; }
// Accessors for parcel sellWithObjects
void setPreviousOwnerID(LLUUID prev_owner) { mPreviousOwnerID = prev_owner; }
@ -589,8 +601,7 @@ public:
LLUUID getPreviousOwnerID() const { return mPreviousOwnerID; }
BOOL getPreviouslyGroupOwned() const { return mPreviouslyGroupOwned; }
BOOL getSellWithObjects() const { return (mParcelFlags & PF_SELL_PARCEL_OBJECTS) ? TRUE : FALSE; }
protected:
LLUUID mID;
LLUUID mOwnerID;
@ -662,10 +673,13 @@ protected:
BOOL mRegionDenyAnonymousOverride;
BOOL mRegionDenyAgeUnverifiedOverride;
BOOL mRegionAllowAccessoverride;
BOOL mRegionAllowEnvironmentOverride;
BOOL mAllowGroupAVSounds;
BOOL mAllowAnyAVSounds;
S32 mCurrentEnvironmentVersion;
bool mIsDefaultDayCycle;
public:
// HACK, make private
S32 mLocalID;

View File

@ -0,0 +1,751 @@
/**
* @file llsettingsbase.cpp
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llsettingsbase.h"
#include "llmath.h"
#include <algorithm>
#include "llsdserialize.h"
//=========================================================================
namespace
{
const LLSettingsBase::TrackPosition BREAK_POINT = 0.5;
}
const LLSettingsBase::TrackPosition LLSettingsBase::INVALID_TRACKPOS(-1.0);
const std::string LLSettingsBase::DEFAULT_SETTINGS_NAME("_default_");
//=========================================================================
std::ostream &operator <<(std::ostream& os, LLSettingsBase &settings)
{
LLSDSerialize::serialize(settings.getSettings(), os, LLSDSerialize::LLSD_NOTATION);
return os;
}
//=========================================================================
const std::string LLSettingsBase::SETTING_ID("id");
const std::string LLSettingsBase::SETTING_NAME("name");
const std::string LLSettingsBase::SETTING_HASH("hash");
const std::string LLSettingsBase::SETTING_TYPE("type");
const std::string LLSettingsBase::SETTING_ASSETID("asset_id");
const std::string LLSettingsBase::SETTING_FLAGS("flags");
const U32 LLSettingsBase::FLAG_NOCOPY(0x01 << 0);
const U32 LLSettingsBase::FLAG_NOMOD(0x01 << 1);
const U32 LLSettingsBase::FLAG_NOTRANS(0x01 << 2);
const U32 LLSettingsBase::FLAG_NOSAVE(0x01 << 3);
const U32 LLSettingsBase::Validator::VALIDATION_PARTIAL(0x01 << 0);
//=========================================================================
LLSettingsBase::LLSettingsBase():
mSettings(LLSD::emptyMap()),
mDirty(true),
mBlendedFactor(0.0)
{
}
LLSettingsBase::LLSettingsBase(const LLSD setting) :
mSettings(setting),
mDirty(true),
mBlendedFactor(0.0)
{
}
//=========================================================================
void LLSettingsBase::lerpSettings(const LLSettingsBase &other, F64 mix)
{
mSettings = interpolateSDMap(mSettings, other.mSettings, other.getParameterMap(), mix);
setDirtyFlag(true);
}
LLSD LLSettingsBase::combineSDMaps(const LLSD &settings, const LLSD &other) const
{
LLSD newSettings;
for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it)
{
std::string key_name = (*it).first;
LLSD value = (*it).second;
LLSD::Type setting_type = value.type();
switch (setting_type)
{
case LLSD::TypeMap:
newSettings[key_name] = combineSDMaps(value, LLSD());
break;
case LLSD::TypeArray:
newSettings[key_name] = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
{
newSettings[key_name].append(*ita);
}
break;
//case LLSD::TypeInteger:
//case LLSD::TypeReal:
//case LLSD::TypeBoolean:
//case LLSD::TypeString:
//case LLSD::TypeUUID:
//case LLSD::TypeURI:
//case LLSD::TypeDate:
//case LLSD::TypeBinary:
default:
newSettings[key_name] = value;
break;
}
}
if (!other.isUndefined())
{
for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
{
std::string key_name = (*it).first;
LLSD value = (*it).second;
LLSD::Type setting_type = value.type();
switch (setting_type)
{
case LLSD::TypeMap:
newSettings[key_name] = combineSDMaps(value, LLSD());
break;
case LLSD::TypeArray:
newSettings[key_name] = LLSD::emptyArray();
for (LLSD::array_const_iterator ita = value.beginArray(); ita != value.endArray(); ++ita)
{
newSettings[key_name].append(*ita);
}
break;
//case LLSD::TypeInteger:
//case LLSD::TypeReal:
//case LLSD::TypeBoolean:
//case LLSD::TypeString:
//case LLSD::TypeUUID:
//case LLSD::TypeURI:
//case LLSD::TypeDate:
//case LLSD::TypeBinary:
default:
newSettings[key_name] = value;
break;
}
}
}
return newSettings;
}
LLSD LLSettingsBase::interpolateSDMap(const LLSD &settings, const LLSD &other, const parammapping_t& defaults, F64 mix) const
{
LLSD newSettings;
stringset_t skip = getSkipInterpolateKeys();
stringset_t slerps = getSlerpKeys();
llassert(mix >= 0.0f && mix <= 1.0f);
for (LLSD::map_const_iterator it = settings.beginMap(); it != settings.endMap(); ++it)
{
std::string key_name = (*it).first;
LLSD value = (*it).second;
if (skip.find(key_name) != skip.end())
continue;
LLSD other_value;
if (other.has(key_name))
{
other_value = other[key_name];
}
else
{
parammapping_t::const_iterator def_iter = defaults.find(key_name);
if (def_iter != defaults.end())
{
other_value = def_iter->second.getDefaultValue();
}
else if (value.type() == LLSD::TypeMap)
{
// interpolate in case there are defaults inside (part of legacy)
other_value = LLSDMap();
}
else
{
// The other or defaults does not contain this setting, keep the original value
// TODO: Should I blend this out instead?
newSettings[key_name] = value;
continue;
}
}
newSettings[key_name] = interpolateSDValue(key_name, value, other_value, defaults, mix, slerps);
}
// Special handling cases
// Flags
if (settings.has(SETTING_FLAGS))
{
U32 flags = (U32)settings[SETTING_FLAGS].asInteger();
if (other.has(SETTING_FLAGS))
flags |= (U32)other[SETTING_FLAGS].asInteger();
newSettings[SETTING_FLAGS] = LLSD::Integer(flags);
}
// Now add anything that is in other but not in the settings
for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
{
std::string key_name = (*it).first;
if (skip.find(key_name) != skip.end())
continue;
if (settings.has(key_name))
continue;
parammapping_t::const_iterator def_iter = defaults.find(key_name);
if (def_iter != defaults.end())
{
// Blend against default value
newSettings[key_name] = interpolateSDValue(key_name, def_iter->second.getDefaultValue(), (*it).second, defaults, mix, slerps);
}
else if ((*it).second.type() == LLSD::TypeMap)
{
// interpolate in case there are defaults inside (part of legacy)
newSettings[key_name] = interpolateSDValue(key_name, LLSDMap(), (*it).second, defaults, mix, slerps);
}
// else do nothing when no known defaults
// TODO: Should I blend this out instead?
}
// Note: writes variables from skip list, bug?
for (LLSD::map_const_iterator it = other.beginMap(); it != other.endMap(); ++it)
{
// TODO: Should I blend this in instead?
if (skip.find((*it).first) == skip.end())
continue;
if (!settings.has((*it).first))
continue;
newSettings[(*it).first] = (*it).second;
}
return newSettings;
}
LLSD LLSettingsBase::interpolateSDValue(const std::string& key_name, const LLSD &value, const LLSD &other_value, const parammapping_t& defaults, BlendFactor mix, const stringset_t& slerps) const
{
LLSD new_value;
LLSD::Type setting_type = value.type();
if (other_value.type() != setting_type)
{
// The data type mismatched between this and other. Hard switch when we pass the break point
// but issue a warning.
LL_WARNS("SETTINGS") << "Setting lerp between mismatched types for '" << key_name << "'." << LL_ENDL;
new_value = (mix > BREAK_POINT) ? other_value : value;
}
switch (setting_type)
{
case LLSD::TypeInteger:
// lerp between the two values rounding the result to the nearest integer.
new_value = LLSD::Integer(llroundf(lerp(value.asReal(), other_value.asReal(), mix)));
break;
case LLSD::TypeReal:
// lerp between the two values.
new_value = LLSD::Real(lerp(value.asReal(), other_value.asReal(), mix));
break;
case LLSD::TypeMap:
// deep copy.
new_value = interpolateSDMap(value, other_value, defaults, mix);
break;
case LLSD::TypeArray:
{
LLSD new_array(LLSD::emptyArray());
if (slerps.find(key_name) != slerps.end())
{
LLQuaternion a(value);
LLQuaternion b(other_value);
LLQuaternion q = slerp(mix, a, b);
new_array = q.getValue();
}
else
{ // TODO: We could expand this to inspect the type and do a deep lerp based on type.
// for now assume a heterogeneous array of reals.
size_t len = std::max(value.size(), other_value.size());
for (size_t i = 0; i < len; ++i)
{
new_array[i] = lerp(value[i].asReal(), other_value[i].asReal(), mix);
}
}
new_value = new_array;
}
break;
case LLSD::TypeUUID:
new_value = value.asUUID();
break;
// case LLSD::TypeBoolean:
// case LLSD::TypeString:
// case LLSD::TypeURI:
// case LLSD::TypeBinary:
// case LLSD::TypeDate:
default:
// atomic or unknown data types. Lerping between them does not make sense so switch at the break.
new_value = (mix > BREAK_POINT) ? other_value : value;
break;
}
return new_value;
}
LLSettingsBase::stringset_t LLSettingsBase::getSkipInterpolateKeys() const
{
static stringset_t skipSet;
if (skipSet.empty())
{
skipSet.insert(SETTING_FLAGS);
skipSet.insert(SETTING_HASH);
}
return skipSet;
}
LLSD LLSettingsBase::getSettings() const
{
return mSettings;
}
LLSD LLSettingsBase::cloneSettings() const
{
U32 flags = getFlags();
LLSD settings (combineSDMaps(getSettings(), LLSD()));
if (flags)
settings[SETTING_FLAGS] = LLSD::Integer(flags);
return settings;
}
size_t LLSettingsBase::getHash() const
{ // get a shallow copy of the LLSD filtering out values to not include in the hash
LLSD hash_settings = llsd_shallow(getSettings(),
LLSDMap(SETTING_NAME, false)(SETTING_ID, false)(SETTING_HASH, false)("*", true));
boost::hash<LLSD> hasher;
return hasher(hash_settings);
}
bool LLSettingsBase::validate()
{
validation_list_t validations = getValidationList();
if (!mSettings.has(SETTING_TYPE))
{
mSettings[SETTING_TYPE] = getSettingsType();
}
LLSD result = LLSettingsBase::settingValidation(mSettings, validations);
if (result["errors"].size() > 0)
{
LL_WARNS("SETTINGS") << "Validation errors: " << result["errors"] << LL_ENDL;
}
if (result["warnings"].size() > 0)
{
LL_DEBUGS("SETTINGS") << "Validation warnings: " << result["warnings"] << LL_ENDL;
}
return result["success"].asBoolean();
}
LLSD LLSettingsBase::settingValidation(LLSD &settings, validation_list_t &validations, bool partial)
{
static Validator validateName(SETTING_NAME, false, LLSD::TypeString, boost::bind(&Validator::verifyStringLength, _1, 63));
static Validator validateId(SETTING_ID, false, LLSD::TypeUUID);
static Validator validateHash(SETTING_HASH, false, LLSD::TypeInteger);
static Validator validateType(SETTING_TYPE, false, LLSD::TypeString);
static Validator validateAssetId(SETTING_ASSETID, false, LLSD::TypeUUID);
static Validator validateFlags(SETTING_FLAGS, false, LLSD::TypeInteger);
stringset_t validated;
stringset_t strip;
bool isValid(true);
LLSD errors(LLSD::emptyArray());
LLSD warnings(LLSD::emptyArray());
U32 flags(0);
if (partial)
flags |= Validator::VALIDATION_PARTIAL;
// Fields common to all settings.
if (!validateName.verify(settings, flags))
{
errors.append( LLSD::String("Unable to validate 'name'.") );
isValid = false;
}
validated.insert(validateName.getName());
if (!validateId.verify(settings, flags))
{
errors.append( LLSD::String("Unable to validate 'id'.") );
isValid = false;
}
validated.insert(validateId.getName());
if (!validateHash.verify(settings, flags))
{
errors.append( LLSD::String("Unable to validate 'hash'.") );
isValid = false;
}
validated.insert(validateHash.getName());
if (!validateAssetId.verify(settings, flags))
{
errors.append(LLSD::String("Invalid asset Id"));
isValid = false;
}
validated.insert(validateAssetId.getName());
if (!validateType.verify(settings, flags))
{
errors.append( LLSD::String("Unable to validate 'type'.") );
isValid = false;
}
validated.insert(validateType.getName());
if (!validateFlags.verify(settings, flags))
{
errors.append(LLSD::String("Unable to validate 'flags'."));
isValid = false;
}
validated.insert(validateFlags.getName());
// Fields for specific settings.
for (validation_list_t::iterator itv = validations.begin(); itv != validations.end(); ++itv)
{
#ifdef VALIDATION_DEBUG
LLSD oldvalue;
if (settings.has((*itv).getName()))
{
oldvalue = llsd_clone(mSettings[(*itv).getName()]);
}
#endif
if (!(*itv).verify(settings, flags))
{
std::stringstream errtext;
errtext << "Settings LLSD fails validation and could not be corrected for '" << (*itv).getName() << "'!\n";
errors.append( errtext.str() );
isValid = false;
}
validated.insert((*itv).getName());
#ifdef VALIDATION_DEBUG
if (!oldvalue.isUndefined())
{
if (!compare_llsd(settings[(*itv).getName()], oldvalue))
{
LL_WARNS("SETTINGS") << "Setting '" << (*itv).getName() << "' was changed: " << oldvalue << " -> " << settings[(*itv).getName()] << LL_ENDL;
}
}
#endif
}
// strip extra entries
for (LLSD::map_const_iterator itm = settings.beginMap(); itm != settings.endMap(); ++itm)
{
if (validated.find((*itm).first) == validated.end())
{
std::stringstream warntext;
warntext << "Stripping setting '" << (*itm).first << "'";
warnings.append( warntext.str() );
strip.insert((*itm).first);
}
}
for (stringset_t::iterator its = strip.begin(); its != strip.end(); ++its)
{
settings.erase(*its);
}
return LLSDMap("success", LLSD::Boolean(isValid))
("errors", errors)
("warnings", warnings);
}
//=========================================================================
bool LLSettingsBase::Validator::verify(LLSD &data, U32 flags)
{
if (!data.has(mName) || (data.has(mName) && data[mName].isUndefined()))
{
if ((flags & VALIDATION_PARTIAL) != 0) // we are doing a partial validation. Do no attempt to set a default if missing (or fail even if required)
return true;
if (!mDefault.isUndefined())
{
data[mName] = mDefault;
return true;
}
if (mRequired)
LL_WARNS("SETTINGS") << "Missing required setting '" << mName << "' with no default." << LL_ENDL;
return !mRequired;
}
if (data[mName].type() != mType)
{
LL_WARNS("SETTINGS") << "Setting '" << mName << "' is incorrect type." << LL_ENDL;
return false;
}
if (!mVerify.empty() && !mVerify(data[mName]))
{
LL_WARNS("SETTINGS") << "Setting '" << mName << "' fails validation." << LL_ENDL;
return false;
}
return true;
}
bool LLSettingsBase::Validator::verifyColor(LLSD &value)
{
return (value.size() == 3 || value.size() == 4);
}
bool LLSettingsBase::Validator::verifyVector(LLSD &value, S32 length)
{
return (value.size() == length);
}
bool LLSettingsBase::Validator::verifyVectorNormalized(LLSD &value, S32 length)
{
if (value.size() != length)
return false;
LLSD newvector;
switch (length)
{
case 2:
{
LLVector2 vect(value);
if (is_approx_equal(vect.normalize(), 1.0f))
return true;
newvector = vect.getValue();
break;
}
case 3:
{
LLVector3 vect(value);
if (is_approx_equal(vect.normalize(), 1.0f))
return true;
newvector = vect.getValue();
break;
}
case 4:
{
LLVector4 vect(value);
if (is_approx_equal(vect.normalize(), 1.0f))
return true;
newvector = vect.getValue();
break;
}
default:
return false;
}
return true;
}
bool LLSettingsBase::Validator::verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals)
{
for (S32 index = 0; index < value.size(); ++index)
{
if (minvals[index].asString() != "*")
{
if (minvals[index].asReal() > value[index].asReal())
{
value[index] = minvals[index].asReal();
}
}
if (maxvals[index].asString() != "*")
{
if (maxvals[index].asReal() < value[index].asReal())
{
value[index] = maxvals[index].asReal();
}
}
}
return true;
}
bool LLSettingsBase::Validator::verifyQuaternion(LLSD &value)
{
return (value.size() == 4);
}
bool LLSettingsBase::Validator::verifyQuaternionNormal(LLSD &value)
{
if (value.size() != 4)
return false;
LLQuaternion quat(value);
if (is_approx_equal(quat.normalize(), 1.0f))
return true;
LLSD newquat = quat.getValue();
for (S32 index = 0; index < 4; ++index)
{
value[index] = newquat[index];
}
return true;
}
bool LLSettingsBase::Validator::verifyFloatRange(LLSD &value, LLSD range)
{
F64 real = value.asReal();
F64 clampedval = llclamp(LLSD::Real(real), range[0].asReal(), range[1].asReal());
if (is_approx_equal(clampedval, real))
return true;
value = LLSD::Real(clampedval);
return true;
}
bool LLSettingsBase::Validator::verifyIntegerRange(LLSD &value, LLSD range)
{
S32 ival = value.asInteger();
S32 clampedval = llclamp(LLSD::Integer(ival), range[0].asInteger(), range[1].asInteger());
if (clampedval == ival)
return true;
value = LLSD::Integer(clampedval);
return true;
}
bool LLSettingsBase::Validator::verifyStringLength(LLSD &value, S32 length)
{
std::string sval = value.asString();
if (!sval.empty())
{
sval = sval.substr(0, length);
value = LLSD::String(sval);
}
return true;
}
//=========================================================================
void LLSettingsBlender::update(const LLSettingsBase::BlendFactor& blendf)
{
F64 res = setBlendFactor(blendf);
llassert(res >= 0.0 && res <= 1.0);
(void)res;
mTarget->update();
}
F64 LLSettingsBlender::setBlendFactor(const LLSettingsBase::BlendFactor& blendf_in)
{
LLSettingsBase::TrackPosition blendf = blendf_in;
if (blendf >= 1.0)
{
triggerComplete();
}
blendf = llclamp(blendf, 0.0f, 1.0f);
if (mTarget)
{
mTarget->replaceSettings(mInitial->getSettings());
mTarget->blend(mFinal, blendf);
}
else
{
LL_WARNS("SETTINGS") << "No target for settings blender." << LL_ENDL;
}
return blendf;
}
void LLSettingsBlender::triggerComplete()
{
if (mTarget)
mTarget->replaceSettings(mFinal->getSettings());
LLSettingsBlender::ptr_t hold = shared_from_this(); // prevents this from deleting too soon
mTarget->update();
mOnFinished(shared_from_this());
}
//-------------------------------------------------------------------------
const LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::MIN_BLEND_DELTA(FLT_EPSILON);
LLSettingsBase::BlendFactor LLSettingsBlenderTimeDelta::calculateBlend(const LLSettingsBase::TrackPosition& spanpos, const LLSettingsBase::TrackPosition& spanlen) const
{
return LLSettingsBase::BlendFactor(fmod((F64)spanpos, (F64)spanlen) / (F64)spanlen);
}
bool LLSettingsBlenderTimeDelta::applyTimeDelta(const LLSettingsBase::Seconds& timedelta)
{
mTimeSpent += timedelta;
if (mTimeSpent > mBlendSpan)
{
triggerComplete();
return false;
}
LLSettingsBase::BlendFactor blendf = calculateBlend(mTimeSpent, mBlendSpan);
if (fabs(mLastBlendF - blendf) < mBlendFMinDelta)
{
return false;
}
mLastBlendF = blendf;
update(blendf);
return true;
}

View File

@ -0,0 +1,518 @@
/**
* @file llsettingsbase.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_SETTINGS_BASE_H
#define LL_SETTINGS_BASE_H
#include <string>
#include <map>
#include <vector>
#include <boost/signals2.hpp>
#include "llsd.h"
#include "llsdutil.h"
#include "v2math.h"
#include "v3math.h"
#include "v4math.h"
#include "llquaternion.h"
#include "v4color.h"
#include "v3color.h"
#include "llunits.h"
#include "llinventorysettings.h"
#define PTR_NAMESPACE std
#define SETTINGS_OVERRIDE override
class LLSettingsBase :
public PTR_NAMESPACE::enable_shared_from_this<LLSettingsBase>,
private boost::noncopyable
{
friend class LLEnvironment;
friend class LLSettingsDay;
friend std::ostream &operator <<(std::ostream& os, LLSettingsBase &settings);
protected:
LOG_CLASS(LLSettingsBase);
public:
typedef F64Seconds Seconds;
typedef F64 BlendFactor;
typedef F32 TrackPosition; // 32-bit as these are stored in LLSD as such
static const TrackPosition INVALID_TRACKPOS;
static const std::string DEFAULT_SETTINGS_NAME;
static const std::string SETTING_ID;
static const std::string SETTING_NAME;
static const std::string SETTING_HASH;
static const std::string SETTING_TYPE;
static const std::string SETTING_ASSETID;
static const std::string SETTING_FLAGS;
static const U32 FLAG_NOCOPY;
static const U32 FLAG_NOMOD;
static const U32 FLAG_NOTRANS;
static const U32 FLAG_NOSAVE;
class DefaultParam
{
public:
DefaultParam(S32 key, const LLSD& value) : mShaderKey(key), mDefaultValue(value) {}
DefaultParam() : mShaderKey(-1) {}
S32 getShaderKey() const { return mShaderKey; }
const LLSD getDefaultValue() const { return mDefaultValue; }
private:
S32 mShaderKey;
LLSD mDefaultValue;
};
// Contains settings' names (map key), related shader id-key and default
// value for revert in case we need to reset shader (no need to search each time)
typedef std::map<std::string, DefaultParam> parammapping_t;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsBase> ptr_t;
virtual ~LLSettingsBase() { };
//---------------------------------------------------------------------
virtual std::string getSettingsType() const = 0;
virtual LLSettingsType::type_e getSettingsTypeValue() const = 0;
//---------------------------------------------------------------------
// Settings status
inline bool hasSetting(const std::string &param) const { return mSettings.has(param); }
virtual bool isDirty() const { return mDirty; }
virtual bool isVeryDirty() const { return mReplaced; }
inline void setDirtyFlag(bool dirty) { mDirty = dirty; clearAssetId(); }
size_t getHash() const; // Hash will not include Name, ID or a previously stored Hash
inline LLUUID getId() const
{
return getValue(SETTING_ID).asUUID();
}
inline std::string getName() const
{
return getValue(SETTING_NAME).asString();
}
inline void setName(std::string val)
{
setValue(SETTING_NAME, val);
}
inline LLUUID getAssetId() const
{
if (mSettings.has(SETTING_ASSETID))
return mSettings[SETTING_ASSETID].asUUID();
return LLUUID();
}
inline U32 getFlags() const
{
if (mSettings.has(SETTING_FLAGS))
return static_cast<U32>(mSettings[SETTING_FLAGS].asInteger());
return 0;
}
inline void setFlags(U32 value)
{
setLLSD(SETTING_FLAGS, LLSD::Integer(value));
}
inline bool getFlag(U32 flag) const
{
if (mSettings.has(SETTING_FLAGS))
return ((U32)mSettings[SETTING_FLAGS].asInteger() & flag) == flag;
return false;
}
inline void setFlag(U32 flag)
{
U32 flags((mSettings.has(SETTING_FLAGS)) ? (U32)mSettings[SETTING_FLAGS].asInteger() : 0);
flags |= flag;
if (flags)
mSettings[SETTING_FLAGS] = LLSD::Integer(flags);
else
mSettings.erase(SETTING_FLAGS);
}
inline void clearFlag(U32 flag)
{
U32 flags((mSettings.has(SETTING_FLAGS)) ? (U32)mSettings[SETTING_FLAGS].asInteger() : 0);
flags &= ~flag;
if (flags)
mSettings[SETTING_FLAGS] = LLSD::Integer(flags);
else
mSettings.erase(SETTING_FLAGS);
}
virtual void replaceSettings(LLSD settings)
{
mBlendedFactor = 0.0;
setDirtyFlag(true);
mReplaced = true;
mSettings = settings;
}
virtual LLSD getSettings() const;
//---------------------------------------------------------------------
//
inline void setLLSD(const std::string &name, const LLSD &value)
{
mSettings[name] = value;
mDirty = true;
if (name != SETTING_ASSETID)
clearAssetId();
}
inline void setValue(const std::string &name, const LLSD &value)
{
setLLSD(name, value);
}
inline LLSD getValue(const std::string &name, const LLSD &deflt = LLSD()) const
{
if (!mSettings.has(name))
return deflt;
return mSettings[name];
}
inline void setValue(const std::string &name, F32 v)
{
setLLSD(name, LLSD::Real(v));
}
inline void setValue(const std::string &name, const LLVector2 &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLVector3 &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLVector4 &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLQuaternion &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLColor3 &value)
{
setValue(name, value.getValue());
}
inline void setValue(const std::string &name, const LLColor4 &value)
{
setValue(name, value.getValue());
}
inline BlendFactor getBlendFactor() const
{
return mBlendedFactor;
}
// Note this method is marked const but may modify the settings object.
// (note the internal const cast). This is so that it may be called without
// special consideration from getters.
inline void update() const
{
if ((!mDirty) && (!mReplaced))
return;
(const_cast<LLSettingsBase *>(this))->updateSettings();
}
virtual void blend(const ptr_t &end, BlendFactor blendf) = 0;
virtual bool validate();
virtual ptr_t buildDerivedClone() const = 0;
class Validator
{
public:
static const U32 VALIDATION_PARTIAL;
typedef boost::function<bool(LLSD &)> verify_pr;
Validator(std::string name, bool required, LLSD::Type type, verify_pr verify = verify_pr(), LLSD defval = LLSD()) :
mName(name),
mRequired(required),
mType(type),
mVerify(verify),
mDefault(defval)
{ }
std::string getName() const { return mName; }
bool isRequired() const { return mRequired; }
LLSD::Type getType() const { return mType; }
bool verify(LLSD &data, U32 flags);
// Some basic verifications
static bool verifyColor(LLSD &value);
static bool verifyVector(LLSD &value, S32 length);
static bool verifyVectorMinMax(LLSD &value, LLSD minvals, LLSD maxvals);
static bool verifyVectorNormalized(LLSD &value, S32 length);
static bool verifyQuaternion(LLSD &value);
static bool verifyQuaternionNormal(LLSD &value);
static bool verifyFloatRange(LLSD &value, LLSD range);
static bool verifyIntegerRange(LLSD &value, LLSD range);
static bool verifyStringLength(LLSD &value, S32 length);
private:
std::string mName;
bool mRequired;
LLSD::Type mType;
verify_pr mVerify;
LLSD mDefault;
};
typedef std::vector<Validator> validation_list_t;
static LLSD settingValidation(LLSD &settings, validation_list_t &validations, bool partial = false);
inline void setAssetId(LLUUID value)
{ // note that this skips setLLSD
mSettings[SETTING_ASSETID] = value;
}
inline void clearAssetId()
{
if (mSettings.has(SETTING_ASSETID))
mSettings.erase(SETTING_ASSETID);
}
// Calculate any custom settings that may need to be cached.
virtual void updateSettings() { mDirty = false; mReplaced = false; }
protected:
LLSettingsBase();
LLSettingsBase(const LLSD setting);
static LLSD settingValidation(LLSD settings);
typedef std::set<std::string> stringset_t;
// combining settings objects. Customize for specific setting types
virtual void lerpSettings(const LLSettingsBase &other, BlendFactor mix);
// combining settings maps where it can based on mix rate
// @settings initial value (mix==0)
// @other target value (mix==1)
// @defaults list of default values for legacy fields and (re)setting shaders
// @mix from 0 to 1, ratio or rate of transition from initial 'settings' to 'other'
// return interpolated and combined LLSD map
LLSD interpolateSDMap(const LLSD &settings, const LLSD &other, const parammapping_t& defaults, BlendFactor mix) const;
LLSD interpolateSDValue(const std::string& name, const LLSD &value, const LLSD &other, const parammapping_t& defaults, BlendFactor mix, const stringset_t& slerps) const;
/// when lerping between settings, some may require special handling.
/// Get a list of these key to be skipped by the default settings lerp.
/// (handling should be performed in the override of lerpSettings.
virtual stringset_t getSkipInterpolateKeys() const;
// A list of settings that represent quaternions and should be slerped
// rather than lerped.
virtual stringset_t getSlerpKeys() const { return stringset_t(); }
virtual validation_list_t getValidationList() const = 0;
// Apply any settings that need special handling.
virtual void applySpecial(void *, bool force = false) { };
virtual parammapping_t getParameterMap() const { return parammapping_t(); }
LLSD mSettings;
bool mIsValid;
LLSD cloneSettings() const;
inline void setBlendFactor(BlendFactor blendfactor)
{
mBlendedFactor = blendfactor;
}
void replaceWith(LLSettingsBase::ptr_t other)
{
replaceSettings(other->cloneSettings());
setBlendFactor(other->getBlendFactor());
}
private:
bool mDirty;
bool mReplaced; // super dirty!
LLSD combineSDMaps(const LLSD &first, const LLSD &other) const;
BlendFactor mBlendedFactor;
};
class LLSettingsBlender : public PTR_NAMESPACE::enable_shared_from_this<LLSettingsBlender>
{
LOG_CLASS(LLSettingsBlender);
public:
typedef PTR_NAMESPACE::shared_ptr<LLSettingsBlender> ptr_t;
typedef boost::signals2::signal<void(const ptr_t )> finish_signal_t;
typedef boost::signals2::connection connection_t;
LLSettingsBlender(const LLSettingsBase::ptr_t &target,
const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting) :
mOnFinished(),
mTarget(target),
mInitial(initsetting),
mFinal(endsetting)
{
if (mInitial && mTarget)
mTarget->replaceSettings(mInitial->getSettings());
if (!mFinal)
mFinal = mInitial;
}
virtual ~LLSettingsBlender() {}
virtual void reset( LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, const LLSettingsBase::TrackPosition&)
{
// note: the 'span' reset parameter is unused by the base class.
if (!mInitial)
LL_WARNS("BLENDER") << "Reseting blender with empty initial setting. Expect badness in the future." << LL_ENDL;
mInitial = initsetting;
mFinal = endsetting;
if (!mFinal)
mFinal = mInitial;
if (mTarget)
mTarget->replaceSettings(mInitial->getSettings());
}
LLSettingsBase::ptr_t getTarget() const
{
return mTarget;
}
LLSettingsBase::ptr_t getInitial() const
{
return mInitial;
}
LLSettingsBase::ptr_t getFinal() const
{
return mFinal;
}
connection_t setOnFinished(const finish_signal_t::slot_type &onfinished)
{
return mOnFinished.connect(onfinished);
}
virtual void update(const LLSettingsBase::BlendFactor& blendf);
virtual bool applyTimeDelta(const LLSettingsBase::Seconds& timedelta)
{
llassert(false);
// your derived class needs to implement an override of this func
return false;
}
virtual F64 setBlendFactor(const LLSettingsBase::BlendFactor& position);
virtual void switchTrack(S32 trackno, const LLSettingsBase::TrackPosition& position) { /*NoOp*/ }
protected:
void triggerComplete();
finish_signal_t mOnFinished;
LLSettingsBase::ptr_t mTarget;
LLSettingsBase::ptr_t mInitial;
LLSettingsBase::ptr_t mFinal;
};
class LLSettingsBlenderTimeDelta : public LLSettingsBlender
{
LOG_CLASS(LLSettingsBlenderTimeDelta);
public:
static const LLSettingsBase::BlendFactor MIN_BLEND_DELTA;
LLSettingsBlenderTimeDelta(const LLSettingsBase::ptr_t &target,
const LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, const LLSettingsBase::Seconds& blend_span) :
LLSettingsBlender(target, initsetting, endsetting),
mBlendSpan(blend_span),
mLastUpdate(0.0f),
mTimeSpent(0.0f),
mBlendFMinDelta(MIN_BLEND_DELTA),
mLastBlendF(-1.0f)
{
mTimeStart = LLSettingsBase::Seconds(LLDate::now().secondsSinceEpoch());
mLastUpdate = mTimeStart;
}
virtual ~LLSettingsBlenderTimeDelta()
{
}
virtual void reset(LLSettingsBase::ptr_t &initsetting, const LLSettingsBase::ptr_t &endsetting, const LLSettingsBase::TrackPosition& blend_span) SETTINGS_OVERRIDE
{
LLSettingsBlender::reset(initsetting, endsetting, blend_span);
mBlendSpan = blend_span;
mTimeStart = LLSettingsBase::Seconds(LLDate::now().secondsSinceEpoch());
mLastUpdate = mTimeStart;
mTimeSpent = LLSettingsBase::Seconds(0.0f);
mLastBlendF = LLSettingsBase::BlendFactor(-1.0f);
}
virtual bool applyTimeDelta(const LLSettingsBase::Seconds& timedelta) SETTINGS_OVERRIDE;
inline void setTimeSpent(LLSettingsBase::Seconds time) { mTimeSpent = time; }
protected:
LLSettingsBase::BlendFactor calculateBlend(const LLSettingsBase::TrackPosition& spanpos, const LLSettingsBase::TrackPosition& spanlen) const;
LLSettingsBase::TrackPosition mBlendSpan;
LLSettingsBase::Seconds mLastUpdate;
LLSettingsBase::Seconds mTimeSpent;
LLSettingsBase::Seconds mTimeStart;
LLSettingsBase::BlendFactor mBlendFMinDelta;
LLSettingsBase::BlendFactor mLastBlendF;
};
#endif

View File

@ -0,0 +1,896 @@
/**
* @file llsettingsdaycycle.cpp
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llsettingsdaycycle.h"
#include "llerror.h"
#include <algorithm>
#include <boost/make_shared.hpp>
#include "lltrace.h"
#include "llfasttimer.h"
#include "v3colorutil.h"
#include "llsettingssky.h"
#include "llsettingswater.h"
#include "llframetimer.h"
//=========================================================================
namespace
{
LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment");
LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment");
template<typename T>
inline T get_wrapping_distance(T begin, T end)
{
if (begin < end)
{
return end - begin;
}
else if (begin > end)
{
return T(1.0) - (begin - end);
}
return 0;
}
LLSettingsDay::CycleTrack_t::iterator get_wrapping_atafter(LLSettingsDay::CycleTrack_t &collection, const LLSettingsBase::TrackPosition& key)
{
if (collection.empty())
return collection.end();
LLSettingsDay::CycleTrack_t::iterator it = collection.upper_bound(key);
if (it == collection.end())
{ // wrap around
it = collection.begin();
}
return it;
}
LLSettingsDay::CycleTrack_t::iterator get_wrapping_atbefore(LLSettingsDay::CycleTrack_t &collection, const LLSettingsBase::TrackPosition& key)
{
if (collection.empty())
return collection.end();
LLSettingsDay::CycleTrack_t::iterator it = collection.lower_bound(key);
if (it == collection.end())
{ // all keyframes are lower, take the last one.
--it; // we know the range is not empty
}
else if ((*it).first > key)
{ // the keyframe we are interested in is smaller than the found.
if (it == collection.begin())
it = collection.end();
--it;
}
return it;
}
}
//=========================================================================
const std::string LLSettingsDay::SETTING_KEYID("key_id");
const std::string LLSettingsDay::SETTING_KEYNAME("key_name");
const std::string LLSettingsDay::SETTING_KEYKFRAME("key_keyframe");
const std::string LLSettingsDay::SETTING_KEYHASH("key_hash");
const std::string LLSettingsDay::SETTING_TRACKS("tracks");
const std::string LLSettingsDay::SETTING_FRAMES("frames");
const LLSettingsDay::Seconds LLSettingsDay::MINIMUM_DAYLENGTH(14400); // 4 hours
const LLSettingsDay::Seconds LLSettingsDay::DEFAULT_DAYLENGTH(14400); // 4 hours
const LLSettingsDay::Seconds LLSettingsDay::MAXIMUM_DAYLENGTH(604800); // 7 days
const LLSettingsDay::Seconds LLSettingsDay::MINIMUM_DAYOFFSET(0);
const LLSettingsDay::Seconds LLSettingsDay::DEFAULT_DAYOFFSET(57600); // +16 hours == -8 hours (SLT time offset)
const LLSettingsDay::Seconds LLSettingsDay::MAXIMUM_DAYOFFSET(86400); // 24 hours
const S32 LLSettingsDay::TRACK_WATER(0); // water track is 0
const S32 LLSettingsDay::TRACK_GROUND_LEVEL(1);
const S32 LLSettingsDay::TRACK_MAX(5); // 5 tracks, 4 skys, 1 water
const S32 LLSettingsDay::FRAME_MAX(56);
const F32 LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR(0.02501f);
const LLUUID LLSettingsDay::DEFAULT_ASSET_ID("5646d39e-d3d7-6aff-ed71-30fc87d64a91");
// Minimum value to prevent multislider in edit floaters from eating up frames that 'encroach' on one another's space
static const F32 DEFAULT_MULTISLIDER_INCREMENT(0.005f);
//=========================================================================
LLSettingsDay::LLSettingsDay(const LLSD &data) :
LLSettingsBase(data),
mInitialized(false)
{
mDayTracks.resize(TRACK_MAX);
}
LLSettingsDay::LLSettingsDay() :
LLSettingsBase(),
mInitialized(false)
{
mDayTracks.resize(TRACK_MAX);
}
//=========================================================================
LLSD LLSettingsDay::getSettings() const
{
LLSD settings(LLSD::emptyMap());
if (mSettings.has(SETTING_NAME))
settings[SETTING_NAME] = mSettings[SETTING_NAME];
if (mSettings.has(SETTING_ID))
settings[SETTING_ID] = mSettings[SETTING_ID];
if (mSettings.has(SETTING_ASSETID))
settings[SETTING_ASSETID] = mSettings[SETTING_ASSETID];
settings[SETTING_TYPE] = getSettingsType();
std::map<std::string, LLSettingsBase::ptr_t> in_use;
LLSD tracks(LLSD::emptyArray());
for (CycleList_t::const_iterator itTrack = mDayTracks.begin(); itTrack != mDayTracks.end(); ++itTrack)
{
LLSD trackout(LLSD::emptyArray());
for (CycleTrack_t::const_iterator itFrame = (*itTrack).begin(); itFrame != (*itTrack).end(); ++itFrame)
{
F32 frame = (*itFrame).first;
LLSettingsBase::ptr_t data = (*itFrame).second;
size_t datahash = data->getHash();
std::stringstream keyname;
keyname << datahash;
trackout.append(LLSD(LLSDMap(SETTING_KEYKFRAME, LLSD::Real(frame))(SETTING_KEYNAME, keyname.str())));
in_use[keyname.str()] = data;
}
tracks.append(trackout);
}
settings[SETTING_TRACKS] = tracks;
LLSD frames(LLSD::emptyMap());
for (std::map<std::string, LLSettingsBase::ptr_t>::iterator itFrame = in_use.begin(); itFrame != in_use.end(); ++itFrame)
{
LLSD framesettings = llsd_clone((*itFrame).second->getSettings(),
LLSDMap("*", true)(SETTING_NAME, false)(SETTING_ID, false)(SETTING_HASH, false));
frames[(*itFrame).first] = framesettings;
}
settings[SETTING_FRAMES] = frames;
return settings;
}
bool LLSettingsDay::initialize(bool validate_frames)
{
LLSD tracks = mSettings[SETTING_TRACKS];
LLSD frames = mSettings[SETTING_FRAMES];
// save for later...
LLUUID assetid;
if (mSettings.has(SETTING_ASSETID))
{
assetid = mSettings[SETTING_ASSETID].asUUID();
}
std::map<std::string, LLSettingsBase::ptr_t> used;
for (LLSD::map_const_iterator itFrame = frames.beginMap(); itFrame != frames.endMap(); ++itFrame)
{
std::string name = (*itFrame).first;
LLSD data = (*itFrame).second;
LLSettingsBase::ptr_t keyframe;
if (data[SETTING_TYPE].asString() == "sky")
{
keyframe = buildSky(data);
}
else if (data[SETTING_TYPE].asString() == "water")
{
keyframe = buildWater(data);
}
else
{
LL_WARNS("DAYCYCLE") << "Unknown child setting type '" << data[SETTING_TYPE].asString() << "' named '" << name << "'" << LL_ENDL;
}
if (!keyframe)
{
LL_WARNS("DAYCYCLE") << "Invalid frame data" << LL_ENDL;
continue;
}
used[name] = keyframe;
}
bool haswater(false);
bool hassky(false);
for (S32 i = 0; (i < tracks.size()) && (i < TRACK_MAX); ++i)
{
mDayTracks[i].clear();
LLSD curtrack = tracks[i];
for (LLSD::array_const_iterator it = curtrack.beginArray(); it != curtrack.endArray(); ++it)
{
LLSettingsBase::TrackPosition keyframe = LLSettingsBase::TrackPosition((*it)[SETTING_KEYKFRAME].asReal());
keyframe = llclamp(keyframe, 0.0f, 1.0f);
LLSettingsBase::ptr_t setting;
if ((*it).has(SETTING_KEYNAME))
{
std::string key_name = (*it)[SETTING_KEYNAME];
if (i == TRACK_WATER)
{
setting = used[key_name];
if (setting && setting->getSettingsType() != "water")
{
LL_WARNS("DAYCYCLE") << "Water track referencing " << setting->getSettingsType() << " frame at " << keyframe << "." << LL_ENDL;
setting.reset();
}
}
else
{
setting = used[key_name];
if (setting && setting->getSettingsType() != "sky")
{
LL_WARNS("DAYCYCLE") << "Sky track #" << i << " referencing " << setting->getSettingsType() << " frame at " << keyframe << "." << LL_ENDL;
setting.reset();
}
}
}
if (setting)
{
if (i == TRACK_WATER)
haswater |= true;
else
hassky |= true;
if (validate_frames && mDayTracks[i].size() > 0)
{
// check if we hit close to anything in the list
LLSettingsDay::CycleTrack_t::value_type frame = getSettingsNearKeyframe(keyframe, i, DEFAULT_FRAME_SLOP_FACTOR);
if (frame.second)
{
// figure out direction of search
LLSettingsBase::TrackPosition found = frame.first;
LLSettingsBase::TrackPosition new_frame = keyframe;
F32 total_frame_shift = 0;
// We consider frame DEFAULT_FRAME_SLOP_FACTOR away as still encroaching, so add minimum increment
F32 move_factor = DEFAULT_FRAME_SLOP_FACTOR + DEFAULT_MULTISLIDER_INCREMENT;
bool move_forward = true;
if ((new_frame < found && (found - new_frame) <= DEFAULT_FRAME_SLOP_FACTOR)
|| (new_frame > found && (new_frame - found) > DEFAULT_FRAME_SLOP_FACTOR))
{
move_forward = false;
}
if (move_forward)
{
CycleTrack_t::iterator iter = mDayTracks[i].find(found);
new_frame = found; // for total_frame_shift
while (total_frame_shift < 1)
{
// calculate shifted position from previous found point
total_frame_shift += move_factor + (found >= new_frame ? found : found + 1) - new_frame;
new_frame = found + move_factor;
if (new_frame > 1) new_frame--;
// we know that current point is too close, go for next one
iter++;
if (iter == mDayTracks[i].end())
{
iter = mDayTracks[i].begin();
}
if (((iter->first >= (new_frame - DEFAULT_MULTISLIDER_INCREMENT)) && ((new_frame + DEFAULT_FRAME_SLOP_FACTOR) >= iter->first))
|| ((iter->first < new_frame) && ((new_frame + DEFAULT_FRAME_SLOP_FACTOR) >= (iter->first + 1))))
{
// we are encroaching at new point as well
found = iter->first;
}
else // (new_frame + DEFAULT_FRAME_SLOP_FACTOR < iter->first)
{
//we found clear spot
break;
}
}
}
else
{
CycleTrack_t::reverse_iterator iter = mDayTracks[i].rbegin();
while (iter->first != found)
{
iter++;
}
new_frame = found; // for total_frame_shift
while (total_frame_shift < 1)
{
// calculate shifted position from current found point
total_frame_shift += move_factor + new_frame - (found <= new_frame ? found : found - 1);
new_frame = found - move_factor;
if (new_frame < 0) new_frame++;
// we know that current point is too close, go for next one
iter++;
if (iter == mDayTracks[i].rend())
{
iter = mDayTracks[i].rbegin();
}
if ((iter->first <= (new_frame + DEFAULT_MULTISLIDER_INCREMENT) && (new_frame - DEFAULT_FRAME_SLOP_FACTOR) <= iter->first)
|| ((iter->first > new_frame) && ((new_frame - DEFAULT_FRAME_SLOP_FACTOR) <= (iter->first - 1))))
{
// we are encroaching at new point as well
found = iter->first;
}
else // (new_frame - DEFAULT_FRAME_SLOP_FACTOR > iter->first)
{
//we found clear spot
break;
}
}
}
if (total_frame_shift >= 1)
{
LL_WARNS("SETTINGS") << "Could not fix frame position, adding as is to position: " << keyframe << LL_ENDL;
}
else
{
// Mark as new position
keyframe = new_frame;
}
}
}
mDayTracks[i][keyframe] = setting;
}
}
}
if (!haswater || !hassky)
{
LL_WARNS("DAYCYCLE") << "Must have at least one water and one sky frame!" << LL_ENDL;
return false;
}
// these are no longer needed and just take up space now.
mSettings.erase(SETTING_TRACKS);
mSettings.erase(SETTING_FRAMES);
if (!assetid.isNull())
{
mSettings[SETTING_ASSETID] = assetid;
}
mInitialized = true;
return true;
}
//=========================================================================
LLSD LLSettingsDay::defaults()
{
static LLSD dfltsetting;
if (dfltsetting.size() == 0)
{
dfltsetting[SETTING_NAME] = DEFAULT_SETTINGS_NAME;
dfltsetting[SETTING_TYPE] = "daycycle";
LLSD frames(LLSD::emptyMap());
LLSD waterTrack;
LLSD skyTrack;
const U32 FRAME_COUNT = 8;
const F32 FRAME_STEP = 1.0f / F32(FRAME_COUNT);
F32 time = 0.0f;
for (U32 i = 0; i < FRAME_COUNT; i++)
{
std::string name(DEFAULT_SETTINGS_NAME);
name += ('a' + i);
std::string water_frame_name("water:");
std::string sky_frame_name("sky:");
water_frame_name += name;
sky_frame_name += name;
waterTrack[SETTING_KEYKFRAME] = time;
waterTrack[SETTING_KEYNAME] = water_frame_name;
skyTrack[SETTING_KEYKFRAME] = time;
skyTrack[SETTING_KEYNAME] = sky_frame_name;
frames[water_frame_name] = LLSettingsWater::defaults(time);
frames[sky_frame_name] = LLSettingsSky::defaults(time);
time += FRAME_STEP;
}
LLSD tracks;
tracks.append(LLSDArray(waterTrack));
tracks.append(LLSDArray(skyTrack));
dfltsetting[SETTING_TRACKS] = tracks;
dfltsetting[SETTING_FRAMES] = frames;
}
return dfltsetting;
}
void LLSettingsDay::blend(const LLSettingsBase::ptr_t &other, F64 mix)
{
LL_ERRS("DAYCYCLE") << "Day cycles are not blendable!" << LL_ENDL;
}
namespace
{
bool validateDayCycleTrack(LLSD &value)
{
// Trim extra tracks.
while (value.size() > LLSettingsDay::TRACK_MAX)
{
value.erase(value.size() - 1);
}
S32 framecount(0);
for (LLSD::array_iterator track = value.beginArray(); track != value.endArray(); ++track)
{
S32 index = 0;
while (index < (*track).size())
{
LLSD& elem = (*track)[index];
++framecount;
if (index >= LLSettingsDay::FRAME_MAX)
{
(*track).erase(index);
continue;
}
if (!elem.has(LLSettingsDay::SETTING_KEYKFRAME))
{
(*track).erase(index);
continue;
}
if (!elem[LLSettingsDay::SETTING_KEYKFRAME].isReal())
{
(*track).erase(index);
continue;
}
if (!elem.has(LLSettingsDay::SETTING_KEYNAME) &&
!elem.has(LLSettingsDay::SETTING_KEYID))
{
(*track).erase(index);
continue;
}
LLSettingsBase::TrackPosition frame = elem[LLSettingsDay::SETTING_KEYKFRAME].asReal();
if ((frame < 0.0) || (frame > 1.0))
{
frame = llclamp(frame, 0.0f, 1.0f);
elem[LLSettingsDay::SETTING_KEYKFRAME] = frame;
}
++index;
}
}
int waterTracks = value[0].size();
int skyTracks = framecount - waterTracks;
if (waterTracks < 1)
{
LL_WARNS("SETTINGS") << "Missing water track" << LL_ENDL;
return false;
}
if (skyTracks < 1)
{
LL_WARNS("SETTINGS") << "Missing sky tracks" << LL_ENDL;
return false;
}
return true;
}
bool validateDayCycleFrames(LLSD &value)
{
bool hasSky(false);
bool hasWater(false);
for (LLSD::map_iterator itf = value.beginMap(); itf != value.endMap(); ++itf)
{
LLSD frame = (*itf).second;
std::string ftype = frame[LLSettingsBase::SETTING_TYPE];
if (ftype == "sky")
{
LLSettingsSky::validation_list_t valid_sky = LLSettingsSky::validationList();
LLSD res_sky = LLSettingsBase::settingValidation(frame, valid_sky);
if (res_sky["success"].asInteger() == 0)
{
LL_WARNS("SETTINGS") << "Sky setting named '" << (*itf).first << "' validation failed!: " << res_sky << LL_ENDL;
LL_WARNS("SETTINGS") << "Sky: " << frame << LL_ENDL;
continue;
}
hasSky |= true;
}
else if (ftype == "water")
{
LLSettingsWater::validation_list_t valid_h2o = LLSettingsWater::validationList();
LLSD res_h2o = LLSettingsBase::settingValidation(frame, valid_h2o);
if (res_h2o["success"].asInteger() == 0)
{
LL_WARNS("SETTINGS") << "Water setting named '" << (*itf).first << "' validation failed!: " << res_h2o << LL_ENDL;
LL_WARNS("SETTINGS") << "Water: " << frame << LL_ENDL;
continue;
}
hasWater |= true;
}
else
{
LL_WARNS("SETTINGS") << "Unknown settings block of type '" << ftype << "' named '" << (*itf).first << "'" << LL_ENDL;
return false;
}
}
if (!hasSky)
{
LL_WARNS("SETTINGS") << "No skies defined." << LL_ENDL;
return false;
}
if (!hasWater)
{
LL_WARNS("SETTINGS") << "No waters defined." << LL_ENDL;
return false;
}
return true;
}
}
LLSettingsDay::validation_list_t LLSettingsDay::getValidationList() const
{
return LLSettingsDay::validationList();
}
LLSettingsDay::validation_list_t LLSettingsDay::validationList()
{
static validation_list_t validation;
if (validation.empty())
{
validation.push_back(Validator(SETTING_TRACKS, true, LLSD::TypeArray,
&validateDayCycleTrack));
validation.push_back(Validator(SETTING_FRAMES, true, LLSD::TypeMap,
&validateDayCycleFrames));
}
return validation;
}
LLSettingsDay::CycleTrack_t& LLSettingsDay::getCycleTrack(S32 track)
{
static CycleTrack_t emptyTrack;
if (mDayTracks.size() <= track)
return emptyTrack;
return mDayTracks[track];
}
const LLSettingsDay::CycleTrack_t& LLSettingsDay::getCycleTrackConst(S32 track) const
{
static CycleTrack_t emptyTrack;
if (mDayTracks.size() <= track)
return emptyTrack;
return mDayTracks[track];
}
bool LLSettingsDay::clearCycleTrack(S32 track)
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to clear track (#" << track << ") out of range!" << LL_ENDL;
return false;
}
mDayTracks[track].clear();
clearAssetId();
setDirtyFlag(true);
return true;
}
bool LLSettingsDay::replaceCycleTrack(S32 track, const CycleTrack_t &source)
{
if (source.empty())
{
LL_WARNS("DAYCYCLE") << "Attempt to copy an empty track." << LL_ENDL;
return false;
}
{
LLSettingsBase::ptr_t first((*source.begin()).second);
std::string setting_type = first->getSettingsType();
if (((setting_type == "water") && (track != 0)) ||
((setting_type == "sky") && (track == 0)))
{
LL_WARNS("DAYCYCLE") << "Attempt to copy track missmatch" << LL_ENDL;
return false;
}
}
if (!clearCycleTrack(track))
return false;
mDayTracks[track] = source;
return true;
}
bool LLSettingsDay::isTrackEmpty(S32 track) const
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to test track (#" << track << ") out of range!" << LL_ENDL;
return true;
}
return mDayTracks[track].empty();
}
//=========================================================================
void LLSettingsDay::startDayCycle()
{
if (!mInitialized)
{
LL_WARNS("DAYCYCLE") << "Attempt to start day cycle on uninitialized object." << LL_ENDL;
return;
}
}
void LLSettingsDay::updateSettings()
{
}
//=========================================================================
LLSettingsDay::KeyframeList_t LLSettingsDay::getTrackKeyframes(S32 trackno)
{
if ((trackno < 0) || (trackno >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL;
return KeyframeList_t();
}
KeyframeList_t keyframes;
CycleTrack_t &track = mDayTracks[trackno];
keyframes.reserve(track.size());
for (CycleTrack_t::iterator it = track.begin(); it != track.end(); ++it)
{
keyframes.push_back((*it).first);
}
return keyframes;
}
bool LLSettingsDay::moveTrackKeyframe(S32 trackno, const LLSettingsBase::TrackPosition& old_frame, const LLSettingsBase::TrackPosition& new_frame)
{
if ((trackno < 0) || (trackno >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL;
return false;
}
if (llabs(old_frame - new_frame) < F_APPROXIMATELY_ZERO)
{
return false;
}
CycleTrack_t &track = mDayTracks[trackno];
CycleTrack_t::iterator iter = track.find(old_frame);
if (iter != track.end())
{
LLSettingsBase::ptr_t base = iter->second;
track.erase(iter);
track[llclamp(new_frame, 0.0f, 1.0f)] = base;
track[new_frame] = base;
return true;
}
return false;
}
bool LLSettingsDay::removeTrackKeyframe(S32 trackno, const LLSettingsBase::TrackPosition& frame)
{
if ((trackno < 0) || (trackno >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt get track (#" << trackno << ") out of range!" << LL_ENDL;
return false;
}
CycleTrack_t &track = mDayTracks[trackno];
CycleTrack_t::iterator iter = track.find(frame);
if (iter != track.end())
{
LLSettingsBase::ptr_t base = iter->second;
track.erase(iter);
return true;
}
return false;
}
void LLSettingsDay::setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, const LLSettingsBase::TrackPosition& keyframe)
{
setSettingsAtKeyframe(water, keyframe, TRACK_WATER);
}
LLSettingsWater::ptr_t LLSettingsDay::getWaterAtKeyframe(const LLSettingsBase::TrackPosition& keyframe) const
{
LLSettingsBase* p = getSettingsAtKeyframe(keyframe, TRACK_WATER).get();
return LLSettingsWater::ptr_t((LLSettingsWater*)p);
}
void LLSettingsDay::setSkyAtKeyframe(const LLSettingsSky::ptr_t &sky, const LLSettingsBase::TrackPosition& keyframe, S32 track)
{
if ((track < 1) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL;
return;
}
setSettingsAtKeyframe(sky, keyframe, track);
}
LLSettingsSky::ptr_t LLSettingsDay::getSkyAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const
{
if ((track < 1) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL;
return LLSettingsSky::ptr_t();
}
return PTR_NAMESPACE::dynamic_pointer_cast<LLSettingsSky>(getSettingsAtKeyframe(keyframe, track));
}
void LLSettingsDay::setSettingsAtKeyframe(const LLSettingsBase::ptr_t &settings, const LLSettingsBase::TrackPosition& keyframe, S32 track)
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to set track (#" << track << ") out of range!" << LL_ENDL;
return;
}
std::string type = settings->getSettingsType();
if ((track == TRACK_WATER) && (type != "water"))
{
LL_WARNS("DAYCYCLE") << "Attempt to add frame of type '" << type << "' to water track!" << LL_ENDL;
llassert(type == "water");
return;
}
else if ((track != TRACK_WATER) && (type != "sky"))
{
LL_WARNS("DAYCYCLE") << "Attempt to add frame of type '" << type << "' to sky track!" << LL_ENDL;
llassert(type == "sky");
return;
}
mDayTracks[track][llclamp(keyframe, 0.0f, 1.0f)] = settings;
setDirtyFlag(true);
}
LLSettingsBase::ptr_t LLSettingsDay::getSettingsAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to set sky track (#" << track << ") out of range!" << LL_ENDL;
return LLSettingsBase::ptr_t();
}
// todo: better way to identify keyframes?
CycleTrack_t::const_iterator iter = mDayTracks[track].find(keyframe);
if (iter != mDayTracks[track].end())
{
return iter->second;
}
return LLSettingsBase::ptr_t();
}
LLSettingsDay::CycleTrack_t::value_type LLSettingsDay::getSettingsNearKeyframe(const LLSettingsBase::TrackPosition &keyframe, S32 track, F32 fudge) const
{
if ((track < 0) || (track >= TRACK_MAX))
{
LL_WARNS("DAYCYCLE") << "Attempt to get track (#" << track << ") out of range!" << LL_ENDL;
return CycleTrack_t::value_type(TrackPosition(INVALID_TRACKPOS), LLSettingsBase::ptr_t());
}
if (mDayTracks[track].empty())
{
LL_INFOS("DAYCYCLE") << "Empty track" << LL_ENDL;
return CycleTrack_t::value_type(TrackPosition(INVALID_TRACKPOS), LLSettingsBase::ptr_t());
}
TrackPosition startframe(keyframe - fudge);
if (startframe < 0.0f)
startframe = 1.0f + startframe;
LLSettingsDay::CycleTrack_t collection = const_cast<CycleTrack_t &>(mDayTracks[track]);
CycleTrack_t::iterator it = get_wrapping_atafter(collection, startframe);
F32 dist = get_wrapping_distance(startframe, (*it).first);
CycleTrack_t::iterator next_it = std::next(it);
if ((dist <= DEFAULT_MULTISLIDER_INCREMENT) && next_it != collection.end())
return (*next_it);
else if (dist <= (fudge * 2.0f))
return (*it);
return CycleTrack_t::value_type(TrackPosition(INVALID_TRACKPOS), LLSettingsBase::ptr_t());
}
LLSettingsBase::TrackPosition LLSettingsDay::getUpperBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe)
{
return get_wrapping_atafter(mDayTracks[track], keyframe)->first;
}
LLSettingsBase::TrackPosition LLSettingsDay::getLowerBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe)
{
return get_wrapping_atbefore(mDayTracks[track], keyframe)->first;
}
LLSettingsDay::TrackBound_t LLSettingsDay::getBoundingEntries(LLSettingsDay::CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe)
{
return TrackBound_t(get_wrapping_atbefore(track, keyframe), get_wrapping_atafter(track, keyframe));
}
LLUUID LLSettingsDay::GetDefaultAssetId()
{
return DEFAULT_ASSET_ID;
}
//=========================================================================

View File

@ -0,0 +1,154 @@
/**
* @file llsettingsdaycycle.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_SETTINGS_DAYCYCLE_H
#define LL_SETTINGS_DAYCYCLE_H
#include "llsettingsbase.h"
class LLSettingsWater;
class LLSettingsSky;
// These are alias for LLSettingsWater::ptr_t and LLSettingsSky::ptr_t respectively.
// Here for definitions only.
typedef PTR_NAMESPACE::shared_ptr<LLSettingsWater> LLSettingsWaterPtr_t;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsSky> LLSettingsSkyPtr_t;
class LLSettingsDay : public LLSettingsBase
{
public:
// 32-bit as LLSD only supports that width at present
typedef S32Seconds Seconds;
static const std::string SETTING_KEYID;
static const std::string SETTING_KEYNAME;
static const std::string SETTING_KEYKFRAME;
static const std::string SETTING_KEYHASH;
static const std::string SETTING_TRACKS;
static const std::string SETTING_FRAMES;
static const Seconds MINIMUM_DAYLENGTH;
static const Seconds DEFAULT_DAYLENGTH;
static const Seconds MAXIMUM_DAYLENGTH;
static const Seconds MINIMUM_DAYOFFSET;
static const Seconds DEFAULT_DAYOFFSET;
static const Seconds MAXIMUM_DAYOFFSET;
static const S32 TRACK_WATER;
static const S32 TRACK_GROUND_LEVEL;
static const S32 TRACK_MAX;
static const S32 FRAME_MAX;
static const F32 DEFAULT_FRAME_SLOP_FACTOR;
static const LLUUID DEFAULT_ASSET_ID;
typedef std::map<LLSettingsBase::TrackPosition, LLSettingsBase::ptr_t> CycleTrack_t;
typedef std::vector<CycleTrack_t> CycleList_t;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsDay> ptr_t;
typedef PTR_NAMESPACE::weak_ptr<LLSettingsDay> wptr_t;
typedef std::vector<LLSettingsBase::TrackPosition> KeyframeList_t;
typedef std::pair<CycleTrack_t::iterator, CycleTrack_t::iterator> TrackBound_t;
//---------------------------------------------------------------------
LLSettingsDay(const LLSD &data);
virtual ~LLSettingsDay() { };
bool initialize(bool validate_frames = false);
virtual ptr_t buildClone() const = 0;
virtual ptr_t buildDeepCloneAndUncompress() const = 0;
virtual LLSD getSettings() const SETTINGS_OVERRIDE;
virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_DAYCYCLE; }
//---------------------------------------------------------------------
virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("daycycle"); }
// Settings status
virtual void blend(const LLSettingsBase::ptr_t &other, F64 mix) SETTINGS_OVERRIDE;
static LLSD defaults();
//---------------------------------------------------------------------
KeyframeList_t getTrackKeyframes(S32 track);
bool moveTrackKeyframe(S32 track, const LLSettingsBase::TrackPosition& old_frame, const LLSettingsBase::TrackPosition& new_frame);
bool removeTrackKeyframe(S32 track, const LLSettingsBase::TrackPosition& frame);
void setWaterAtKeyframe(const LLSettingsWaterPtr_t &water, const LLSettingsBase::TrackPosition& keyframe);
LLSettingsWaterPtr_t getWaterAtKeyframe(const LLSettingsBase::TrackPosition& keyframe) const;
void setSkyAtKeyframe(const LLSettingsSkyPtr_t &sky, const LLSettingsBase::TrackPosition& keyframe, S32 track);
LLSettingsSkyPtr_t getSkyAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const;
void setSettingsAtKeyframe(const LLSettingsBase::ptr_t &settings, const LLSettingsBase::TrackPosition& keyframe, S32 track);
LLSettingsBase::ptr_t getSettingsAtKeyframe(const LLSettingsBase::TrackPosition& keyframe, S32 track) const;
CycleTrack_t::value_type getSettingsNearKeyframe(const LLSettingsBase::TrackPosition &keyframe, S32 track, F32 fudge) const;
//---------------------------------------------------------------------
void startDayCycle();
virtual LLSettingsSkyPtr_t getDefaultSky() const = 0;
virtual LLSettingsWaterPtr_t getDefaultWater() const = 0;
virtual LLSettingsSkyPtr_t buildSky(LLSD) const = 0;
virtual LLSettingsWaterPtr_t buildWater(LLSD) const = 0;
void setInitialized(bool value = true) { mInitialized = value; }
CycleTrack_t & getCycleTrack(S32 track);
const CycleTrack_t & getCycleTrackConst(S32 track) const;
bool clearCycleTrack(S32 track);
bool replaceCycleTrack(S32 track, const CycleTrack_t &source);
bool isTrackEmpty(S32 track) const;
virtual validation_list_t getValidationList() const SETTINGS_OVERRIDE;
static validation_list_t validationList();
virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); }
LLSettingsBase::TrackPosition getUpperBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe);
LLSettingsBase::TrackPosition getLowerBoundFrame(S32 track, const LLSettingsBase::TrackPosition& keyframe);
static LLUUID GetDefaultAssetId();
protected:
LLSettingsDay();
virtual void updateSettings() SETTINGS_OVERRIDE;
bool mInitialized;
private:
CycleList_t mDayTracks;
LLSettingsBase::Seconds mLastUpdateTime;
static CycleTrack_t::iterator getEntryAtOrBefore(CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe);
static CycleTrack_t::iterator getEntryAtOrAfter(CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe);
TrackBound_t getBoundingEntries(CycleTrack_t &track, const LLSettingsBase::TrackPosition& keyframe);
};
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,374 @@
/**
* @file llsettingssky.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_SETTINGS_SKY_H
#define LL_SETTINGS_SKY_H
#include "llsettingsbase.h"
#include "v4coloru.h"
const F32 EARTH_RADIUS = 6.370e6f;
const F32 SUN_RADIUS = 695.508e6f;
const F32 SUN_DIST = 149598.260e6f;
const F32 MOON_RADIUS = 1.737e6f;
const F32 MOON_DIST = 384.400e6f;
class LLSettingsSky: public LLSettingsBase
{
public:
static const std::string SETTING_AMBIENT;
static const std::string SETTING_BLOOM_TEXTUREID;
static const std::string SETTING_RAINBOW_TEXTUREID;
static const std::string SETTING_HALO_TEXTUREID;
static const std::string SETTING_BLUE_DENSITY;
static const std::string SETTING_BLUE_HORIZON;
static const std::string SETTING_DENSITY_MULTIPLIER;
static const std::string SETTING_DISTANCE_MULTIPLIER;
static const std::string SETTING_HAZE_DENSITY;
static const std::string SETTING_HAZE_HORIZON;
static const std::string SETTING_CLOUD_COLOR;
static const std::string SETTING_CLOUD_POS_DENSITY1;
static const std::string SETTING_CLOUD_POS_DENSITY2;
static const std::string SETTING_CLOUD_SCALE;
static const std::string SETTING_CLOUD_SCROLL_RATE;
static const std::string SETTING_CLOUD_SHADOW;
static const std::string SETTING_CLOUD_TEXTUREID;
static const std::string SETTING_CLOUD_VARIANCE;
static const std::string SETTING_DOME_OFFSET;
static const std::string SETTING_DOME_RADIUS;
static const std::string SETTING_GAMMA;
static const std::string SETTING_GLOW;
static const std::string SETTING_LIGHT_NORMAL;
static const std::string SETTING_MAX_Y;
static const std::string SETTING_MOON_ROTATION;
static const std::string SETTING_MOON_SCALE;
static const std::string SETTING_MOON_TEXTUREID;
static const std::string SETTING_MOON_BRIGHTNESS;
static const std::string SETTING_STAR_BRIGHTNESS;
static const std::string SETTING_SUNLIGHT_COLOR;
static const std::string SETTING_SUN_ROTATION;
static const std::string SETTING_SUN_SCALE;
static const std::string SETTING_SUN_TEXTUREID;
static const std::string SETTING_PLANET_RADIUS;
static const std::string SETTING_SKY_BOTTOM_RADIUS;
static const std::string SETTING_SKY_TOP_RADIUS;
static const std::string SETTING_SUN_ARC_RADIANS;
static const std::string SETTING_MIE_ANISOTROPY_FACTOR;
static const std::string SETTING_RAYLEIGH_CONFIG;
static const std::string SETTING_MIE_CONFIG;
static const std::string SETTING_ABSORPTION_CONFIG;
static const std::string KEY_DENSITY_PROFILE;
static const std::string SETTING_DENSITY_PROFILE_WIDTH;
static const std::string SETTING_DENSITY_PROFILE_EXP_TERM;
static const std::string SETTING_DENSITY_PROFILE_EXP_SCALE_FACTOR;
static const std::string SETTING_DENSITY_PROFILE_LINEAR_TERM;
static const std::string SETTING_DENSITY_PROFILE_CONSTANT_TERM;
static const std::string SETTING_SKY_MOISTURE_LEVEL;
static const std::string SETTING_SKY_DROPLET_RADIUS;
static const std::string SETTING_SKY_ICE_LEVEL;
static const std::string SETTING_LEGACY_HAZE;
static const LLUUID DEFAULT_ASSET_ID;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsSky> ptr_t;
//---------------------------------------------------------------------
LLSettingsSky(const LLSD &data);
virtual ~LLSettingsSky() { };
virtual ptr_t buildClone() const = 0;
//---------------------------------------------------------------------
virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("sky"); }
virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_SKY; }
// Settings status
virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE;
virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE;
void replaceWithSky(LLSettingsSky::ptr_t pother);
static LLSD defaults(const LLSettingsBase::TrackPosition& position = 0.0f);
F32 getPlanetRadius() const;
F32 getSkyBottomRadius() const;
F32 getSkyTopRadius() const;
F32 getSunArcRadians() const;
F32 getMieAnisotropy() const;
F32 getSkyMoistureLevel() const;
F32 getSkyDropletRadius() const;
F32 getSkyIceLevel() const;
// Return first (only) profile layer represented in LLSD
LLSD getRayleighConfig() const;
LLSD getMieConfig() const;
LLSD getAbsorptionConfig() const;
// Return entire LLSDArray of profile layers represented in LLSD
LLSD getRayleighConfigs() const;
LLSD getMieConfigs() const;
LLSD getAbsorptionConfigs() const;
LLUUID getBloomTextureId() const;
LLUUID getRainbowTextureId() const;
LLUUID getHaloTextureId() const;
void setRayleighConfigs(const LLSD& rayleighConfig);
void setMieConfigs(const LLSD& mieConfig);
void setAbsorptionConfigs(const LLSD& absorptionConfig);
void setPlanetRadius(F32 radius);
void setSkyBottomRadius(F32 radius);
void setSkyTopRadius(F32 radius);
void setSunArcRadians(F32 radians);
void setMieAnisotropy(F32 aniso_factor);
void setSkyMoistureLevel(F32 moisture_level);
void setSkyDropletRadius(F32 radius);
void setSkyIceLevel(F32 ice_level);
//---------------------------------------------------------------------
LLColor3 getAmbientColor() const;
void setAmbientColor(const LLColor3 &val);
LLColor3 getCloudColor() const;
void setCloudColor(const LLColor3 &val);
LLUUID getCloudNoiseTextureId() const;
void setCloudNoiseTextureId(const LLUUID &id);
LLColor3 getCloudPosDensity1() const;
void setCloudPosDensity1(const LLColor3 &val);
LLColor3 getCloudPosDensity2() const;
void setCloudPosDensity2(const LLColor3 &val);
F32 getCloudScale() const;
void setCloudScale(F32 val);
LLVector2 getCloudScrollRate() const;
void setCloudScrollRate(const LLVector2 &val);
void setCloudScrollRateX(F32 val);
void setCloudScrollRateY(F32 val);
F32 getCloudShadow() const;
void setCloudShadow(F32 val);
F32 getCloudVariance() const;
void setCloudVariance(F32 val);
F32 getDomeOffset() const;
F32 getDomeRadius() const;
F32 getGamma() const;
void setGamma(F32 val);
LLColor3 getGlow() const;
void setGlow(const LLColor3 &val);
F32 getMaxY() const;
void setMaxY(F32 val);
LLQuaternion getMoonRotation() const;
void setMoonRotation(const LLQuaternion &val);
F32 getMoonScale() const;
void setMoonScale(F32 val);
LLUUID getMoonTextureId() const;
void setMoonTextureId(LLUUID id);
F32 getMoonBrightness() const;
void setMoonBrightness(F32 brightness_factor);
F32 getStarBrightness() const;
void setStarBrightness(F32 val);
LLColor3 getSunlightColor() const;
void setSunlightColor(const LLColor3 &val);
LLQuaternion getSunRotation() const;
void setSunRotation(const LLQuaternion &val) ;
F32 getSunScale() const;
void setSunScale(F32 val);
LLUUID getSunTextureId() const;
void setSunTextureId(LLUUID id);
//=====================================================================
// transient properties used in animations.
LLUUID getNextSunTextureId() const;
LLUUID getNextMoonTextureId() const;
LLUUID getNextCloudNoiseTextureId() const;
LLUUID getNextBloomTextureId() const;
//=====================================================================
virtual void loadTextures() { };
//=====================================================================
virtual validation_list_t getValidationList() const SETTINGS_OVERRIDE;
static validation_list_t validationList();
static LLSD translateLegacySettings(const LLSD& legacy);
// LEGACY_ATMOSPHERICS
static LLSD translateLegacyHazeSettings(const LLSD& legacy);
LLColor3 getLightAttenuation(F32 distance) const;
LLColor3 getLightTransmittance(F32 distance) const;
LLColor3 getTotalDensity() const;
LLColor3 gammaCorrect(const LLColor3& in) const;
LLColor3 getBlueDensity() const;
LLColor3 getBlueHorizon() const;
F32 getHazeDensity() const;
F32 getHazeHorizon() const;
F32 getDensityMultiplier() const;
F32 getDistanceMultiplier() const;
void setBlueDensity(const LLColor3 &val);
void setBlueHorizon(const LLColor3 &val);
void setDensityMultiplier(F32 val);
void setDistanceMultiplier(F32 val);
void setHazeDensity(F32 val);
void setHazeHorizon(F32 val);
// Internal/calculated settings
bool getIsSunUp() const;
bool getIsMoonUp() const;
// determines how much the haze glow effect occurs in rendering
F32 getSunMoonGlowFactor() const;
LLVector3 getLightDirection() const;
LLColor3 getLightDiffuse() const;
LLVector3 getSunDirection() const;
LLVector3 getMoonDirection() const;
// color based on brightness
LLColor3 getMoonlightColor() const;
LLColor4 getMoonAmbient() const;
LLColor3 getMoonDiffuse() const;
LLColor4 getSunAmbient() const;
LLColor3 getSunDiffuse() const;
LLColor4 getTotalAmbient() const;
LLColor4 getHazeColor() const;
LLColor3 getSunlightColorClamped() const;
LLColor3 getAmbientColorClamped() const;
virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); }
static LLUUID GetDefaultAssetId();
static LLUUID GetDefaultSunTextureId();
static LLUUID GetBlankSunTextureId();
static LLUUID GetDefaultMoonTextureId();
static LLUUID GetDefaultCloudNoiseTextureId();
static LLUUID GetDefaultBloomTextureId();
static LLUUID GetDefaultRainbowTextureId();
static LLUUID GetDefaultHaloTextureId();
static LLSD createDensityProfileLayer(
F32 width,
F32 exponential_term,
F32 exponential_scale_factor,
F32 linear_term,
F32 constant_term,
F32 aniso_factor = 0.0f);
static LLSD createSingleLayerDensityProfile(
F32 width,
F32 exponential_term,
F32 exponential_scale_factor,
F32 linear_term,
F32 constant_term,
F32 aniso_factor = 0.0f);
virtual void updateSettings() SETTINGS_OVERRIDE;
protected:
static const std::string SETTING_LEGACY_EAST_ANGLE;
static const std::string SETTING_LEGACY_ENABLE_CLOUD_SCROLL;
static const std::string SETTING_LEGACY_SUN_ANGLE;
LLSettingsSky();
virtual stringset_t getSlerpKeys() const SETTINGS_OVERRIDE;
virtual stringset_t getSkipInterpolateKeys() const SETTINGS_OVERRIDE;
LLUUID mNextSunTextureId;
LLUUID mNextMoonTextureId;
LLUUID mNextCloudTextureId;
LLUUID mNextBloomTextureId;
LLUUID mNextRainbowTextureId;
LLUUID mNextHaloTextureId;
private:
static LLSD rayleighConfigDefault();
static LLSD absorptionConfigDefault();
static LLSD mieConfigDefault();
LLColor3 getColor(const std::string& key, const LLColor3& default_value) const;
F32 getFloat(const std::string& key, F32 default_value) const;
void calculateHeavenlyBodyPositions() const;
void calculateLightSettings() const;
void clampColor(LLColor3& color, F32 gamma, const F32 scale = 1.0f) const;
mutable LLVector3 mSunDirection;
mutable LLVector3 mMoonDirection;
mutable LLVector3 mLightDirection;
static const F32 DOME_RADIUS;
static const F32 DOME_OFFSET;
mutable LLColor4 mMoonAmbient;
mutable LLColor3 mMoonDiffuse;
mutable LLColor4 mSunAmbient;
mutable LLColor3 mSunDiffuse;
mutable LLColor4 mTotalAmbient;
mutable LLColor4 mHazeColor;
typedef std::map<std::string, S32> mapNameToUniformId_t;
static mapNameToUniformId_t sNameToUniformMapping;
};
#endif

View File

@ -0,0 +1,304 @@
/**
* @file llsettingswater.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "llsettingswater.h"
#include <algorithm>
#include <boost/make_shared.hpp>
#include "lltrace.h"
#include "llfasttimer.h"
#include "v3colorutil.h"
#include "indra_constants.h"
//=========================================================================
namespace
{
LLTrace::BlockTimerStatHandle FTM_BLEND_WATERVALUES("Blending Water Environment");
LLTrace::BlockTimerStatHandle FTM_UPDATE_WATERVALUES("Update Water Environment");
}
//=========================================================================
const std::string LLSettingsWater::SETTING_BLUR_MULTIPLIER("blur_multiplier");
const std::string LLSettingsWater::SETTING_FOG_COLOR("water_fog_color");
const std::string LLSettingsWater::SETTING_FOG_DENSITY("water_fog_density");
const std::string LLSettingsWater::SETTING_FOG_MOD("underwater_fog_mod");
const std::string LLSettingsWater::SETTING_FRESNEL_OFFSET("fresnel_offset");
const std::string LLSettingsWater::SETTING_FRESNEL_SCALE("fresnel_scale");
const std::string LLSettingsWater::SETTING_TRANSPARENT_TEXTURE("transparent_texture");
const std::string LLSettingsWater::SETTING_NORMAL_MAP("normal_map");
const std::string LLSettingsWater::SETTING_NORMAL_SCALE("normal_scale");
const std::string LLSettingsWater::SETTING_SCALE_ABOVE("scale_above");
const std::string LLSettingsWater::SETTING_SCALE_BELOW("scale_below");
const std::string LLSettingsWater::SETTING_WAVE1_DIR("wave1_direction");
const std::string LLSettingsWater::SETTING_WAVE2_DIR("wave2_direction");
const std::string LLSettingsWater::SETTING_LEGACY_BLUR_MULTIPLIER("blurMultiplier");
const std::string LLSettingsWater::SETTING_LEGACY_FOG_COLOR("waterFogColor");
const std::string LLSettingsWater::SETTING_LEGACY_FOG_DENSITY("waterFogDensity");
const std::string LLSettingsWater::SETTING_LEGACY_FOG_MOD("underWaterFogMod");
const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_OFFSET("fresnelOffset");
const std::string LLSettingsWater::SETTING_LEGACY_FRESNEL_SCALE("fresnelScale");
const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_MAP("normalMap");
const std::string LLSettingsWater::SETTING_LEGACY_NORMAL_SCALE("normScale");
const std::string LLSettingsWater::SETTING_LEGACY_SCALE_ABOVE("scaleAbove");
const std::string LLSettingsWater::SETTING_LEGACY_SCALE_BELOW("scaleBelow");
const std::string LLSettingsWater::SETTING_LEGACY_WAVE1_DIR("wave1Dir");
const std::string LLSettingsWater::SETTING_LEGACY_WAVE2_DIR("wave2Dir");
const LLUUID LLSettingsWater::DEFAULT_ASSET_ID("59d1a851-47e7-0e5f-1ed7-6b715154f41a");
static const LLUUID DEFAULT_TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004");
static const LLUUID DEFAULT_OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");
//=========================================================================
LLSettingsWater::LLSettingsWater(const LLSD &data) :
LLSettingsBase(data),
mNextNormalMapID()
{
}
LLSettingsWater::LLSettingsWater() :
LLSettingsBase(),
mNextNormalMapID()
{
}
//=========================================================================
LLSD LLSettingsWater::defaults(const LLSettingsBase::TrackPosition& position)
{
static LLSD dfltsetting;
if (dfltsetting.size() == 0)
{
// give the normal scale offset some variability over track time...
F32 normal_scale_offset = (position * 0.5f) - 0.25f;
// Magic constants copied form defaults.xml
dfltsetting[SETTING_BLUR_MULTIPLIER] = LLSD::Real(0.04000f);
dfltsetting[SETTING_FOG_COLOR] = LLColor3(0.0156f, 0.1490f, 0.2509f).getValue();
dfltsetting[SETTING_FOG_DENSITY] = LLSD::Real(2.0f);
dfltsetting[SETTING_FOG_MOD] = LLSD::Real(0.25f);
dfltsetting[SETTING_FRESNEL_OFFSET] = LLSD::Real(0.5f);
dfltsetting[SETTING_FRESNEL_SCALE] = LLSD::Real(0.3999);
dfltsetting[SETTING_TRANSPARENT_TEXTURE] = GetDefaultTransparentTextureAssetId();
dfltsetting[SETTING_NORMAL_MAP] = GetDefaultWaterNormalAssetId();
dfltsetting[SETTING_NORMAL_SCALE] = LLVector3(2.0f + normal_scale_offset, 2.0f + normal_scale_offset, 2.0f + normal_scale_offset).getValue();
dfltsetting[SETTING_SCALE_ABOVE] = LLSD::Real(0.0299f);
dfltsetting[SETTING_SCALE_BELOW] = LLSD::Real(0.2000f);
dfltsetting[SETTING_WAVE1_DIR] = LLVector2(1.04999f, -0.42000f).getValue();
dfltsetting[SETTING_WAVE2_DIR] = LLVector2(1.10999f, -1.16000f).getValue();
dfltsetting[SETTING_TYPE] = "water";
}
return dfltsetting;
}
LLSD LLSettingsWater::translateLegacySettings(LLSD legacy)
{
bool converted_something(false);
LLSD newsettings(defaults());
if (legacy.has(SETTING_LEGACY_BLUR_MULTIPLIER))
{
newsettings[SETTING_BLUR_MULTIPLIER] = LLSD::Real(legacy[SETTING_LEGACY_BLUR_MULTIPLIER].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FOG_COLOR))
{
newsettings[SETTING_FOG_COLOR] = LLColor3(legacy[SETTING_LEGACY_FOG_COLOR]).getValue();
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FOG_DENSITY))
{
newsettings[SETTING_FOG_DENSITY] = LLSD::Real(legacy[SETTING_LEGACY_FOG_DENSITY]);
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FOG_MOD))
{
newsettings[SETTING_FOG_MOD] = LLSD::Real(legacy[SETTING_LEGACY_FOG_MOD].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FRESNEL_OFFSET))
{
newsettings[SETTING_FRESNEL_OFFSET] = LLSD::Real(legacy[SETTING_LEGACY_FRESNEL_OFFSET].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_FRESNEL_SCALE))
{
newsettings[SETTING_FRESNEL_SCALE] = LLSD::Real(legacy[SETTING_LEGACY_FRESNEL_SCALE].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_NORMAL_MAP))
{
newsettings[SETTING_NORMAL_MAP] = LLSD::UUID(legacy[SETTING_LEGACY_NORMAL_MAP].asUUID());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_NORMAL_SCALE))
{
newsettings[SETTING_NORMAL_SCALE] = LLVector3(legacy[SETTING_LEGACY_NORMAL_SCALE]).getValue();
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_SCALE_ABOVE))
{
newsettings[SETTING_SCALE_ABOVE] = LLSD::Real(legacy[SETTING_LEGACY_SCALE_ABOVE].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_SCALE_BELOW))
{
newsettings[SETTING_SCALE_BELOW] = LLSD::Real(legacy[SETTING_LEGACY_SCALE_BELOW].asReal());
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_WAVE1_DIR))
{
newsettings[SETTING_WAVE1_DIR] = LLVector2(legacy[SETTING_LEGACY_WAVE1_DIR]).getValue();
converted_something |= true;
}
if (legacy.has(SETTING_LEGACY_WAVE2_DIR))
{
newsettings[SETTING_WAVE2_DIR] = LLVector2(legacy[SETTING_LEGACY_WAVE2_DIR]).getValue();
converted_something |= true;
}
if (!converted_something)
return LLSD();
return newsettings;
}
void LLSettingsWater::blend(const LLSettingsBase::ptr_t &end, F64 blendf)
{
LLSettingsWater::ptr_t other = PTR_NAMESPACE::static_pointer_cast<LLSettingsWater>(end);
if (other)
{
LLSD blenddata = interpolateSDMap(mSettings, other->mSettings, other->getParameterMap(), blendf);
replaceSettings(blenddata);
mNextNormalMapID = other->getNormalMapID();
mNextTransparentTextureID = other->getTransparentTextureID();
}
else
{
LL_WARNS("SETTINGS") << "Could not cast end settings to water. No blend performed." << LL_ENDL;
}
setBlendFactor(blendf);
}
void LLSettingsWater::replaceSettings(LLSD settings)
{
LLSettingsBase::replaceSettings(settings);
mNextNormalMapID.setNull();
mNextTransparentTextureID.setNull();
}
void LLSettingsWater::replaceWithWater(LLSettingsWater::ptr_t other)
{
replaceWith(other);
mNextNormalMapID = other->mNextNormalMapID;
mNextTransparentTextureID = other->mNextTransparentTextureID;
}
LLSettingsWater::validation_list_t LLSettingsWater::getValidationList() const
{
return LLSettingsWater::validationList();
}
LLSettingsWater::validation_list_t LLSettingsWater::validationList()
{
static validation_list_t validation;
if (validation.empty())
{ // Note the use of LLSD(LLSDArray()()()...) This is due to an issue with the
// copy constructor for LLSDArray. Directly binding the LLSDArray as
// a parameter without first wrapping it in a pure LLSD object will result
// in deeply nested arrays like this [[[[[[[[[[v1,v2,v3]]]]]]]]]]
validation.push_back(Validator(SETTING_BLUR_MULTIPLIER, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(-0.5f)(0.5f)))));
validation.push_back(Validator(SETTING_FOG_COLOR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)(1.0f)),
LLSD(LLSDArray(1.0f)(1.0f)(1.0f)(1.0f)))));
validation.push_back(Validator(SETTING_FOG_DENSITY, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(-10.0f)(10.0f)))));
validation.push_back(Validator(SETTING_FOG_MOD, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(20.0f)))));
validation.push_back(Validator(SETTING_FRESNEL_OFFSET, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_FRESNEL_SCALE, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(1.0f)))));
validation.push_back(Validator(SETTING_NORMAL_MAP, true, LLSD::TypeUUID));
validation.push_back(Validator(SETTING_NORMAL_SCALE, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1,
LLSD(LLSDArray(0.0f)(0.0f)(0.0f)),
LLSD(LLSDArray(10.0f)(10.0f)(10.0f)))));
validation.push_back(Validator(SETTING_SCALE_ABOVE, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(3.0f)))));
validation.push_back(Validator(SETTING_SCALE_BELOW, true, LLSD::TypeReal,
boost::bind(&Validator::verifyFloatRange, _1, LLSD(LLSDArray(0.0f)(3.0f)))));
validation.push_back(Validator(SETTING_WAVE1_DIR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1,
LLSD(LLSDArray(-20.0f)(-20.0f)),
LLSD(LLSDArray(20.0f)(20.0f)))));
validation.push_back(Validator(SETTING_WAVE2_DIR, true, LLSD::TypeArray,
boost::bind(&Validator::verifyVectorMinMax, _1,
LLSD(LLSDArray(-20.0f)(-20.0f)),
LLSD(LLSDArray(20.0f)(20.0f)))));
}
return validation;
}
LLUUID LLSettingsWater::GetDefaultAssetId()
{
return DEFAULT_ASSET_ID;
}
LLUUID LLSettingsWater::GetDefaultWaterNormalAssetId()
{
return DEFAULT_WATER_NORMAL;
}
LLUUID LLSettingsWater::GetDefaultTransparentTextureAssetId()
{
return DEFAULT_TRANSPARENT_WATER_TEXTURE;
}
LLUUID LLSettingsWater::GetDefaultOpaqueTextureAssetId()
{
return DEFAULT_OPAQUE_WATER_TEXTURE;
}
F32 LLSettingsWater::getModifiedWaterFogDensity(bool underwater) const
{
F32 fog_density = getWaterFogDensity();
F32 underwater_fog_mod = getFogMod();
if (underwater && underwater_fog_mod > 0.0f)
{
underwater_fog_mod = llclamp(underwater_fog_mod, 0.0f, 10.0f);
fog_density = pow(fog_density, underwater_fog_mod);
}
return fog_density;
}

View File

@ -0,0 +1,249 @@
/**
* @file llsettingssky.h
* @author optional
* @brief A base class for asset based settings groups.
*
* $LicenseInfo:2011&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2017, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_SETTINGS_WATER_H
#define LL_SETTINGS_WATER_H
#include "llsettingsbase.h"
class LLSettingsWater : public LLSettingsBase
{
public:
static const std::string SETTING_BLUR_MULTIPLIER;
static const std::string SETTING_FOG_COLOR;
static const std::string SETTING_FOG_DENSITY;
static const std::string SETTING_FOG_MOD;
static const std::string SETTING_FRESNEL_OFFSET;
static const std::string SETTING_FRESNEL_SCALE;
static const std::string SETTING_TRANSPARENT_TEXTURE;
static const std::string SETTING_NORMAL_MAP;
static const std::string SETTING_NORMAL_SCALE;
static const std::string SETTING_SCALE_ABOVE;
static const std::string SETTING_SCALE_BELOW;
static const std::string SETTING_WAVE1_DIR;
static const std::string SETTING_WAVE2_DIR;
static const LLUUID DEFAULT_ASSET_ID;
typedef PTR_NAMESPACE::shared_ptr<LLSettingsWater> ptr_t;
//---------------------------------------------------------------------
LLSettingsWater(const LLSD &data);
virtual ~LLSettingsWater() { };
virtual ptr_t buildClone() const = 0;
//---------------------------------------------------------------------
virtual std::string getSettingsType() const SETTINGS_OVERRIDE { return std::string("water"); }
virtual LLSettingsType::type_e getSettingsTypeValue() const SETTINGS_OVERRIDE { return LLSettingsType::ST_WATER; }
// Settings status
virtual void blend(const LLSettingsBase::ptr_t &end, F64 blendf) SETTINGS_OVERRIDE;
virtual void replaceSettings(LLSD settings) SETTINGS_OVERRIDE;
void replaceWithWater(LLSettingsWater::ptr_t other);
static LLSD defaults(const LLSettingsBase::TrackPosition& position = 0.0f);
//---------------------------------------------------------------------
F32 getBlurMultiplier() const
{
return mSettings[SETTING_BLUR_MULTIPLIER].asReal();
}
void setBlurMultiplier(F32 val)
{
setValue(SETTING_BLUR_MULTIPLIER, val);
}
LLColor3 getWaterFogColor() const
{
return LLColor3(mSettings[SETTING_FOG_COLOR]);
}
void setWaterFogColor(LLColor3 val)
{
setValue(SETTING_FOG_COLOR, val);
}
F32 getWaterFogDensity() const
{
return mSettings[SETTING_FOG_DENSITY].asReal();
}
F32 getModifiedWaterFogDensity(bool underwater) const;
void setWaterFogDensity(F32 val)
{
setValue(SETTING_FOG_DENSITY, val);
}
F32 getFogMod() const
{
return mSettings[SETTING_FOG_MOD].asReal();
}
void setFogMod(F32 val)
{
setValue(SETTING_FOG_MOD, val);
}
F32 getFresnelOffset() const
{
return mSettings[SETTING_FRESNEL_OFFSET].asReal();
}
void setFresnelOffset(F32 val)
{
setValue(SETTING_FRESNEL_OFFSET, val);
}
F32 getFresnelScale() const
{
return mSettings[SETTING_FRESNEL_SCALE].asReal();
}
void setFresnelScale(F32 val)
{
setValue(SETTING_FRESNEL_SCALE, val);
}
LLUUID getTransparentTextureID() const
{
return mSettings[SETTING_TRANSPARENT_TEXTURE].asUUID();
}
void setTransparentTextureID(LLUUID val)
{
setValue(SETTING_TRANSPARENT_TEXTURE, val);
}
LLUUID getNormalMapID() const
{
return mSettings[SETTING_NORMAL_MAP].asUUID();
}
void setNormalMapID(LLUUID val)
{
setValue(SETTING_NORMAL_MAP, val);
}
LLVector3 getNormalScale() const
{
return LLVector3(mSettings[SETTING_NORMAL_SCALE]);
}
void setNormalScale(LLVector3 val)
{
setValue(SETTING_NORMAL_SCALE, val);
}
F32 getScaleAbove() const
{
return mSettings[SETTING_SCALE_ABOVE].asReal();
}
void setScaleAbove(F32 val)
{
setValue(SETTING_SCALE_ABOVE, val);
}
F32 getScaleBelow() const
{
return mSettings[SETTING_SCALE_BELOW].asReal();
}
void setScaleBelow(F32 val)
{
setValue(SETTING_SCALE_BELOW, val);
}
LLVector2 getWave1Dir() const
{
return LLVector2(mSettings[SETTING_WAVE1_DIR]);
}
void setWave1Dir(LLVector2 val)
{
setValue(SETTING_WAVE1_DIR, val);
}
LLVector2 getWave2Dir() const
{
return LLVector2(mSettings[SETTING_WAVE2_DIR]);
}
void setWave2Dir(LLVector2 val)
{
setValue(SETTING_WAVE2_DIR, val);
}
//-------------------------------------------
LLUUID getNextNormalMapID() const
{
return mNextNormalMapID;
}
LLUUID getNextTransparentTextureID() const
{
return mNextTransparentTextureID;
}
virtual validation_list_t getValidationList() const SETTINGS_OVERRIDE;
static validation_list_t validationList();
static LLSD translateLegacySettings(LLSD legacy);
virtual LLSettingsBase::ptr_t buildDerivedClone() const SETTINGS_OVERRIDE { return buildClone(); }
static LLUUID GetDefaultAssetId();
static LLUUID GetDefaultWaterNormalAssetId();
static LLUUID GetDefaultTransparentTextureAssetId();
static LLUUID GetDefaultOpaqueTextureAssetId();
protected:
static const std::string SETTING_LEGACY_BLUR_MULTIPLIER;
static const std::string SETTING_LEGACY_FOG_COLOR;
static const std::string SETTING_LEGACY_FOG_DENSITY;
static const std::string SETTING_LEGACY_FOG_MOD;
static const std::string SETTING_LEGACY_FRESNEL_OFFSET;
static const std::string SETTING_LEGACY_FRESNEL_SCALE;
static const std::string SETTING_LEGACY_NORMAL_MAP;
static const std::string SETTING_LEGACY_NORMAL_SCALE;
static const std::string SETTING_LEGACY_SCALE_ABOVE;
static const std::string SETTING_LEGACY_SCALE_BELOW;
static const std::string SETTING_LEGACY_WAVE1_DIR;
static const std::string SETTING_LEGACY_WAVE2_DIR;
LLSettingsWater();
LLUUID mNextTransparentTextureID;
LLUUID mNextNormalMapID;
};
#endif

View File

@ -90,6 +90,7 @@ set(llmath_HEADER_FILES
raytrace.h
v2math.h
v3color.h
v3colorutil.h
v3dmath.h
v3math.h
v4color.h

View File

@ -93,6 +93,11 @@ F32 LLCamera::getMaxView() const
: MAX_FIELD_OF_VIEW; // narrow views
}
LLPlane LLCamera::getUserClipPlane()
{
return mAgentPlanes[AGENT_PLANE_USER_CLIP];
}
// ---------------- LLCamera::setFoo() member functions ----------------
void LLCamera::setUserClipPlane(LLPlane& plane)

View File

@ -154,6 +154,7 @@ public:
bool isChanged(); //check if mAgentPlanes changed since last frame.
LLPlane getUserClipPlane();
void setUserClipPlane(LLPlane& plane);
void disableUserClipPlane();
virtual void setView(F32 vertical_fov_rads);

View File

@ -34,6 +34,20 @@
#include "llquaternion.h"
#include "llcoordframe.h"
#define CHECK_FINITE(var) \
if (!var.isFinite()) \
{ \
LL_WARNS() << "Non Finite " << std::string(#var) << LL_ENDL; \
reset(); \
}
#define CHECK_FINITE_OBJ() \
if (!isFinite()) \
{ \
LL_WARNS() << "Non Finite in LLCoordFrame " << LL_ENDL; \
reset(); \
}
#ifndef X_AXIS
#define X_AXIS 1.0f,0.0f,0.0f
#define Y_AXIS 0.0f,1.0f,0.0f
@ -56,11 +70,7 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin) :
mYAxis(Y_AXIS),
mZAxis(Z_AXIS)
{
if( !mOrigin.isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
}
CHECK_FINITE(mOrigin);
}
LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLVector3 &direction) :
@ -68,11 +78,7 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLVector3 &direction)
{
lookDir(direction);
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
LLCoordFrame::LLCoordFrame(const LLVector3 &x_axis,
@ -83,11 +89,7 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &x_axis,
mYAxis(y_axis),
mZAxis(z_axis)
{
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
LLCoordFrame::LLCoordFrame(const LLVector3 &origin,
@ -99,11 +101,7 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin,
mYAxis(y_axis),
mZAxis(z_axis)
{
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
@ -114,11 +112,7 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin,
mYAxis(rotation.mMatrix[VY]),
mZAxis(rotation.mMatrix[VZ])
{
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
LLCoordFrame::LLCoordFrame(const LLQuaternion &q) :
@ -129,11 +123,7 @@ LLCoordFrame::LLCoordFrame(const LLQuaternion &q) :
mYAxis.setVec(rotation_matrix.mMatrix[VY]);
mZAxis.setVec(rotation_matrix.mMatrix[VZ]);
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLQuaternion &q) :
@ -144,11 +134,7 @@ LLCoordFrame::LLCoordFrame(const LLVector3 &origin, const LLQuaternion &q) :
mYAxis.setVec(rotation_matrix.mMatrix[VY]);
mZAxis.setVec(rotation_matrix.mMatrix[VZ]);
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
LLCoordFrame::LLCoordFrame(const LLMatrix4 &mat) :
@ -157,11 +143,7 @@ LLCoordFrame::LLCoordFrame(const LLMatrix4 &mat) :
mYAxis(mat.mMatrix[VY]),
mZAxis(mat.mMatrix[VZ])
{
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
@ -173,11 +155,7 @@ LLCoordFrame::LLCoordFrame(const F32 *origin, const F32 *rotation) :
mYAxis(rotation+3*VY),
mZAxis(rotation+3*VZ)
{
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
*/
@ -188,11 +166,7 @@ LLCoordFrame::LLCoordFrame(const F32 *origin_and_rotation) :
mYAxis(origin_and_rotation + 3*(VY+1)),
mZAxis(origin_and_rotation + 3*(VZ+1))
{
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::LLCoordFrame()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
*/
@ -217,21 +191,13 @@ void LLCoordFrame::setOrigin(F32 x, F32 y, F32 z)
{
mOrigin.setVec(x, y, z);
if( !mOrigin.isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::setOrigin()" << LL_ENDL;
}
CHECK_FINITE(mOrigin);
}
void LLCoordFrame::setOrigin(const LLVector3 &new_origin)
{
mOrigin = new_origin;
if( !mOrigin.isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::setOrigin()" << LL_ENDL;
}
CHECK_FINITE(mOrigin);
}
void LLCoordFrame::setOrigin(const F32 *origin)
@ -239,23 +205,13 @@ void LLCoordFrame::setOrigin(const F32 *origin)
mOrigin.mV[VX] = *(origin + VX);
mOrigin.mV[VY] = *(origin + VY);
mOrigin.mV[VZ] = *(origin + VZ);
if( !mOrigin.isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::setOrigin()" << LL_ENDL;
}
CHECK_FINITE(mOrigin);
}
void LLCoordFrame::setOrigin(const LLCoordFrame &frame)
{
mOrigin = frame.getOrigin();
if( !mOrigin.isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::setOrigin()" << LL_ENDL;
}
CHECK_FINITE(mOrigin);
}
// setAxes() member functions set the axes, and assume that
@ -268,11 +224,7 @@ void LLCoordFrame::setAxes(const LLVector3 &x_axis,
mXAxis = x_axis;
mYAxis = y_axis;
mZAxis = z_axis;
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::setAxes()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
@ -281,11 +233,7 @@ void LLCoordFrame::setAxes(const LLMatrix3 &rotation_matrix)
mXAxis.setVec(rotation_matrix.mMatrix[VX]);
mYAxis.setVec(rotation_matrix.mMatrix[VY]);
mZAxis.setVec(rotation_matrix.mMatrix[VZ]);
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::setAxes()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
@ -293,11 +241,7 @@ void LLCoordFrame::setAxes(const LLQuaternion &q )
{
LLMatrix3 rotation_matrix(q);
setAxes(rotation_matrix);
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::setAxes()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
@ -313,11 +257,7 @@ void LLCoordFrame::setAxes( const F32 *rotation_matrix )
mZAxis.mV[VY] = *(rotation_matrix + 3*VZ + VY);
mZAxis.mV[VZ] = *(rotation_matrix + 3*VZ + VZ);
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::setAxes()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
@ -326,40 +266,22 @@ void LLCoordFrame::setAxes(const LLCoordFrame &frame)
mXAxis = frame.getXAxis();
mYAxis = frame.getYAxis();
mZAxis = frame.getZAxis();
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::setAxes()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
// translate() member functions move mOrigin to a relative position
void LLCoordFrame::translate(F32 x, F32 y, F32 z)
{
mOrigin.mV[VX] += x;
mOrigin.mV[VY] += y;
mOrigin.mV[VZ] += z;
if( !mOrigin.isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::translate()" << LL_ENDL;
}
CHECK_FINITE(mOrigin);
}
void LLCoordFrame::translate(const LLVector3 &v)
{
mOrigin += v;
if( !mOrigin.isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::translate()" << LL_ENDL;
}
CHECK_FINITE(mOrigin);
}
@ -368,12 +290,7 @@ void LLCoordFrame::translate(const F32 *origin)
mOrigin.mV[VX] += *(origin + VX);
mOrigin.mV[VY] += *(origin + VY);
mOrigin.mV[VZ] += *(origin + VZ);
if( !mOrigin.isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::translate()" << LL_ENDL;
}
CHECK_FINITE(mOrigin);
}
@ -383,6 +300,7 @@ void LLCoordFrame::rotate(F32 angle, F32 x, F32 y, F32 z)
{
LLQuaternion q(angle, LLVector3(x,y,z));
rotate(q);
CHECK_FINITE_OBJ();
}
@ -390,6 +308,7 @@ void LLCoordFrame::rotate(F32 angle, const LLVector3 &rotation_axis)
{
LLQuaternion q(angle, rotation_axis);
rotate(q);
CHECK_FINITE_OBJ();
}
@ -397,6 +316,7 @@ void LLCoordFrame::rotate(const LLQuaternion &q)
{
LLMatrix3 rotation_matrix(q);
rotate(rotation_matrix);
CHECK_FINITE_OBJ();
}
@ -405,12 +325,7 @@ void LLCoordFrame::rotate(const LLMatrix3 &rotation_matrix)
mXAxis.rotVec(rotation_matrix);
mYAxis.rotVec(rotation_matrix);
orthonormalize();
if( !isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::rotate()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
@ -419,12 +334,7 @@ void LLCoordFrame::roll(F32 angle)
LLQuaternion q(angle, mXAxis);
LLMatrix3 rotation_matrix(q);
rotate(rotation_matrix);
if( !mYAxis.isFinite() || !mZAxis.isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::roll()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
void LLCoordFrame::pitch(F32 angle)
@ -432,12 +342,7 @@ void LLCoordFrame::pitch(F32 angle)
LLQuaternion q(angle, mYAxis);
LLMatrix3 rotation_matrix(q);
rotate(rotation_matrix);
if( !mXAxis.isFinite() || !mZAxis.isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::pitch()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
void LLCoordFrame::yaw(F32 angle)
@ -445,12 +350,7 @@ void LLCoordFrame::yaw(F32 angle)
LLQuaternion q(angle, mZAxis);
LLMatrix3 rotation_matrix(q);
rotate(rotation_matrix);
if( !mXAxis.isFinite() || !mYAxis.isFinite() )
{
reset();
LL_WARNS() << "Non Finite in LLCoordFrame::yaw()" << LL_ENDL;
}
CHECK_FINITE_OBJ();
}
// get*() routines

View File

@ -537,6 +537,35 @@ inline void ll_remove_outliers(std::vector<VEC_TYPE>& data, F32 k)
}
}
// Converts given value from a linear RGB floating point value (0..1) to a gamma corrected (sRGB) value.
// Some shaders require color values in linear space, while others require color values in gamma corrected (sRGB) space.
// Note: in our code, values labeled as sRGB are ALWAYS gamma corrected linear values, NOT linear values with monitor gamma applied
// Note: stored color values should always be gamma corrected linear (i.e. the values returned from an on-screen color swatch)
// Note: DO NOT cache the conversion. This leads to error prone synchronization and is actually slower in the typical case due to cache misses
inline float linearTosRGB(const float val) {
if (val < 0.0031308f) {
return val * 12.92f;
}
else {
return 1.055f * pow(val, 1.0f / 2.4f) - 0.055f;
}
}
// Converts given value from a gamma corrected (sRGB) floating point value (0..1) to a linear color value.
// Some shaders require color values in linear space, while others require color values in gamma corrected (sRGB) space.
// Note: In our code, values labeled as sRGB are gamma corrected linear values, NOT linear values with monitor gamma applied
// Note: Stored color values should generally be gamma corrected sRGB.
// If you're serializing the return value of this function, you're probably doing it wrong.
// Note: DO NOT cache the conversion. This leads to error prone synchronization and is actually slower in the typical case due to cache misses.
inline float sRGBtoLinear(const float val) {
if (val < 0.04045f) {
return val / 12.92f;
}
else {
return pow((val + 0.055f) / 1.055f, 2.4f);
}
}
// Include simd math header
#include "llsimdmath.h"

View File

@ -104,6 +104,11 @@ LLQuaternion::LLQuaternion(const LLVector3 &x_axis,
normalize();
}
LLQuaternion::LLQuaternion(const LLSD &sd)
{
setValue(sd);
}
// Quatizations
void LLQuaternion::quantize16(F32 lower, F32 upper)
{
@ -860,6 +865,26 @@ void LLQuaternion::getAngleAxis(F32* angle, LLVector3 &vec) const
}
}
const LLQuaternion& LLQuaternion::setFromAzimuthAndAltitude(F32 azimuthRadians, F32 altitudeRadians)
{
// euler angle inputs are complements of azimuth/altitude which are measured from zenith
F32 pitch = llclamp(F_PI_BY_TWO - altitudeRadians, 0.0f, F_PI_BY_TWO);
F32 yaw = llclamp(F_PI_BY_TWO - azimuthRadians, 0.0f, F_PI_BY_TWO);
setEulerAngles(0.0f, pitch, yaw);
return *this;
}
void LLQuaternion::getAzimuthAndAltitude(F32 &azimuthRadians, F32 &altitudeRadians)
{
F32 rick_roll;
F32 pitch;
F32 yaw;
getEulerAngles(&rick_roll, &pitch, &yaw);
// make these measured from zenith
altitudeRadians = llclamp(F_PI_BY_TWO - pitch, 0.0f, F_PI_BY_TWO);
azimuthRadians = llclamp(F_PI_BY_TWO - yaw, 0.0f, F_PI_BY_TWO);
}
// quaternion does not need to be normalized
void LLQuaternion::getEulerAngles(F32 *roll, F32 *pitch, F32 *yaw) const
{

View File

@ -28,6 +28,7 @@
#define LLQUATERNION_H
#include <iostream>
#include "llsd.h"
#ifndef LLMATH_H //enforce specific include order to avoid tangling inline dependencies
#error "Please include llmath.h first."
@ -63,6 +64,10 @@ public:
LLQuaternion(const LLVector3 &x_axis,
const LLVector3 &y_axis,
const LLVector3 &z_axis); // Initializes Quaternion from Matrix3 = [x_axis ; y_axis ; z_axis]
explicit LLQuaternion(const LLSD &sd); // Initializes Quaternion from LLSD array.
LLSD getValue() const;
void setValue(const LLSD& sd);
BOOL isIdentity() const;
BOOL isNotIdentity() const;
@ -79,7 +84,8 @@ public:
const LLQuaternion& set(const F32 *q); // Sets Quaternion to normalize(quat[VX], quat[VY], quat[VZ], quat[VW])
const LLQuaternion& set(const LLMatrix3 &mat); // Sets Quaternion to mat2quat(mat)
const LLQuaternion& set(const LLMatrix4 &mat); // Sets Quaternion to mat2quat(mat)
const LLQuaternion& setFromAzimuthAndAltitude(F32 azimuth, F32 altitude);
const LLQuaternion& setAngleAxis(F32 angle, F32 x, F32 y, F32 z); // Sets Quaternion to axis_angle2quat(angle, x, y, z)
const LLQuaternion& setAngleAxis(F32 angle, const LLVector3 &vec); // Sets Quaternion to axis_angle2quat(angle, vec)
const LLQuaternion& setAngleAxis(F32 angle, const LLVector4 &vec); // Sets Quaternion to axis_angle2quat(angle, vec)
@ -100,6 +106,7 @@ public:
void getAngleAxis(F32* angle, F32* x, F32* y, F32* z) const; // returns rotation in radians about axis x,y,z
void getAngleAxis(F32* angle, LLVector3 &vec) const;
void getEulerAngles(F32 *roll, F32* pitch, F32 *yaw) const;
void getAzimuthAndAltitude(F32 &azimuth, F32 &altitude);
F32 normalize(); // Normalizes Quaternion and returns magnitude
F32 normQuat(); // deprecated
@ -166,6 +173,24 @@ public:
//static U32 mMultCount;
};
inline LLSD LLQuaternion::getValue() const
{
LLSD ret;
ret[0] = mQ[0];
ret[1] = mQ[1];
ret[2] = mQ[2];
ret[3] = mQ[3];
return ret;
}
inline void LLQuaternion::setValue(const LLSD& sd)
{
mQ[0] = sd[0].asReal();
mQ[1] = sd[1].asReal();
mQ[2] = sd[2].asReal();
mQ[3] = sd[3].asReal();
}
// checker
inline BOOL LLQuaternion::isFinite() const
{

View File

@ -2205,7 +2205,6 @@ BOOL LLVolume::generate()
{
rot_mat.rotate(*profile++, tmp);
dst->setAdd(tmp,offset);
llassert(dst->isFinite3()); // MAINT-5660; don't know why this happens, does not affect Release builds
++dst;
}
}
@ -2400,9 +2399,9 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
{ //face has no geometry, continue
face.resizeIndices(3);
face.resizeVertices(1);
memset(face.mPositions, 0, sizeof(LLVector4a));
memset(face.mNormals, 0, sizeof(LLVector4a));
memset(face.mTexCoords, 0, sizeof(LLVector2));
face.mPositions->clear();
face.mNormals->clear();
face.mTexCoords->setZero();
memset(face.mIndices, 0, sizeof(U16)*3);
continue;
}
@ -2490,7 +2489,11 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
}
else
{
memset(norm_out, 0, sizeof(LLVector4a)*num_verts);
for (U32 j = 0; j < num_verts; ++j)
{
norm_out->clear();
norm_out++; // or just norm_out[j].clear();
}
}
}
@ -2520,7 +2523,11 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
}
else
{
memset(tc_out, 0, sizeof(LLVector2)*num_verts);
for (U32 j = 0; j < num_verts; j += 2)
{
tc_out->clear();
tc_out++;
}
}
}
@ -4657,6 +4664,10 @@ LLVolumeFace::LLVolumeFace() :
mTexCoords(NULL),
mIndices(NULL),
mWeights(NULL),
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
mJustWeights(NULL),
mJointIndices(NULL),
#endif
mWeightsScrubbed(FALSE),
mOctree(NULL),
mOptimized(FALSE)
@ -4683,6 +4694,10 @@ LLVolumeFace::LLVolumeFace(const LLVolumeFace& src)
mTexCoords(NULL),
mIndices(NULL),
mWeights(NULL),
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
mJustWeights(NULL),
mJointIndices(NULL),
#endif
mWeightsScrubbed(FALSE),
mOctree(NULL)
{
@ -4747,24 +4762,46 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src)
if (src.mWeights)
{
llassert(!mWeights); // don't orphan an old alloc here accidentally
allocateWeights(src.mNumVertices);
LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size);
LLVector4a::memcpyNonAliased16((F32*) mWeights, (F32*) src.mWeights, vert_size);
mWeightsScrubbed = src.mWeightsScrubbed;
}
else
{
ll_aligned_free_16(mWeights);
mWeights = NULL;
}
mWeightsScrubbed = src.mWeightsScrubbed;
}
ll_aligned_free_16(mWeights);
mWeights = NULL;
mWeightsScrubbed = FALSE;
}
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
if (src.mJointIndices)
{
llassert(!mJointIndices); // don't orphan an old alloc here accidentally
allocateJointIndices(src.mNumVertices);
LLVector4a::memcpyNonAliased16((F32*) mJointIndices, (F32*) src.mJointIndices, src.mNumVertices * sizeof(U8) * 4);
}
else*/
{
ll_aligned_free_16(mJointIndices);
mJointIndices = NULL;
}
#endif
}
if (mNumIndices)
{
S32 idx_size = (mNumIndices*sizeof(U16)+0xF) & ~0xF;
LLVector4a::memcpyNonAliased16((F32*) mIndices, (F32*) src.mIndices, idx_size);
}
else
{
ll_aligned_free_16(mIndices);
mIndices = NULL;
}
mOptimized = src.mOptimized;
//delete
@ -4796,6 +4833,13 @@ void LLVolumeFace::freeData()
ll_aligned_free_16(mWeights);
mWeights = NULL;
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
ll_aligned_free_16(mJointIndices);
mJointIndices = NULL;
ll_aligned_free_16(mJustWeights);
mJustWeights = NULL;
#endif
delete mOctree;
mOctree = NULL;
}
@ -5252,7 +5296,7 @@ bool LLVolumeFace::cacheOptimize()
triangle_data.resize(mNumIndices / 3);
vertex_data.resize(mNumVertices);
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
LL_WARNS("LLVOLUME") << "Resize failed" << LL_ENDL;
return false;
@ -5406,7 +5450,7 @@ bool LLVolumeFace::cacheOptimize()
{
new_idx.resize(mNumVertices, -1);
}
catch (std::bad_alloc)
catch (std::bad_alloc&)
{
ll_aligned_free<64>(pos);
ll_aligned_free_16(wght);
@ -5449,11 +5493,17 @@ bool LLVolumeFace::cacheOptimize()
// DO NOT free mNormals and mTexCoords as they are part of mPositions buffer
ll_aligned_free_16(mWeights);
ll_aligned_free_16(mTangents);
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
ll_aligned_free_16(mJointIndices);
ll_aligned_free_16(mJustWeights);
mJustWeights = NULL;
mJointIndices = NULL; // filled in later as necessary by skinning code for acceleration
#endif
mPositions = pos;
mNormals = norm;
mTexCoords = tc;
mWeights = wght;
mWeights = wght;
mTangents = binorm;
//std::string result = llformat("ACMR pre/post: %.3f/%.3f -- %d triangles %d breaks", pre_acmr, post_acmr, mNumIndices/3, breaks);
@ -6363,7 +6413,19 @@ void LLVolumeFace::allocateTangents(S32 num_verts)
void LLVolumeFace::allocateWeights(S32 num_verts)
{
ll_aligned_free_16(mWeights);
mWeights = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
mWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts);
}
void LLVolumeFace::allocateJointIndices(S32 num_verts)
{
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
ll_aligned_free_16(mJointIndices);
ll_aligned_free_16(mJustWeights);
mJointIndices = (U8*)ll_aligned_malloc_16(sizeof(U8) * 4 * num_verts);
mJustWeights = (LLVector4a*)ll_aligned_malloc_16(sizeof(LLVector4a) * num_verts);
#endif
}
void LLVolumeFace::resizeIndices(S32 num_indices)
@ -6914,11 +6976,16 @@ void CalculateTangentArray(U32 vertexCount, const LLVector4a *vertex, const LLVe
{
//LLVector4a *tan1 = new LLVector4a[vertexCount * 2];
LLVector4a* tan1 = (LLVector4a*) ll_aligned_malloc_16(vertexCount*2*sizeof(LLVector4a));
// new(tan1) LLVector4a;
LLVector4a* tan2 = tan1 + vertexCount;
memset(tan1, 0, vertexCount*2*sizeof(LLVector4a));
U32 count = vertexCount * 2;
for (U32 i = 0; i < count; i++)
{
tan1[i].clear();
}
for (U32 a = 0; a < triangleCount; a++)
{
U32 i1 = *index_array++;

View File

@ -875,6 +875,7 @@ public:
void resizeVertices(S32 num_verts);
void allocateTangents(S32 num_verts);
void allocateWeights(S32 num_verts);
void allocateJointIndices(S32 num_verts);
void resizeIndices(S32 num_indices);
void fillFromLegacyData(std::vector<LLVolumeFace::VertexData>& v, std::vector<U16>& idx);
@ -956,6 +957,11 @@ public:
// mWeights.size() should be empty or match mVertices.size()
LLVector4a* mWeights;
#if USE_SEPARATE_JOINT_INDICES_AND_WEIGHTS
LLVector4a* mJustWeights;
U8* mJointIndices;
#endif
mutable BOOL mWeightsScrubbed;
// Which joints are rigged to, and the bounding box of any rigged

View File

@ -75,13 +75,6 @@ LLMatrix3::LLMatrix3(const F32 angle, const LLVector4 &vec)
setRot(quat);
}
LLMatrix3::LLMatrix3(const F32 angle, const F32 x, const F32 y, const F32 z)
{
LLVector3 vec(x, y, z);
LLQuaternion quat(angle, vec);
setRot(quat);
}
LLMatrix3::LLMatrix3(const F32 roll, const F32 pitch, const F32 yaw)
{
setRot(roll,pitch,yaw);
@ -294,14 +287,6 @@ LLQuaternion LLMatrix3::quaternion() const
return quat;
}
// These functions take Rotation arguments
const LLMatrix3& LLMatrix3::setRot(const F32 angle, const F32 x, const F32 y, const F32 z)
{
setRot(LLQuaternion(angle,x,y,z));
return *this;
}
const LLMatrix3& LLMatrix3::setRot(const F32 angle, const LLVector3 &vec)
{
setRot(LLQuaternion(angle, vec));
@ -394,15 +379,6 @@ const LLMatrix3& LLMatrix3::setCol( U32 colIndex, const LLVector3& col )
return *this;
}
// Rotate exisitng mMatrix
const LLMatrix3& LLMatrix3::rotate(const F32 angle, const F32 x, const F32 y, const F32 z)
{
LLMatrix3 mat(angle, x, y, z);
*this *= mat;
return *this;
}
const LLMatrix3& LLMatrix3::rotate(const F32 angle, const LLVector3 &vec)
{

View File

@ -60,7 +60,6 @@ class LLMatrix3
explicit LLMatrix3(const F32 *mat); // Initializes Matrix to values in mat
explicit LLMatrix3(const LLQuaternion &q); // Initializes Matrix with rotation q
LLMatrix3(const F32 angle, const F32 x, const F32 y, const F32 z); // Initializes Matrix with axis angle
LLMatrix3(const F32 angle, const LLVector3 &vec); // Initializes Matrix with axis angle
LLMatrix3(const F32 angle, const LLVector3d &vec); // Initializes Matrix with axis angle
LLMatrix3(const F32 angle, const LLVector4 &vec); // Initializes Matrix with axis angle
@ -81,8 +80,7 @@ class LLMatrix3
// Matrix setters - set some properties without modifying others
//
// These functions take Rotation arguments
const LLMatrix3& setRot(const F32 angle, const F32 x, const F32 y, const F32 z); // Calculate rotation matrix for rotating angle radians about (x, y, z)
// These functions take Rotation arguments
const LLMatrix3& setRot(const F32 angle, const LLVector3 &vec); // Calculate rotation matrix for rotating angle radians about vec
const LLMatrix3& setRot(const F32 roll, const F32 pitch, const F32 yaw); // Calculate rotation matrix from Euler angles
const LLMatrix3& setRot(const LLQuaternion &q); // Transform matrix by Euler angles and translating by pos

View File

@ -384,13 +384,6 @@ void LLMatrix4::initRows(const LLVector4 &row0,
}
const LLMatrix4& LLMatrix4::initRotation(const F32 angle, const F32 x, const F32 y, const F32 z)
{
LLMatrix3 mat(angle, x, y, z);
return initMatrix(mat);
}
const LLMatrix4& LLMatrix4::initRotation(F32 angle, const LLVector4 &vec)
{
LLMatrix3 mat(angle, vec);
@ -412,17 +405,6 @@ const LLMatrix4& LLMatrix4::initRotation(const LLQuaternion &q)
}
// Position and Rotation
const LLMatrix4& LLMatrix4::initRotTrans(const F32 angle, const F32 rx, const F32 ry, const F32 rz,
const F32 tx, const F32 ty, const F32 tz)
{
LLMatrix3 mat(angle, rx, ry, rz);
LLVector3 translation(tx, ty, tz);
initMatrix(mat);
setTranslation(translation);
return (*this);
}
const LLMatrix4& LLMatrix4::initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3&translation)
{
LLMatrix3 mat(angle, axis);
@ -513,15 +495,6 @@ const LLMatrix4& LLMatrix4::initAll(const LLVector3 &scale, const LLQuaternion &
return (*this);
}
// Rotate exisitng mMatrix
const LLMatrix4& LLMatrix4::rotate(const F32 angle, const F32 x, const F32 y, const F32 z)
{
LLVector4 vec4(x, y, z);
LLMatrix4 mat(angle, vec4);
*this *= mat;
return *this;
}
const LLMatrix4& LLMatrix4::rotate(const F32 angle, const LLVector4 &vec)
{
LLMatrix4 mat(angle, vec);

View File

@ -137,7 +137,6 @@ public:
bool isIdentity() const;
const LLMatrix4& setZero(); // Clears matrix to all zeros.
const LLMatrix4& initRotation(const F32 angle, const F32 x, const F32 y, const F32 z); // Calculate rotation matrix by rotating angle radians about (x, y, z)
const LLMatrix4& initRotation(const F32 angle, const LLVector4 &axis); // Calculate rotation matrix for rotating angle radians about vec
const LLMatrix4& initRotation(const F32 roll, const F32 pitch, const F32 yaw); // Calculate rotation matrix from Euler angles
const LLMatrix4& initRotation(const LLQuaternion &q); // Set with Quaternion and position
@ -148,10 +147,6 @@ public:
// These operation create a matrix that will rotate and translate by the
// specified amounts.
const LLMatrix4& initRotTrans(const F32 angle,
const F32 rx, const F32 ry, const F32 rz,
const F32 px, const F32 py, const F32 pz);
const LLMatrix4& initRotTrans(const F32 angle, const LLVector3 &axis, const LLVector3 &translation); // Rotation from axis angle + translation
const LLMatrix4& initRotTrans(const F32 roll, const F32 pitch, const F32 yaw, const LLVector4 &pos); // Rotation from Euler + translation
const LLMatrix4& initRotTrans(const LLQuaternion &q, const LLVector4 &pos); // Set with Quaternion and position
@ -211,7 +206,6 @@ public:
// Rotate existing matrix
// These are really, really, inefficient as implemented! - djs
const LLMatrix4& rotate(const F32 angle, const F32 x, const F32 y, const F32 z); // Rotate matrix by rotating angle radians about (x, y, z)
const LLMatrix4& rotate(const F32 angle, const LLVector4 &vec); // Rotate matrix by rotating angle radians about vec
const LLMatrix4& rotate(const F32 roll, const F32 pitch, const F32 yaw); // Rotate matrix by Euler angles
const LLMatrix4& rotate(const LLQuaternion &q); // Rotate matrix by Quaternion

View File

@ -77,7 +77,7 @@ namespace tut
template<> template<>
void m3math_test_object_t::test<2>()
{
LLMatrix3 llmat3_obj(30, 1, 2, 3);
LLMatrix3 llmat3_obj;
llmat3_obj.setZero();
ensure("LLMatrix3::setZero failed", 0.f == llmat3_obj.setZero().mMatrix[0][0] &&

View File

@ -118,7 +118,7 @@ LLSD LLVector2::getValue() const
return ret;
}
void LLVector2::setValue(LLSD& sd)
void LLVector2::setValue(const LLSD& sd)
{
mV[0] = (F32) sd[0].asReal();
mV[1] = (F32) sd[1].asReal();

View File

@ -49,6 +49,7 @@ class LLVector2
LLVector2(F32 x, F32 y); // Initializes LLVector2 to (x. y)
LLVector2(const F32 *vec); // Initializes LLVector2 to (vec[0]. vec[1])
explicit LLVector2(const LLVector3 &vec); // Initializes LLVector2 to (vec[0]. vec[1])
explicit LLVector2(const LLSD &sd);
// Clears LLVector2 to (0, 0). DEPRECATED - prefer zeroVec.
void clear();
@ -61,7 +62,7 @@ class LLVector2
void set(const F32 *vec); // Sets LLVector2 to vec
LLSD getValue() const;
void setValue(LLSD& sd);
void setValue(const LLSD& sd);
void setVec(F32 x, F32 y); // deprecated
void setVec(const LLVector2 &vec); // deprecated
@ -145,6 +146,10 @@ inline LLVector2::LLVector2(const LLVector3 &vec)
mV[VY] = vec.mV[VY];
}
inline LLVector2::LLVector2(const LLSD &sd)
{
setValue(sd);
}
// Clear and Assignment Functions

View File

@ -100,6 +100,23 @@ public:
const LLColor3& operator=(const LLColor4 &a);
LL_FORCE_INLINE LLColor3 divide(const LLColor3 &col2)
{
return LLColor3(
mV[0] / col2.mV[0],
mV[1] / col2.mV[1],
mV[2] / col2.mV[2] );
}
LL_FORCE_INLINE LLColor3 color_norm()
{
F32 l = length();
return LLColor3(
mV[0] / l,
mV[1] / l,
mV[2] / l );
}
friend std::ostream& operator<<(std::ostream& s, const LLColor3 &a); // Print a
friend LLColor3 operator+(const LLColor3 &a, const LLColor3 &b); // Return vector a + b
friend LLColor3 operator-(const LLColor3 &a, const LLColor3 &b); // Return vector a minus b
@ -458,5 +475,22 @@ inline LLColor3 lerp(const LLColor3 &a, const LLColor3 &b, F32 u)
a.mV[VZ] + (b.mV[VZ] - a.mV[VZ]) * u);
}
inline const LLColor3 srgbColor3(const LLColor3 &a) {
LLColor3 srgbColor;
srgbColor.mV[0] = linearTosRGB(a.mV[0]);
srgbColor.mV[1] = linearTosRGB(a.mV[1]);
srgbColor.mV[2] = linearTosRGB(a.mV[2]);
return srgbColor;
}
inline const LLColor3 linearColor3(const LLColor3 &a) {
LLColor3 linearColor;
linearColor.mV[0] = sRGBtoLinear(a.mV[0]);
linearColor.mV[1] = sRGBtoLinear(a.mV[1]);
linearColor.mV[2] = sRGBtoLinear(a.mV[2]);
return linearColor;
}
#endif

115
indra/llmath/v3colorutil.h Normal file
View File

@ -0,0 +1,115 @@
/**
* @file v3color.h
* @brief LLColor3 class header file.
*
* $LicenseInfo:firstyear=2001&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2010, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_V3COLORUTIL_H
#define LL_V3COLORUTIL_H
#include "v3color.h"
inline LLColor3 componentDiv(LLColor3 const &left, LLColor3 const & right)
{
return LLColor3(left.mV[0] / right.mV[0],
left.mV[1] / right.mV[1],
left.mV[2] / right.mV[2]);
}
inline LLColor3 componentMult(LLColor3 const &left, LLColor3 const & right)
{
return LLColor3(left.mV[0] * right.mV[0],
left.mV[1] * right.mV[1],
left.mV[2] * right.mV[2]);
}
inline LLColor3 componentExp(LLColor3 const &v)
{
return LLColor3(exp(v.mV[0]),
exp(v.mV[1]),
exp(v.mV[2]));
}
inline LLColor3 componentPow(LLColor3 const &v, F32 exponent)
{
return LLColor3(pow(v.mV[0], exponent),
pow(v.mV[1], exponent),
pow(v.mV[2], exponent));
}
inline LLColor3 componentSaturate(LLColor3 const &v)
{
return LLColor3(std::max(std::min(v.mV[0], 1.f), 0.f),
std::max(std::min(v.mV[1], 1.f), 0.f),
std::max(std::min(v.mV[2], 1.f), 0.f));
}
inline LLColor3 componentSqrt(LLColor3 const &v)
{
return LLColor3(sqrt(v.mV[0]),
sqrt(v.mV[1]),
sqrt(v.mV[2]));
}
inline void componentMultBy(LLColor3 & left, LLColor3 const & right)
{
left.mV[0] *= right.mV[0];
left.mV[1] *= right.mV[1];
left.mV[2] *= right.mV[2];
}
inline LLColor3 colorMix(LLColor3 const & left, LLColor3 const & right, F32 amount)
{
return (left + ((right - left) * amount));
}
inline LLColor3 smear(F32 val)
{
return LLColor3(val, val, val);
}
inline F32 color_intens(const LLColor3 &col)
{
return col.mV[0] + col.mV[1] + col.mV[2];
}
inline F32 color_max(const LLColor3 &col)
{
return llmax(col.mV[0], col.mV[1], col.mV[2]);
}
inline F32 color_max(const LLColor4 &col)
{
return llmax(col.mV[0], col.mV[1], col.mV[2]);
}
inline F32 color_min(const LLColor3 &col)
{
return llmin(col.mV[0], col.mV[1], col.mV[2]);
}
#endif

View File

@ -114,9 +114,11 @@ class LLColor4
friend LLColor4 operator-(const LLColor4 &a, const LLColor4 &b); // Return vector a minus b
friend LLColor4 operator*(const LLColor4 &a, const LLColor4 &b); // Return component wise a * b
friend LLColor4 operator*(const LLColor4 &a, F32 k); // Return rgb times scaler k (no alpha change)
friend LLColor4 operator/(const LLColor4 &a, F32 k); // Return rgb divided by scalar k (no alpha change)
friend LLColor4 operator*(F32 k, const LLColor4 &a); // Return rgb times scaler k (no alpha change)
friend LLColor4 operator%(const LLColor4 &a, F32 k); // Return alpha times scaler k (no rgb change)
friend LLColor4 operator%(F32 k, const LLColor4 &a); // Return alpha times scaler k (no rgb change)
friend bool operator==(const LLColor4 &a, const LLColor4 &b); // Return a == b
friend bool operator!=(const LLColor4 &a, const LLColor4 &b); // Return a != b
@ -477,6 +479,15 @@ inline LLColor4 operator*(const LLColor4 &a, F32 k)
a.mV[VW]);
}
inline LLColor4 operator/(const LLColor4 &a, F32 k)
{
return LLColor4(
a.mV[VX] / k,
a.mV[VY] / k,
a.mV[VZ] / k,
a.mV[VW]);
}
inline LLColor4 operator*(F32 k, const LLColor4 &a)
{
// only affects rgb (not a!)
@ -645,5 +656,29 @@ void LLColor4::clamp()
}
}
// Return the given linear space color value in gamma corrected (sRGB) space
inline const LLColor4 srgbColor4(const LLColor4 &a) {
LLColor4 srgbColor;
srgbColor.mV[0] = linearTosRGB(a.mV[0]);
srgbColor.mV[1] = linearTosRGB(a.mV[1]);
srgbColor.mV[2] = linearTosRGB(a.mV[2]);
srgbColor.mV[3] = a.mV[3];
return srgbColor;
}
// Return the given gamma corrected (sRGB) color in linear space
inline const LLColor4 linearColor4(const LLColor4 &a)
{
LLColor4 linearColor;
linearColor.mV[0] = sRGBtoLinear(a.mV[0]);
linearColor.mV[1] = sRGBtoLinear(a.mV[1]);
linearColor.mV[2] = sRGBtoLinear(a.mV[2]);
linearColor.mV[3] = a.mV[3];
return linearColor;
}
#endif

View File

@ -30,6 +30,7 @@
#include "llerror.h"
#include "llmath.h"
#include "v3math.h"
#include "v2math.h"
class LLMatrix3;
class LLMatrix4;
@ -46,8 +47,11 @@ class LLVector4
LLVector4(); // Initializes LLVector4 to (0, 0, 0, 1)
explicit LLVector4(const F32 *vec); // Initializes LLVector4 to (vec[0]. vec[1], vec[2], vec[3])
explicit LLVector4(const F64 *vec); // Initialized LLVector4 to ((F32) vec[0], (F32) vec[1], (F32) vec[3], (F32) vec[4]);
explicit LLVector4(const LLVector2 &vec);
explicit LLVector4(const LLVector2 &vec, F32 z, F32 w);
explicit LLVector4(const LLVector3 &vec); // Initializes LLVector4 to (vec, 1)
explicit LLVector4(const LLVector3 &vec, F32 w); // Initializes LLVector4 to (vec, w)
explicit LLVector4(const LLSD &sd);
LLVector4(F32 x, F32 y, F32 z); // Initializes LLVector4 to (x. y, z, 1)
LLVector4(F32 x, F32 y, F32 z, F32 w);
@ -61,6 +65,15 @@ class LLVector4
return ret;
}
void setValue(const LLSD& sd)
{
mV[0] = sd[0].asReal();
mV[1] = sd[1].asReal();
mV[2] = sd[2].asReal();
mV[3] = sd[3].asReal();
}
inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite
inline void clear(); // Clears LLVector4 to (0, 0, 0, 1)
@ -175,6 +188,22 @@ inline LLVector4::LLVector4(const F64 *vec)
mV[VW] = (F32) vec[VW];
}
inline LLVector4::LLVector4(const LLVector2 &vec)
{
mV[VX] = vec[VX];
mV[VY] = vec[VY];
mV[VZ] = 0.f;
mV[VW] = 0.f;
}
inline LLVector4::LLVector4(const LLVector2 &vec, F32 z, F32 w)
{
mV[VX] = vec[VX];
mV[VY] = vec[VY];
mV[VZ] = z;
mV[VW] = w;
}
inline LLVector4::LLVector4(const LLVector3 &vec)
{
mV[VX] = vec.mV[VX];
@ -191,6 +220,11 @@ inline LLVector4::LLVector4(const LLVector3 &vec, F32 w)
mV[VW] = w;
}
inline LLVector4::LLVector4(const LLSD &sd)
{
setValue(sd);
}
inline BOOL LLVector4::isFinite() const
{
@ -500,6 +534,18 @@ inline F32 LLVector4::normVec(void)
return (mag);
}
// Because apparently some parts of the viewer use this for color info.
inline const LLVector4 srgbVector4(const LLVector4 &a) {
LLVector4 srgbColor;
srgbColor.mV[0] = linearTosRGB(a.mV[0]);
srgbColor.mV[1] = linearTosRGB(a.mV[1]);
srgbColor.mV[2] = linearTosRGB(a.mV[2]);
srgbColor.mV[3] = a.mV[3];
return srgbColor;
}
#endif

View File

@ -62,6 +62,42 @@ const LLUUID CATEGORIZE_LOST_AND_FOUND_ID(std::string("00000000-0000-0000-0000-0
const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000); // microseconds
namespace
{
bool operator == (const LLAssetStorage::LLGetAssetCallback &lhs, const LLAssetStorage::LLGetAssetCallback &rhs)
{
auto fnPtrLhs = lhs.target<LLAssetStorage::LLGetAssetCallback>();
auto fnPtrRhs = rhs.target<LLAssetStorage::LLGetAssetCallback>();
if (fnPtrLhs && fnPtrRhs)
return (*fnPtrLhs == *fnPtrRhs);
else if (!fnPtrLhs && !fnPtrRhs)
return true;
return false;
}
// Rider: This is the general case of the operator declared above. The code compares the callback
// passed into the LLAssetStorage functions to determine if there are duplicated requests for an
// asset. Unfortunately std::function does not provide a direct way to compare two variables so
// we define the operator here.
// XCode is not very happy with the variadic temples in use below so we will just define the specific
// case of comparing two LLGetAssetCallback objects since that is all we really use.
//
// template<typename T, typename... U>
// bool operator == (const std::function<T(U...)> &a, const std::function <T(U...)> &b)
// {
// typedef T(fnType)(U...);
//
// auto fnPtrA = a.target<T(*)(U...)>();
// auto fnPtrB = b.target<T(*)(U...)>();
// if (fnPtrA && fnPtrB)
// return (*fnPtrA == *fnPtrB);
// else if (!fnPtrA && !fnPtrB)
// return true;
// return false;
// }
}
///----------------------------------------------------------------------------
/// LLAssetInfo
///----------------------------------------------------------------------------
@ -160,7 +196,7 @@ void LLAssetInfo::setFromNameValue( const LLNameValue& nv )
LLBaseDownloadRequest::LLBaseDownloadRequest(const LLUUID &uuid, const LLAssetType::EType type)
: mUUID(uuid),
mType(type),
mDownCallback(NULL),
mDownCallback(),
mUserData(NULL),
mHost(),
mIsTemp(FALSE),
@ -191,7 +227,7 @@ LLBaseDownloadRequest* LLBaseDownloadRequest::getCopy()
LLAssetRequest::LLAssetRequest(const LLUUID &uuid, const LLAssetType::EType type)
: LLBaseDownloadRequest(uuid, type),
mUpCallback( NULL ),
mUpCallback(),
mInfoCallback( NULL ),
mIsLocal(FALSE),
mIsUserWaiting(FALSE),
@ -449,7 +485,7 @@ bool LLAssetStorage::findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAsse
// IW - uuid is passed by value to avoid side effects, please don't re-add &
void LLAssetStorage::getAssetData(const LLUUID uuid,
LLAssetType::EType type,
LLGetAssetCallback callback,
LLAssetStorage::LLGetAssetCallback callback,
void *user_data,
BOOL is_priority)
{
@ -496,7 +532,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
BOOL exists = mVFS->getExists(uuid, type);
LLVFile file(mVFS, uuid, type);
U32 size = exists ? file.getSize() : 0;
if (size > 0)
{
// we've already got the file
@ -1326,9 +1362,13 @@ void LLAssetStorage::getAssetData(const LLUUID uuid,
iter != mPendingDownloads.end(); )
{
LLAssetRequest* tmp = *iter++;
//void(*const* cbptr)(LLVFS *, const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat)
auto cbptr = tmp->mDownCallback.target<void(*)(LLVFS *, const LLUUID &, LLAssetType::EType, void *, S32, LLExtStat)>();
if (type == tmp->getType() &&
uuid == tmp->getUUID() &&
legacyGetDataCallback == tmp->mDownCallback &&
(cbptr && (*cbptr == legacyGetDataCallback)) &&
callback == ((LLLegacyAssetRequest *)tmp->mUserData)->mDownCallback &&
user_data == ((LLLegacyAssetRequest *)tmp->mUserData)->mUserData)
{

View File

@ -28,6 +28,7 @@
#ifndef LL_LLASSETSTORAGE_H
#define LL_LLASSETSTORAGE_H
#include <string>
#include <functional>
#include "lluuid.h"
#include "lltimer.h"
@ -59,6 +60,14 @@ const int LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE = -4;
const int LL_ERR_INSUFFICIENT_PERMISSIONS = -5;
const int LL_ERR_PRICE_MISMATCH = -23018;
// *TODO: these typedefs are passed into the VFS via a legacy C function pointer
// future project would be to convert these to C++ callables (std::function<>) so that
// we can use bind and remove the userData parameter.
//
typedef std::function<void(LLVFS *vfs, const LLUUID &asset_id, LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status)> LLGetAssetCallback;
typedef std::function<void(const LLUUID &asset_id, void *user_data, S32 status, LLExtStat ext_status)> LLStoreAssetCallback;
class LLAssetInfo
{
protected:
@ -110,7 +119,8 @@ protected:
LLAssetType::EType mType;
public:
void(*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat);
LLGetAssetCallback mDownCallback;
// void(*mDownCallback)(LLVFS*, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat);
void *mUserData;
LLHost mHost;
@ -131,7 +141,8 @@ public:
virtual LLBaseDownloadRequest* getCopy();
void (*mUpCallback)(const LLUUID&, void *, S32, LLExtStat);
LLStoreAssetCallback mUpCallback;
// void (*mUpCallback)(const LLUUID&, void *, S32, LLExtStat);
void (*mInfoCallback)(LLAssetInfo *, void *, S32);
BOOL mIsLocal;
@ -182,12 +193,7 @@ protected:
// Map of known bad assets
typedef std::map<LLUUID,U64,lluuid_less> toxic_asset_map_t;
// *TODO: these typedefs are passed into the VFS via a legacy C function pointer
// future project would be to convert these to C++ callables (std::function<>) so that
// we can use bind and remove the userData parameter.
//
typedef void (*LLGetAssetCallback)(LLVFS *vfs, const LLUUID &asset_id,
LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status);
class LLAssetStorage
{
@ -195,7 +201,8 @@ public:
// VFS member is public because static child methods need it :(
LLVFS *mVFS;
LLVFS *mStaticVFS;
typedef void (*LLStoreAssetCallback)(const LLUUID &asset_id, void *user_data, S32 status, LLExtStat ext_status);
typedef ::LLStoreAssetCallback LLStoreAssetCallback;
typedef ::LLGetAssetCallback LLGetAssetCallback;
enum ERequestType
{
@ -377,8 +384,8 @@ protected:
void _cleanupRequests(BOOL all, S32 error);
void _callUploadCallbacks(const LLUUID &uuid, const LLAssetType::EType asset_type, BOOL success, LLExtStat ext_status);
virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type,
void (*callback)(LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type, LLGetAssetCallback callback,
// void (*callback)(LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
void *user_data, BOOL duplicate,
BOOL is_priority) = 0;
@ -424,7 +431,7 @@ class LLLegacyAssetRequest
{
public:
void (*mDownCallback)(const char *, const LLUUID&, void *, S32, LLExtStat);
LLAssetStorage::LLStoreAssetCallback mUpCallback;
LLStoreAssetCallback mUpCallback;
void *mUserData;
};

View File

@ -543,7 +543,7 @@ void LLCircuitData::checkPeriodTime()
mBytesOutLastPeriod = mBytesOutThisPeriod;
mBytesInThisPeriod = S32Bytes(0);
mBytesOutThisPeriod = S32Bytes(0);
mLastPeriodLength = period_length;
mLastPeriodLength = F32Seconds::convert(period_length);
mPeriodTime = mt_sec;
}
@ -1378,8 +1378,8 @@ F32Milliseconds LLCircuitData::getPingInTransitTime()
if (mPingsInTransit)
{
time_since_ping_was_sent = ((mPingsInTransit*mHeartbeatInterval - F32Seconds(1))
+ (LLMessageSystem::getMessageTimeSeconds() - mPingTime));
time_since_ping_was_sent = F32Milliseconds::convert(((mPingsInTransit*mHeartbeatInterval - F32Seconds(1))
+ (LLMessageSystem::getMessageTimeSeconds() - mPingTime)));
}
return time_since_ping_was_sent;

View File

@ -597,7 +597,7 @@ LLSD HttpCoroJSONHandler::handleSuccess(LLCore::HttpResponse * response, LLCore:
{
bas >> jsonRoot;
}
catch (std::runtime_error e)
catch (std::runtime_error& e)
{ // deserialization failed. Record the reason and pass back an empty map for markup.
status = LLCore::HttpStatus(499, std::string(e.what()));
return result;
@ -625,7 +625,7 @@ LLSD HttpCoroJSONHandler::parseBody(LLCore::HttpResponse *response, bool &succes
{
bas >> jsonRoot;
}
catch (std::runtime_error e)
catch (std::runtime_error&)
{
success = false;
return LLSD();

View File

@ -101,48 +101,70 @@ LLDispatchHandler* LLDispatcher::addHandler(
// static
bool LLDispatcher::unpackMessage(
LLMessageSystem* msg,
LLDispatcher::key_t& method,
LLUUID& invoice,
LLDispatcher::sparam_t& parameters)
LLMessageSystem* msg,
LLDispatcher::key_t& method,
LLUUID& invoice,
LLDispatcher::sparam_t& parameters)
{
char buf[MAX_STRING]; /*Flawfinder: ignore*/
msg->getStringFast(_PREHASH_MethodData, _PREHASH_Method, method);
msg->getUUIDFast(_PREHASH_MethodData, _PREHASH_Invoice, invoice);
S32 size;
S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList);
for (S32 i = 0; i < count; ++i)
{
// we treat the SParam as binary data (since it might be an
// LLUUID in compressed form which may have embedded \0's,)
size = msg->getSizeFast(_PREHASH_ParamList, i, _PREHASH_Parameter);
if (size >= 0)
{
msg->getBinaryDataFast(
_PREHASH_ParamList, _PREHASH_Parameter,
buf, size, i, MAX_STRING-1);
char buf[MAX_STRING]; /*Flawfinder: ignore*/
msg->getStringFast(_PREHASH_MethodData, _PREHASH_Method, method);
msg->getUUIDFast(_PREHASH_MethodData, _PREHASH_Invoice, invoice);
S32 size;
S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList);
for (S32 i = 0; i < count; ++i)
{
// we treat the SParam as binary data (since it might be an
// LLUUID in compressed form which may have embedded \0's,)
size = msg->getSizeFast(_PREHASH_ParamList, i, _PREHASH_Parameter);
if (size >= 0)
{
msg->getBinaryDataFast(
_PREHASH_ParamList, _PREHASH_Parameter,
buf, size, i, MAX_STRING - 1);
// If the last byte of the data is 0x0, this is either a normally
// packed string, or a binary packed UUID (which for these messages
// are packed with a 17th byte 0x0). Unpack into a std::string
// without the trailing \0, so "abc\0" becomes std::string("abc", 3)
// which matches const char* "abc".
if (size > 0
&& buf[size-1] == 0x0)
{
// special char*/size constructor because UUIDs may have embedded
// 0x0 bytes.
std::string binary_data(buf, size-1);
parameters.push_back(binary_data);
}
else
{
// This is either a NULL string, or a string that was packed
// incorrectly as binary data, without the usual trailing '\0'.
std::string string_data(buf, size);
parameters.push_back(string_data);
}
}
}
return true;
// If the last byte of the data is 0x0, this is either a normally
// packed string, or a binary packed UUID (which for these messages
// are packed with a 17th byte 0x0). Unpack into a std::string
// without the trailing \0, so "abc\0" becomes std::string("abc", 3)
// which matches const char* "abc".
if (size > 0
&& buf[size - 1] == 0x0)
{
// special char*/size constructor because UUIDs may have embedded
// 0x0 bytes.
std::string binary_data(buf, size - 1);
parameters.push_back(binary_data);
}
else
{
// This is either a NULL string, or a string that was packed
// incorrectly as binary data, without the usual trailing '\0'.
std::string string_data(buf, size);
parameters.push_back(string_data);
}
}
}
return true;
}
// static
bool LLDispatcher::unpackLargeMessage(
LLMessageSystem* msg,
LLDispatcher::key_t& method,
LLUUID& invoice,
LLDispatcher::sparam_t& parameters)
{
msg->getStringFast(_PREHASH_MethodData, _PREHASH_Method, method);
msg->getUUIDFast(_PREHASH_MethodData, _PREHASH_Invoice, invoice);
S32 count = msg->getNumberOfBlocksFast(_PREHASH_ParamList);
for (S32 i = 0; i < count; ++i)
{
// This method treats all Parameter List params as strings and unpacks
// them regardless of length. If there is binary data it is the callers
// responsibility to decode it.
std::string param;
msg->getStringFast(_PREHASH_ParamList, _PREHASH_Parameter, param, i);
parameters.push_back(param);
}
return true;
}

View File

@ -105,6 +105,12 @@ public:
LLUUID& invoice,
sparam_t& parameters);
static bool unpackLargeMessage(
LLMessageSystem* msg,
key_t& method,
LLUUID& invoice,
sparam_t& parameters);
protected:
typedef std::map<key_t, LLDispatchHandler*> dispatch_map_t;
dispatch_map_t mHandlers;

View File

@ -125,7 +125,7 @@ void LLHTTPNode::get(LLHTTPNode::ResponsePtr response, const LLSD& context) cons
{
response->result(simpleGet());
}
catch (NotImplemented)
catch (NotImplemented&)
{
response->methodNotAllowed();
}
@ -138,7 +138,7 @@ void LLHTTPNode::put(LLHTTPNode::ResponsePtr response, const LLSD& context, cons
{
response->result(simplePut(input));
}
catch (NotImplemented)
catch (NotImplemented&)
{
response->methodNotAllowed();
}
@ -151,7 +151,7 @@ void LLHTTPNode::post(LLHTTPNode::ResponsePtr response, const LLSD& context, con
{
response->result(simplePost(input));
}
catch (NotImplemented)
catch (NotImplemented&)
{
response->methodNotAllowed();
}
@ -164,7 +164,7 @@ void LLHTTPNode::del(LLHTTPNode::ResponsePtr response, const LLSD& context) cons
{
response->result(simpleDel(context));
}
catch (NotImplemented)
catch (NotImplemented&)
{
response->methodNotAllowed();
}

View File

@ -54,6 +54,9 @@ const U64 REGION_FLAGS_BLOCK_LAND_RESELL = (1 << 7);
// All content wiped once per night
const U64 REGION_FLAGS_SANDBOX = (1 << 8);
const U64 REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE = (1 << 9);
const U64 REGION_FLAGS_SKIP_COLLISIONS = (1 << 12); // Pin all non agent rigid bodies
const U64 REGION_FLAGS_SKIP_SCRIPTS = (1 << 13);
const U64 REGION_FLAGS_SKIP_PHYSICS = (1 << 14); // Skip all physics

View File

@ -1376,7 +1376,9 @@ char const* const _PREHASH_RegionDenyAgeUnverified = LLMessageStringTable::getIn
char const* const _PREHASH_AgeVerificationBlock = LLMessageStringTable::getInstance()->getString("AgeVerificationBlock");
char const* const _PREHASH_RegionAllowAccessBlock = LLMessageStringTable::getInstance()->getString("RegionAllowAccessBlock");
char const* const _PREHASH_RegionAllowAccessOverride = LLMessageStringTable::getInstance()->getString("RegionAllowAccessOverride");
char const* const _PREHASH_ParcelEnvironmentBlock = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentBlock");
char const* const _PREHASH_ParcelEnvironmentVersion = LLMessageStringTable::getInstance()->getString("ParcelEnvironmentVersion");
char const* const _PREHASH_RegionAllowEnvironmentOverride = LLMessageStringTable::getInstance()->getString("RegionAllowEnvironmentOverride");
char const* const _PREHASH_UCoord = LLMessageStringTable::getInstance()->getString("UCoord");
char const* const _PREHASH_VCoord = LLMessageStringTable::getInstance()->getString("VCoord");
char const* const _PREHASH_FaceIndex = LLMessageStringTable::getInstance()->getString("FaceIndex");
@ -1392,3 +1394,4 @@ char const* const _PREHASH_AppearanceHover = LLMessageStringTable::getInstance()
char const* const _PREHASH_HoverHeight = LLMessageStringTable::getInstance()->getString("HoverHeight");
char const* const _PREHASH_Experience = LLMessageStringTable::getInstance()->getString("Experience");
char const* const _PREHASH_ExperienceID = LLMessageStringTable::getInstance()->getString("ExperienceID");
char const* const _PREHASH_LargeGenericMessage = LLMessageStringTable::getInstance()->getString("LargeGenericMessage");

View File

@ -1376,6 +1376,9 @@ extern char const* const _PREHASH_RegionDenyAgeUnverified;
extern char const* const _PREHASH_AgeVerificationBlock;
extern char const* const _PREHASH_RegionAllowAccessBlock;
extern char const* const _PREHASH_RegionAllowAccessOverride;
extern char const* const _PREHASH_ParcelEnvironmentBlock;
extern char const* const _PREHASH_ParcelEnvironmentVersion;
extern char const* const _PREHASH_RegionAllowEnvironmentOverride;
extern char const* const _PREHASH_UCoord;
extern char const* const _PREHASH_VCoord;
extern char const* const _PREHASH_FaceIndex;
@ -1391,4 +1394,6 @@ extern char const* const _PREHASH_AppearanceHover;
extern char const* const _PREHASH_HoverHeight;
extern char const* const _PREHASH_Experience;
extern char const* const _PREHASH_ExperienceID;
extern char const* const _PREHASH_LargeGenericMessage;
#endif

View File

@ -258,7 +258,7 @@ void LLPluginProcessChild::sleep(F64 seconds)
}
else
{
ms_sleep((int)(seconds * 1000.0f));
ms_sleep((int)(seconds * 1000.0f));
}
}

View File

@ -1784,7 +1784,7 @@ void LLDAELoader::extractTranslationViaElement( daeElement* pTranslateElement, L
{
if ( pTranslateElement )
{
domTranslate* pTranslateChild = dynamic_cast<domTranslate*>( pTranslateElement );
domTranslate* pTranslateChild = static_cast<domTranslate*>( pTranslateElement );
domFloat3 translateChild = pTranslateChild->getValue();
LLVector3 singleJointTranslation( translateChild[0], translateChild[1], translateChild[2] );
transform.setTranslation( singleJointTranslation );

View File

@ -1659,7 +1659,7 @@ BOOL LLLightParams::unpack(LLDataPacker &dp)
{
LLColor4U color;
dp.unpackColor4U(color, "color");
setColor(LLColor4(color));
setLinearColor(LLColor4(color));
F32 radius;
dp.unpackF32(radius, "radius");
@ -1707,7 +1707,7 @@ LLSD LLLightParams::asLLSD() const
{
LLSD sd;
sd["color"] = ll_sd_from_color4(getColor());
sd["color"] = ll_sd_from_color4(getLinearColor());
sd["radius"] = getRadius();
sd["falloff"] = getFalloff();
sd["cutoff"] = getCutoff();
@ -1721,7 +1721,7 @@ bool LLLightParams::fromLLSD(LLSD& sd)
w = "color";
if (sd.has(w))
{
setColor( ll_color4_from_sd(sd["color"]) );
setLinearColor( ll_color4_from_sd(sd["color"]) );
} else goto fail;
w = "radius";
if (sd.has(w))

View File

@ -131,8 +131,8 @@ extern const F32 LIGHT_MAX_CUTOFF;
class LLLightParams : public LLNetworkData
{
protected:
LLColor4 mColor; // alpha = intensity
private:
LLColor4 mColor; // linear color (not gamma corrected), alpha = intensity
F32 mRadius;
F32 mFalloff;
F32 mCutoff;
@ -149,13 +149,22 @@ public:
operator LLSD() const { return asLLSD(); }
bool fromLLSD(LLSD& sd);
void setColor(const LLColor4& color) { mColor = color; mColor.clamp(); }
// set the color by gamma corrected color value
// color - gamma corrected color value (directly taken from an on-screen color swatch)
void setSRGBColor(const LLColor4& color) { setLinearColor(linearColor4(color)); }
// set the color by linear color value
// color - linear color value (value as it appears in shaders)
void setLinearColor(const LLColor4& color) { mColor = color; mColor.clamp(); }
void setRadius(F32 radius) { mRadius = llclamp(radius, LIGHT_MIN_RADIUS, LIGHT_MAX_RADIUS); }
void setFalloff(F32 falloff) { mFalloff = llclamp(falloff, LIGHT_MIN_FALLOFF, LIGHT_MAX_FALLOFF); }
void setCutoff(F32 cutoff) { mCutoff = llclamp(cutoff, LIGHT_MIN_CUTOFF, LIGHT_MAX_CUTOFF); }
LLColor4 getColor() const { return mColor; }
// get the linear space color of this light. This value can be fed directly to shaders
LLColor4 getLinearColor() const { return mColor; }
// get the sRGB (gamma corrected) color of this light, this is the value that should be displayed in the UI
LLColor4 getSRGBColor() const { return srgbColor4(mColor); }
F32 getRadius() const { return mRadius; }
F32 getFalloff() const { return mFalloff; }
F32 getCutoff() const { return mCutoff; }

View File

@ -31,6 +31,7 @@ include_directories(SYSTEM
)
set(llrender_SOURCE_FILES
llatmosphere.cpp
llcubemap.cpp
llfontbitmapcache.cpp
llfontfreetype.cpp
@ -57,6 +58,7 @@ set(llrender_SOURCE_FILES
set(llrender_HEADER_FILES
CMakeLists.txt
llatmosphere.h
llcubemap.h
llfontgl.h
llfontfreetype.h
@ -78,6 +80,7 @@ set(llrender_HEADER_FILES
llshadermgr.h
lltexture.h
lluiimage.h
lluiimage.inl
llvertexbuffer.h
llglcommonfunc.h
)

View File

@ -0,0 +1,290 @@
/**
* @file llatmosphere.cpp
* @brief LLAtmosphere integration impl
*
* $LicenseInfo:firstyear=2018&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2018, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#include "linden_common.h"
#include "llatmosphere.h"
#include "llfasttimer.h"
#include "llsys.h"
#include "llglheaders.h"
#include "llrender.h"
#include "llshadermgr.h"
#include "llglslshader.h"
LLAtmosphere* gAtmosphere = nullptr;
// Values from "Reference Solar Spectral Irradiance: ASTM G-173", ETR column
// (see http://rredc.nrel.gov/solar/spectra/am1.5/ASTMG173/ASTMG173.html),
// summed and averaged in each bin (e.g. the value for 360nm is the average
// of the ASTM G-173 values for all wavelengths between 360 and 370nm).
// Values in W.m^-2.
const int kLambdaMin = 360;
const int kLambdaMax = 830;
const double kSolarIrradiance[48] = {
1.11776, 1.14259, 1.01249, 1.14716, 1.72765, 1.73054, 1.6887, 1.61253,
1.91198, 2.03474, 2.02042, 2.02212, 1.93377, 1.95809, 1.91686, 1.8298,
1.8685, 1.8931, 1.85149, 1.8504, 1.8341, 1.8345, 1.8147, 1.78158, 1.7533,
1.6965, 1.68194, 1.64654, 1.6048, 1.52143, 1.55622, 1.5113, 1.474, 1.4482,
1.41018, 1.36775, 1.34188, 1.31429, 1.28303, 1.26758, 1.2367, 1.2082,
1.18737, 1.14683, 1.12362, 1.1058, 1.07124, 1.04992
};
// Values from http://www.iup.uni-bremen.de/gruppen/molspec/databases/
// referencespectra/o3spectra2011/index.html for 233K, summed and averaged in
// each bin (e.g. the value for 360nm is the average of the original values
// for all wavelengths between 360 and 370nm). Values in m^2.
const double kOzoneCrossSection[48] = {
1.18e-27, 2.182e-28, 2.818e-28, 6.636e-28, 1.527e-27, 2.763e-27, 5.52e-27,
8.451e-27, 1.582e-26, 2.316e-26, 3.669e-26, 4.924e-26, 7.752e-26, 9.016e-26,
1.48e-25, 1.602e-25, 2.139e-25, 2.755e-25, 3.091e-25, 3.5e-25, 4.266e-25,
4.672e-25, 4.398e-25, 4.701e-25, 5.019e-25, 4.305e-25, 3.74e-25, 3.215e-25,
2.662e-25, 2.238e-25, 1.852e-25, 1.473e-25, 1.209e-25, 9.423e-26, 7.455e-26,
6.566e-26, 5.105e-26, 4.15e-26, 4.228e-26, 3.237e-26, 2.451e-26, 2.801e-26,
2.534e-26, 1.624e-26, 1.465e-26, 2.078e-26, 1.383e-26, 7.105e-27
};
// From https://en.wikipedia.org/wiki/Dobson_unit, in molecules.m^-2.
const double kDobsonUnit = 2.687e20;
// Maximum number density of ozone molecules, in m^-3 (computed so at to get
// 300 Dobson units of ozone - for this we divide 300 DU by the integral of
// the ozone density profile defined below, which is equal to 15km).
const double kMaxOzoneNumberDensity = 300.0 * kDobsonUnit / 15000.0;
const double kRayleigh = 1.24062e-6;
const double kRayleighScaleHeight = 8000.0;
const double kMieScaleHeight = 1200.0;
const double kMieAngstromAlpha = 0.0;
const double kMieAngstromBeta = 5.328e-3;
const double kMieSingleScatteringAlbedo = 0.9;
const double kGroundAlbedo = 0.1;
AtmosphericModelSettings::AtmosphericModelSettings()
: m_skyBottomRadius(6360.0f)
, m_skyTopRadius(6420.0f)
, m_sunArcRadians(0.00045f)
, m_mieAnisotropy(0.8f)
{
DensityLayer rayleigh_density(0.0, 1.0, -1.0 / kRayleighScaleHeight, 0.0, 0.0);
DensityLayer mie_density(0.0, 1.0, -1.0 / kMieScaleHeight, 0.0, 0.0);
m_rayleighProfile.push_back(rayleigh_density);
m_mieProfile.push_back(mie_density);
// Density profile increasing linearly from 0 to 1 between 10 and 25km, and
// decreasing linearly from 1 to 0 between 25 and 40km. This is an approximate
// profile from http://www.kln.ac.lk/science/Chemistry/Teaching_Resources/
// Documents/Introduction%20to%20atmospheric%20chemistry.pdf (page 10).
m_absorptionProfile.push_back(DensityLayer(25000.0, 0.0, 0.0, 1.0 / 15000.0, -2.0 / 3.0));
m_absorptionProfile.push_back(DensityLayer(0.0, 0.0, 0.0, -1.0 / 15000.0, 8.0 / 3.0));
}
AtmosphericModelSettings::AtmosphericModelSettings(
DensityProfile& rayleighProfile,
DensityProfile& mieProfile,
DensityProfile& absorptionProfile)
: m_skyBottomRadius(6360.0f)
, m_skyTopRadius(6420.0f)
, m_rayleighProfile(rayleighProfile)
, m_mieProfile(mieProfile)
, m_absorptionProfile(absorptionProfile)
, m_sunArcRadians(0.00045f)
, m_mieAnisotropy(0.8f)
{
}
AtmosphericModelSettings::AtmosphericModelSettings(
F32 skyBottomRadius,
F32 skyTopRadius,
DensityProfile& rayleighProfile,
DensityProfile& mieProfile,
DensityProfile& absorptionProfile,
F32 sunArcRadians,
F32 mieAniso)
: m_skyBottomRadius(skyBottomRadius)
, m_skyTopRadius(skyTopRadius)
, m_rayleighProfile(rayleighProfile)
, m_mieProfile(mieProfile)
, m_absorptionProfile(absorptionProfile)
, m_sunArcRadians(sunArcRadians)
, m_mieAnisotropy(mieAniso)
{
}
bool AtmosphericModelSettings::operator==(const AtmosphericModelSettings& rhs) const
{
if (m_skyBottomRadius != rhs.m_skyBottomRadius)
{
return false;
}
if (m_skyTopRadius != rhs.m_skyTopRadius)
{
return false;
}
if (m_sunArcRadians != rhs.m_sunArcRadians)
{
return false;
}
if (m_mieAnisotropy != rhs.m_mieAnisotropy)
{
return false;
}
if (m_rayleighProfile != rhs.m_rayleighProfile)
{
return false;
}
if (m_mieProfile != rhs.m_mieProfile)
{
return false;
}
if (m_absorptionProfile != rhs.m_absorptionProfile)
{
return false;
}
return true;
}
void LLAtmosphere::initClass()
{
if (!gAtmosphere)
{
gAtmosphere = new LLAtmosphere;
}
}
void LLAtmosphere::cleanupClass()
{
if(gAtmosphere)
{
delete gAtmosphere;
}
gAtmosphere = NULL;
}
LLAtmosphere::LLAtmosphere()
{
for (int l = kLambdaMin; l <= kLambdaMax; l += 10)
{
double lambda = static_cast<double>(l) * 1e-3; // micro-meters
double mie = kMieAngstromBeta / kMieScaleHeight * pow(lambda, -kMieAngstromAlpha);
m_wavelengths.push_back(l);
m_solar_irradiance.push_back(kSolarIrradiance[(l - kLambdaMin) / 10]);
m_rayleigh_scattering.push_back(kRayleigh * pow(lambda, -4));
m_mie_scattering.push_back(mie * kMieSingleScatteringAlbedo);
m_mie_extinction.push_back(mie);
m_absorption_extinction.push_back(kMaxOzoneNumberDensity * kOzoneCrossSection[(l - kLambdaMin) / 10]);
m_ground_albedo.push_back(kGroundAlbedo);
}
AtmosphericModelSettings defaults;
configureAtmosphericModel(defaults);
}
LLAtmosphere::~LLAtmosphere()
{
// Cease referencing textures from atmosphere::model from our LLGLTextures wrappers for same.
if (m_transmittance)
{
m_transmittance->setTexName(0);
}
if (m_scattering)
{
m_scattering->setTexName(0);
}
if (m_mie_scatter_texture)
{
m_mie_scatter_texture->setTexName(0);
}
}
bool LLAtmosphere::configureAtmosphericModel(AtmosphericModelSettings& settings)
{
// TBD
return true;
}
LLGLTexture* LLAtmosphere::getTransmittance()
{
if (!m_transmittance)
{
m_transmittance = new LLGLTexture;
m_transmittance->generateGLTexture();
m_transmittance->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP);
m_transmittance->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR);
m_transmittance->setExplicitFormat(GL_RGB32F_ARB, GL_RGB, GL_FLOAT);
m_transmittance->setTarget(GL_TEXTURE_2D, LLTexUnit::TT_TEXTURE);
}
return m_transmittance;
}
LLGLTexture* LLAtmosphere::getScattering()
{
if (!m_scattering)
{
m_scattering = new LLGLTexture;
m_scattering->generateGLTexture();
m_scattering->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP);
m_scattering->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR);
m_scattering->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT);
m_scattering->setTarget(GL_TEXTURE_3D, LLTexUnit::TT_TEXTURE_3D);
}
return m_scattering;
}
LLGLTexture* LLAtmosphere::getMieScattering()
{
if (!m_mie_scatter_texture)
{
m_mie_scatter_texture = new LLGLTexture;
m_mie_scatter_texture->generateGLTexture();
m_mie_scatter_texture->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP);
m_mie_scatter_texture->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR);
m_mie_scatter_texture->setExplicitFormat(GL_RGB16F_ARB, GL_RGB, GL_FLOAT);
m_mie_scatter_texture->setTarget(GL_TEXTURE_3D, LLTexUnit::TT_TEXTURE_3D);
}
return m_mie_scatter_texture;
}
LLGLTexture* LLAtmosphere::getIlluminance()
{
if (!m_illuminance)
{
m_illuminance = new LLGLTexture;
m_illuminance->generateGLTexture();
m_illuminance->setAddressMode(LLTexUnit::eTextureAddressMode::TAM_CLAMP);
m_illuminance->setFilteringOption(LLTexUnit::eTextureFilterOptions::TFO_BILINEAR);
m_illuminance->setExplicitFormat(GL_RGB32F_ARB, GL_RGB, GL_FLOAT);
m_illuminance->setTarget(GL_TEXTURE_2D, LLTexUnit::TT_TEXTURE);
}
return m_illuminance;
}

View File

@ -0,0 +1,173 @@
/**
* @file llatmosphere.h
* @brief LLAtmosphere class
*
* $LicenseInfo:firstyear=2018&license=viewerlgpl$
* Second Life Viewer Source Code
* Copyright (C) 2018, Linden Research, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License only.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
* $/LicenseInfo$
*/
#ifndef LL_ATMOSPHERE_H
#define LL_ATMOSPHERE_H
#include "llglheaders.h"
#include "llgltexture.h"
// An atmosphere layer of width 'width' (in m), and whose density is defined as
// 'exp_term' * exp('exp_scale' * h) + 'linear_term' * h + 'constant_term',
// clamped to [0,1], and where h is the altitude (in m). 'exp_term' and
// 'constant_term' are unitless, while 'exp_scale' and 'linear_term' are in
// m^-1.
class DensityLayer {
public:
DensityLayer()
: width(0.0f)
, exp_term(0.0f)
, exp_scale(0.0f)
, linear_term(0.0f)
, constant_term(0.0f)
{
}
DensityLayer(float width, float exp_term, float exp_scale, float linear_term, float constant_term)
: width(width)
, exp_term(exp_term)
, exp_scale(exp_scale)
, linear_term(linear_term)
, constant_term(constant_term)
{
}
bool operator==(const DensityLayer& rhs) const
{
if (width != rhs.width)
{
return false;
}
if (exp_term != rhs.exp_term)
{
return false;
}
if (exp_scale != rhs.exp_scale)
{
return false;
}
if (linear_term != rhs.linear_term)
{
return false;
}
if (constant_term != rhs.constant_term)
{
return false;
}
return true;
}
float width = 1024.0f;
float exp_term = 1.0f;
float exp_scale = 1.0f;
float linear_term = 1.0f;
float constant_term = 0.0f;
};
typedef std::vector<DensityLayer> DensityProfile;
class AtmosphericModelSettings
{
public:
AtmosphericModelSettings();
AtmosphericModelSettings(
DensityProfile& rayleighProfile,
DensityProfile& mieProfile,
DensityProfile& absorptionProfile);
AtmosphericModelSettings(
F32 skyBottomRadius,
F32 skyTopRadius,
DensityProfile& rayleighProfile,
DensityProfile& mieProfile,
DensityProfile& absorptionProfile,
F32 sunArcRadians,
F32 mieAniso);
bool operator==(const AtmosphericModelSettings& rhs) const;
F32 m_skyBottomRadius;
F32 m_skyTopRadius;
DensityProfile m_rayleighProfile;
DensityProfile m_mieProfile;
DensityProfile m_absorptionProfile;
F32 m_sunArcRadians;
F32 m_mieAnisotropy;
};
class LLAtmosphere
{
public:
LLAtmosphere();
~LLAtmosphere();
static void initClass();
static void cleanupClass();
const LLAtmosphere& operator=(const LLAtmosphere& rhs)
{
LL_ERRS() << "Illegal operation!" << LL_ENDL;
return *this;
}
LLGLTexture* getTransmittance();
LLGLTexture* getScattering();
LLGLTexture* getMieScattering();
LLGLTexture* getIlluminance();
bool configureAtmosphericModel(AtmosphericModelSettings& settings);
protected:
LLAtmosphere(const LLAtmosphere& rhs)
{
*this = rhs;
}
LLPointer<LLGLTexture> m_transmittance;
LLPointer<LLGLTexture> m_scattering;
LLPointer<LLGLTexture> m_mie_scatter_texture;
LLPointer<LLGLTexture> m_illuminance;
std::vector<double> m_wavelengths;
std::vector<double> m_solar_irradiance;
std::vector<double> m_rayleigh_scattering;
std::vector<double> m_mie_scattering;
std::vector<double> m_mie_extinction;
std::vector<double> m_absorption_extinction;
std::vector<double> m_ground_albedo;
AtmosphericModelSettings m_settings;
};
extern LLAtmosphere* gAtmosphere;
#endif // LL_ATMOSPHERE_H

View File

@ -43,20 +43,13 @@
const F32 epsilon = 1e-7f;
const U16 RESOLUTION = 64;
#if LL_DARWIN
// mipmap generation on cubemap textures seems to be broken on the Mac for at least some cards.
// Since the cubemap is small (64x64 per face) and doesn't have any fine detail, turning off mipmaps is a usable workaround.
const BOOL use_cube_mipmaps = FALSE;
#else
const BOOL use_cube_mipmaps = FALSE; //current build works best without cube mipmaps
#endif
bool LLCubeMap::sUseCubeMaps = true;
LLCubeMap::LLCubeMap()
LLCubeMap::LLCubeMap(bool init_as_srgb)
: mTextureStage(0),
mTextureCoordStage(0),
mMatrixStage(0)
mMatrixStage(0),
mIssRGB(init_as_srgb)
{
mTargets[0] = GL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB;
mTargets[1] = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB;
@ -82,12 +75,17 @@ void LLCubeMap::initGL()
U32 texname = 0;
LLImageGL::generateTextures(1, &texname);
for (int i = 0; i < 6; i++)
{
mImages[i] = new LLImageGL(64, 64, 4, (use_cube_mipmaps? TRUE : FALSE));
mImages[i] = new LLImageGL(RESOLUTION, RESOLUTION, 4, FALSE);
#if USE_SRGB_DECODE
if (mIssRGB) {
mImages[i]->setExplicitFormat(GL_SRGB8_ALPHA8, GL_RGBA);
}
#endif
mImages[i]->setTarget(mTargets[i], LLTexUnit::TT_CUBE_MAP);
mRawImages[i] = new LLImageRaw(64, 64, 4);
mRawImages[i] = new LLImageRaw(RESOLUTION, RESOLUTION, 4);
mImages[i]->createGLTexture(0, mRawImages[i], texname);
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_CUBE_MAP, texname);
@ -154,7 +152,7 @@ void LLCubeMap::initGLData()
{
for (int i = 0; i < 6; i++)
{
mImages[i]->setSubImage(mRawImages[i], 0, 0, 64, 64);
mImages[i]->setSubImage(mRawImages[i], 0, 0, RESOLUTION, RESOLUTION);
}
}
@ -484,7 +482,7 @@ void LLCubeMap::paintIn(LLVector3 dir[4], const LLColor4U& col)
td[offset + cc] = U8((td[offset + cc] + col.mV[cc]) * 0.5);
}
}
mImages[side]->setSubImage(mRawImages[side], 0, 0, 64, 64);
mImages[side]->setSubImage(mRawImages[side], 0, 0, RESOLUTION, RESOLUTION);
}
}

View File

@ -36,8 +36,9 @@ class LLVector3;
// Environment map hack!
class LLCubeMap : public LLRefCount
{
bool mIssRGB;
public:
LLCubeMap();
LLCubeMap(bool init_as_srgb);
void init(const std::vector<LLPointer<LLImageRaw> >& rawimages);
void initGL();
void initRawData(const std::vector<LLPointer<LLImageRaw> >& rawimages);

View File

@ -36,6 +36,7 @@
#include "llsys.h"
#include "llgl.h"
#include "llglstates.h"
#include "llrender.h"
#include "llerror.h"
@ -49,6 +50,10 @@
#include "llglheaders.h"
#include "llglslshader.h"
#if LL_WINDOWS
#include "lldxhardware.h"
#endif
#ifdef _DEBUG
//#define GL_STATE_VERIFY
#endif
@ -394,6 +399,8 @@ PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB = NULL;
PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = NULL;
#if LL_WINDOWS
PFNWGLGETGPUIDSAMDPROC wglGetGPUIDsAMD = NULL;
PFNWGLGETGPUINFOAMDPROC wglGetGPUInfoAMD = NULL;
PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT = NULL;
#endif
@ -413,6 +420,7 @@ LLGLManager::LLGLManager() :
mHasMultitexture(FALSE),
mHasATIMemInfo(FALSE),
mHasAMDAssociations(FALSE),
mHasNVXMemInfo(FALSE),
mNumTextureUnits(1),
mHasMipMapGeneration(FALSE),
@ -497,7 +505,16 @@ void LLGLManager::initWGL()
{
LL_WARNS("RenderInit") << "No ARB create context extensions" << LL_ENDL;
}
// For retreiving information per AMD adapter,
// because we can't trust curently selected/default one when there are multiple
mHasAMDAssociations = ExtensionExists("WGL_AMD_gpu_association", gGLHExts.mSysExts);
if (mHasAMDAssociations)
{
GLH_EXT_NAME(wglGetGPUIDsAMD) = (PFNWGLGETGPUIDSAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUIDsAMD");
GLH_EXT_NAME(wglGetGPUInfoAMD) = (PFNWGLGETGPUINFOAMDPROC)GLH_EXT_GET_PROC_ADDRESS("wglGetGPUInfoAMD");
}
if (ExtensionExists("WGL_EXT_swap_control", gGLHExts.mSysExts))
{
GLH_EXT_NAME(wglSwapIntervalEXT) = (PFNWGLSWAPINTERVALEXTPROC)GLH_EXT_GET_PROC_ADDRESS("wglSwapIntervalEXT");
@ -683,23 +700,78 @@ bool LLGLManager::initGL()
stop_glerror();
S32 old_vram = mVRAM;
mVRAM = 0;
if (mHasATIMemInfo)
#if LL_WINDOWS
if (mHasAMDAssociations)
{
GLuint gl_gpus_count = wglGetGPUIDsAMD(0, 0);
if (gl_gpus_count > 0)
{
GLuint* ids = new GLuint[gl_gpus_count];
wglGetGPUIDsAMD(gl_gpus_count, ids);
GLuint mem_mb = 0;
for (U32 i = 0; i < gl_gpus_count; i++)
{
wglGetGPUInfoAMD(ids[i],
WGL_GPU_RAM_AMD,
GL_UNSIGNED_INT,
sizeof(GLuint),
&mem_mb);
if (mVRAM < mem_mb)
{
// basically pick the best AMD and trust driver/OS to know to switch
mVRAM = mem_mb;
}
}
}
if (mVRAM != 0)
{
LL_WARNS("RenderInit") << "VRAM Detected (AMDAssociations):" << mVRAM << LL_ENDL;
}
}
#endif
if (mHasATIMemInfo && mVRAM == 0)
{ //ask the gl how much vram is free at startup and attempt to use no more than half of that
S32 meminfo[4];
glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo);
mVRAM = meminfo[0]/1024;
mVRAM = meminfo[0] / 1024;
LL_WARNS("RenderInit") << "VRAM Detected (ATIMemInfo):" << mVRAM << LL_ENDL;
}
else if (mHasNVXMemInfo)
if (mHasNVXMemInfo && mVRAM == 0)
{
S32 dedicated_memory;
glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated_memory);
mVRAM = dedicated_memory/1024;
LL_WARNS("RenderInit") << "VRAM Detected (NVXMemInfo):" << mVRAM << LL_ENDL;
}
#if LL_WINDOWS
if (mVRAM < 256)
{ //something likely went wrong using the above extensions, fall back to old method
{
// Something likely went wrong using the above extensions
// try WMI first and fall back to old method (from dxdiag) if all else fails
// Function will check all GPUs WMI knows of and will pick up the one with most
// memory. We need to check all GPUs because system can switch active GPU to
// weaker one, to preserve power when not under load.
S32 mem = LLDXHardware::getMBVideoMemoryViaWMI();
if (mem != 0)
{
mVRAM = mem;
LL_WARNS("RenderInit") << "VRAM Detected (WMI):" << mVRAM<< LL_ENDL;
}
}
#endif
if (mVRAM < 256 && old_vram > 0)
{
// fall back to old method
// Note: on Windows value will be from LLDXHardware.
// Either received via dxdiag or via WMI by id from dxdiag.
mVRAM = old_vram;
}
@ -961,7 +1033,7 @@ void LLGLManager::initExtensions()
mHasTextureRectangle = FALSE;
#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts); //Basic AMD method, also see mHasAMDAssociations
mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
@ -998,6 +1070,12 @@ void LLGLManager::initExtensions()
mHassRGBFramebuffer = ExtensionExists("GL_EXT_framebuffer_sRGB", gGLHExts.mSysExts);
#endif
#ifdef GL_EXT_texture_sRGB_decode
mHasTexturesRGBDecode = ExtensionExists("GL_EXT_texture_sRGB_decode", gGLHExts.mSysExts);
#else
mHasTexturesRGBDecode = ExtensionExists("GL_ARB_texture_sRGB_decode", gGLHExts.mSysExts);
#endif
mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f;
mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
@ -2044,7 +2122,8 @@ LLGLState::LLGLState(LLGLenum state, S32 enabled) :
if (mState)
{
mWasEnabled = sStateMap[state];
llassert(mWasEnabled == glIsEnabled(state));
// we can't actually assert on this as queued changes to state are not reflected by glIsEnabled
//llassert(mWasEnabled == glIsEnabled(state));
setEnabled(enabled);
stop_glerror();
}
@ -2267,6 +2346,17 @@ LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& mode
}
}
void LLGLUserClipPlane::disable()
{
if (mApply)
{
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
mApply = false;
}
void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
{
glh::matrix4f& P = mProjection;
@ -2295,12 +2385,7 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
LLGLUserClipPlane::~LLGLUserClipPlane()
{
if (mApply)
{
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
}
disable();
}
LLGLNamePool::LLGLNamePool()
@ -2476,27 +2561,45 @@ void LLGLDepthTest::checkState()
}
}
LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P, U32 layer)
LLGLSquashToFarClip::LLGLSquashToFarClip()
{
glh::matrix4f proj = get_current_projection();
setProjectionMatrix(proj, 0);
}
LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f& P, U32 layer)
{
setProjectionMatrix(P, layer);
}
void LLGLSquashToFarClip::setProjectionMatrix(glh::matrix4f& projection, U32 layer)
{
F32 depth = 0.99999f - 0.0001f * layer;
for (U32 i = 0; i < 4; i++)
{
P.element(2, i) = P.element(3, i) * depth;
projection.element(2, i) = projection.element(3, i) * depth;
}
LLRender::eMatrixMode last_matrix_mode = gGL.getMatrixMode();
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.pushMatrix();
gGL.loadMatrix(P.m);
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.loadMatrix(projection.m);
gGL.matrixMode(last_matrix_mode);
}
LLGLSquashToFarClip::~LLGLSquashToFarClip()
{
LLRender::eMatrixMode last_matrix_mode = gGL.getMatrixMode();
gGL.matrixMode(LLRender::MM_PROJECTION);
gGL.popMatrix();
gGL.matrixMode(LLRender::MM_MODELVIEW);
gGL.matrixMode(last_matrix_mode);
}
@ -2559,6 +2662,43 @@ void LLGLSyncFence::wait()
#endif
}
LLGLSPipelineSkyBox::LLGLSPipelineSkyBox()
: mAlphaTest(GL_ALPHA_TEST)
, mCullFace(GL_CULL_FACE)
, mSquashClip()
{
if (!LLGLSLShader::sNoFixedFunction)
{
glDisable(GL_LIGHTING);
glDisable(GL_FOG);
glDisable(GL_CLIP_PLANE0);
}
}
LLGLSPipelineSkyBox::~LLGLSPipelineSkyBox()
{
if (!LLGLSLShader::sNoFixedFunction)
{
glEnable(GL_LIGHTING);
glEnable(GL_FOG);
glEnable(GL_CLIP_PLANE0);
}
}
LLGLSPipelineDepthTestSkyBox::LLGLSPipelineDepthTestSkyBox(bool depth_test, bool depth_write)
: LLGLSPipelineSkyBox()
, mDepth(depth_test ? GL_TRUE : GL_FALSE, depth_write ? GL_TRUE : GL_FALSE, GL_LEQUAL)
{
}
LLGLSPipelineBlendSkyBox::LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_write)
: LLGLSPipelineDepthTestSkyBox(depth_test, depth_write)
, mBlend(GL_BLEND)
{
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
#if LL_WINDOWS
// Expose desired use of high-performance graphics processor to Optimus driver
extern "C"

View File

@ -78,6 +78,7 @@ public:
// Extensions used by everyone
BOOL mHasMultitexture;
BOOL mHasATIMemInfo;
BOOL mHasAMDAssociations;
BOOL mHasNVXMemInfo;
S32 mNumTextureUnits;
BOOL mHasMipMapGeneration;
@ -118,6 +119,7 @@ public:
BOOL mHasDebugOutput;
BOOL mHassRGBTexture;
BOOL mHassRGBFramebuffer;
BOOL mHasTexturesRGBDecode;
// Vendor-specific extensions
BOOL mIsATI;
@ -348,6 +350,7 @@ public:
~LLGLUserClipPlane();
void setPlane(F32 a, F32 b, F32 c, F32 d);
void disable();
private:
bool mApply;
@ -360,14 +363,17 @@ private:
Modify and load projection matrix to push depth values to far clip plane.
Restores projection matrix on destruction.
GL_MODELVIEW_MATRIX is active whenever program execution
leaves this class.
Saves/restores matrix mode around projection manipulation.
Does not stack.
*/
class LLGLSquashToFarClip
{
public:
LLGLSquashToFarClip(glh::matrix4f projection, U32 layer = 0);
LLGLSquashToFarClip();
LLGLSquashToFarClip(glh::matrix4f& projection, U32 layer = 0);
void setProjectionMatrix(glh::matrix4f& projection, U32 layer);
~LLGLSquashToFarClip();
};

View File

@ -1,5 +1,5 @@
/**
* @file llphoenixfunc.h
* @file llglcommonfunc.h
* @brief File include common opengl code snippets
*
* $LicenseInfo:firstyear=2003&license=viewerlgpl$

View File

@ -618,6 +618,8 @@ extern PFNGLVARIANTARRAYOBJECTATIPROC glVariantObjectArrayATI;
extern PFNGLGETVARIANTARRAYOBJECTFVATIPROC glGetVariantArrayObjectfvATI;
extern PFNGLGETVARIANTARRAYOBJECTIVATIPROC glGetVariantArrayObjectivATI;
extern PFNWGLGETGPUIDSAMDPROC wglGetGPUIDsAMD;
extern PFNWGLGETGPUINFOAMDPROC wglGetGPUInfoAMD;
extern PFNWGLSWAPINTERVALEXTPROC wglSwapIntervalEXT;
// GL_ARB_occlusion_query

View File

@ -37,12 +37,6 @@
#include "OpenGL/OpenGL.h"
#endif
#ifdef LL_RELEASE_FOR_DOWNLOAD
#define UNIFORM_ERRS LL_WARNS_ONCE("Shader")
#else
#define UNIFORM_ERRS LL_ERRS("Shader")
#endif
// Lots of STL stuff in here, using namespace std to keep things more readable
using std::vector;
using std::pair;
@ -84,6 +78,12 @@ LLShaderFeatures::LLShaderFeatures()
, hasObjectSkinning(false)
, hasAtmospherics(false)
, hasGamma(false)
, hasSrgb(false)
, encodesNormal(false)
, isDeferred(false)
, hasIndirect(false)
, hasShadows(false)
, hasAmbientOcclusion(false)
, mIndexedTextureChannels(0)
, disableTextureIndex(false)
, hasAlphaMask(false)
@ -344,13 +344,13 @@ void LLGLSLShader::unloadInternal()
{
GLhandleARB obj[1024];
GLsizei count;
glGetAttachedObjectsARB(mProgramObject, 1024, &count, obj);
glGetAttachedObjectsARB(mProgramObject, sizeof(obj)/sizeof(obj[0]), &count, obj);
for (GLsizei i = 0; i < count; i++)
{
glDetachObjectARB(mProgramObject, obj[i]);
glDeleteObjectARB(obj[i]);
}
glDeleteObjectARB(obj[i]);
}
glDeleteObjectARB(mProgramObject);
@ -448,12 +448,12 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
}
if( !success )
{
LL_WARNS("ShaderLoading") << "Failed to link shader: " << mName << LL_ENDL;
LL_SHADER_LOADING_WARNS() << "Failed to link shader: " << mName << LL_ENDL;
// Try again using a lower shader level;
if (mShaderLevel > 0)
{
LL_WARNS("ShaderLoading") << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
LL_SHADER_LOADING_WARNS() << "Failed to link using shader level " << mShaderLevel << " trying again using shader level " << (mShaderLevel - 1) << LL_ENDL;
mShaderLevel--;
return createShader(attributes,uniforms);
}
@ -485,18 +485,33 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
return success;
}
BOOL LLGLSLShader::attachObject(std::string object)
{
if (LLShaderMgr::instance()->mShaderObjects.count(object) > 0)
BOOL LLGLSLShader::attachVertexObject(std::string object_path) {
if (LLShaderMgr::instance()->mVertexShaderObjects.count(object_path) > 0)
{
stop_glerror();
glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mShaderObjects[object]);
glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mVertexShaderObjects[object_path]);
stop_glerror();
return TRUE;
}
else
{
LL_WARNS("ShaderLoading") << "Attempting to attach shader object that hasn't been compiled: " << object << LL_ENDL;
LL_SHADER_LOADING_WARNS() << "Attempting to attach shader object: '" << object_path << "' that hasn't been compiled." << LL_ENDL;
return FALSE;
}
}
BOOL LLGLSLShader::attachFragmentObject(std::string object_path)
{
if (LLShaderMgr::instance()->mFragmentShaderObjects.count(object_path) > 0)
{
stop_glerror();
glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mFragmentShaderObjects[object_path]);
stop_glerror();
return TRUE;
}
else
{
LL_SHADER_LOADING_WARNS() << "Attempting to attach shader object: '" << object_path << "' that hasn't been compiled." << LL_ENDL;
return FALSE;
}
}
@ -511,7 +526,7 @@ void LLGLSLShader::attachObject(GLhandleARB object)
}
else
{
LL_WARNS("ShaderLoading") << "Attempting to attach non existing shader object. " << LL_ENDL;
LL_SHADER_LOADING_WARNS() << "Attempting to attach non existing shader object. " << LL_ENDL;
}
}
@ -690,6 +705,11 @@ void LLGLSLShader::mapUniform(GLint index, const vector<LLStaticHashedString> *
}
}
void LLGLSLShader::clearPermutations()
{
mDefines.clear();
}
void LLGLSLShader::addPermutation(std::string name, std::string value)
{
mDefines[name] = value;
@ -759,18 +779,19 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
S32 diffuseMap = glGetUniformLocationARB(mProgramObject, "diffuseMap");
S32 specularMap = glGetUniformLocationARB(mProgramObject, "specularMap");
S32 bumpMap = glGetUniformLocationARB(mProgramObject, "bumpMap");
S32 altDiffuseMap = glGetUniformLocationARB(mProgramObject, "altDiffuseMap");
S32 environmentMap = glGetUniformLocationARB(mProgramObject, "environmentMap");
std::set<S32> skip_index;
if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap))
if (-1 != diffuseMap && (-1 != specularMap || -1 != bumpMap || -1 != environmentMap || -1 != altDiffuseMap))
{
GLenum type;
GLsizei length;
GLint size = -1;
char name[1024];
diffuseMap = specularMap = bumpMap = environmentMap = -1;
diffuseMap = altDiffuseMap = specularMap = bumpMap = environmentMap = -1;
for (S32 i = 0; i < activeCount; i++)
{
@ -790,12 +811,6 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
continue;
}
if (-1 == specularMap && std::string(name) == "specularMap")
{
specularMap = i;
continue;
}
if (-1 == bumpMap && std::string(name) == "bumpMap")
{
bumpMap = i;
@ -807,6 +822,12 @@ BOOL LLGLSLShader::mapUniforms(const vector<LLStaticHashedString> * uniforms)
environmentMap = i;
continue;
}
if (-1 == altDiffuseMap && std::string(name) == "altDiffuseMap")
{
altDiffuseMap = i;
continue;
}
}
bool specularDiff = specularMap < diffuseMap && -1 != specularMap;
@ -858,7 +879,7 @@ BOOL LLGLSLShader::link(BOOL suppress_errors)
{
BOOL success = LLShaderMgr::instance()->linkProgramObject(mProgramObject, suppress_errors);
if (!suppress_errors)
if (!success && !suppress_errors)
{
LLShaderMgr::instance()->dumpObjectLog(mProgramObject, !success, mName);
}
@ -916,19 +937,19 @@ void LLGLSLShader::bindNoShader(void)
}
}
S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
S32 LLGLSLShader::bindTexture(const std::string &uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace)
{
S32 channel = 0;
channel = getUniformLocation(uniform);
return bindTexture(channel, texture, mode);
return bindTexture(channel, texture, mode, colorspace);
}
S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode)
S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace colorspace)
{
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
return -1;
}
@ -937,6 +958,7 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLTexture *texture, LLTexUnit::eTextu
if (uniform > -1)
{
gGL.getTexUnit(uniform)->bind(texture, mode);
gGL.getTexUnit(uniform)->setTextureColorSpace(colorspace);
}
return uniform;
@ -954,7 +976,7 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
return -1;
}
@ -968,11 +990,11 @@ S32 LLGLSLShader::unbindTexture(S32 uniform, LLTexUnit::eTextureType mode)
return uniform;
}
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space)
{
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
return -1;
}
S32 index = mTexture[uniform];
@ -980,21 +1002,22 @@ S32 LLGLSLShader::enableTexture(S32 uniform, LLTexUnit::eTextureType mode)
{
gGL.getTexUnit(index)->activate();
gGL.getTexUnit(index)->enable(mode);
gGL.getTexUnit(index)->setTextureColorSpace(space);
}
return index;
}
S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode, LLTexUnit::eTextureColorSpace space)
{
if (uniform < 0 || uniform >= (S32)mTexture.size())
{
UNIFORM_ERRS << "Uniform out of range: " << uniform << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform out of range: " << uniform << LL_ENDL;
return -1;
}
S32 index = mTexture[uniform];
if (index != -1 && gGL.getTexUnit(index)->getCurrType() != LLTexUnit::TT_NONE)
{
if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode)
if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode && gGL.getTexUnit(index)->getCurrColorSpace() != space)
{
if (gDebugSession)
{
@ -1017,7 +1040,7 @@ void LLGLSLShader::uniform1i(U32 index, GLint x)
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@ -1039,7 +1062,7 @@ void LLGLSLShader::uniform1f(U32 index, GLfloat x)
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@ -1061,7 +1084,7 @@ void LLGLSLShader::uniform2f(U32 index, GLfloat x, GLfloat y)
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@ -1084,7 +1107,7 @@ void LLGLSLShader::uniform3f(U32 index, GLfloat x, GLfloat y, GLfloat z)
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@ -1107,7 +1130,7 @@ void LLGLSLShader::uniform4f(U32 index, GLfloat x, GLfloat y, GLfloat z, GLfloat
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@ -1130,7 +1153,7 @@ void LLGLSLShader::uniform1iv(U32 index, U32 count, const GLint* v)
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@ -1153,7 +1176,7 @@ void LLGLSLShader::uniform1fv(U32 index, U32 count, const GLfloat* v)
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@ -1176,7 +1199,7 @@ void LLGLSLShader::uniform2fv(U32 index, U32 count, const GLfloat* v)
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@ -1199,7 +1222,7 @@ void LLGLSLShader::uniform3fv(U32 index, U32 count, const GLfloat* v)
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@ -1222,7 +1245,7 @@ void LLGLSLShader::uniform4fv(U32 index, U32 count, const GLfloat* v)
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@ -1245,7 +1268,7 @@ void LLGLSLShader::uniformMatrix2fv(U32 index, U32 count, GLboolean transpose, c
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@ -1262,7 +1285,7 @@ void LLGLSLShader::uniformMatrix3fv(U32 index, U32 count, GLboolean transpose, c
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@ -1279,7 +1302,7 @@ void LLGLSLShader::uniformMatrix3x4fv(U32 index, U32 count, GLboolean transpose,
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}
@ -1296,7 +1319,7 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
{
if (mUniform.size() <= index)
{
UNIFORM_ERRS << "Uniform index out of bounds." << LL_ENDL;
LL_SHADER_UNIFORM_ERRS() << "Uniform index out of bounds." << LL_ENDL;
return;
}

Some files were not shown because too many files have changed in this diff Show More