phoenix-firestorm/indra/newview/llsettingssky.cpp

553 lines
21 KiB
C++

/**
* @file llsettingssky.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 "llviewerprecompiledheaders.h"
#include "llviewercontrol.h"
#include "llsettingssky.h"
#include <algorithm>
#include <boost/make_shared.hpp>
#include "lltrace.h"
#include "llfasttimer.h"
#include "v3colorutil.h"
#include "llglslshader.h"
#include "llviewershadermgr.h"
#include "llenvironment.h"
#include "llsky.h"
//=========================================================================
namespace
{
const LLVector3 DUE_EAST(-1.0f, 0.0f, 0.0);
LLTrace::BlockTimerStatHandle FTM_BLEND_ENVIRONMENT("Blending Environment Params");
LLTrace::BlockTimerStatHandle FTM_UPDATE_ENVIRONMENT("Update Environment Params");
LLQuaternion body_position_from_angles(F32 azimuth, F32 altitude);
}
//=========================================================================
const std::string LLSettingsSky::SETTING_AMBIENT("ambient");
const std::string LLSettingsSky::SETTING_BLOOM_TEXTUREID("bloom_id");
const std::string LLSettingsSky::SETTING_BLUE_DENSITY("blue_density");
const std::string LLSettingsSky::SETTING_BLUE_HORIZON("blue_horizon");
const std::string LLSettingsSky::SETTING_CLOUD_COLOR("cloud_color");
const std::string LLSettingsSky::SETTING_CLOUD_POS_DENSITY1("cloud_pos_density1");
const std::string LLSettingsSky::SETTING_CLOUD_POS_DENSITY2("cloud_pos_density2");
const std::string LLSettingsSky::SETTING_CLOUD_SCALE("cloud_scale");
const std::string LLSettingsSky::SETTING_CLOUD_SCROLL_RATE("cloud_scroll_rate");
const std::string LLSettingsSky::SETTING_CLOUD_SHADOW("cloud_shadow");
const std::string LLSettingsSky::SETTING_CLOUD_TEXTUREID("cloud_id");
const std::string LLSettingsSky::SETTING_DENSITY_MULTIPLIER("density_multiplier");
const std::string LLSettingsSky::SETTING_DISTANCE_MULTIPLIER("distance_multiplier");
const std::string LLSettingsSky::SETTING_DOME_OFFSET("dome_offset");
const std::string LLSettingsSky::SETTING_DOME_RADIUS("dome_radius");
const std::string LLSettingsSky::SETTING_GAMMA("gamma");
const std::string LLSettingsSky::SETTING_GLOW("glow");
const std::string LLSettingsSky::SETTING_HAZE_DENSITY("haze_density");
const std::string LLSettingsSky::SETTING_HAZE_HORIZON("haze_horizon");
const std::string LLSettingsSky::SETTING_LIGHT_NORMAL("lightnorm");
const std::string LLSettingsSky::SETTING_MAX_Y("max_y");
const std::string LLSettingsSky::SETTING_MOON_ROTATION("moon_rotation");
const std::string LLSettingsSky::SETTING_MOON_TEXTUREID("moon_id");
const std::string LLSettingsSky::SETTING_NAME("name");
const std::string LLSettingsSky::SETTING_STAR_BRIGHTNESS("star_brightness");
const std::string LLSettingsSky::SETTING_SUNLIGHT_COLOR("sunlight_color");
const std::string LLSettingsSky::SETTING_SUN_ROTATION("sun_rotation");
const std::string LLSettingsSky::SETTING_SUN_TEXUTUREID("sun_id");
const std::string LLSettingsSky::SETTING_LEGACY_EAST_ANGLE("east_angle");
const std::string LLSettingsSky::SETTING_LEGACY_ENABLE_CLOUD_SCROLL("enable_cloud_scroll");
const std::string LLSettingsSky::SETTING_LEGACY_SUN_ANGLE("sun_angle");
//=========================================================================
LLSettingsSky::LLSettingsSky(const LLSD &data) :
LLSettingsBase(data)
{
}
LLSettingsSky::LLSettingsSky():
LLSettingsBase()
{
}
LLSettingsSky::stringset_t LLSettingsSky::getSlerpKeys() const
{
static stringset_t slepSet;
if (slepSet.empty())
{
slepSet.insert(SETTING_SUN_ROTATION);
slepSet.insert(SETTING_MOON_ROTATION);
}
return slepSet;
}
LLSettingsSky::ptr_t LLSettingsSky::buildFromLegacyPreset(const std::string &name, const LLSD &oldsettings)
{
LLSD newsettings(defaults());
newsettings[SETTING_NAME] = name;
if (oldsettings.has(SETTING_AMBIENT))
{
newsettings[SETTING_AMBIENT] = LLColor4(oldsettings[SETTING_AMBIENT]).getValue();
}
if (oldsettings.has(SETTING_BLUE_DENSITY))
{
newsettings[SETTING_BLUE_DENSITY] = LLColor4(oldsettings[SETTING_BLUE_DENSITY]).getValue();
}
if (oldsettings.has(SETTING_BLUE_HORIZON))
{
newsettings[SETTING_BLUE_HORIZON] = LLColor4(oldsettings[SETTING_BLUE_HORIZON]).getValue();
}
if (oldsettings.has(SETTING_CLOUD_COLOR))
{
newsettings[SETTING_CLOUD_COLOR] = LLColor4(oldsettings[SETTING_CLOUD_COLOR]).getValue();
}
if (oldsettings.has(SETTING_CLOUD_POS_DENSITY1))
{
newsettings[SETTING_CLOUD_POS_DENSITY1] = LLColor4(oldsettings[SETTING_CLOUD_POS_DENSITY1]).getValue();
}
if (oldsettings.has(SETTING_CLOUD_POS_DENSITY2))
{
newsettings[SETTING_CLOUD_POS_DENSITY2] = LLColor4(oldsettings[SETTING_CLOUD_POS_DENSITY2]).getValue();
}
if (oldsettings.has(SETTING_CLOUD_SCALE))
{
newsettings[SETTING_CLOUD_SCALE] = LLSD::Real(oldsettings[SETTING_CLOUD_SCALE][0].asReal());
}
if (oldsettings.has(SETTING_CLOUD_SCROLL_RATE))
{
LLVector2 cloud_scroll(oldsettings[SETTING_CLOUD_SCROLL_RATE]);
if (oldsettings.has(SETTING_LEGACY_ENABLE_CLOUD_SCROLL))
{
LLSD enabled = oldsettings[SETTING_LEGACY_ENABLE_CLOUD_SCROLL];
if (!enabled[0].asBoolean())
cloud_scroll.mV[0] = 0.0f;
if (!enabled[1].asBoolean())
cloud_scroll.mV[1] = 0.0f;
}
newsettings[SETTING_CLOUD_SCROLL_RATE] = cloud_scroll.getValue();
}
if (oldsettings.has(SETTING_CLOUD_SHADOW))
{
newsettings[SETTING_CLOUD_SHADOW] = LLSD::Real(oldsettings[SETTING_CLOUD_SHADOW][0].asReal());
}
if (oldsettings.has(SETTING_DENSITY_MULTIPLIER))
{
newsettings[SETTING_DENSITY_MULTIPLIER] = LLSD::Real(oldsettings[SETTING_DENSITY_MULTIPLIER][0].asReal());
}
if (oldsettings.has(SETTING_DISTANCE_MULTIPLIER))
{
newsettings[SETTING_DISTANCE_MULTIPLIER] = LLSD::Real(oldsettings[SETTING_DISTANCE_MULTIPLIER][0].asReal());
}
if (oldsettings.has(SETTING_GAMMA))
{
newsettings[SETTING_GAMMA] = LLVector4(oldsettings[SETTING_GAMMA]).getValue();
}
if (oldsettings.has(SETTING_GLOW))
{
newsettings[SETTING_GLOW] = LLColor4(oldsettings[SETTING_GLOW]).getValue();
}
if (oldsettings.has(SETTING_HAZE_DENSITY))
{
newsettings[SETTING_HAZE_DENSITY] = LLSD::Real(oldsettings[SETTING_HAZE_DENSITY][0].asReal());
}
if (oldsettings.has(SETTING_HAZE_HORIZON))
{
newsettings[SETTING_HAZE_HORIZON] = LLSD::Real(oldsettings[SETTING_HAZE_HORIZON][0].asReal());
}
if (oldsettings.has(SETTING_LIGHT_NORMAL))
{
newsettings[SETTING_LIGHT_NORMAL] = LLVector4(oldsettings[SETTING_LIGHT_NORMAL]).getValue();
}
if (oldsettings.has(SETTING_MAX_Y))
{
newsettings[SETTING_MAX_Y] = LLSD::Real(oldsettings[SETTING_MAX_Y][0].asReal());
}
if (oldsettings.has(SETTING_STAR_BRIGHTNESS))
{
newsettings[SETTING_STAR_BRIGHTNESS] = LLSD::Real(oldsettings[SETTING_STAR_BRIGHTNESS].asReal());
}
if (oldsettings.has(SETTING_SUNLIGHT_COLOR))
{
newsettings[SETTING_SUNLIGHT_COLOR] = LLColor4(oldsettings[SETTING_SUNLIGHT_COLOR]).getValue();
}
// dfltsetting[SETTING_DOME_OFFSET] = LLSD::Real(0.96f);
// dfltsetting[SETTING_DOME_RADIUS] = LLSD::Real(15000.f);
//
// dfltsetting[SETTING_MOON_ROTATION] = moonquat.getValue();
// dfltsetting[SETTING_SUN_ROTATION] = sunquat.getValue();
//
// dfltsetting[SETTING_BLOOM_TEXTUREID] = LLUUID::null;
// dfltsetting[SETTING_CLOUD_TEXTUREID] = LLUUID::null;
// dfltsetting[SETTING_MOON_TEXTUREID] = IMG_SUN; // gMoonTextureID; // These two are returned by the login... wow!
// dfltsetting[SETTING_SUN_TEXUTUREID] = IMG_MOON; // gSunTextureID;
if (oldsettings.has(SETTING_LEGACY_EAST_ANGLE) && oldsettings.has(SETTING_LEGACY_SUN_ANGLE))
{ // convert the east and sun angles into a quaternion.
F32 azimuth = oldsettings[SETTING_LEGACY_EAST_ANGLE].asReal();
F32 altitude = oldsettings[SETTING_LEGACY_SUN_ANGLE].asReal();
LLQuaternion sunquat = ::body_position_from_angles(azimuth, altitude);
LLQuaternion moonquat = ~sunquat;
newsettings[SETTING_SUN_ROTATION] = sunquat.getValue();
newsettings[SETTING_MOON_ROTATION] = moonquat.getValue();
}
LLSettingsSky::ptr_t skyp = boost::make_shared<LLSettingsSky>(newsettings);
skyp->update();
return skyp;
}
LLSettingsSky::ptr_t LLSettingsSky::buildDefaultSky()
{
LLSD settings = LLSettingsSky::defaults();
LLSettingsSky::ptr_t skyp = boost::make_shared<LLSettingsSky>(settings);
//skyp->update();
return skyp;
}
// Settings status
LLSettingsSky::ptr_t LLSettingsSky::blend(const LLSettingsSky::ptr_t &other, F32 mix) const
{
LL_RECORD_BLOCK_TIME(FTM_BLEND_ENVIRONMENT);
LL_INFOS("WINDLIGHT", "SKY", "EEP") << "Blending new sky settings object." << LL_ENDL;
LLSettingsSky::ptr_t skyp = boost::make_shared<LLSettingsSky>(mSettings);
// the settings in the initial constructor are references tho this' settings block.
// They will be replaced in the following lerp
skyp->lerpSettings(*other, mix);
return skyp;
}
LLSD LLSettingsSky::defaults()
{
LLSD dfltsetting;
LLQuaternion sunquat;
sunquat.setEulerAngles(1.39626, 0.0, 0.0); // 80deg Azumith/0deg East
LLQuaternion moonquat = ~sunquat;
// Magic constants copied form dfltsetting.xml
dfltsetting[SETTING_AMBIENT] = LLColor4::white.getValue();
dfltsetting[SETTING_BLUE_DENSITY] = LLColor4(0.2447, 0.4487, 0.7599, 1.0).getValue();
dfltsetting[SETTING_BLUE_HORIZON] = LLColor4(0.4954, 0.4954, 0.6399, 1.0).getValue();
dfltsetting[SETTING_CLOUD_COLOR] = LLColor4(0.4099, 0.4099, 0.4099, 1.0).getValue();
dfltsetting[SETTING_CLOUD_POS_DENSITY1] = LLColor4(1.0000, 0.5260, 1.0000, 1.0).getValue();
dfltsetting[SETTING_CLOUD_POS_DENSITY2] = LLColor4(1.0000, 0.5260, 1.0000, 1.0).getValue();
dfltsetting[SETTING_CLOUD_SCALE] = LLSD::Real(0.4199);
dfltsetting[SETTING_CLOUD_SCROLL_RATE] = LLSDArray(10.1999)(10.0109);
dfltsetting[SETTING_CLOUD_SHADOW] = LLSD::Real(0.2699);
dfltsetting[SETTING_DENSITY_MULTIPLIER] = LLSD::Real(0.0001);
dfltsetting[SETTING_DISTANCE_MULTIPLIER] = LLSD::Real(0.8000);
dfltsetting[SETTING_DOME_OFFSET] = LLSD::Real(0.96f);
dfltsetting[SETTING_DOME_RADIUS] = LLSD::Real(15000.f);
dfltsetting[SETTING_GAMMA] = LLVector4(1.0, 0.0, 0.0, 1.0).getValue();
dfltsetting[SETTING_GLOW] = LLColor4(5.000, 0.0010, -0.4799, 1.0).getValue(); // *RIDER: This is really weird for a color... TODO: check if right.
dfltsetting[SETTING_HAZE_DENSITY] = LLSD::Real(0.6999);
dfltsetting[SETTING_HAZE_HORIZON] = LLSD::Real(0.1899);
dfltsetting[SETTING_LIGHT_NORMAL] = LLVector4(0.0000, 0.9126, -0.4086, 0.0000).getValue();
dfltsetting[SETTING_MAX_Y] = LLSD::Real(1605);
dfltsetting[SETTING_MOON_ROTATION] = moonquat.getValue();
dfltsetting[SETTING_NAME] = std::string("_default_");
dfltsetting[SETTING_STAR_BRIGHTNESS] = LLSD::Real(0.0000);
dfltsetting[SETTING_SUNLIGHT_COLOR] = LLColor4(0.7342, 0.7815, 0.8999, 1.0).getValue();
dfltsetting[SETTING_SUN_ROTATION] = sunquat.getValue();
dfltsetting[SETTING_BLOOM_TEXTUREID] = LLUUID::null;
dfltsetting[SETTING_CLOUD_TEXTUREID] = LLUUID::null;
dfltsetting[SETTING_MOON_TEXTUREID] = IMG_SUN; // gMoonTextureID; // These two are returned by the login... wow!
dfltsetting[SETTING_SUN_TEXUTUREID] = IMG_MOON; // gSunTextureID;
return dfltsetting;
}
void LLSettingsSky::updateSettings()
{
LL_RECORD_BLOCK_TIME(FTM_UPDATE_ENVIRONMENT);
LL_INFOS("WINDLIGHT", "SKY", "EEP") << "WL Parameters are dirty. Reticulating Splines..." << LL_ENDL;
// base class clears dirty flag so as to not trigger recursive update
LLSettingsBase::updateSettings();
calculateHeavnlyBodyPositions();
calculateLightSettings();
}
void LLSettingsSky::calculateHeavnlyBodyPositions()
{
mSunDirection = DUE_EAST * getSunRotation();
mSunDirection.normalize();
mMoonDirection = DUE_EAST * getMoonRotation();
mMoonDirection.normalize();
// is the normal from the sun or the moon
if (mSunDirection.mV[1] >= 0.0)
{
mLightDirection = mSunDirection;
}
else if (mSunDirection.mV[1] < 0.0 && mSunDirection.mV[1] > LLSky::NIGHTTIME_ELEVATION_COS)
{
// clamp v1 to 0 so sun never points up and causes weirdness on some machines
LLVector3 vec(mSunDirection);
vec.mV[1] = 0.0;
vec.normVec();
mLightDirection = vec;
}
else
{
mLightDirection = mMoonDirection;
}
// calculate the clamp lightnorm for sky (to prevent ugly banding in sky
// when haze goes below the horizon
mLightDirectionClamped = mSunDirection;
if (mLightDirectionClamped.mV[1] < -0.1f)
{
mLightDirectionClamped.mV[1] = -0.1f;
}
}
void LLSettingsSky::calculateLightSettings()
{
LLColor3 vary_HazeColor;
LLColor3 vary_SunlightColor;
LLColor3 vary_AmbientColor;
{
// Initialize temp variables
LLColor3 sunlight = getSunlightColor();
// Fetch these once...
F32 haze_density = getHazeDensity();
F32 haze_horizon = getHazeHorizon();
F32 density_multiplier = getDensityMultiplier();
F32 max_y = getMaxY();
F32 gamma = getGama();
F32 cloud_shadow = getCloudShadow();
LLColor3 blue_density = getBlueDensity();
LLColor3 blue_horizon = getBlueHorizon();
LLColor3 ambient = getAmbientColor();
// Sunlight attenuation effect (hue and brightness) due to atmosphere
// this is used later for sunlight modulation at various altitudes
LLColor3 light_atten =
(blue_density * 1.0 + smear(haze_density * 0.25f)) * (density_multiplier * max_y);
// Calculate relative weights
LLColor3 temp2(0.f, 0.f, 0.f);
LLColor3 temp1 = blue_density + smear(haze_density);
LLColor3 blue_weight = componentDiv(blue_density, temp1);
LLColor3 haze_weight = componentDiv(smear(haze_density), temp1);
// Compute sunlight from P & lightnorm (for long rays like sky)
/// USE only lightnorm.
// temp2[1] = llmax(0.f, llmax(0.f, Pn[1]) * 1.0f + lightnorm[1] );
// and vary_sunlight will work properly with moon light
F32 lighty = mLightDirection[1];
if (lighty < LLSky::NIGHTTIME_ELEVATION_COS)
{
lighty = -lighty;
}
temp2.mV[1] = llmax(0.f, lighty);
if (temp2.mV[1] > 0.f)
{
temp2.mV[1] = 1.f / temp2.mV[1];
}
componentMultBy(sunlight, componentExp((light_atten * -1.f) * temp2.mV[1]));
// Distance
temp2.mV[2] = density_multiplier;
// Transparency (-> temp1)
temp1 = componentExp((temp1 * -1.f) * temp2.mV[2]);
// vary_AtmosAttenuation = temp1;
//increase ambient when there are more clouds
LLColor3 tmpAmbient = ambient + (smear(1.f) - ambient) * cloud_shadow * 0.5f;
//haze color
vary_HazeColor =
(blue_horizon * blue_weight * (sunlight*(1.f - cloud_shadow) + tmpAmbient)
+ componentMult(haze_horizon * haze_weight, sunlight*(1.f - cloud_shadow) * temp2.mV[0] + tmpAmbient)
);
//brightness of surface both sunlight and ambient
vary_SunlightColor = componentMult(sunlight, temp1) * 1.f;
vary_SunlightColor.clamp();
vary_SunlightColor = smear(1.0f) - vary_SunlightColor;
vary_SunlightColor = componentPow(vary_SunlightColor, gamma);
vary_SunlightColor = smear(1.0f) - vary_SunlightColor;
vary_AmbientColor = componentMult(tmpAmbient, temp1) * 0.5;
vary_AmbientColor.clamp();
vary_AmbientColor = smear(1.0f) - vary_AmbientColor;
vary_AmbientColor = componentPow(vary_AmbientColor, gamma);
vary_AmbientColor = smear(1.0f) - vary_AmbientColor;
componentMultBy(vary_HazeColor, LLColor3(1.f, 1.f, 1.f) - temp1);
}
float dp = getSunDirection() * LLVector3(0, 0, 1.f); // a dot b
if (dp < 0)
{
dp = 0;
}
// Since WL scales everything by 2, there should always be at least a 2:1 brightness ratio
// between sunlight and point lights in windlight to normalize point lights.
F32 sun_dynamic_range = std::max(gSavedSettings.getF32("RenderSunDynamicRange"), 0.0001f);
LLEnvironment::instance().setSceneLightStrength(2.0f * (1.0f + sun_dynamic_range * dp));
mSunDiffuse = vary_SunlightColor;
mSunAmbient = vary_AmbientColor;
mMoonDiffuse = vary_SunlightColor;
mMoonAmbient = vary_AmbientColor;
mTotalAmbient = vary_AmbientColor;
mTotalAmbient.setAlpha(1);
mFadeColor = mTotalAmbient + (mSunDiffuse + mMoonDiffuse) * 0.5f;
mFadeColor.setAlpha(1);
}
LLSettingsSky::parammapping_t LLSettingsSky::getParameterMap() const
{
static parammapping_t param_map;
if (param_map.empty())
{
param_map[SETTING_AMBIENT] = LLShaderMgr::AMBIENT;
param_map[SETTING_BLUE_DENSITY] = LLShaderMgr::BLUE_DENSITY;
param_map[SETTING_BLUE_HORIZON] = LLShaderMgr::BLUE_HORIZON;
param_map[SETTING_CLOUD_COLOR] = LLShaderMgr::CLOUD_COLOR;
param_map[SETTING_CLOUD_POS_DENSITY2] = LLShaderMgr::CLOUD_POS_DENSITY2;
param_map[SETTING_CLOUD_SCALE] = LLShaderMgr::CLOUD_SCALE;
param_map[SETTING_CLOUD_SHADOW] = LLShaderMgr::CLOUD_SHADOW;
param_map[SETTING_DENSITY_MULTIPLIER] = LLShaderMgr::DENSITY_MULTIPLIER;
param_map[SETTING_DISTANCE_MULTIPLIER] = LLShaderMgr::DISTANCE_MULTIPLIER;
param_map[SETTING_GAMMA] = LLShaderMgr::GAMMA;
param_map[SETTING_GLOW] = LLShaderMgr::GLOW;
param_map[SETTING_HAZE_DENSITY] = LLShaderMgr::HAZE_DENSITY;
param_map[SETTING_HAZE_HORIZON] = LLShaderMgr::HAZE_HORIZON;
param_map[SETTING_MAX_Y] = LLShaderMgr::MAX_Y;
param_map[SETTING_SUNLIGHT_COLOR] = LLShaderMgr::SUNLIGHT_COLOR;
}
return param_map;
}
void LLSettingsSky::applySpecial(void *ptarget)
{
LLGLSLShader *shader = (LLGLSLShader *)ptarget;
shader->uniform4fv(LLViewerShaderMgr::LIGHTNORM, 1, mLightDirectionClamped.mV);
shader->uniform4f(LLShaderMgr::GAMMA, getGama(), 0.0, 0.0, 1.0);
{
//LLEnvironment::instance().getCloudDelta();
LLVector4 vect_c_p_d1(mSettings[SETTING_CLOUD_POS_DENSITY1]);
vect_c_p_d1 += LLVector4(LLEnvironment::instance().getCloudScrollDelta());
shader->uniform4fv(LLShaderMgr::CLOUD_POS_DENSITY1, 1, vect_c_p_d1.mV);
}
// {
// LLVector4 val(mSettings[ ];
// val.mV[0] = F32(i->second[0].asReal()) + mCloudScrollXOffset;
// val.mV[1] = F32(i->second[1].asReal()) + mCloudScrollYOffset;
// val.mV[2] = (F32)i->second[2].asReal();
// val.mV[3] = (F32)i->second[3].asReal();
//
// stop_glerror();
// //_WARNS("RIDER") << "pushing '" << param.String() << "' as " << val << LL_ENDL;
// shader->uniform4fv(param, 1, val.mV);
// stop_glerror();
//
// }
//param_map[SETTING_CLOUD_POS_DENSITY1] = LLShaderMgr::CLOUD_POS_DENSITY1;
}
//=========================================================================
namespace
{
LLQuaternion body_position_from_angles(F32 azimuth, F32 altitude)
{
static const LLVector3 VECT_ZENITH(0.f, 0.f, 1.f);
static const LLVector3 VECT_NORTHSOUTH(0.f, 1.f, 0.f);
// Azimuth is traditionally calculated from North, we are going from East.
LLQuaternion rot_azi;
LLQuaternion rot_alt;
rot_azi.setAngleAxis(azimuth, VECT_ZENITH);
rot_alt.setAngleAxis(-altitude, VECT_NORTHSOUTH);
LLQuaternion body_quat = rot_alt * rot_azi;
body_quat.normalize();
LLVector3 sun_vector = (DUE_EAST * body_quat);
LL_WARNS("RIDER") << "Azimuth=" << azimuth << " Altitude=" << altitude << " Body Vector=" << sun_vector.getValue() << LL_ENDL;
return body_quat;
}
}