Merge branch 'V2Renderer'
This commit is contained in:
@@ -673,9 +673,6 @@
|
||||
<key>FetchInventoryDescendents</key>
|
||||
<boolean>false</boolean>
|
||||
|
||||
<key>WebFetchInventoryDescendents</key>
|
||||
<boolean>true</boolean>
|
||||
|
||||
<key>FetchInventory</key>
|
||||
<boolean>true</boolean>
|
||||
|
||||
|
||||
@@ -42,6 +42,7 @@ if (WINDOWS)
|
||||
wldap32
|
||||
gdi32
|
||||
user32
|
||||
dbghelp
|
||||
)
|
||||
else (WINDOWS)
|
||||
set(WINDOWS_LIBRARIES "")
|
||||
|
||||
@@ -48,10 +48,10 @@ using namespace std;
|
||||
|
||||
#define INCHES_TO_METERS 0.02540005f
|
||||
|
||||
const F32 POSITION_KEYFRAME_THRESHOLD = 0.03f;
|
||||
const F32 POSITION_KEYFRAME_THRESHOLD_SQUARED = 0.03f * 0.03f;
|
||||
const F32 ROTATION_KEYFRAME_THRESHOLD = 0.01f;
|
||||
|
||||
const F32 POSITION_MOTION_THRESHOLD = 0.001f;
|
||||
const F32 POSITION_MOTION_THRESHOLD_SQUARED = 0.001f * 0.001f;
|
||||
const F32 ROTATION_MOTION_THRESHOLD = 0.001f;
|
||||
|
||||
char gInFile[1024]; /* Flawfinder: ignore */
|
||||
@@ -1202,7 +1202,7 @@ void LLBVHLoader::optimize()
|
||||
if (ki_prev == ki_last_good_pos)
|
||||
{
|
||||
joint->mNumPosKeys++;
|
||||
if (dist_vec(LLVector3(ki_prev->mPos), first_frame_pos) > POSITION_MOTION_THRESHOLD)
|
||||
if (dist_vec_squared(LLVector3(ki_prev->mPos), first_frame_pos) > POSITION_MOTION_THRESHOLD_SQUARED)
|
||||
{
|
||||
pos_changed = TRUE;
|
||||
}
|
||||
@@ -1215,12 +1215,12 @@ void LLBVHLoader::optimize()
|
||||
LLVector3 current_pos(ki->mPos);
|
||||
LLVector3 interp_pos = lerp(current_pos, last_good_pos, 1.f / (F32)numPosFramesConsidered);
|
||||
|
||||
if (dist_vec(current_pos, first_frame_pos) > POSITION_MOTION_THRESHOLD)
|
||||
if (dist_vec_squared(current_pos, first_frame_pos) > POSITION_MOTION_THRESHOLD_SQUARED)
|
||||
{
|
||||
pos_changed = TRUE;
|
||||
}
|
||||
|
||||
if (dist_vec(interp_pos, test_pos) < POSITION_KEYFRAME_THRESHOLD)
|
||||
if (dist_vec_squared(interp_pos, test_pos) < POSITION_KEYFRAME_THRESHOLD_SQUARED)
|
||||
{
|
||||
ki_prev->mIgnorePos = TRUE;
|
||||
numPosFramesConsidered++;
|
||||
|
||||
@@ -261,7 +261,7 @@ public:
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
S32 getVisualParamCount() { return (S32)mVisualParamIndexMap.size(); }
|
||||
S32 getVisualParamCount() const { return (S32)mVisualParamIndexMap.size(); }
|
||||
LLVisualParam* getVisualParam(const char *name);
|
||||
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@
|
||||
#include "llquaternion.h"
|
||||
#include "v3dmath.h"
|
||||
#include "v3math.h"
|
||||
#include "llapr.h"
|
||||
#include "llbvhconsts.h"
|
||||
|
||||
class LLKeyframeDataCache;
|
||||
|
||||
@@ -190,7 +190,7 @@ BOOL LLKeyframeStandMotion::onUpdate(F32 time, U8* joint_mask)
|
||||
if (dot(mPelvisState->getJoint()->getWorldRotation(), mLastGoodPelvisRotation) < ROTATION_THRESHOLD)
|
||||
{
|
||||
mLastGoodPelvisRotation = mPelvisState->getJoint()->getWorldRotation();
|
||||
mLastGoodPelvisRotation.normQuat();
|
||||
mLastGoodPelvisRotation.normalize();
|
||||
mTrackAnkles = TRUE;
|
||||
}
|
||||
else if ((mCharacter->getCharacterPosition() - mLastGoodPosition).magVecSquared() > POSITION_THRESHOLD)
|
||||
|
||||
@@ -36,12 +36,12 @@
|
||||
//-----------------------------------------------------------------------------
|
||||
// Header Files
|
||||
//-----------------------------------------------------------------------------
|
||||
#include <string>
|
||||
|
||||
#include "llmap.h"
|
||||
#include "lljointstate.h"
|
||||
#include "lljoint.h"
|
||||
#include "llmap.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -33,6 +33,7 @@ set(llcommon_SOURCE_FILES
|
||||
llerror.cpp
|
||||
llerrorthread.cpp
|
||||
llevent.cpp
|
||||
lleventtimer.cpp
|
||||
llfasttimer.cpp
|
||||
llfile.cpp
|
||||
llfindlocale.cpp
|
||||
@@ -40,6 +41,7 @@ set(llcommon_SOURCE_FILES
|
||||
llformat.cpp
|
||||
llframetimer.cpp
|
||||
llheartbeat.cpp
|
||||
llinstancetracker.cpp
|
||||
llindraconfigfile.cpp
|
||||
llliveappconfig.cpp
|
||||
lllivefile.cpp
|
||||
@@ -61,6 +63,7 @@ set(llcommon_SOURCE_FILES
|
||||
llsdutil.cpp
|
||||
llsecondlifeurls.cpp
|
||||
llstat.cpp
|
||||
llstacktrace.cpp
|
||||
llstreamtools.cpp
|
||||
llstring.cpp
|
||||
llstringtable.cpp
|
||||
@@ -90,12 +93,12 @@ set(llcommon_HEADER_FILES
|
||||
linden_common.h
|
||||
linked_lists.h
|
||||
llagentconstants.h
|
||||
llavatarname.h
|
||||
llapp.h
|
||||
llapr.h
|
||||
llassettype.h
|
||||
llassoclist.h
|
||||
llavatarconstants.h
|
||||
llavatarname.h
|
||||
llbase32.h
|
||||
llbase64.h
|
||||
llboost.h
|
||||
@@ -123,6 +126,7 @@ set(llcommon_HEADER_FILES
|
||||
llevent.h
|
||||
lleventemitter.h
|
||||
llextendedstatus.h
|
||||
lleventtimer.h
|
||||
llfasttimer.h
|
||||
llfile.h
|
||||
llfindlocale.h
|
||||
@@ -133,6 +137,7 @@ set(llcommon_HEADER_FILES
|
||||
llheartbeat.h
|
||||
llhttpstatuscodes.h
|
||||
llindexedqueue.h
|
||||
llinstancetracker.h
|
||||
llindraconfigfile.h
|
||||
llkeythrottle.h
|
||||
lllinkedqueue.h
|
||||
@@ -169,6 +174,7 @@ set(llcommon_HEADER_FILES
|
||||
llskiplist.h
|
||||
llskipmap.h
|
||||
llstack.h
|
||||
llstacktrace.h
|
||||
llstat.h
|
||||
llstatenums.h
|
||||
llstl.h
|
||||
@@ -189,7 +195,6 @@ set(llcommon_HEADER_FILES
|
||||
metaclasst.h
|
||||
metaproperty.h
|
||||
metapropertyt.h
|
||||
processor.h
|
||||
reflective.h
|
||||
reflectivet.h
|
||||
roles_constants.h
|
||||
|
||||
@@ -48,7 +48,7 @@ class LLUUID;
|
||||
#define PHYSICS_TIMESTEP (1.f / 45.f)
|
||||
|
||||
const F32 COLLISION_TOLERANCE = 0.1f;
|
||||
const F32 HALF_COLLISION_TOLERANCE = COLLISION_TOLERANCE * 0.5f;
|
||||
const F32 HALF_COLLISION_TOLERANCE = 0.05f;
|
||||
|
||||
// Time constants
|
||||
const U32 HOURS_PER_LINDEN_DAY = 4;
|
||||
@@ -99,9 +99,9 @@ const F32 MIN_AGENT_WIDTH = 0.40f;
|
||||
const F32 DEFAULT_AGENT_WIDTH = 0.60f;
|
||||
const F32 MAX_AGENT_WIDTH = 0.80f;
|
||||
|
||||
const F32 MIN_AGENT_HEIGHT = 1.3f - 2.0f * COLLISION_TOLERANCE;
|
||||
const F32 MIN_AGENT_HEIGHT = 1.1f;
|
||||
const F32 DEFAULT_AGENT_HEIGHT = 1.9f;
|
||||
const F32 MAX_AGENT_HEIGHT = 2.65f - 2.0f * COLLISION_TOLERANCE;
|
||||
const F32 MAX_AGENT_HEIGHT = 2.45f;
|
||||
|
||||
// For linked sets
|
||||
const S32 MAX_CHILDREN_PER_TASK = 255;
|
||||
@@ -252,9 +252,6 @@ const U8 SIM_ACCESS_ADULT = 42; // Seriously Adult Only
|
||||
const U8 SIM_ACCESS_DOWN = 254;
|
||||
const U8 SIM_ACCESS_MAX = SIM_ACCESS_ADULT;
|
||||
|
||||
// group constants
|
||||
const S32 DEFAULT_MAX_AGENT_GROUPS = 25;
|
||||
|
||||
// attachment constants
|
||||
const S32 MAX_AGENT_ATTACHMENTS = 38;
|
||||
const U8 ATTACHMENT_ADD = 0x80;
|
||||
@@ -293,6 +290,7 @@ const U8 UPD_UNIFORM = 0x10; // used with UPD_SCALE
|
||||
// Agent Update Flags (U8)
|
||||
const U8 AU_FLAGS_NONE = 0x00;
|
||||
const U8 AU_FLAGS_HIDETITLE = 0x01;
|
||||
const U8 AU_FLAGS_CLIENT_AUTOPILOT = 0x02;
|
||||
|
||||
// start location constants
|
||||
const U32 START_LOCATION_ID_LAST = 0;
|
||||
@@ -306,6 +304,14 @@ const U32 START_LOCATION_ID_COUNT = 6;
|
||||
// group constants
|
||||
const U32 GROUP_MIN_SIZE = 2;
|
||||
|
||||
// gMaxAgentGroups is now sent by login.cgi, which
|
||||
// looks it up from globals.xml.
|
||||
//
|
||||
// For now we need an old default value however,
|
||||
// so the viewer can be deployed ahead of login.cgi.
|
||||
//
|
||||
const S32 DEFAULT_MAX_AGENT_GROUPS = 25;
|
||||
|
||||
// radius within which a chat message is fully audible
|
||||
const F32 CHAT_WHISPER_RADIUS = 10.f;
|
||||
const F32 CHAT_NORMAL_RADIUS = 20.f;
|
||||
|
||||
@@ -38,8 +38,10 @@
|
||||
#include "llerrorcontrol.h"
|
||||
#include "llerrorthread.h"
|
||||
#include "llframetimer.h"
|
||||
#include "lllivefile.h"
|
||||
#include "llmemory.h"
|
||||
#include "lltimer.h"
|
||||
#include "llstl.h" // for DeletePointer()
|
||||
#include "lleventtimer.h"
|
||||
|
||||
//
|
||||
// Signal handling
|
||||
@@ -139,6 +141,11 @@ LLApp::~LLApp()
|
||||
delete sSigChildCount;
|
||||
sSigChildCount = NULL;
|
||||
#endif
|
||||
|
||||
// reclaim live file memory
|
||||
std::for_each(mLiveFiles.begin(), mLiveFiles.end(), DeletePointer());
|
||||
mLiveFiles.clear();
|
||||
|
||||
setStopped();
|
||||
// HACK: wait for the error thread to clean itself
|
||||
ms_sleep(20);
|
||||
@@ -212,6 +219,15 @@ bool LLApp::parseCommandOptions(int argc, char** argv)
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void LLApp::manageLiveFile(LLLiveFile* livefile)
|
||||
{
|
||||
if(!livefile) return;
|
||||
livefile->checkAndReload();
|
||||
livefile->addToEventTimer();
|
||||
mLiveFiles.push_back(livefile);
|
||||
}
|
||||
|
||||
bool LLApp::setOptionData(OptionPriority level, LLSD data)
|
||||
{
|
||||
if((level < 0)
|
||||
|
||||
@@ -131,6 +131,19 @@ public:
|
||||
*/
|
||||
bool parseCommandOptions(int argc, char** argv);
|
||||
|
||||
/**
|
||||
* @brief Keep track of live files automatically.
|
||||
*
|
||||
* *TODO: it currently uses the <code>addToEventTimer()</code> API
|
||||
* instead of the runner. I should probalby use the runner.
|
||||
*
|
||||
* *NOTE: DO NOT add the livefile instance to any kind of check loop.
|
||||
*
|
||||
* @param livefile A valid instance of an LLLiveFile. This LLApp
|
||||
* instance will delete the livefile instance.
|
||||
*/
|
||||
void manageLiveFile(LLLiveFile* livefile);
|
||||
|
||||
/**
|
||||
* @brief Set the options at the specified priority.
|
||||
*
|
||||
@@ -285,6 +298,8 @@ private:
|
||||
// The application options.
|
||||
LLSD mOptions;
|
||||
|
||||
// The live files for this application
|
||||
std::vector<LLLiveFile*> mLiveFiles;
|
||||
//@}
|
||||
|
||||
private:
|
||||
|
||||
@@ -81,7 +81,7 @@ bool ll_apr_warn_status(apr_status_t status)
|
||||
{
|
||||
if(APR_SUCCESS == status) return false;
|
||||
char buf[MAX_STRING]; /* Flawfinder: ignore */
|
||||
apr_strerror(status, buf, MAX_STRING);
|
||||
apr_strerror(status, buf, sizeof(buf));
|
||||
LL_WARNS("APR") << "APR: " << buf << LL_ENDL;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -33,207 +33,115 @@
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llassettype.h"
|
||||
#include "lldictionary.h"
|
||||
#include "llmemory.h"
|
||||
|
||||
#include "llstring.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
// I added lookups for exact text of asset type enums in addition to the ones below, so shoot me. -Steve
|
||||
|
||||
struct asset_info_t
|
||||
///----------------------------------------------------------------------------
|
||||
/// Class LLAssetType
|
||||
///----------------------------------------------------------------------------
|
||||
struct AssetEntry : public LLDictionaryEntry
|
||||
{
|
||||
LLAssetType::EType type;
|
||||
const char* desc;
|
||||
AssetEntry(const char *desc_name,
|
||||
const char *type_name, // 8 character limit!
|
||||
const char *human_name, // for decoding to human readable form; put any and as many printable characters you want in each one
|
||||
bool can_link, // can you create a link to this type?
|
||||
bool can_fetch, // can you fetch this asset by ID?
|
||||
bool can_know) // can you see this asset's ID?
|
||||
:
|
||||
LLDictionaryEntry(desc_name),
|
||||
mTypeName(type_name),
|
||||
mHumanName(human_name),
|
||||
mCanLink(can_link),
|
||||
mCanFetch(can_fetch),
|
||||
mCanKnow(can_know)
|
||||
{
|
||||
llassert(strlen(mTypeName) <= 8);
|
||||
}
|
||||
|
||||
const char *mTypeName;
|
||||
const char *mHumanName;
|
||||
bool mCanLink;
|
||||
bool mCanFetch;
|
||||
bool mCanKnow;
|
||||
};
|
||||
|
||||
asset_info_t asset_types[] =
|
||||
class LLAssetDictionary : public LLSingleton<LLAssetDictionary>,
|
||||
public LLDictionary<LLAssetType::EType, AssetEntry>
|
||||
{
|
||||
{ LLAssetType::AT_TEXTURE, "TEXTURE" },
|
||||
{ LLAssetType::AT_SOUND, "SOUND" },
|
||||
{ LLAssetType::AT_CALLINGCARD, "CALLINGCARD" },
|
||||
{ LLAssetType::AT_LANDMARK, "LANDMARK" },
|
||||
{ LLAssetType::AT_SCRIPT, "SCRIPT" },
|
||||
{ LLAssetType::AT_CLOTHING, "CLOTHING" },
|
||||
{ LLAssetType::AT_OBJECT, "OBJECT" },
|
||||
{ LLAssetType::AT_NOTECARD, "NOTECARD" },
|
||||
{ LLAssetType::AT_CATEGORY, "CATEGORY" },
|
||||
{ LLAssetType::AT_ROOT_CATEGORY, "ROOT_CATEGORY" },
|
||||
{ LLAssetType::AT_LSL_TEXT, "LSL_TEXT" },
|
||||
{ LLAssetType::AT_LSL_BYTECODE, "LSL_BYTECODE" },
|
||||
{ LLAssetType::AT_TEXTURE_TGA, "TEXTURE_TGA" },
|
||||
{ LLAssetType::AT_BODYPART, "BODYPART" },
|
||||
{ LLAssetType::AT_TRASH, "TRASH" },
|
||||
{ LLAssetType::AT_SNAPSHOT_CATEGORY, "SNAPSHOT_CATEGORY" },
|
||||
{ LLAssetType::AT_LOST_AND_FOUND, "LOST_AND_FOUND" },
|
||||
{ LLAssetType::AT_SOUND_WAV, "SOUND_WAV" },
|
||||
{ LLAssetType::AT_IMAGE_TGA, "IMAGE_TGA" },
|
||||
{ LLAssetType::AT_IMAGE_JPEG, "IMAGE_JPEG" },
|
||||
{ LLAssetType::AT_ANIMATION, "ANIMATION" },
|
||||
{ LLAssetType::AT_GESTURE, "GESTURE" },
|
||||
{ LLAssetType::AT_SIMSTATE, "SIMSTATE" },
|
||||
{ LLAssetType::AT_FAVORITE, "FAVORITE" },
|
||||
{ LLAssetType::AT_LINK, "LINK" },
|
||||
{ LLAssetType::AT_LINK_FOLDER, "CURRENT" },
|
||||
{ LLAssetType::AT_CURRENT_OUTFIT, "FOLDER_LINK" },
|
||||
{ LLAssetType::AT_OUTFIT, "OUTFIT" },
|
||||
{ LLAssetType::AT_MY_OUTFITS, "MY_OUTFITS" },
|
||||
{ LLAssetType::AT_NONE, "NONE" }
|
||||
public:
|
||||
LLAssetDictionary();
|
||||
};
|
||||
|
||||
LLAssetType::EType LLAssetType::getType(const std::string& sin)
|
||||
LLAssetDictionary::LLAssetDictionary()
|
||||
{
|
||||
std::string s = sin;
|
||||
// DESCRIPTION TYPE NAME HUMAN NAME CAN LINK? CAN FETCH? CAN KNOW?
|
||||
// |--------------------|-----------|-------------------|-----------|-----------|---------|
|
||||
addEntry(LLAssetType::AT_TEXTURE, new AssetEntry("TEXTURE", "texture", "texture", true, false, true));
|
||||
addEntry(LLAssetType::AT_SOUND, new AssetEntry("SOUND", "sound", "sound", true, true, true));
|
||||
addEntry(LLAssetType::AT_CALLINGCARD, new AssetEntry("CALLINGCARD", "callcard", "calling card", true, false, false));
|
||||
addEntry(LLAssetType::AT_LANDMARK, new AssetEntry("LANDMARK", "landmark", "landmark", true, true, true));
|
||||
addEntry(LLAssetType::AT_SCRIPT, new AssetEntry("SCRIPT", "script", "legacy script", true, false, false));
|
||||
addEntry(LLAssetType::AT_CLOTHING, new AssetEntry("CLOTHING", "clothing", "clothing", true, true, true));
|
||||
addEntry(LLAssetType::AT_OBJECT, new AssetEntry("OBJECT", "object", "object", true, false, false));
|
||||
addEntry(LLAssetType::AT_NOTECARD, new AssetEntry("NOTECARD", "notecard", "note card", true, false, true));
|
||||
addEntry(LLAssetType::AT_CATEGORY, new AssetEntry("CATEGORY", "category", "folder", true, false, false));
|
||||
addEntry(LLAssetType::AT_ROOT_CATEGORY, new AssetEntry("ROOT_CATEGORY", "root", "root", false, false, false));
|
||||
addEntry(LLAssetType::AT_LSL_TEXT, new AssetEntry("LSL_TEXT", "lsltext", "lsl2 script", true, false, false));
|
||||
addEntry(LLAssetType::AT_LSL_BYTECODE, new AssetEntry("LSL_BYTECODE", "lslbyte", "lsl bytecode", true, false, false));
|
||||
addEntry(LLAssetType::AT_TEXTURE_TGA, new AssetEntry("TEXTURE_TGA", "txtr_tga", "tga texture", true, false, false));
|
||||
addEntry(LLAssetType::AT_BODYPART, new AssetEntry("BODYPART", "bodypart", "body part", true, true, true));
|
||||
addEntry(LLAssetType::AT_TRASH, new AssetEntry("TRASH", "trash", "trash", false, false, false));
|
||||
addEntry(LLAssetType::AT_SNAPSHOT_CATEGORY, new AssetEntry("SNAPSHOT_CATEGORY", "snapshot", "snapshot", false, false, false));
|
||||
addEntry(LLAssetType::AT_LOST_AND_FOUND, new AssetEntry("LOST_AND_FOUND", "lstndfnd", "lost and found", false, false, false));
|
||||
addEntry(LLAssetType::AT_SOUND_WAV, new AssetEntry("SOUND_WAV", "snd_wav", "sound", true, false, false));
|
||||
addEntry(LLAssetType::AT_IMAGE_TGA, new AssetEntry("IMAGE_TGA", "img_tga", "targa image", true, false, false));
|
||||
addEntry(LLAssetType::AT_IMAGE_JPEG, new AssetEntry("IMAGE_JPEG", "jpeg", "jpeg image", true, false, false));
|
||||
addEntry(LLAssetType::AT_ANIMATION, new AssetEntry("ANIMATION", "animatn", "animation", true, true, true));
|
||||
addEntry(LLAssetType::AT_GESTURE, new AssetEntry("GESTURE", "gesture", "gesture", true, true, true));
|
||||
addEntry(LLAssetType::AT_SIMSTATE, new AssetEntry("SIMSTATE", "simstate", "simstate", false, false, false));
|
||||
addEntry(LLAssetType::AT_FAVORITE, new AssetEntry("FAVORITE", "favorite", "", false, false, false));
|
||||
addEntry(LLAssetType::AT_LINK, new AssetEntry("LINK", "link", "sym link", false, false, true));
|
||||
addEntry(LLAssetType::AT_LINK_FOLDER, new AssetEntry("FOLDER_LINK", "link_f", "sym folder link", false, false, true));
|
||||
addEntry(LLAssetType::AT_CURRENT_OUTFIT, new AssetEntry("FOLDER_LINK", "current", "current outfit", false, false, false));
|
||||
addEntry(LLAssetType::AT_OUTFIT, new AssetEntry("OUTFIT", "outfit", "outfit", false, false, false));
|
||||
addEntry(LLAssetType::AT_MY_OUTFITS, new AssetEntry("MY_OUTFITS", "my_otfts", "my outfits", false, false, false));
|
||||
addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, false, false, false));
|
||||
};
|
||||
|
||||
// static
|
||||
LLAssetType::EType LLAssetType::getType(const std::string& desc_name)
|
||||
{
|
||||
std::string s = desc_name;
|
||||
LLStringUtil::toUpper(s);
|
||||
for (S32 idx = 0; ;idx++)
|
||||
{
|
||||
asset_info_t* info = asset_types + idx;
|
||||
if (info->type == LLAssetType::AT_NONE)
|
||||
break;
|
||||
if (s == info->desc)
|
||||
return info->type;
|
||||
}
|
||||
return LLAssetType::AT_NONE;
|
||||
return LLAssetDictionary::getInstance()->lookup(s);
|
||||
}
|
||||
|
||||
std::string LLAssetType::getDesc(LLAssetType::EType type)
|
||||
{
|
||||
for (S32 idx = 0; ;idx++)
|
||||
{
|
||||
asset_info_t* info = asset_types + idx;
|
||||
if (type == info->type)
|
||||
return info->desc;
|
||||
if (info->type == LLAssetType::AT_NONE)
|
||||
break;
|
||||
}
|
||||
return "BAD TYPE";
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
// The asset type names are limited to 8 characters.
|
||||
// static
|
||||
const char* LLAssetType::mAssetTypeNames[LLAssetType::AT_COUNT] =
|
||||
{
|
||||
"texture",
|
||||
"sound",
|
||||
"callcard",
|
||||
"landmark",
|
||||
"script",
|
||||
"clothing",
|
||||
"object",
|
||||
"notecard",
|
||||
"category",
|
||||
"root",
|
||||
"lsltext",
|
||||
"lslbyte",
|
||||
"txtr_tga",// Intentionally spelled this way. Limited to eight characters.
|
||||
"bodypart",
|
||||
"trash",
|
||||
"snapshot",
|
||||
"lstndfnd",
|
||||
"snd_wav",
|
||||
"img_tga",
|
||||
"jpeg",
|
||||
"animatn",
|
||||
"gesture",
|
||||
"simstate",
|
||||
"favorite",
|
||||
"link",
|
||||
"link_f",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"current",
|
||||
"outfit",
|
||||
"my_otfts"
|
||||
};
|
||||
|
||||
// This table is meant for decoding to human readable form. Put any
|
||||
// and as many printable characters you want in each one.
|
||||
// See also llinventory.cpp INVENTORY_TYPE_HUMAN_NAMES
|
||||
const char* LLAssetType::mAssetTypeHumanNames[LLAssetType::AT_COUNT] =
|
||||
{
|
||||
"texture",
|
||||
"sound",
|
||||
"calling card",
|
||||
"landmark",
|
||||
"legacy script",
|
||||
"clothing",
|
||||
"object",
|
||||
"note card",
|
||||
"folder",
|
||||
"root",
|
||||
"lsl2 script",
|
||||
"lsl bytecode",
|
||||
"tga texture",
|
||||
"body part",
|
||||
"trash",
|
||||
"snapshot",
|
||||
"lost and found",
|
||||
"sound",
|
||||
"targa image",
|
||||
"jpeg image",
|
||||
"animation",
|
||||
"gesture",
|
||||
"simstate",
|
||||
"",
|
||||
"symbolic link",
|
||||
"symbolic folder link"
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"current outfit",
|
||||
"outfit",
|
||||
"my outfits"
|
||||
};
|
||||
|
||||
///----------------------------------------------------------------------------
|
||||
/// class LLAssetType
|
||||
///----------------------------------------------------------------------------
|
||||
|
||||
// static
|
||||
const char* LLAssetType::lookup( LLAssetType::EType type )
|
||||
const std::string &LLAssetType::getDesc(LLAssetType::EType asset_type)
|
||||
{
|
||||
if( (type >= 0) && (type < AT_COUNT ))
|
||||
const AssetEntry *entry = LLAssetDictionary::getInstance()->lookup(asset_type);
|
||||
if (entry)
|
||||
{
|
||||
return mAssetTypeNames[ S32( type ) ];
|
||||
return entry->mName;
|
||||
}
|
||||
else
|
||||
{
|
||||
return "-1";
|
||||
return badLookup();
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
const char *LLAssetType::lookup(LLAssetType::EType asset_type)
|
||||
{
|
||||
const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
|
||||
const AssetEntry *entry = dict->lookup(asset_type);
|
||||
if (entry)
|
||||
{
|
||||
return entry->mTypeName;
|
||||
}
|
||||
else
|
||||
{
|
||||
return badLookup().c_str();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,29 +151,35 @@ LLAssetType::EType LLAssetType::lookup( const char* name )
|
||||
return lookup(ll_safe_string(name));
|
||||
}
|
||||
|
||||
LLAssetType::EType LLAssetType::lookup( const std::string& name )
|
||||
// static
|
||||
LLAssetType::EType LLAssetType::lookup(const std::string& type_name)
|
||||
{
|
||||
for( S32 i = 0; i < AT_COUNT; i++ )
|
||||
const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
|
||||
for (LLAssetDictionary::const_iterator iter = dict->begin();
|
||||
iter != dict->end();
|
||||
iter++)
|
||||
{
|
||||
if( name == mAssetTypeNames[i] )
|
||||
const AssetEntry *entry = iter->second;
|
||||
if (type_name == entry->mTypeName)
|
||||
{
|
||||
// match
|
||||
return (EType)i;
|
||||
return iter->first;
|
||||
}
|
||||
}
|
||||
return AT_NONE;
|
||||
}
|
||||
|
||||
// static
|
||||
const char* LLAssetType::lookupHumanReadable(LLAssetType::EType type)
|
||||
const char *LLAssetType::lookupHumanReadable(LLAssetType::EType asset_type)
|
||||
{
|
||||
if( (type >= 0) && (type < AT_COUNT ))
|
||||
const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
|
||||
const AssetEntry *entry = dict->lookup(asset_type);
|
||||
if (entry)
|
||||
{
|
||||
return mAssetTypeHumanNames[S32(type)];
|
||||
return entry->mHumanName;
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
return badLookup().c_str();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -275,14 +189,18 @@ LLAssetType::EType LLAssetType::lookupHumanReadable( const char* name )
|
||||
return lookupHumanReadable(ll_safe_string(name));
|
||||
}
|
||||
|
||||
LLAssetType::EType LLAssetType::lookupHumanReadable( const std::string& name )
|
||||
// static
|
||||
LLAssetType::EType LLAssetType::lookupHumanReadable(const std::string& readable_name)
|
||||
{
|
||||
for( S32 i = 0; i < AT_COUNT; i++ )
|
||||
const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
|
||||
for (LLAssetDictionary::const_iterator iter = dict->begin();
|
||||
iter != dict->end();
|
||||
iter++)
|
||||
{
|
||||
if( name == mAssetTypeHumanNames[i] )
|
||||
const AssetEntry *entry = iter->second;
|
||||
if (entry->mHumanName && (readable_name == entry->mHumanName))
|
||||
{
|
||||
// match
|
||||
return (EType)i;
|
||||
return iter->first;
|
||||
}
|
||||
}
|
||||
return AT_NONE;
|
||||
@@ -333,6 +251,16 @@ void LLAssetType::generateDescriptionFor(LLAssetType::EType type,
|
||||
// static
|
||||
bool LLAssetType::lookupCanLink(EType asset_type)
|
||||
{
|
||||
//Check that enabling all these other types as linkable doesn't break things.
|
||||
/*const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
|
||||
const AssetEntry *entry = dict->lookup(asset_type);
|
||||
if (entry)
|
||||
{
|
||||
return entry->mCanLink;
|
||||
}
|
||||
return false;
|
||||
*/
|
||||
|
||||
return (asset_type == AT_CLOTHING || asset_type == AT_OBJECT || asset_type == AT_CATEGORY ||
|
||||
asset_type == AT_BODYPART || asset_type == AT_GESTURE);
|
||||
}
|
||||
@@ -341,45 +269,42 @@ bool LLAssetType::lookupCanLink(EType asset_type)
|
||||
// Not adding this to dictionary since we probably will only have these two types
|
||||
bool LLAssetType::lookupIsLinkType(EType asset_type)
|
||||
{
|
||||
return (asset_type == AT_LINK || asset_type == AT_LINK_FOLDER);
|
||||
if (asset_type == AT_LINK || asset_type == AT_LINK_FOLDER)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
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)
|
||||
{
|
||||
// *FIX: Make this list smaller.
|
||||
switch(asset_type)
|
||||
const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
|
||||
const AssetEntry *entry = dict->lookup(asset_type);
|
||||
if (entry)
|
||||
{
|
||||
case LLAssetType::AT_SOUND:
|
||||
case LLAssetType::AT_LANDMARK:
|
||||
case LLAssetType::AT_CLOTHING:
|
||||
case LLAssetType::AT_BODYPART:
|
||||
case LLAssetType::AT_ANIMATION:
|
||||
case LLAssetType::AT_GESTURE:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
return entry->mCanFetch;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
bool LLAssetType::lookupIsAssetIDKnowable(EType asset_type)
|
||||
{
|
||||
switch(asset_type)
|
||||
const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
|
||||
const AssetEntry *entry = dict->lookup(asset_type);
|
||||
if (entry)
|
||||
{
|
||||
case LLAssetType::AT_TEXTURE:
|
||||
case LLAssetType::AT_SOUND:
|
||||
case LLAssetType::AT_LANDMARK:
|
||||
case LLAssetType::AT_CLOTHING:
|
||||
case LLAssetType::AT_NOTECARD:
|
||||
case LLAssetType::AT_BODYPART:
|
||||
case LLAssetType::AT_ANIMATION:
|
||||
case LLAssetType::AT_GESTURE:
|
||||
case LLAssetType::AT_LINK:
|
||||
case LLAssetType::AT_LINK_FOLDER:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
return entry->mCanKnow;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -160,39 +160,36 @@ public:
|
||||
};
|
||||
|
||||
// machine transation between type and strings
|
||||
static EType lookup(const char* name); // safe conversion to std::string, *TODO: deprecate
|
||||
static EType lookup(const std::string& name);
|
||||
static const char* lookup(EType type);
|
||||
static EType lookup(const char* name); // safe conversion to std::string, *TODO: deprecate
|
||||
static EType lookup(const std::string& type_name);
|
||||
static const char* lookup(EType asset_type);
|
||||
|
||||
// translation from a type to a human readable form.
|
||||
static EType lookupHumanReadable( const char* name ); // safe conversion to std::string, *TODO: deprecate
|
||||
static EType lookupHumanReadable( const std::string& name );
|
||||
static const char* lookupHumanReadable(EType type);
|
||||
static EType lookupHumanReadable(const char* desc_name); // safe conversion to std::string, *TODO: deprecate
|
||||
static EType lookupHumanReadable(const std::string& readable_name);
|
||||
static const char* lookupHumanReadable(EType asset_type);
|
||||
|
||||
static EDragAndDropType lookupDragAndDropType( EType );
|
||||
static EDragAndDropType lookupDragAndDropType( EType );
|
||||
|
||||
// Generate a good default description. You may want to add a verb
|
||||
// or agent name after this depending on your application.
|
||||
static void generateDescriptionFor(LLAssetType::EType type,
|
||||
std::string& desc);
|
||||
|
||||
static EType getType(const std::string& sin);
|
||||
static std::string getDesc(EType type);
|
||||
|
||||
static EType getType(const std::string& desc_name);
|
||||
static const std::string& getDesc(EType asset_type);
|
||||
|
||||
static bool lookupCanLink(EType asset_type);
|
||||
static bool lookupIsLinkType(EType asset_type);
|
||||
|
||||
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
|
||||
|
||||
private:
|
||||
// don't instantiate or derive one of these objects
|
||||
LLAssetType( void ) {}
|
||||
~LLAssetType( void ) {}
|
||||
static const std::string& badLookup(); // error string when a lookup fails
|
||||
|
||||
private:
|
||||
static const char* mAssetTypeNames[];
|
||||
static const char* mAssetTypeHumanNames[];
|
||||
protected:
|
||||
LLAssetType() {}
|
||||
~LLAssetType() {}
|
||||
};
|
||||
|
||||
#ifdef CWDEBUG
|
||||
|
||||
@@ -46,4 +46,18 @@
|
||||
*/
|
||||
typedef boost::tokenizer<boost::char_separator<char> > boost_tokenizer;
|
||||
|
||||
// Useful combiner for boost signals that return a bool (e.g. validation)
|
||||
// returns false if any of the callbacks return false
|
||||
struct boost_boolean_combiner
|
||||
{
|
||||
typedef bool result_type;
|
||||
template<typename InputIterator>
|
||||
bool operator()(InputIterator first, InputIterator last) const
|
||||
{
|
||||
bool res = true;
|
||||
while (first != last)
|
||||
res &= *first++;
|
||||
return res;
|
||||
}
|
||||
};
|
||||
#endif // LL_LLBOOST_H
|
||||
|
||||
@@ -38,10 +38,13 @@
|
||||
#include "apr_time.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <locale.h>
|
||||
#include <string>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
|
||||
#include "lltimer.h"
|
||||
#include "llstring.h"
|
||||
|
||||
static const F64 DATE_EPOCH = 0.0;
|
||||
|
||||
@@ -88,47 +91,40 @@ std::string LLDate::asString() const
|
||||
// is one of the standards used and the prefered format
|
||||
std::string LLDate::asRFC1123() const
|
||||
{
|
||||
std::ostringstream stream;
|
||||
toHTTPDateStream(stream);
|
||||
return stream.str();
|
||||
return toHTTPDateString (std::string ("%A, %d %b %Y %H:%M:%S GMT"));
|
||||
}
|
||||
|
||||
void LLDate::toHTTPDateStream(std::ostream& s) const
|
||||
|
||||
std::string LLDate::toHTTPDateString (std::string fmt) const
|
||||
{
|
||||
// http://apr.apache.org/docs/apr/0.9/group__apr__time.html
|
||||
apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC);
|
||||
|
||||
time_t locSeconds = (time_t) mSecondsSinceEpoch;
|
||||
struct tm * gmt = gmtime (&locSeconds);
|
||||
return toHTTPDateString(gmt, fmt);
|
||||
}
|
||||
|
||||
apr_time_exp_t exp_time ; //Apache time module
|
||||
|
||||
if (apr_time_exp_gmt(&exp_time, time) != APR_SUCCESS)
|
||||
{
|
||||
std::string LLDate::toHTTPDateString (tm * gmt, std::string fmt)
|
||||
{
|
||||
// Return Epoch UTC date
|
||||
s << "Thursday, 01 Jan 1970 00:00:00 GMT" ;
|
||||
return;
|
||||
}
|
||||
|
||||
s << std::dec << std::setfill('0');
|
||||
#if( LL_WINDOWS || __GNUC__ > 2)
|
||||
s << std::right ;
|
||||
#else
|
||||
s.setf(ios::right);
|
||||
#endif
|
||||
static char const* const weekdays[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
|
||||
static char const* const months[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
|
||||
std::string day = weekdays[exp_time.tm_wday];
|
||||
std::string month = months[exp_time.tm_mon];
|
||||
// avoid calling setlocale() unnecessarily - it's expensive.
|
||||
static std::string prev_locale = "";
|
||||
std::string this_locale = LLStringUtil::getLocale();
|
||||
if (this_locale != prev_locale)
|
||||
{
|
||||
setlocale(LC_TIME, this_locale.c_str());
|
||||
prev_locale = this_locale;
|
||||
}
|
||||
|
||||
s << std::setw(day.length()) << (day)
|
||||
<< ", " << std::setw(2) << (exp_time.tm_mday)
|
||||
<< ' ' << std::setw(month.length()) << (month)
|
||||
<< ' ' << std::setw(4) << (exp_time.tm_year + 1900)
|
||||
<< ' ' << std::setw(2) << (exp_time.tm_hour)
|
||||
<< ':' << std::setw(2) << (exp_time.tm_min)
|
||||
<< ':' << std::setw(2) << (exp_time.tm_sec)
|
||||
<< " GMT";
|
||||
|
||||
// RFC 1123 date does not use microseconds
|
||||
//llinfos << "Date in RFC 1123 format is " << s << llendl;
|
||||
// use strftime() as it appears to be faster than std::time_put
|
||||
char buffer[128];
|
||||
strftime(buffer, 128, fmt.c_str(), gmt);
|
||||
std::string res(buffer);
|
||||
#if LL_WINDOWS
|
||||
// Convert from locale-dependant charset to UTF-8 (EXT-8524).
|
||||
res = ll_convert_string_to_utf8_string(res);
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
void LLDate::toStream(std::ostream& s) const
|
||||
@@ -159,7 +155,39 @@ void LLDate::toStream(std::ostream& s) const
|
||||
s << '.' << std::setw(2)
|
||||
<< (int)(exp_time.tm_usec / (LL_APR_USEC_PER_SEC / 100));
|
||||
}
|
||||
s << 'Z';
|
||||
s << 'Z'
|
||||
<< std::setfill(' ');
|
||||
}
|
||||
|
||||
bool LLDate::split(S32 *year, S32 *month, S32 *day, S32 *hour, S32 *min, S32 *sec) const
|
||||
{
|
||||
apr_time_t time = (apr_time_t)(mSecondsSinceEpoch * LL_APR_USEC_PER_SEC);
|
||||
|
||||
apr_time_exp_t exp_time;
|
||||
if (apr_time_exp_gmt(&exp_time, time) != APR_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (year)
|
||||
*year = exp_time.tm_year + 1900;
|
||||
|
||||
if (month)
|
||||
*month = exp_time.tm_mon + 1;
|
||||
|
||||
if (day)
|
||||
*day = exp_time.tm_mday;
|
||||
|
||||
if (hour)
|
||||
*hour = exp_time.tm_hour;
|
||||
|
||||
if (min)
|
||||
*min = exp_time.tm_min;
|
||||
|
||||
if (sec)
|
||||
*sec = exp_time.tm_sec;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLDate::fromString(const std::string& iso8601_date)
|
||||
@@ -223,13 +251,62 @@ bool LLDate::fromStream(std::istream& s)
|
||||
s >> fractional;
|
||||
seconds_since_epoch += fractional;
|
||||
}
|
||||
c = s.get(); // skip the Z
|
||||
if (c != 'Z') { return false; }
|
||||
|
||||
c = s.peek(); // check for offset
|
||||
if (c == '+' || c == '-')
|
||||
{
|
||||
S32 offset_sign = (c == '+') ? 1 : -1;
|
||||
S32 offset_hours = 0;
|
||||
S32 offset_minutes = 0;
|
||||
S32 offset_in_seconds = 0;
|
||||
|
||||
s >> offset_hours;
|
||||
|
||||
c = s.get(); // skip the colon a get the minutes if there are any
|
||||
if (c == ':')
|
||||
{
|
||||
s >> offset_minutes;
|
||||
}
|
||||
|
||||
offset_in_seconds = (offset_hours * 60 + offset_sign * offset_minutes) * 60;
|
||||
seconds_since_epoch -= offset_in_seconds;
|
||||
}
|
||||
else if (c != 'Z') { return false; } // skip the Z
|
||||
|
||||
mSecondsSinceEpoch = seconds_since_epoch;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LLDate::fromYMDHMS(S32 year, S32 month, S32 day, S32 hour, S32 min, S32 sec)
|
||||
{
|
||||
struct apr_time_exp_t exp_time;
|
||||
|
||||
exp_time.tm_year = year - 1900;
|
||||
exp_time.tm_mon = month - 1;
|
||||
exp_time.tm_mday = day;
|
||||
exp_time.tm_hour = hour;
|
||||
exp_time.tm_min = min;
|
||||
exp_time.tm_sec = sec;
|
||||
|
||||
// zero out the unused fields
|
||||
exp_time.tm_usec = 0;
|
||||
exp_time.tm_wday = 0;
|
||||
exp_time.tm_yday = 0;
|
||||
exp_time.tm_isdst = 0;
|
||||
exp_time.tm_gmtoff = 0;
|
||||
|
||||
// generate a time_t from that
|
||||
apr_time_t time;
|
||||
if (apr_time_exp_gmt_get(&time, &exp_time) != APR_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
mSecondsSinceEpoch = time / LL_APR_USEC_PER_SEC;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
F64 LLDate::secondsSinceEpoch() const
|
||||
{
|
||||
return mSecondsSinceEpoch;
|
||||
|
||||
@@ -84,7 +84,9 @@ public:
|
||||
std::string asString() const;
|
||||
std::string asRFC1123() const;
|
||||
void toStream(std::ostream&) const;
|
||||
void toHTTPDateStream(std::ostream&) const;
|
||||
bool split(S32 *year, S32 *month = NULL, S32 *day = NULL, S32 *hour = NULL, S32 *min = NULL, S32 *sec = NULL) const;
|
||||
std::string toHTTPDateString (std::string fmt) const;
|
||||
static std::string toHTTPDateString (tm * gmt, std::string fmt);
|
||||
/**
|
||||
* @brief Set the date from an ISO-8601 string.
|
||||
*
|
||||
@@ -99,6 +101,7 @@ public:
|
||||
*/
|
||||
bool fromString(const std::string& iso8601_date);
|
||||
bool fromStream(std::istream&);
|
||||
bool fromYMDHMS(S32 year, S32 month = 1, S32 day = 0, S32 hour = 0, S32 min = 0, S32 sec = 0);
|
||||
|
||||
/**
|
||||
* @brief Return the date in seconds since epoch.
|
||||
|
||||
@@ -242,5 +242,13 @@ inline LLDATATYPE llclampb(const LLDATATYPE& a)
|
||||
return llmin(llmax(a, (LLDATATYPE)0), (LLDATATYPE)255);
|
||||
}
|
||||
|
||||
template <class LLDATATYPE>
|
||||
inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs)
|
||||
{
|
||||
LLDATATYPE tmp = lhs;
|
||||
lhs = rhs;
|
||||
rhs = tmp;
|
||||
}
|
||||
|
||||
#endif // LL_LLDEFS_H
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ namespace LLError
|
||||
{ return s; }
|
||||
// used to indicate the end of a message
|
||||
|
||||
class NoClassInfo { };
|
||||
class LL_COMMON_API NoClassInfo { };
|
||||
// used to indicate no class info known for logging
|
||||
|
||||
//LLCallStacks keeps track of call stacks and output the call stacks to log file
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
#ifndef LL_LLERRORLEGACY_H
|
||||
#define LL_LLERRORLEGACY_H
|
||||
|
||||
|
||||
#include "llpreprocessor.h"
|
||||
|
||||
/*
|
||||
LEGACY -- DO NOT USE THIS STUFF ANYMORE
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
#include "linden_common.h"
|
||||
#include "llerrorthread.h"
|
||||
#include "llapp.h"
|
||||
#include "lltimer.h"
|
||||
#include "lltimer.h" // ms_sleep()
|
||||
|
||||
LLErrorThread::LLErrorThread()
|
||||
: LLThread("Error"),
|
||||
|
||||
115
indra/llcommon/lleventtimer.cpp
Normal file
115
indra/llcommon/lleventtimer.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
/**
|
||||
* @file lleventtimer.cpp
|
||||
* @brief Cross-platform objects for doing timing
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-2010, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlife.com/developers/opensource/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlife.com/developers/opensource/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "lleventtimer.h"
|
||||
|
||||
#include "u64.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// LLEventTimer Implementation
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//std::list<LLEventTimer*> LLEventTimer::sActiveList;
|
||||
|
||||
LLEventTimer::LLEventTimer(F32 period)
|
||||
: mEventTimer()
|
||||
{
|
||||
mPeriod = period;
|
||||
//sActiveList.push_back(this);
|
||||
}
|
||||
|
||||
LLEventTimer::LLEventTimer(const LLDate& time)
|
||||
: mEventTimer()
|
||||
{
|
||||
mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch());
|
||||
//sActiveList.push_back(this);
|
||||
}
|
||||
|
||||
|
||||
LLEventTimer::~LLEventTimer()
|
||||
{
|
||||
//sActiveList.remove(this);
|
||||
}
|
||||
|
||||
//static
|
||||
void LLEventTimer::updateClass()
|
||||
{
|
||||
std::list<LLEventTimer*> completed_timers;
|
||||
|
||||
/*{
|
||||
for (std::list<LLEventTimer*>::iterator iter = sActiveList.begin(); iter != sActiveList.end(); )
|
||||
{
|
||||
LLEventTimer* timer = *iter++;
|
||||
F32 et = timer->mEventTimer.getElapsedTimeF32();
|
||||
if (timer->mEventTimer.getStarted() && et > timer->mPeriod) {
|
||||
timer->mEventTimer.reset();
|
||||
if ( timer->tick() )
|
||||
{
|
||||
completed_timers.push_back( timer );
|
||||
}
|
||||
}
|
||||
}
|
||||
}*/
|
||||
{
|
||||
LLInstanceTrackerScopedGuard guard;
|
||||
for (instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); )
|
||||
{
|
||||
LLEventTimer& timer = *iter++;
|
||||
F32 et = timer.mEventTimer.getElapsedTimeF32();
|
||||
if (timer.mEventTimer.getStarted() && et > timer.mPeriod) {
|
||||
timer.mEventTimer.reset();
|
||||
if ( timer.tick() )
|
||||
{
|
||||
completed_timers.push_back( &timer );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( completed_timers.size() > 0 )
|
||||
{
|
||||
for (std::list<LLEventTimer*>::iterator completed_iter = completed_timers.begin();
|
||||
completed_iter != completed_timers.end();
|
||||
completed_iter++ )
|
||||
{
|
||||
delete *completed_iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
66
indra/llcommon/lleventtimer.h
Normal file
66
indra/llcommon/lleventtimer.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* @file lleventtimer.h
|
||||
* @brief Cross-platform objects for doing timing
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-2010, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlife.com/developers/opensource/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlife.com/developers/opensource/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LL_EVENTTIMER_H
|
||||
#define LL_EVENTTIMER_H
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include "lldate.h"
|
||||
#include "llinstancetracker.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
// class for scheduling a function to be called at a given frequency (approximate, inprecise)
|
||||
class LL_COMMON_API LLEventTimer : public LLInstanceTracker<LLEventTimer>
|
||||
{
|
||||
public:
|
||||
LLEventTimer(F32 period); // period is the amount of time between each call to tick() in seconds
|
||||
LLEventTimer(const LLDate& time);
|
||||
virtual ~LLEventTimer();
|
||||
|
||||
//function to be called at the supplied frequency
|
||||
// Normally return FALSE; TRUE will delete the timer after the function returns.
|
||||
virtual BOOL tick() = 0;
|
||||
|
||||
static void updateClass();
|
||||
|
||||
protected:
|
||||
LLTimer mEventTimer;
|
||||
F32 mPeriod;
|
||||
|
||||
//private:
|
||||
//list of active timers
|
||||
// static std::list<LLEventTimer*> sActiveList; // TODO should this be a vector
|
||||
};
|
||||
|
||||
|
||||
#endif //LL_EVENTTIMER_H
|
||||
@@ -33,13 +33,18 @@
|
||||
|
||||
#include "llfasttimer.h"
|
||||
|
||||
#include "llmemory.h"
|
||||
#include "llprocessor.h"
|
||||
|
||||
|
||||
#if LL_WINDOWS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
#include "lltimer.h"
|
||||
#elif LL_LINUX || LL_SOLARIS
|
||||
#include <sys/time.h>
|
||||
#include <sched.h>
|
||||
#include "lltimer.h"
|
||||
#elif LL_DARWIN
|
||||
#include <sys/time.h>
|
||||
#include "lltimer.h" // get_clock_count()
|
||||
@@ -65,7 +70,7 @@ S32 LLFastTimer::sLastFrameIndex = -1;
|
||||
int LLFastTimer::sPauseHistory = 0;
|
||||
int LLFastTimer::sResetHistory = 0;
|
||||
|
||||
F64 LLFastTimer::sCPUClockFrequency = 0.0;
|
||||
#define USE_RDTSC 0
|
||||
|
||||
#if LL_LINUX || LL_SOLARIS
|
||||
U64 LLFastTimer::sClockResolution = 1000000000; // 1e9, Nanosecond resolution
|
||||
@@ -73,81 +78,34 @@ U64 LLFastTimer::sClockResolution = 1000000000; // 1e9, Nanosecond resolution
|
||||
U64 LLFastTimer::sClockResolution = 1000000; // 1e6, Microsecond resolution
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// CPU clock/other clock frequency and count functions
|
||||
//
|
||||
|
||||
#if LL_WINDOWS
|
||||
|
||||
U64 get_cpu_clock_count()
|
||||
{ U32 hi,lo;
|
||||
|
||||
__asm
|
||||
{
|
||||
_emit 0x0f
|
||||
_emit 0x31
|
||||
mov lo,eax
|
||||
mov hi,edx
|
||||
}
|
||||
|
||||
U64 ret = hi;
|
||||
ret *= 4294967296L;
|
||||
ret |= lo;
|
||||
return ret;
|
||||
};
|
||||
|
||||
#endif // LL_WINDOWS
|
||||
|
||||
#if LL_LINUX || LL_SOLARIS
|
||||
// Try to use the MONOTONIC clock if available, this is a constant time counter
|
||||
// with nanosecond resolution (but not necessarily accuracy) and attempts are made
|
||||
// to synchronize this value between cores at kernel start. It should not be affected
|
||||
// by CPU frequency. If not available use the REALTIME clock, but this may be affected by
|
||||
// NTP adjustments or other user activity affecting the system time.
|
||||
U64 get_cpu_clock_count()
|
||||
{
|
||||
struct timespec tp;
|
||||
|
||||
#ifdef CLOCK_MONOTONIC
|
||||
clock_gettime(CLOCK_MONOTONIC,&tp);
|
||||
#else
|
||||
clock_gettime(CLOCK_REALTIME,&tp);
|
||||
#endif
|
||||
return (tp.tv_sec*LLFastTimer::sClockResolution)+tp.tv_nsec;
|
||||
}
|
||||
#endif // (LL_LINUX || LL_SOLARIS))
|
||||
|
||||
#if LL_DARWIN
|
||||
//
|
||||
// Mac implementation of CPU clock
|
||||
//
|
||||
// Just use gettimeofday implementation for now
|
||||
|
||||
U64 get_cpu_clock_count()
|
||||
{
|
||||
return get_clock_count();
|
||||
}
|
||||
#endif
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//static
|
||||
#if LL_DARWIN || LL_LINUX || LL_SOLARIS
|
||||
U64 LLFastTimer::countsPerSecond()
|
||||
#if (LL_DARWIN || LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
|
||||
U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
|
||||
{
|
||||
return sClockResolution;
|
||||
return sClockResolution >> 8;
|
||||
}
|
||||
#else
|
||||
U64 LLFastTimer::countsPerSecond()
|
||||
#else // windows or x86-mac or x86-linux or x86-solaris
|
||||
U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
|
||||
{
|
||||
if (!sCPUClockFrequency)
|
||||
#if USE_RDTSC || !LL_WINDOWS
|
||||
//getCPUFrequency returns MHz and sCPUClockFrequency wants to be in Hz
|
||||
static U64 sCPUClockFrequency = U64(LLProcessorInfo().getCPUFrequency()*1000000.0);
|
||||
|
||||
// we drop the low-order byte in our timers, so report a lower frequency
|
||||
#else
|
||||
// If we're not using RDTSC, each fasttimer tick is just a performance counter tick.
|
||||
// Not redefining the clock frequency itself (in llprocessor.cpp/calculate_cpu_frequency())
|
||||
// since that would change displayed MHz stats for CPUs
|
||||
static bool firstcall = true;
|
||||
static U64 sCPUClockFrequency;
|
||||
if (firstcall)
|
||||
{
|
||||
CProcessor proc;
|
||||
sCPUClockFrequency = proc.GetCPUFrequency(50);
|
||||
QueryPerformanceFrequency((LARGE_INTEGER*)&sCPUClockFrequency);
|
||||
firstcall = false;
|
||||
}
|
||||
return U64(sCPUClockFrequency);
|
||||
#endif
|
||||
return sCPUClockFrequency >> 8;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -200,3 +158,143 @@ void LLFastTimer::reset()
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Important note: These implementations must be FAST!
|
||||
//
|
||||
|
||||
|
||||
#if LL_WINDOWS
|
||||
//
|
||||
// Windows implementation of CPU clock
|
||||
//
|
||||
|
||||
//
|
||||
// NOTE: put back in when we aren't using platform sdk anymore
|
||||
//
|
||||
// because MS has different signatures for these functions in winnt.h
|
||||
// need to rename them to avoid conflicts
|
||||
//#define _interlockedbittestandset _renamed_interlockedbittestandset
|
||||
//#define _interlockedbittestandreset _renamed_interlockedbittestandreset
|
||||
//#include <intrin.h>
|
||||
//#undef _interlockedbittestandset
|
||||
//#undef _interlockedbittestandreset
|
||||
|
||||
//inline U32 LLFastTimer::getCPUClockCount32()
|
||||
//{
|
||||
// U64 time_stamp = __rdtsc();
|
||||
// return (U32)(time_stamp >> 8);
|
||||
//}
|
||||
//
|
||||
//// return full timer value, *not* shifted by 8 bits
|
||||
//inline U64 LLFastTimer::getCPUClockCount64()
|
||||
//{
|
||||
// return __rdtsc();
|
||||
//}
|
||||
|
||||
// shift off lower 8 bits for lower resolution but longer term timing
|
||||
// on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing
|
||||
#if USE_RDTSC
|
||||
U32 LLFastTimer::getCPUClockCount32()
|
||||
{
|
||||
U32 ret_val;
|
||||
__asm
|
||||
{
|
||||
_emit 0x0f
|
||||
_emit 0x31
|
||||
shr eax,8
|
||||
shl edx,24
|
||||
or eax, edx
|
||||
mov dword ptr [ret_val], eax
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
// return full timer value, *not* shifted by 8 bits
|
||||
U64 LLFastTimer::getCPUClockCount64()
|
||||
{
|
||||
U64 ret_val;
|
||||
__asm
|
||||
{
|
||||
_emit 0x0f
|
||||
_emit 0x31
|
||||
mov eax,eax
|
||||
mov edx,edx
|
||||
mov dword ptr [ret_val+4], edx
|
||||
mov dword ptr [ret_val], eax
|
||||
}
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
std::string LLFastTimer::sClockType = "rdtsc";
|
||||
|
||||
#else
|
||||
//LL_COMMON_API U64 get_clock_count(); // in lltimer.cpp
|
||||
// These use QueryPerformanceCounter, which is arguably fine and also works on amd architectures.
|
||||
U32 LLFastTimer::getCPUClockCount32()
|
||||
{
|
||||
return (U32)(get_clock_count()>>8);
|
||||
}
|
||||
|
||||
U64 LLFastTimer::getCPUClockCount64()
|
||||
{
|
||||
return get_clock_count();
|
||||
}
|
||||
|
||||
std::string LLFastTimer::sClockType = "QueryPerformanceCounter";
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#if (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
|
||||
//
|
||||
// Linux and Solaris implementation of CPU clock - non-x86.
|
||||
// This is accurate but SLOW! Only use out of desperation.
|
||||
//
|
||||
// Try to use the MONOTONIC clock if available, this is a constant time counter
|
||||
// with nanosecond resolution (but not necessarily accuracy) and attempts are
|
||||
// made to synchronize this value between cores at kernel start. It should not
|
||||
// be affected by CPU frequency. If not available use the REALTIME clock, but
|
||||
// this may be affected by NTP adjustments or other user activity affecting
|
||||
// the system time.
|
||||
U64 LLFastTimer::getCPUClockCount64()
|
||||
{
|
||||
struct timespec tp;
|
||||
|
||||
#ifdef CLOCK_MONOTONIC // MONOTONIC supported at build-time?
|
||||
if (-1 == clock_gettime(CLOCK_MONOTONIC,&tp)) // if MONOTONIC isn't supported at runtime then ouch, try REALTIME
|
||||
#endif
|
||||
clock_gettime(CLOCK_REALTIME,&tp);
|
||||
|
||||
return (tp.tv_sec*LLFastTimer::sClockResolution)+tp.tv_nsec;
|
||||
}
|
||||
|
||||
U32 LLFastTimer::getCPUClockCount32()
|
||||
{
|
||||
return (U32)(LLFastTimer::getCPUClockCount64() >> 8);
|
||||
}
|
||||
|
||||
std::string LLFastTimer::sClockType = "clock_gettime";
|
||||
|
||||
#endif // (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
|
||||
|
||||
|
||||
#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
|
||||
//
|
||||
// Mac+Linux+Solaris FAST x86 implementation of CPU clock
|
||||
U32 LLFastTimer::getCPUClockCount32()
|
||||
{
|
||||
U64 x;
|
||||
__asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
|
||||
return (U32)(x >> 8);
|
||||
}
|
||||
|
||||
U64 LLFastTimer::getCPUClockCount64()
|
||||
{
|
||||
U64 x;
|
||||
__asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
|
||||
return x;
|
||||
}
|
||||
|
||||
std::string LLFastTimer::sClockType = "rdtsc";
|
||||
#endif
|
||||
@@ -35,7 +35,6 @@
|
||||
|
||||
#define FAST_TIMER_ON 1
|
||||
|
||||
LL_COMMON_API U64 get_cpu_clock_count();
|
||||
|
||||
class LL_COMMON_API LLFastTimer
|
||||
{
|
||||
@@ -51,6 +50,9 @@ public:
|
||||
FTM_IDLE,
|
||||
FTM_SLEEP,
|
||||
|
||||
// general timers
|
||||
FT_STRING_FORMAT,
|
||||
|
||||
// common messaging components
|
||||
FTM_PUMP,
|
||||
FTM_CURL,
|
||||
@@ -104,7 +106,23 @@ public:
|
||||
FTM_RENDER_BLOOM,
|
||||
FTM_RENDER_BLOOM_FBO,
|
||||
FTM_RENDER_FONTS,
|
||||
|
||||
|
||||
// deferred rendering
|
||||
FTM_RENDER_DEFERRED,
|
||||
FTM_BIND_DEFERRED,
|
||||
FTM_SUN_SHADOW,
|
||||
FTM_SOFTEN_SHADOW,
|
||||
FTM_EDGE_DETECTION,
|
||||
FTM_GI_TRACE,
|
||||
FTM_GI_GATHER,
|
||||
FTM_ATMOSPHERICS,
|
||||
FTM_LOCAL_LIGHTS,
|
||||
FTM_FULLSCREEN_LIGHTS,
|
||||
FTM_PROJECTORS,
|
||||
FTM_POST,
|
||||
|
||||
FTM_VISIBLE_CLOUD,
|
||||
|
||||
// newview specific
|
||||
FTM_MESSAGES,
|
||||
FTM_MOUSEHANDLER,
|
||||
@@ -208,7 +226,7 @@ public:
|
||||
//gTimerBins[gCurTimerBin]++;
|
||||
//LLTimer::sNumTimerCalls++;
|
||||
|
||||
U64 cpu_clocks = get_cpu_clock_count();
|
||||
U64 cpu_clocks = getCPUClockCount64();
|
||||
|
||||
sStart[sCurDepth] = cpu_clocks;
|
||||
sCurDepth++;
|
||||
@@ -223,7 +241,7 @@ public:
|
||||
// These don't get counted, because they use CPU clockticks
|
||||
//gTimerBins[gCurTimerBin]++;
|
||||
//LLTimer::sNumTimerCalls++;
|
||||
end = get_cpu_clock_count();
|
||||
end = getCPUClockCount64();
|
||||
|
||||
sCurDepth--;
|
||||
delta = end - sStart[sCurDepth];
|
||||
@@ -238,6 +256,7 @@ public:
|
||||
static void reset();
|
||||
static U64 countsPerSecond();
|
||||
|
||||
static std::string sClockType;
|
||||
public:
|
||||
static int sCurDepth;
|
||||
static U64 sStart[FTM_MAX_DEPTH];
|
||||
@@ -247,14 +266,17 @@ public:
|
||||
static U64 sCallAverage[FTM_NUM_TYPES];
|
||||
static U64 sCountHistory[FTM_HISTORY_NUM][FTM_NUM_TYPES];
|
||||
static U64 sCallHistory[FTM_HISTORY_NUM][FTM_NUM_TYPES];
|
||||
static S32 sCurFrameIndex;
|
||||
static S32 sLastFrameIndex;
|
||||
|
||||
static int sPauseHistory;
|
||||
static int sResetHistory;
|
||||
static F64 sCPUClockFrequency;
|
||||
static U64 sClockResolution;
|
||||
|
||||
private:
|
||||
static U32 getCPUClockCount32();
|
||||
static U64 getCPUClockCount64();
|
||||
|
||||
static U64 sClockResolution;
|
||||
static S32 sCurFrameIndex;
|
||||
static S32 sLastFrameIndex;
|
||||
|
||||
EFastTimerType mType;
|
||||
};
|
||||
|
||||
|
||||
@@ -233,7 +233,7 @@ public:
|
||||
* and should only be used for config files and the like -- not in a
|
||||
* loop.
|
||||
*/
|
||||
std::streamsize llifstream_size(llifstream& fstr);
|
||||
std::streamsize llofstream_size(llofstream& fstr);
|
||||
std::streamsize LL_COMMON_API llifstream_size(llifstream& fstr);
|
||||
std::streamsize LL_COMMON_API llofstream_size(llofstream& fstr);
|
||||
|
||||
#endif // not LL_LLFILE_H
|
||||
|
||||
@@ -37,17 +37,41 @@
|
||||
|
||||
#include <cstdarg>
|
||||
|
||||
std::string llformat(const char *fmt, ...)
|
||||
// common used function with va_list argument
|
||||
// wrapper for vsnprintf to be called from llformatXXX functions.
|
||||
static void va_format(std::string& out, const char *fmt, va_list va)
|
||||
{
|
||||
char tstr[1024]; /* Flawfinder: ignore */
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
#if LL_WINDOWS
|
||||
_vsnprintf(tstr, 1024, fmt, va);
|
||||
#else
|
||||
vsnprintf(tstr, 1024, fmt, va); /* Flawfinder: ignore */
|
||||
#endif
|
||||
va_end(va);
|
||||
tstr[1023] = '\0';
|
||||
return std::string(tstr);
|
||||
out.assign(tstr);
|
||||
}
|
||||
|
||||
std::string llformat(const char *fmt, ...)
|
||||
{
|
||||
std::string res;
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
va_format(res, fmt, va);
|
||||
va_end(va);
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string llformat_to_utf8(const char *fmt, ...)
|
||||
{
|
||||
std::string res;
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
va_format(res, fmt, va);
|
||||
va_end(va);
|
||||
|
||||
#if LL_WINDOWS
|
||||
// made converting to utf8. See EXT-8318.
|
||||
res = ll_convert_string_to_utf8_string(res);
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
// *NOTE: buffer limited to 1024, (but vsnprintf prevents overrun)
|
||||
// should perhaps be replaced with boost::format.
|
||||
|
||||
LL_COMMON_API std::string llformat(const char *fmt, ...);
|
||||
std::string LL_COMMON_API llformat(const char *fmt, ...);
|
||||
|
||||
// the same version as above but ensures that returned string is in utf8 on windows
|
||||
// to enable correct converting utf8_to_wstring.
|
||||
std::string LL_COMMON_API llformat_to_utf8(const char *fmt, ...);
|
||||
#endif // LL_LLFORMAT_H
|
||||
|
||||
47
indra/llcommon/llinstancetracker.cpp
Normal file
47
indra/llcommon/llinstancetracker.cpp
Normal file
@@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @file lllinstancetracker.cpp
|
||||
*
|
||||
* $LicenseInfo:firstyear=2009&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$
|
||||
*/
|
||||
|
||||
// Precompiled header
|
||||
#include "linden_common.h"
|
||||
// associated header
|
||||
#include "llinstancetracker.h"
|
||||
// STL headers
|
||||
// std headers
|
||||
// external library headers
|
||||
// other Linden headers
|
||||
|
||||
//static
|
||||
void * & LLInstanceTrackerBase::getInstances(std::type_info const & info)
|
||||
{
|
||||
static std::map<std::string, void *> instances;
|
||||
|
||||
std::string k = info.name();
|
||||
if(instances.find(k) == instances.end())
|
||||
{
|
||||
instances[k] = NULL;
|
||||
}
|
||||
|
||||
return instances[k];
|
||||
}
|
||||
202
indra/llcommon/llinstancetracker.h
Normal file
202
indra/llcommon/llinstancetracker.h
Normal file
@@ -0,0 +1,202 @@
|
||||
/**
|
||||
* @file llinstancetracker.h
|
||||
* @brief LLInstanceTracker is a mixin class that automatically tracks object
|
||||
* instances with or without an associated key
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-2010, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlife.com/developers/opensource/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlife.com/developers/opensource/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LL_LLINSTANCETRACKER_H
|
||||
#define LL_LLINSTANCETRACKER_H
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "string_table.h"
|
||||
#include <boost/utility.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/iterator/transform_iterator.hpp>
|
||||
#include <boost/iterator/indirect_iterator.hpp>
|
||||
|
||||
class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
|
||||
{
|
||||
protected:
|
||||
static void * & getInstances(std::type_info const & info);
|
||||
};
|
||||
/// This mix-in class adds support for tracking all instances of the specified class parameter T
|
||||
/// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
|
||||
/// If KEY is not provided, then instances are stored in a simple set
|
||||
/// @NOTE: see explicit specialization below for default KEY==T* case
|
||||
template<typename T, typename KEY = T*>
|
||||
class LLInstanceTracker : public LLInstanceTrackerBase
|
||||
{
|
||||
typedef typename std::map<KEY, T*> InstanceMap;
|
||||
typedef LLInstanceTracker<T, KEY> MyT;
|
||||
typedef boost::function<const KEY&(typename InstanceMap::value_type&)> KeyGetter;
|
||||
typedef boost::function<T*(typename InstanceMap::value_type&)> InstancePtrGetter;
|
||||
public:
|
||||
/// Dereferencing key_iter gives you a const KEY&
|
||||
typedef boost::transform_iterator<KeyGetter, typename InstanceMap::iterator> key_iter;
|
||||
/// Dereferencing instance_iter gives you a T&
|
||||
typedef boost::indirect_iterator< boost::transform_iterator<InstancePtrGetter, typename InstanceMap::iterator> > instance_iter;
|
||||
|
||||
static T* getInstance(const KEY& k)
|
||||
{
|
||||
typename InstanceMap::const_iterator found = getMap_().find(k);
|
||||
return (found == getMap_().end()) ? NULL : found->second;
|
||||
}
|
||||
|
||||
static key_iter beginKeys()
|
||||
{
|
||||
return boost::make_transform_iterator(getMap_().begin(),
|
||||
boost::bind(&InstanceMap::value_type::first, _1));
|
||||
}
|
||||
static key_iter endKeys()
|
||||
{
|
||||
return boost::make_transform_iterator(getMap_().end(),
|
||||
boost::bind(&InstanceMap::value_type::first, _1));
|
||||
}
|
||||
static instance_iter beginInstances()
|
||||
{
|
||||
return instance_iter(boost::make_transform_iterator(getMap_().begin(),
|
||||
boost::bind(&InstanceMap::value_type::second, _1)));
|
||||
}
|
||||
static instance_iter endInstances()
|
||||
{
|
||||
return instance_iter(boost::make_transform_iterator(getMap_().end(),
|
||||
boost::bind(&InstanceMap::value_type::second, _1)));
|
||||
}
|
||||
static S32 instanceCount() { return getMap_().size(); }
|
||||
protected:
|
||||
LLInstanceTracker(KEY key) { add_(key); }
|
||||
virtual ~LLInstanceTracker() { remove_(); }
|
||||
virtual void setKey(KEY key) { remove_(); add_(key); }
|
||||
virtual const KEY& getKey() const { return mKey; }
|
||||
|
||||
private:
|
||||
void add_(KEY key)
|
||||
{
|
||||
mKey = key;
|
||||
getMap_()[key] = static_cast<T*>(this);
|
||||
}
|
||||
void remove_()
|
||||
{
|
||||
getMap_().erase(mKey);
|
||||
}
|
||||
|
||||
static InstanceMap& getMap_()
|
||||
{
|
||||
void * & instances = getInstances(typeid(MyT));
|
||||
if (! instances)
|
||||
{
|
||||
instances = new InstanceMap;
|
||||
}
|
||||
return * static_cast<InstanceMap*>(instances);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
KEY mKey;
|
||||
};
|
||||
|
||||
/// explicit specialization for default case where KEY is T*
|
||||
/// use a simple std::set<T*>
|
||||
template<typename T>
|
||||
class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
|
||||
{
|
||||
typedef typename std::set<T*> InstanceSet;
|
||||
typedef LLInstanceTracker<T, T*> MyT;
|
||||
public:
|
||||
/// Dereferencing key_iter gives you a T* (since T* is the key)
|
||||
typedef typename InstanceSet::iterator key_iter;
|
||||
/// Dereferencing instance_iter gives you a T&
|
||||
typedef boost::indirect_iterator<key_iter> instance_iter;
|
||||
|
||||
/// for completeness of analogy with the generic implementation
|
||||
static T* getInstance(T* k) { return k; }
|
||||
static S32 instanceCount() { return getSet_().size(); }
|
||||
|
||||
// Instantiate this to get access to iterators for this type. It's a 'guard' in the sense
|
||||
// that it treats deletes of this type as errors as long as there is an instance of
|
||||
// this class alive in scope somewhere (i.e. deleting while iterating is bad).
|
||||
class LLInstanceTrackerScopedGuard
|
||||
{
|
||||
public:
|
||||
LLInstanceTrackerScopedGuard()
|
||||
{
|
||||
++sIterationNestDepth;
|
||||
}
|
||||
|
||||
~LLInstanceTrackerScopedGuard()
|
||||
{
|
||||
--sIterationNestDepth;
|
||||
}
|
||||
|
||||
static instance_iter beginInstances() { return instance_iter(getSet_().begin()); }
|
||||
static instance_iter endInstances() { return instance_iter(getSet_().end()); }
|
||||
static key_iter beginKeys() { return getSet_().begin(); }
|
||||
static key_iter endKeys() { return getSet_().end(); }
|
||||
};
|
||||
|
||||
protected:
|
||||
LLInstanceTracker()
|
||||
{
|
||||
// it's safe but unpredictable to create instances of this type while all instances are being iterated over. I hate unpredictable. This assert will probably be turned on early in the next development cycle.
|
||||
//llassert(sIterationNestDepth == 0);
|
||||
getSet_().insert(static_cast<T*>(this));
|
||||
}
|
||||
virtual ~LLInstanceTracker()
|
||||
{
|
||||
// it's unsafe to delete instances of this type while all instances are being iterated over.
|
||||
llassert(sIterationNestDepth == 0);
|
||||
getSet_().erase(static_cast<T*>(this));
|
||||
}
|
||||
|
||||
LLInstanceTracker(const LLInstanceTracker& other)
|
||||
{
|
||||
//llassert(sIterationNestDepth == 0);
|
||||
getSet_().insert(static_cast<T*>(this));
|
||||
}
|
||||
|
||||
static InstanceSet& getSet_()
|
||||
{
|
||||
void * & instances = getInstances(typeid(MyT));
|
||||
if (! instances)
|
||||
{
|
||||
instances = new InstanceSet;
|
||||
}
|
||||
return * static_cast<InstanceSet *>(instances);
|
||||
}
|
||||
|
||||
static S32 sIterationNestDepth;
|
||||
};
|
||||
|
||||
template <typename T> S32 LLInstanceTracker<T, T*>::sIterationNestDepth = 0;
|
||||
|
||||
#endif
|
||||
@@ -38,9 +38,12 @@
|
||||
#include "llsd.h"
|
||||
#include "llsdserialize.h"
|
||||
|
||||
LLLiveAppConfig::LLLiveAppConfig(LLApp* app, const std::string& filename, F32 refresh_period)
|
||||
: LLLiveFile(filename, refresh_period),
|
||||
mApp(app)
|
||||
LLLiveAppConfig::LLLiveAppConfig(
|
||||
const std::string& filename,
|
||||
F32 refresh_period,
|
||||
LLApp::OptionPriority priority) :
|
||||
LLLiveFile(filename, refresh_period),
|
||||
mPriority(priority)
|
||||
{ }
|
||||
|
||||
|
||||
@@ -77,7 +80,7 @@ bool LLLiveAppConfig::loadFile()
|
||||
// to set the config to an empty config, and return that it
|
||||
// changed.
|
||||
|
||||
mApp->setOptionData(
|
||||
LLApp::PRIORITY_SPECIFIC_CONFIGURATION, config);
|
||||
LLApp* app = LLApp::instance();
|
||||
if(app) app->setOptionData(mPriority, config);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -33,25 +33,43 @@
|
||||
#ifndef LLLIVEAPPCONFIG_H
|
||||
#define LLLIVEAPPCONFIG_H
|
||||
|
||||
#include "llapp.h"
|
||||
#include "lllivefile.h"
|
||||
|
||||
class LLApp;
|
||||
|
||||
/**
|
||||
* @class LLLiveAppConfig
|
||||
* @see LLLiveFile
|
||||
*
|
||||
* To use this, instantiate a LLLiveAppConfig object inside your main
|
||||
* loop. The traditional name for it is live_config. Be sure to call
|
||||
* <code>live_config.checkAndReload()</code> periodically.
|
||||
*/
|
||||
class LL_COMMON_API LLLiveAppConfig : public LLLiveFile
|
||||
{
|
||||
public:
|
||||
// To use this, instantiate a LLLiveAppConfig object inside your main loop.
|
||||
// The traditional name for it is live_config.
|
||||
// Be sure to call live_config.checkAndReload() periodically.
|
||||
|
||||
LLLiveAppConfig(LLApp* app, const std::string& filename, F32 refresh_period);
|
||||
~LLLiveAppConfig();
|
||||
/**
|
||||
* @brief Constructor
|
||||
*
|
||||
* @param filename. The name of the file for periodically checking
|
||||
* configuration.
|
||||
* @param refresh_period How often the internal timer should
|
||||
* bother checking the filesystem.
|
||||
* @param The application priority level of that configuration file.
|
||||
*/
|
||||
LLLiveAppConfig(
|
||||
const std::string& filename,
|
||||
F32 refresh_period,
|
||||
LLApp::OptionPriority priority);
|
||||
|
||||
~LLLiveAppConfig(); ///< Destructor
|
||||
|
||||
protected:
|
||||
/*virtual*/ bool loadFile();
|
||||
|
||||
private:
|
||||
LLApp* mApp;
|
||||
LLApp::OptionPriority mPriority;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
|
||||
#include "lllivefile.h"
|
||||
#include "llframetimer.h"
|
||||
#include "lltimer.h"
|
||||
#include "lleventtimer.h"
|
||||
|
||||
const F32 DEFAULT_CONFIG_FILE_REFRESH = 5.0f;
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ documentation and/or software.
|
||||
#include "llmd5.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <iostream> // cerr
|
||||
|
||||
// how many bytes to grab at a time when checking files
|
||||
const int LLMD5::BLOCK_LEN = 4096;
|
||||
|
||||
@@ -108,9 +108,8 @@ public:
|
||||
// methods to acquire finalized result
|
||||
void raw_digest(unsigned char *array) const; // provide 16-byte array for binary data
|
||||
void hex_digest(char *string) const; // provide 33-byte array for ascii-hex string
|
||||
friend std::ostream& operator<< (std::ostream&, LLMD5 context);
|
||||
|
||||
|
||||
friend LL_COMMON_API std::ostream& operator<< (std::ostream&, LLMD5 context);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ void LLMetricsImpl::recordEventDetails(const std::string& location,
|
||||
metrics["location"] = location;
|
||||
metrics["stats"] = stats;
|
||||
|
||||
llinfos << "LLMETRICS: " << LLSDNotationStreamer(metrics) << llendl;
|
||||
llinfos << "LLMETRICS: " << (LLSDNotationStreamer(metrics)) << llendl;
|
||||
}
|
||||
|
||||
// Store this:
|
||||
|
||||
@@ -68,6 +68,11 @@ void LLProcessLauncher::setWorkingDirectory(const std::string &dir)
|
||||
mWorkingDir = dir;
|
||||
}
|
||||
|
||||
const std::string& LLProcessLauncher::getExecutable() const
|
||||
{
|
||||
return mExecutable;
|
||||
}
|
||||
|
||||
void LLProcessLauncher::clearArguments()
|
||||
{
|
||||
mLaunchArguments.clear();
|
||||
|
||||
@@ -53,6 +53,8 @@ public:
|
||||
void setExecutable(const std::string &executable);
|
||||
void setWorkingDirectory(const std::string &dir);
|
||||
|
||||
const std::string& getExecutable() const;
|
||||
|
||||
void clearArguments();
|
||||
void addArgument(const std::string &arg);
|
||||
void addArgument(const char *arg);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -30,166 +30,26 @@
|
||||
* $/LicenseInfo$
|
||||
*/
|
||||
|
||||
// Author: Benjamin Jurke
|
||||
// File history: 27.02.2002 File created.
|
||||
///////////////////////////////////////////
|
||||
|
||||
|
||||
#ifndef LLPROCESSOR_H
|
||||
#define LLPROCESSOR_H
|
||||
class LLProcessorInfoImpl;
|
||||
|
||||
// Options:
|
||||
///////////
|
||||
#if LL_WINDOWS
|
||||
#define PROCESSOR_FREQUENCY_MEASURE_AVAILABLE
|
||||
#endif
|
||||
|
||||
#if LL_MSVC && _M_X64
|
||||
# define LL_X86_64 1
|
||||
# define LL_X86 1
|
||||
#elif LL_MSVC && _M_IX86
|
||||
# define LL_X86 1
|
||||
#elif LL_GNUC && ( defined(__amd64__) || defined(__x86_64__) )
|
||||
# define LL_X86_64 1
|
||||
# define LL_X86 1
|
||||
#elif LL_GNUC && ( defined(__i386__) )
|
||||
# define LL_X86 1
|
||||
#elif LL_GNUC && ( defined(__powerpc__) || defined(__ppc__) )
|
||||
# define LL_PPC 1
|
||||
#endif
|
||||
|
||||
|
||||
struct ProcessorExtensions
|
||||
class LL_COMMON_API LLProcessorInfo
|
||||
{
|
||||
bool FPU_FloatingPointUnit;
|
||||
bool VME_Virtual8086ModeEnhancements;
|
||||
bool DE_DebuggingExtensions;
|
||||
bool PSE_PageSizeExtensions;
|
||||
bool TSC_TimeStampCounter;
|
||||
bool MSR_ModelSpecificRegisters;
|
||||
bool PAE_PhysicalAddressExtension;
|
||||
bool MCE_MachineCheckException;
|
||||
bool CX8_COMPXCHG8B_Instruction;
|
||||
bool APIC_AdvancedProgrammableInterruptController;
|
||||
unsigned int APIC_ID;
|
||||
bool SEP_FastSystemCall;
|
||||
bool MTRR_MemoryTypeRangeRegisters;
|
||||
bool PGE_PTE_GlobalFlag;
|
||||
bool MCA_MachineCheckArchitecture;
|
||||
bool CMOV_ConditionalMoveAndCompareInstructions;
|
||||
bool FGPAT_PageAttributeTable;
|
||||
bool PSE36_36bitPageSizeExtension;
|
||||
bool PN_ProcessorSerialNumber;
|
||||
bool CLFSH_CFLUSH_Instruction;
|
||||
unsigned int CLFLUSH_InstructionCacheLineSize;
|
||||
bool DS_DebugStore;
|
||||
bool ACPI_ThermalMonitorAndClockControl;
|
||||
bool EMMX_MultimediaExtensions;
|
||||
bool MMX_MultimediaExtensions;
|
||||
bool FXSR_FastStreamingSIMD_ExtensionsSaveRestore;
|
||||
bool SSE_StreamingSIMD_Extensions;
|
||||
bool SSE2_StreamingSIMD2_Extensions;
|
||||
bool Altivec_Extensions;
|
||||
bool SS_SelfSnoop;
|
||||
bool HT_HyperThreading;
|
||||
unsigned int HT_HyterThreadingSiblings;
|
||||
bool TM_ThermalMonitor;
|
||||
bool IA64_Intel64BitArchitecture;
|
||||
bool _3DNOW_InstructionExtensions;
|
||||
bool _E3DNOW_InstructionExtensions;
|
||||
bool AA64_AMD64BitArchitecture;
|
||||
};
|
||||
|
||||
struct ProcessorCache
|
||||
{
|
||||
bool bPresent;
|
||||
char strSize[32]; /* Flawfinder: ignore */
|
||||
unsigned int uiAssociativeWays;
|
||||
unsigned int uiLineSize;
|
||||
bool bSectored;
|
||||
char strCache[128]; /* Flawfinder: ignore */
|
||||
};
|
||||
|
||||
struct ProcessorL1Cache
|
||||
{
|
||||
ProcessorCache Instruction;
|
||||
ProcessorCache Data;
|
||||
};
|
||||
|
||||
struct ProcessorTLB
|
||||
{
|
||||
bool bPresent;
|
||||
char strPageSize[32]; /* Flawfinder: ignore */
|
||||
unsigned int uiAssociativeWays;
|
||||
unsigned int uiEntries;
|
||||
char strTLB[128]; /* Flawfinder: ignore */
|
||||
};
|
||||
|
||||
struct ProcessorInfo
|
||||
{
|
||||
char strVendor[16]; /* Flawfinder: ignore */
|
||||
unsigned int uiFamily;
|
||||
unsigned int uiExtendedFamily;
|
||||
char strFamily[64]; /* Flawfinder: ignore */
|
||||
unsigned int uiModel;
|
||||
unsigned int uiExtendedModel;
|
||||
char strModel[128]; /* Flawfinder: ignore */
|
||||
unsigned int uiStepping;
|
||||
unsigned int uiType;
|
||||
char strType[64]; /* Flawfinder: ignore */
|
||||
unsigned int uiBrandID;
|
||||
char strBrandID[64]; /* Flawfinder: ignore */
|
||||
char strProcessorSerial[64]; /* Flawfinder: ignore */
|
||||
unsigned long MaxSupportedLevel;
|
||||
unsigned long MaxSupportedExtendedLevel;
|
||||
ProcessorExtensions _Ext;
|
||||
ProcessorL1Cache _L1;
|
||||
ProcessorCache _L2;
|
||||
ProcessorCache _L3;
|
||||
ProcessorCache _Trace;
|
||||
ProcessorTLB _Instruction;
|
||||
ProcessorTLB _Data;
|
||||
};
|
||||
|
||||
|
||||
// CProcessor
|
||||
// ==========
|
||||
// Class for detecting the processor name, type and available
|
||||
// extensions as long as it's speed.
|
||||
/////////////////////////////////////////////////////////////
|
||||
class CProcessor
|
||||
{
|
||||
// Constructor / Destructor:
|
||||
////////////////////////////
|
||||
public:
|
||||
CProcessor();
|
||||
LLProcessorInfo();
|
||||
~LLProcessorInfo();
|
||||
|
||||
// Private vars:
|
||||
////////////////
|
||||
public:
|
||||
F64 uqwFrequency;
|
||||
char strCPUName[128]; /* Flawfinder: ignore */
|
||||
ProcessorInfo CPUInfo;
|
||||
|
||||
// Private functions:
|
||||
/////////////////////
|
||||
F64 getCPUFrequency() const;
|
||||
bool hasSSE() const;
|
||||
bool hasSSE2() const;
|
||||
bool hasAltivec() const;
|
||||
std::string getCPUFamilyName() const;
|
||||
std::string getCPUBrandName() const;
|
||||
std::string getCPUFeatureDescription() const;
|
||||
private:
|
||||
bool AnalyzeIntelProcessor();
|
||||
bool AnalyzeAMDProcessor();
|
||||
bool AnalyzeUnknownProcessor();
|
||||
bool CheckCPUIDPresence();
|
||||
void DecodeProcessorConfiguration(unsigned int cfg);
|
||||
void TranslateProcessorConfiguration();
|
||||
void GetStandardProcessorConfiguration();
|
||||
void GetStandardProcessorExtensions();
|
||||
|
||||
// Public functions:
|
||||
////////////////////
|
||||
public:
|
||||
F64 GetCPUFrequency(unsigned int uiMeasureMSecs);
|
||||
const ProcessorInfo *GetCPUInfo();
|
||||
bool CPUInfoToText(char *strBuffer, unsigned int uiMaxLen);
|
||||
bool WriteInfoTextFile(const std::string& strFilename);
|
||||
LLProcessorInfoImpl* mImpl;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -65,32 +65,32 @@
|
||||
/**
|
||||
*@brief Generate a float from [0, RAND_MAX).
|
||||
*/
|
||||
LL_COMMON_API S32 ll_rand();
|
||||
S32 LL_COMMON_API ll_rand();
|
||||
|
||||
/**
|
||||
*@brief Generate a float from [0, val) or (val, 0].
|
||||
*/
|
||||
LL_COMMON_API S32 ll_rand(S32 val);
|
||||
S32 LL_COMMON_API ll_rand(S32 val);
|
||||
|
||||
/**
|
||||
*@brief Generate a float from [0, 1.0).
|
||||
*/
|
||||
LL_COMMON_API F32 ll_frand();
|
||||
F32 LL_COMMON_API ll_frand();
|
||||
|
||||
/**
|
||||
*@brief Generate a float from [0, val) or (val, 0].
|
||||
*/
|
||||
LL_COMMON_API F32 ll_frand(F32 val);
|
||||
F32 LL_COMMON_API ll_frand(F32 val);
|
||||
|
||||
/**
|
||||
*@brief Generate a double from [0, 1.0).
|
||||
*/
|
||||
LL_COMMON_API F64 ll_drand();
|
||||
F64 LL_COMMON_API ll_drand();
|
||||
|
||||
/**
|
||||
*@brief Generate a double from [0, val) or (val, 0].
|
||||
*/
|
||||
LL_COMMON_API F64 ll_drand(F64 val);
|
||||
F64 LL_COMMON_API ll_drand(F64 val);
|
||||
|
||||
/**
|
||||
* @brief typedefs for good boost lagged fibonacci.
|
||||
|
||||
@@ -38,8 +38,6 @@
|
||||
#include <vector>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
#include "llpreprocessor.h"
|
||||
|
||||
class LLRunnable;
|
||||
|
||||
/**
|
||||
|
||||
143
indra/llcommon/llstacktrace.cpp
Normal file
143
indra/llcommon/llstacktrace.cpp
Normal file
@@ -0,0 +1,143 @@
|
||||
/**
|
||||
* @file llstacktrace.cpp
|
||||
* @brief stack tracing functionality
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2001-2010, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
* to you under the terms of the GNU General Public License, version 2.0
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlife.com/developers/opensource/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlife.com/developers/opensource/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
* and agree to abide by those obligations.
|
||||
*
|
||||
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "linden_common.h"
|
||||
#include "llstacktrace.h"
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "windows.h"
|
||||
#include "Dbghelp.h"
|
||||
|
||||
typedef USHORT NTAPI RtlCaptureStackBackTrace_Function(
|
||||
IN ULONG frames_to_skip,
|
||||
IN ULONG frames_to_capture,
|
||||
OUT PVOID *backtrace,
|
||||
OUT PULONG backtrace_hash);
|
||||
|
||||
static RtlCaptureStackBackTrace_Function* const RtlCaptureStackBackTrace_fn =
|
||||
(RtlCaptureStackBackTrace_Function*)
|
||||
GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlCaptureStackBackTrace");
|
||||
|
||||
bool ll_get_stack_trace(std::vector<std::string>& lines)
|
||||
{
|
||||
const S32 MAX_STACK_DEPTH = 32;
|
||||
const S32 STRING_NAME_LENGTH = 200;
|
||||
const S32 FRAME_SKIP = 2;
|
||||
static BOOL symbolsLoaded = false;
|
||||
static BOOL firstCall = true;
|
||||
|
||||
HANDLE hProc = GetCurrentProcess();
|
||||
|
||||
// load the symbols if they're not loaded
|
||||
if(!symbolsLoaded && firstCall)
|
||||
{
|
||||
symbolsLoaded = SymInitialize(hProc, NULL, true);
|
||||
firstCall = false;
|
||||
}
|
||||
|
||||
// if loaded, get the call stack
|
||||
if(symbolsLoaded)
|
||||
{
|
||||
// create the frames to hold the addresses
|
||||
void* frames[MAX_STACK_DEPTH];
|
||||
memset(frames, 0, sizeof(void*)*MAX_STACK_DEPTH);
|
||||
S32 depth = 0;
|
||||
|
||||
// get the addresses
|
||||
depth = RtlCaptureStackBackTrace_fn(FRAME_SKIP, MAX_STACK_DEPTH, frames, NULL);
|
||||
|
||||
IMAGEHLP_LINE64 line;
|
||||
memset(&line, 0, sizeof(IMAGEHLP_LINE64));
|
||||
line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
|
||||
// create something to hold address info
|
||||
PIMAGEHLP_SYMBOL64 pSym;
|
||||
pSym = (PIMAGEHLP_SYMBOL64)malloc(sizeof(IMAGEHLP_SYMBOL64) + STRING_NAME_LENGTH);
|
||||
memset(pSym, 0, sizeof(IMAGEHLP_SYMBOL64) + STRING_NAME_LENGTH);
|
||||
pSym->MaxNameLength = STRING_NAME_LENGTH;
|
||||
pSym->SizeOfStruct = sizeof(IMAGEHLP_SYMBOL64);
|
||||
|
||||
// get address info for each address frame
|
||||
// and store
|
||||
for(S32 i=0; i < depth; i++)
|
||||
{
|
||||
std::stringstream stack_line;
|
||||
BOOL ret;
|
||||
|
||||
DWORD64 addr = (DWORD64)frames[i];
|
||||
ret = SymGetSymFromAddr64(hProc, addr, 0, pSym);
|
||||
if(ret)
|
||||
{
|
||||
stack_line << pSym->Name << " ";
|
||||
}
|
||||
|
||||
DWORD dummy;
|
||||
ret = SymGetLineFromAddr64(hProc, addr, &dummy, &line);
|
||||
if(ret)
|
||||
{
|
||||
std::string file_name = line.FileName;
|
||||
std::string::size_type index = file_name.rfind("\\");
|
||||
stack_line << file_name.substr(index + 1, file_name.size()) << ":" << line.LineNumber;
|
||||
}
|
||||
|
||||
lines.push_back(stack_line.str());
|
||||
}
|
||||
|
||||
free(pSym);
|
||||
|
||||
// TODO: figure out a way to cleanup symbol loading
|
||||
// Not hugely necessary, however.
|
||||
//SymCleanup(hProc);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
lines.push_back("Stack Trace Failed. PDB symbol info not loaded");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
bool ll_get_stack_trace(std::vector<std::string>& lines)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/**
|
||||
* @file processor.h
|
||||
* @brief Legacy wrapper header.
|
||||
* @file llstacktrace.h
|
||||
* @brief stack trace functions
|
||||
*
|
||||
* $LicenseInfo:firstyear=2000&license=viewergpl$
|
||||
* $LicenseInfo:firstyear=2001&license=viewergpl$
|
||||
*
|
||||
* Copyright (c) 2000-2009, Linden Research, Inc.
|
||||
* Copyright (c) 2001-2010, Linden Research, Inc.
|
||||
*
|
||||
* Second Life Viewer Source Code
|
||||
* The source code in this file ("Source Code") is provided by Linden Lab
|
||||
@@ -12,13 +12,13 @@
|
||||
* ("GPL"), unless you have obtained a separate licensing agreement
|
||||
* ("Other License"), formally executed by you and Linden Lab. Terms of
|
||||
* the GPL can be found in doc/GPL-license.txt in this distribution, or
|
||||
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
|
||||
* online at http://secondlife.com/developers/opensource/gplv2
|
||||
*
|
||||
* There are special exceptions to the terms and conditions of the GPL as
|
||||
* it is applied to this Source Code. View the full text of the exception
|
||||
* in the file doc/FLOSS-exception.txt in this software distribution, or
|
||||
* online at
|
||||
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
|
||||
* http://secondlife.com/developers/opensource/flossexception
|
||||
*
|
||||
* By copying, modifying or distributing this software, you acknowledge
|
||||
* that you have read and understood your obligations described above,
|
||||
@@ -28,6 +28,18 @@
|
||||
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
|
||||
* COMPLETENESS OR PERFORMANCE.
|
||||
* $/LicenseInfo$
|
||||
*
|
||||
*/
|
||||
|
||||
#include "llprocessor.h"
|
||||
|
||||
#ifndef LL_LLSTACKTRACE_H
|
||||
#define LL_LLSTACKTRACE_H
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
LL_COMMON_API bool ll_get_stack_trace(std::vector<std::string>& lines);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -436,7 +436,7 @@ void get_keyword_and_value(std::string& keyword,
|
||||
while (line_index < line_size)
|
||||
{
|
||||
c = line[line_index];
|
||||
if (!isspace(c))
|
||||
if (!LLStringOps::isSpace(c))
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -448,7 +448,7 @@ void get_keyword_and_value(std::string& keyword,
|
||||
while (line_index < line_size)
|
||||
{
|
||||
c = line[line_index];
|
||||
if (isspace(c) || '\r' == c || '\n' == c)
|
||||
if (LLStringOps::isSpace(c) || '\r' == c || '\n' == c)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -34,6 +34,7 @@
|
||||
|
||||
#include "llstring.h"
|
||||
#include "llerror.h"
|
||||
#include "llfasttimer.h"
|
||||
|
||||
#if LL_WINDOWS
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
@@ -71,6 +72,24 @@ U8 hex_as_nybble(char hex)
|
||||
return 0; // uh - oh, not hex any more...
|
||||
}
|
||||
|
||||
bool iswindividual(llwchar elem)
|
||||
{
|
||||
U32 cur_char = (U32)elem;
|
||||
bool result = false;
|
||||
if (0x2E80<= cur_char && cur_char <= 0x9FFF)
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
else if (0xAC00<= cur_char && cur_char <= 0xD7A0 )
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
else if (0xF900<= cur_char && cur_char <= 0xFA60 )
|
||||
{
|
||||
result = true;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool _read_file_into_string(std::string& str, const std::string& filename)
|
||||
{
|
||||
@@ -630,14 +649,14 @@ namespace snprintf_hack
|
||||
}
|
||||
}
|
||||
|
||||
std::string ll_convert_wide_to_string(const wchar_t* in)
|
||||
std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page)
|
||||
{
|
||||
std::string out;
|
||||
if(in)
|
||||
{
|
||||
int len_in = wcslen(in);
|
||||
int len_out = WideCharToMultiByte(
|
||||
CP_ACP,
|
||||
code_page,
|
||||
0,
|
||||
in,
|
||||
len_in,
|
||||
@@ -652,7 +671,7 @@ std::string ll_convert_wide_to_string(const wchar_t* in)
|
||||
if(pout)
|
||||
{
|
||||
WideCharToMultiByte(
|
||||
CP_ACP,
|
||||
code_page,
|
||||
0,
|
||||
in,
|
||||
len_in,
|
||||
@@ -666,8 +685,55 @@ std::string ll_convert_wide_to_string(const wchar_t* in)
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page)
|
||||
{
|
||||
// From review:
|
||||
// We can preallocate a wide char buffer that is the same length (in wchar_t elements) as the utf8 input,
|
||||
// plus one for a null terminator, and be guaranteed to not overflow.
|
||||
|
||||
// Normally, I'd call that sort of thing premature optimization,
|
||||
// but we *are* seeing string operations taking a bunch of time, especially when constructing widgets.
|
||||
// int output_str_len = MultiByteToWideChar(code_page, 0, in.c_str(), in.length(), NULL, 0);
|
||||
|
||||
// reserve place to NULL terminator
|
||||
int output_str_len = in.length();
|
||||
wchar_t* w_out = new wchar_t[output_str_len + 1];
|
||||
|
||||
memset(w_out, 0, output_str_len + 1);
|
||||
int real_output_str_len = MultiByteToWideChar (code_page, 0, in.c_str(), in.length(), w_out, output_str_len);
|
||||
|
||||
//looks like MultiByteToWideChar didn't add null terminator to converted string, see EXT-4858.
|
||||
w_out[real_output_str_len] = 0;
|
||||
|
||||
return w_out;
|
||||
}
|
||||
|
||||
std::string ll_convert_string_to_utf8_string(const std::string& in)
|
||||
{
|
||||
wchar_t* w_mesg = ll_convert_string_to_wide(in, CP_ACP);
|
||||
std::string out_utf8(ll_convert_wide_to_string(w_mesg, CP_UTF8));
|
||||
delete[] w_mesg;
|
||||
|
||||
return out_utf8;
|
||||
}
|
||||
#endif // LL_WINDOWS
|
||||
|
||||
long LLStringOps::sPacificTimeOffset = 0;
|
||||
long LLStringOps::sLocalTimeOffset = 0;
|
||||
bool LLStringOps::sPacificDaylightTime = 0;
|
||||
std::map<std::string, std::string> LLStringOps::datetimeToCodes;
|
||||
|
||||
std::vector<std::string> LLStringOps::sWeekDayList;
|
||||
std::vector<std::string> LLStringOps::sWeekDayShortList;
|
||||
std::vector<std::string> LLStringOps::sMonthList;
|
||||
std::vector<std::string> LLStringOps::sMonthShortList;
|
||||
|
||||
|
||||
std::string LLStringOps::sDayFormat;
|
||||
std::string LLStringOps::sAM;
|
||||
std::string LLStringOps::sPM;
|
||||
|
||||
S32 LLStringOps::collate(const llwchar* a, const llwchar* b)
|
||||
{
|
||||
#if LL_WINDOWS
|
||||
@@ -679,6 +745,107 @@ S32 LLStringOps::collate(const llwchar* a, const llwchar* b)
|
||||
#endif
|
||||
}
|
||||
|
||||
void LLStringOps::setupDatetimeInfo (bool daylight)
|
||||
{
|
||||
time_t nowT, localT, gmtT;
|
||||
struct tm * tmpT;
|
||||
|
||||
nowT = time (NULL);
|
||||
|
||||
tmpT = gmtime (&nowT);
|
||||
gmtT = mktime (tmpT);
|
||||
|
||||
tmpT = localtime (&nowT);
|
||||
localT = mktime (tmpT);
|
||||
|
||||
sLocalTimeOffset = (long) (gmtT - localT);
|
||||
if (tmpT->tm_isdst)
|
||||
{
|
||||
sLocalTimeOffset -= 60 * 60; // 1 hour
|
||||
}
|
||||
|
||||
sPacificDaylightTime = daylight;
|
||||
sPacificTimeOffset = (sPacificDaylightTime? 7 : 8 ) * 60 * 60;
|
||||
|
||||
datetimeToCodes["wkday"] = "%a"; // Thu
|
||||
datetimeToCodes["weekday"] = "%A"; // Thursday
|
||||
datetimeToCodes["year4"] = "%Y"; // 2009
|
||||
datetimeToCodes["year"] = "%Y"; // 2009
|
||||
datetimeToCodes["year2"] = "%y"; // 09
|
||||
datetimeToCodes["mth"] = "%b"; // Aug
|
||||
datetimeToCodes["month"] = "%B"; // August
|
||||
datetimeToCodes["mthnum"] = "%m"; // 08
|
||||
datetimeToCodes["day"] = "%d"; // 31
|
||||
datetimeToCodes["sday"] = "%-d"; // 9
|
||||
datetimeToCodes["hour24"] = "%H"; // 14
|
||||
datetimeToCodes["hour"] = "%H"; // 14
|
||||
datetimeToCodes["hour12"] = "%I"; // 02
|
||||
datetimeToCodes["min"] = "%M"; // 59
|
||||
datetimeToCodes["ampm"] = "%p"; // AM
|
||||
datetimeToCodes["second"] = "%S"; // 59
|
||||
datetimeToCodes["timezone"] = "%Z"; // PST
|
||||
}
|
||||
|
||||
void tokenizeStringToArray(const std::string& data, std::vector<std::string>& output)
|
||||
{
|
||||
output.clear();
|
||||
size_t length = data.size();
|
||||
|
||||
// tokenize it and put it in the array
|
||||
std::string cur_word;
|
||||
for(size_t i = 0; i < length; ++i)
|
||||
{
|
||||
if(data[i] == ':')
|
||||
{
|
||||
output.push_back(cur_word);
|
||||
cur_word.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
cur_word.append(1, data[i]);
|
||||
}
|
||||
}
|
||||
output.push_back(cur_word);
|
||||
}
|
||||
|
||||
void LLStringOps::setupWeekDaysNames(const std::string& data)
|
||||
{
|
||||
tokenizeStringToArray(data,sWeekDayList);
|
||||
}
|
||||
void LLStringOps::setupWeekDaysShortNames(const std::string& data)
|
||||
{
|
||||
tokenizeStringToArray(data,sWeekDayShortList);
|
||||
}
|
||||
void LLStringOps::setupMonthNames(const std::string& data)
|
||||
{
|
||||
tokenizeStringToArray(data,sMonthList);
|
||||
}
|
||||
void LLStringOps::setupMonthShortNames(const std::string& data)
|
||||
{
|
||||
tokenizeStringToArray(data,sMonthShortList);
|
||||
}
|
||||
void LLStringOps::setupDayFormat(const std::string& data)
|
||||
{
|
||||
sDayFormat = data;
|
||||
}
|
||||
|
||||
|
||||
std::string LLStringOps::getDatetimeCode (std::string key)
|
||||
{
|
||||
std::map<std::string, std::string>::iterator iter;
|
||||
|
||||
iter = datetimeToCodes.find (key);
|
||||
if (iter != datetimeToCodes.end())
|
||||
{
|
||||
return iter->second;
|
||||
}
|
||||
else
|
||||
{
|
||||
return std::string("");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
namespace LLStringFn
|
||||
{
|
||||
// NOTE - this restricts output to ascii
|
||||
@@ -715,12 +882,12 @@ namespace LLStringFn
|
||||
// https://wiki.lindenlab.com/wiki/Unicode_Guidelines has details on
|
||||
// allowable code points for XML. Specifically, they are:
|
||||
// 0x09, 0x0a, 0x0d, and 0x20 on up. JC
|
||||
std::string strip_invalid_xml(const std::string& input)
|
||||
std::string strip_invalid_xml(const std::string& instr)
|
||||
{
|
||||
std::string output;
|
||||
output.reserve( input.size() );
|
||||
std::string::const_iterator it = input.begin();
|
||||
while (it != input.end())
|
||||
output.reserve( instr.size() );
|
||||
std::string::const_iterator it = instr.begin();
|
||||
while (it != instr.end())
|
||||
{
|
||||
// Must compare as unsigned for >=
|
||||
// Test most likely match first
|
||||
@@ -756,6 +923,412 @@ namespace LLStringFn
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// Forward specialization of LLStringUtil::format before use in LLStringUtil::formatDatetime.
|
||||
template<>
|
||||
S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions);
|
||||
|
||||
//static
|
||||
template<>
|
||||
void LLStringUtil::getTokens(const std::string& instr, std::vector<std::string >& tokens, const std::string& delims)
|
||||
{
|
||||
std::string currToken;
|
||||
std::string::size_type begIdx, endIdx;
|
||||
|
||||
begIdx = instr.find_first_not_of (delims);
|
||||
while (begIdx != std::string::npos)
|
||||
{
|
||||
endIdx = instr.find_first_of (delims, begIdx);
|
||||
if (endIdx == std::string::npos)
|
||||
{
|
||||
endIdx = instr.length();
|
||||
}
|
||||
|
||||
currToken = instr.substr(begIdx, endIdx - begIdx);
|
||||
LLStringUtil::trim (currToken);
|
||||
tokens.push_back(currToken);
|
||||
begIdx = instr.find_first_not_of (delims, endIdx);
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
LLStringUtil::size_type LLStringUtil::getSubstitution(const std::string& instr, size_type& start, std::vector<std::string>& tokens)
|
||||
{
|
||||
const std::string delims (",");
|
||||
|
||||
// Find the first ]
|
||||
size_type pos2 = instr.find(']', start);
|
||||
if (pos2 == std::string::npos)
|
||||
return std::string::npos;
|
||||
|
||||
// Find the last [ before ]
|
||||
size_type pos1 = instr.find_last_of('[', pos2-1);
|
||||
if (pos1 == std::string::npos || pos1 < start)
|
||||
return std::string::npos;
|
||||
|
||||
getTokens(std::string(instr,pos1+1,pos2-pos1-1), tokens, delims);
|
||||
start = pos2+1;
|
||||
|
||||
return pos1;
|
||||
}
|
||||
|
||||
// static
|
||||
template<>
|
||||
bool LLStringUtil::simpleReplacement(std::string &replacement, std::string token, const format_map_t& substitutions)
|
||||
{
|
||||
// see if we have a replacement for the bracketed string (without the brackets)
|
||||
// test first using has() because if we just look up with operator[] we get back an
|
||||
// empty string even if the value is missing. We want to distinguish between
|
||||
// missing replacements and deliberately empty replacement strings.
|
||||
format_map_t::const_iterator iter = substitutions.find(token);
|
||||
if (iter != substitutions.end())
|
||||
{
|
||||
replacement = iter->second;
|
||||
return true;
|
||||
}
|
||||
// if not, see if there's one WITH brackets
|
||||
iter = substitutions.find(std::string("[" + token + "]"));
|
||||
if (iter != substitutions.end())
|
||||
{
|
||||
replacement = iter->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
template<>
|
||||
bool LLStringUtil::simpleReplacement(std::string &replacement, std::string token, const LLSD& substitutions)
|
||||
{
|
||||
// see if we have a replacement for the bracketed string (without the brackets)
|
||||
// test first using has() because if we just look up with operator[] we get back an
|
||||
// empty string even if the value is missing. We want to distinguish between
|
||||
// missing replacements and deliberately empty replacement strings.
|
||||
if (substitutions.has(token))
|
||||
{
|
||||
replacement = substitutions[token].asString();
|
||||
return true;
|
||||
}
|
||||
// if not, see if there's one WITH brackets
|
||||
else if (substitutions.has(std::string("[" + token + "]")))
|
||||
{
|
||||
replacement = substitutions[std::string("[" + token + "]")].asString();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//static
|
||||
template<>
|
||||
void LLStringUtil::setLocale(std::string inLocale)
|
||||
{
|
||||
sLocale = inLocale;
|
||||
};
|
||||
|
||||
//static
|
||||
template<>
|
||||
std::string LLStringUtil::getLocale(void)
|
||||
{
|
||||
return sLocale;
|
||||
};
|
||||
|
||||
// static
|
||||
template<>
|
||||
void LLStringUtil::formatNumber(std::string& numStr, std::string decimals)
|
||||
{
|
||||
std::stringstream strStream;
|
||||
S32 intDecimals = 0;
|
||||
|
||||
convertToS32 (decimals, intDecimals);
|
||||
if (!sLocale.empty())
|
||||
{
|
||||
// std::locale() throws if the locale is unknown! (EXT-7926)
|
||||
try
|
||||
{
|
||||
strStream.imbue(std::locale(sLocale.c_str()));
|
||||
} catch (const std::exception &)
|
||||
{
|
||||
LL_WARNS_ONCE("Locale") << "Cannot set locale to " << sLocale << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!intDecimals)
|
||||
{
|
||||
S32 intStr;
|
||||
|
||||
if (convertToS32(numStr, intStr))
|
||||
{
|
||||
strStream << intStr;
|
||||
numStr = strStream.str();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
F32 floatStr;
|
||||
|
||||
if (convertToF32(numStr, floatStr))
|
||||
{
|
||||
strStream << std::fixed << std::showpoint << std::setprecision(intDecimals) << floatStr;
|
||||
numStr = strStream.str();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
template<>
|
||||
bool LLStringUtil::formatDatetime(std::string& replacement, std::string token,
|
||||
std::string param, S32 secFromEpoch)
|
||||
{
|
||||
if (param == "local") // local
|
||||
{
|
||||
secFromEpoch -= LLStringOps::getLocalTimeOffset();
|
||||
}
|
||||
else if (param != "utc") // slt
|
||||
{
|
||||
secFromEpoch -= LLStringOps::getPacificTimeOffset();
|
||||
}
|
||||
|
||||
// if never fell into those two ifs above, param must be utc
|
||||
if (secFromEpoch < 0) secFromEpoch = 0;
|
||||
|
||||
LLDate datetime((F64)secFromEpoch);
|
||||
std::string code = LLStringOps::getDatetimeCode (token);
|
||||
|
||||
// special case to handle timezone
|
||||
if (code == "%Z") {
|
||||
if (param == "utc")
|
||||
{
|
||||
replacement = "GMT";
|
||||
}
|
||||
else if (param == "local")
|
||||
{
|
||||
replacement = ""; // user knows their own timezone
|
||||
}
|
||||
else
|
||||
{
|
||||
// "slt" = Second Life Time, which is deprecated.
|
||||
// If not utc or user local time, fallback to Pacific time
|
||||
replacement = LLStringOps::getPacificDaylightTime() ? "PDT" : "PST";
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//EXT-7013
|
||||
//few codes are not suppotred by strtime function (example - weekdays for Japanise)
|
||||
//so use predefined ones
|
||||
|
||||
//if sWeekDayList is not empty than current locale doesn't support
|
||||
//weekday name.
|
||||
time_t loc_seconds = (time_t) secFromEpoch;
|
||||
if(LLStringOps::sWeekDayList.size() == 7 && code == "%A")
|
||||
{
|
||||
struct tm * gmt = gmtime (&loc_seconds);
|
||||
replacement = LLStringOps::sWeekDayList[gmt->tm_wday];
|
||||
}
|
||||
else if(LLStringOps::sWeekDayShortList.size() == 7 && code == "%a")
|
||||
{
|
||||
struct tm * gmt = gmtime (&loc_seconds);
|
||||
replacement = LLStringOps::sWeekDayShortList[gmt->tm_wday];
|
||||
}
|
||||
else if(LLStringOps::sMonthList.size() == 12 && code == "%B")
|
||||
{
|
||||
struct tm * gmt = gmtime (&loc_seconds);
|
||||
replacement = LLStringOps::sMonthList[gmt->tm_mon];
|
||||
}
|
||||
else if( !LLStringOps::sDayFormat.empty() && code == "%d" )
|
||||
{
|
||||
struct tm * gmt = gmtime (&loc_seconds);
|
||||
LLStringUtil::format_map_t args;
|
||||
args["[MDAY]"] = llformat ("%d", gmt->tm_mday);
|
||||
replacement = LLStringOps::sDayFormat;
|
||||
LLStringUtil::format(replacement, args);
|
||||
}
|
||||
else if (code == "%-d")
|
||||
{
|
||||
struct tm * gmt = gmtime (&loc_seconds);
|
||||
replacement = llformat ("%d", gmt->tm_mday); // day of the month without leading zero
|
||||
}
|
||||
else if( !LLStringOps::sAM.empty() && !LLStringOps::sPM.empty() && code == "%p" )
|
||||
{
|
||||
struct tm * gmt = gmtime (&loc_seconds);
|
||||
if(gmt->tm_hour<12)
|
||||
{
|
||||
replacement = LLStringOps::sAM;
|
||||
}
|
||||
else
|
||||
{
|
||||
replacement = LLStringOps::sPM;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
replacement = datetime.toHTTPDateString(code);
|
||||
}
|
||||
|
||||
// *HACK: delete leading zero from hour string in case 'hour12' (code = %I) time format
|
||||
// to show time without leading zero, e.g. 08:16 -> 8:16 (EXT-2738).
|
||||
// We could have used '%l' format instead, but it's not supported by Windows.
|
||||
if(code == "%I" && token == "hour12" && replacement.at(0) == '0')
|
||||
{
|
||||
replacement = replacement.at(1);
|
||||
}
|
||||
|
||||
return !code.empty();
|
||||
}
|
||||
|
||||
// LLStringUtil::format recogizes the following patterns.
|
||||
// All substitutions *must* be encased in []'s in the input string.
|
||||
// The []'s are optional in the substitution map.
|
||||
// [FOO_123]
|
||||
// [FOO,number,precision]
|
||||
// [FOO,datetime,format]
|
||||
|
||||
|
||||
// static
|
||||
template<>
|
||||
S32 LLStringUtil::format(std::string& s, const format_map_t& substitutions)
|
||||
{
|
||||
LLFastTimer ft(LLFastTimer::FT_STRING_FORMAT);
|
||||
S32 res = 0;
|
||||
|
||||
std::string output;
|
||||
std::vector<std::string> tokens;
|
||||
|
||||
std::string::size_type start = 0;
|
||||
std::string::size_type prev_start = 0;
|
||||
std::string::size_type key_start = 0;
|
||||
while ((key_start = getSubstitution(s, start, tokens)) != std::string::npos)
|
||||
{
|
||||
output += std::string(s, prev_start, key_start-prev_start);
|
||||
prev_start = start;
|
||||
|
||||
bool found_replacement = false;
|
||||
std::string replacement;
|
||||
|
||||
if (tokens.size() == 0)
|
||||
{
|
||||
found_replacement = false;
|
||||
}
|
||||
else if (tokens.size() == 1)
|
||||
{
|
||||
found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
|
||||
}
|
||||
else if (tokens[1] == "number")
|
||||
{
|
||||
std::string param = "0";
|
||||
|
||||
if (tokens.size() > 2) param = tokens[2];
|
||||
found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
|
||||
if (found_replacement) formatNumber (replacement, param);
|
||||
}
|
||||
else if (tokens[1] == "datetime")
|
||||
{
|
||||
std::string param;
|
||||
if (tokens.size() > 2) param = tokens[2];
|
||||
|
||||
format_map_t::const_iterator iter = substitutions.find("datetime");
|
||||
if (iter != substitutions.end())
|
||||
{
|
||||
S32 secFromEpoch = 0;
|
||||
BOOL r = LLStringUtil::convertToS32(iter->second, secFromEpoch);
|
||||
if (r)
|
||||
{
|
||||
found_replacement = formatDatetime(replacement, tokens[0], param, secFromEpoch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found_replacement)
|
||||
{
|
||||
output += replacement;
|
||||
res++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we had no replacement, use the string as is
|
||||
// e.g. "hello [MISSING_REPLACEMENT]" or "-=[Stylized Name]=-"
|
||||
output += std::string(s, key_start, start-key_start);
|
||||
}
|
||||
tokens.clear();
|
||||
}
|
||||
// send the remainder of the string (with no further matches for bracketed names)
|
||||
output += std::string(s, start);
|
||||
s = output;
|
||||
return res;
|
||||
}
|
||||
|
||||
//static
|
||||
template<>
|
||||
S32 LLStringUtil::format(std::string& s, const LLSD& substitutions)
|
||||
{
|
||||
LLFastTimer ft(LLFastTimer::FT_STRING_FORMAT);
|
||||
S32 res = 0;
|
||||
|
||||
if (!substitutions.isMap())
|
||||
{
|
||||
return res;
|
||||
}
|
||||
|
||||
std::string output;
|
||||
std::vector<std::string> tokens;
|
||||
|
||||
std::string::size_type start = 0;
|
||||
std::string::size_type prev_start = 0;
|
||||
std::string::size_type key_start = 0;
|
||||
while ((key_start = getSubstitution(s, start, tokens)) != std::string::npos)
|
||||
{
|
||||
output += std::string(s, prev_start, key_start-prev_start);
|
||||
prev_start = start;
|
||||
|
||||
bool found_replacement = false;
|
||||
std::string replacement;
|
||||
|
||||
if (tokens.size() == 0)
|
||||
{
|
||||
found_replacement = false;
|
||||
}
|
||||
else if (tokens.size() == 1)
|
||||
{
|
||||
found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
|
||||
}
|
||||
else if (tokens[1] == "number")
|
||||
{
|
||||
std::string param = "0";
|
||||
|
||||
if (tokens.size() > 2) param = tokens[2];
|
||||
found_replacement = simpleReplacement (replacement, tokens[0], substitutions);
|
||||
if (found_replacement) formatNumber (replacement, param);
|
||||
}
|
||||
else if (tokens[1] == "datetime")
|
||||
{
|
||||
std::string param;
|
||||
if (tokens.size() > 2) param = tokens[2];
|
||||
|
||||
S32 secFromEpoch = (S32) substitutions["datetime"].asInteger();
|
||||
found_replacement = formatDatetime (replacement, tokens[0], param, secFromEpoch);
|
||||
}
|
||||
|
||||
if (found_replacement)
|
||||
{
|
||||
output += replacement;
|
||||
res++;
|
||||
}
|
||||
else
|
||||
{
|
||||
// we had no replacement, use the string as is
|
||||
// e.g. "hello [MISSING_REPLACEMENT]" or "-=[Stylized Name]=-"
|
||||
output += std::string(s, key_start, start-key_start);
|
||||
}
|
||||
tokens.clear();
|
||||
}
|
||||
// send the remainder of the string (with no further matches for bracketed names)
|
||||
output += std::string(s, start);
|
||||
s = output;
|
||||
return res;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// Testing
|
||||
|
||||
@@ -37,6 +37,9 @@
|
||||
#include <cstdio>
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <locale>
|
||||
#include <iomanip>
|
||||
#include "llsd.h"
|
||||
|
||||
#if LL_LINUX || LL_SOLARIS
|
||||
#include <wctype.h>
|
||||
@@ -148,7 +151,23 @@ struct char_traits<U16>
|
||||
|
||||
class LL_COMMON_API LLStringOps
|
||||
{
|
||||
private:
|
||||
static long sPacificTimeOffset;
|
||||
static long sLocalTimeOffset;
|
||||
static bool sPacificDaylightTime;
|
||||
|
||||
static std::map<std::string, std::string> datetimeToCodes;
|
||||
|
||||
public:
|
||||
static std::vector<std::string> sWeekDayList;
|
||||
static std::vector<std::string> sWeekDayShortList;
|
||||
static std::vector<std::string> sMonthList;
|
||||
static std::vector<std::string> sMonthShortList;
|
||||
static std::string sDayFormat;
|
||||
|
||||
static std::string sAM;
|
||||
static std::string sPM;
|
||||
|
||||
static char toUpper(char elem) { return toupper((unsigned char)elem); }
|
||||
static llwchar toUpper(llwchar elem) { return towupper(elem); }
|
||||
|
||||
@@ -177,14 +196,31 @@ public:
|
||||
static S32 collate(const llwchar* a, const llwchar* b);
|
||||
|
||||
static bool isHexString(const std::string& str);
|
||||
|
||||
static void setupDatetimeInfo(bool pacific_daylight_time);
|
||||
|
||||
static void setupWeekDaysNames(const std::string& data);
|
||||
static void setupWeekDaysShortNames(const std::string& data);
|
||||
static void setupMonthNames(const std::string& data);
|
||||
static void setupMonthShortNames(const std::string& data);
|
||||
static void setupDayFormat(const std::string& data);
|
||||
|
||||
|
||||
static long getPacificTimeOffset(void) { return sPacificTimeOffset;}
|
||||
static long getLocalTimeOffset(void) { return sLocalTimeOffset;}
|
||||
// Is the Pacific time zone (aka server time zone)
|
||||
// currently in daylight savings time?
|
||||
static bool getPacificDaylightTime(void) { return sPacificDaylightTime;}
|
||||
|
||||
static std::string getDatetimeCode (std::string key);
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Return a string constructed from in without crashing if the
|
||||
* pointer is NULL.
|
||||
*/
|
||||
std::string LL_COMMON_API ll_safe_string(const char* in);
|
||||
std::string LL_COMMON_API ll_safe_string(const char* in, S32 maxlen);
|
||||
LL_COMMON_API std::string ll_safe_string(const char* in);
|
||||
LL_COMMON_API std::string ll_safe_string(const char* in, S32 maxlen);
|
||||
|
||||
|
||||
// Allowing assignments from non-strings into format_map_t is apparently
|
||||
@@ -206,6 +242,9 @@ private:
|
||||
template <class T>
|
||||
class LLStringUtilBase
|
||||
{
|
||||
private:
|
||||
static std::string sLocale;
|
||||
|
||||
public:
|
||||
typedef typename std::basic_string<T>::size_type size_type;
|
||||
|
||||
@@ -213,10 +252,18 @@ public:
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Static Utility functions that operate on std::strings
|
||||
|
||||
static std::basic_string<T> const null;
|
||||
static const std::basic_string<T> null;
|
||||
|
||||
typedef std::map<LLFormatMapString, LLFormatMapString> format_map_t;
|
||||
static S32 format(std::basic_string<T>& s, const format_map_t& fmt_map);
|
||||
LL_COMMON_API static void getTokens(const std::basic_string<T>& instr, std::vector<std::basic_string<T> >& tokens, const std::basic_string<T>& delims);
|
||||
LL_COMMON_API static void formatNumber(std::basic_string<T>& numStr, std::basic_string<T> decimals);
|
||||
LL_COMMON_API static bool formatDatetime(std::basic_string<T>& replacement, std::basic_string<T> token, std::basic_string<T> param, S32 secFromEpoch);
|
||||
LL_COMMON_API static S32 format(std::basic_string<T>& s, const format_map_t& substitutions);
|
||||
LL_COMMON_API static S32 format(std::basic_string<T>& s, const LLSD& substitutions);
|
||||
LL_COMMON_API static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const format_map_t& substitutions);
|
||||
LL_COMMON_API static bool simpleReplacement(std::basic_string<T>& replacement, std::basic_string<T> token, const LLSD& substitutions);
|
||||
LL_COMMON_API static void setLocale (std::string inLocale);
|
||||
LL_COMMON_API static std::string getLocale (void);
|
||||
|
||||
static bool isValidIndex(const std::basic_string<T>& string, size_type i)
|
||||
{
|
||||
@@ -233,7 +280,25 @@ public:
|
||||
|
||||
// True if this is the head of s.
|
||||
static BOOL isHead( const std::basic_string<T>& string, const T* s );
|
||||
|
||||
|
||||
/**
|
||||
* @brief Returns true if string starts with substr
|
||||
*
|
||||
* If etither string or substr are empty, this method returns false.
|
||||
*/
|
||||
static bool startsWith(
|
||||
const std::basic_string<T>& string,
|
||||
const std::basic_string<T>& substr);
|
||||
|
||||
/**
|
||||
* @brief Returns true if string ends in substr
|
||||
*
|
||||
* If etither string or substr are empty, this method returns false.
|
||||
*/
|
||||
static bool endsWith(
|
||||
const std::basic_string<T>& string,
|
||||
const std::basic_string<T>& substr);
|
||||
|
||||
static void addCRLF(std::basic_string<T>& string);
|
||||
static void removeCRLF(std::basic_string<T>& string);
|
||||
|
||||
@@ -298,13 +363,19 @@ public:
|
||||
// Copies src into dst at a given offset.
|
||||
static void copyInto(std::basic_string<T>& dst, const std::basic_string<T>& src, size_type offset);
|
||||
|
||||
static bool isPartOfWord(T c) { return (c == (T)'_') || LLStringOps::isAlnum(c); }
|
||||
|
||||
|
||||
#ifdef _DEBUG
|
||||
static void testHarness();
|
||||
LL_COMMON_API static void testHarness();
|
||||
#endif
|
||||
|
||||
private:
|
||||
LL_COMMON_API static size_type getSubstitution(const std::basic_string<T>& instr, size_type& start, std::vector<std::basic_string<T> >& tokens);
|
||||
};
|
||||
|
||||
template<class T> std::basic_string<T> const LLStringUtilBase<T>::null;
|
||||
template<class T> const std::basic_string<T> LLStringUtilBase<T>::null;
|
||||
template<class T> std::string LLStringUtilBase<T>::sLocale;
|
||||
|
||||
typedef LLStringUtilBase<char> LLStringUtil;
|
||||
typedef LLStringUtilBase<llwchar> LLWStringUtil;
|
||||
@@ -366,6 +437,7 @@ LL_COMMON_API U8 hex_as_nybble(char hex);
|
||||
* @return Returns true on success. If false, str is unmodified.
|
||||
*/
|
||||
LL_COMMON_API bool _read_file_into_string(std::string& str, const std::string& filename);
|
||||
LL_COMMON_API bool iswindividual(llwchar elem);
|
||||
|
||||
/**
|
||||
* Unicode support
|
||||
@@ -495,7 +567,20 @@ using snprintf_hack::snprintf;
|
||||
*
|
||||
* This replaces the unsafe W2A macro from ATL.
|
||||
*/
|
||||
LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in);
|
||||
LL_COMMON_API std::string ll_convert_wide_to_string(const wchar_t* in, unsigned int code_page);
|
||||
|
||||
/**
|
||||
* Converts a string to wide string.
|
||||
*
|
||||
* It will allocate memory for result string with "new []". Don't forget to release it with "delete []".
|
||||
*/
|
||||
LL_COMMON_API wchar_t* ll_convert_string_to_wide(const std::string& in, unsigned int code_page);
|
||||
|
||||
/**
|
||||
* Converts incoming string into urf8 string
|
||||
*
|
||||
*/
|
||||
LL_COMMON_API std::string ll_convert_string_to_utf8_string(const std::string& in);
|
||||
|
||||
//@}
|
||||
#endif // LL_WINDOWS
|
||||
@@ -558,63 +643,12 @@ namespace LLStringFn
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
// NOTE: LLStringUtil::format, getTokens, and support functions moved to llstring.cpp.
|
||||
// There is no LLWStringUtil::format implementation currently.
|
||||
// Calling thse for anything other than LLStringUtil will produce link errors.
|
||||
|
||||
// LLStringBase::format()
|
||||
//
|
||||
// This function takes a string 's' and a map 'fmt_map' of strings-to-strings.
|
||||
// All occurances of strings in 's' from the left-hand side of 'fmt_map' are
|
||||
// then replaced with the corresponding right-hand side of 'fmt_map', non-
|
||||
// recursively. The function returns the number of substitutions made.
|
||||
////////////////////////////////////////////////////////////
|
||||
|
||||
// static
|
||||
template<class T>
|
||||
S32 LLStringUtilBase<T>::format(std::basic_string<T>& s, const format_map_t& fmt_map)
|
||||
{
|
||||
typedef typename std::basic_string<T>::size_type string_size_type_t;
|
||||
string_size_type_t scanstart = 0;
|
||||
S32 res = 0;
|
||||
|
||||
// Look for the first match of any keyword, replace that keyword,
|
||||
// repeat from the end of the replacement string. This avoids
|
||||
// accidentally performing substitution on a substituted string.
|
||||
while (1)
|
||||
{
|
||||
string_size_type_t first_match_pos = scanstart;
|
||||
string_size_type_t first_match_str_length = 0;
|
||||
std::basic_string<T> first_match_str_replacement;
|
||||
|
||||
for (format_map_t::const_iterator iter = fmt_map.begin();
|
||||
iter != fmt_map.end();
|
||||
++iter)
|
||||
{
|
||||
string_size_type_t n = s.find(iter->first, scanstart);
|
||||
if (n != std::basic_string<T>::npos &&
|
||||
(n < first_match_pos ||
|
||||
0 == first_match_str_length))
|
||||
{
|
||||
first_match_pos = n;
|
||||
first_match_str_length = iter->first.length();
|
||||
first_match_str_replacement = iter->second;
|
||||
}
|
||||
}
|
||||
|
||||
if (0 == first_match_str_length)
|
||||
{
|
||||
// no more keys found to substitute from this point
|
||||
// in the string forward.
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
s.erase(first_match_pos, first_match_str_length);
|
||||
s.insert(first_match_pos, first_match_str_replacement);
|
||||
scanstart = first_match_pos +
|
||||
first_match_str_replacement.length();
|
||||
++res;
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
// static
|
||||
template<class T>
|
||||
@@ -1003,14 +1037,15 @@ void LLStringUtilBase<T>::stripNonprintable(std::basic_string<T>& string)
|
||||
{
|
||||
return;
|
||||
}
|
||||
char* c_string = new char[string.size() + 1];
|
||||
size_t src_size = string.size();
|
||||
char* c_string = new char[src_size + 1];
|
||||
if(c_string == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
strcpy(c_string, string.c_str()); /*Flawfinder: ignore*/
|
||||
copy(c_string, string.c_str(), src_size+1);
|
||||
char* write_head = &c_string[0];
|
||||
for (size_type i = 0; i < string.size(); i++)
|
||||
for (size_type i = 0; i < src_size; i++)
|
||||
{
|
||||
char* read_head = &string[i];
|
||||
write_head = &c_string[j];
|
||||
@@ -1090,6 +1125,30 @@ BOOL LLStringUtilBase<T>::isHead( const std::basic_string<T>& string, const T* s
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
template<class T>
|
||||
bool LLStringUtilBase<T>::startsWith(
|
||||
const std::basic_string<T>& string,
|
||||
const std::basic_string<T>& substr)
|
||||
{
|
||||
if(string.empty() || (substr.empty())) return false;
|
||||
if(0 == string.find(substr)) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
// static
|
||||
template<class T>
|
||||
bool LLStringUtilBase<T>::endsWith(
|
||||
const std::basic_string<T>& string,
|
||||
const std::basic_string<T>& substr)
|
||||
{
|
||||
if(string.empty() || (substr.empty())) return false;
|
||||
std::string::size_type idx = string.rfind(substr);
|
||||
if(std::string::npos == idx) return false;
|
||||
return (idx == (string.size() - substr.size()));
|
||||
}
|
||||
|
||||
|
||||
template<class T>
|
||||
BOOL LLStringUtilBase<T>::convertToBOOL(const std::basic_string<T>& string, BOOL& value)
|
||||
{
|
||||
|
||||
@@ -38,6 +38,23 @@
|
||||
|
||||
LLStringTable gStringTable(32768);
|
||||
|
||||
LLStringTableEntry::LLStringTableEntry(const char *str)
|
||||
: mString(NULL), mCount(1)
|
||||
{
|
||||
// Copy string
|
||||
U32 length = (U32)strlen(str) + 1; /*Flawfinder: ignore*/
|
||||
length = llmin(length, MAX_STRINGS_LENGTH);
|
||||
mString = new char[length];
|
||||
strncpy(mString, str, length); /*Flawfinder: ignore*/
|
||||
mString[length - 1] = 0;
|
||||
}
|
||||
|
||||
LLStringTableEntry::~LLStringTableEntry()
|
||||
{
|
||||
delete [] mString;
|
||||
mCount = 0;
|
||||
}
|
||||
|
||||
LLStringTable::LLStringTable(int tablesize)
|
||||
: mUniqueEntries(0)
|
||||
{
|
||||
|
||||
@@ -49,11 +49,11 @@
|
||||
#endif
|
||||
|
||||
#if STRING_TABLE_HASH_MAP
|
||||
#if LL_WINDOWS
|
||||
#include <hash_map>
|
||||
#else
|
||||
#include <ext/hash_map>
|
||||
#endif
|
||||
# if LL_WINDOWS
|
||||
# include <hash_map>
|
||||
# else
|
||||
# include <ext/hash_map>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
const U32 MAX_STRINGS_LENGTH = 256;
|
||||
@@ -61,21 +61,9 @@ const U32 MAX_STRINGS_LENGTH = 256;
|
||||
class LL_COMMON_API LLStringTableEntry
|
||||
{
|
||||
public:
|
||||
LLStringTableEntry(const char *str)
|
||||
: mString(NULL), mCount(1)
|
||||
{
|
||||
// Copy string
|
||||
U32 length = (U32)strlen(str) + 1; /*Flawfinder: ignore*/
|
||||
length = llmin(length, MAX_STRINGS_LENGTH);
|
||||
mString = new char[length];
|
||||
strncpy(mString, str, length); /*Flawfinder: ignore*/
|
||||
mString[length - 1] = 0;
|
||||
}
|
||||
~LLStringTableEntry()
|
||||
{
|
||||
delete [] mString;
|
||||
mCount = 0;
|
||||
}
|
||||
LLStringTableEntry(const char *str);
|
||||
~LLStringTableEntry();
|
||||
|
||||
void incCount() { mCount++; }
|
||||
BOOL decCount() { return --mCount; }
|
||||
|
||||
|
||||
@@ -52,13 +52,13 @@
|
||||
# include <sys/sysctl.h>
|
||||
# include <sys/utsname.h>
|
||||
# include <stdint.h>
|
||||
//# include <Carbon/Carbon.h> May be needed?
|
||||
#elif LL_LINUX
|
||||
# include <errno.h>
|
||||
# include <sys/utsname.h>
|
||||
# include <unistd.h>
|
||||
# include <sys/sysinfo.h>
|
||||
const char MEMINFO_FILE[] = "/proc/meminfo";
|
||||
const char CPUINFO_FILE[] = "/proc/cpuinfo";
|
||||
#elif LL_SOLARIS
|
||||
# include <stdio.h>
|
||||
# include <unistd.h>
|
||||
@@ -74,7 +74,7 @@ extern int errno;
|
||||
|
||||
|
||||
static const S32 CPUINFO_BUFFER_SIZE = 16383;
|
||||
LL_COMMON_API LLCPUInfo gSysCPU;
|
||||
LLCPUInfo gSysCPU;
|
||||
|
||||
#if LL_WINDOWS
|
||||
#ifndef DLLVERSIONINFO
|
||||
@@ -325,7 +325,58 @@ LLOSInfo::LLOSInfo() :
|
||||
}
|
||||
mOSString += compatibility_mode;
|
||||
|
||||
#elif LL_DARWIN
|
||||
|
||||
// Initialize mOSStringSimple to something like:
|
||||
// "Mac OS X 10.6.7"
|
||||
{
|
||||
const char * DARWIN_PRODUCT_NAME = "Mac OS X";
|
||||
|
||||
SInt32 major_version, minor_version, bugfix_version;
|
||||
OSErr r1 = Gestalt(gestaltSystemVersionMajor, &major_version);
|
||||
OSErr r2 = Gestalt(gestaltSystemVersionMinor, &minor_version);
|
||||
OSErr r3 = Gestalt(gestaltSystemVersionBugFix, &bugfix_version);
|
||||
|
||||
if((r1 == noErr) && (r2 == noErr) && (r3 == noErr))
|
||||
{
|
||||
mMajorVer = major_version;
|
||||
mMinorVer = minor_version;
|
||||
mBuild = bugfix_version;
|
||||
|
||||
std::stringstream os_version_string;
|
||||
os_version_string << DARWIN_PRODUCT_NAME << " " << mMajorVer << "." << mMinorVer << "." << mBuild;
|
||||
|
||||
// Put it in the OS string we are compiling
|
||||
mOSStringSimple.append(os_version_string.str());
|
||||
}
|
||||
else
|
||||
{
|
||||
mOSStringSimple.append("Unable to collect OS info");
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize mOSString to something like:
|
||||
// "Mac OS X 10.6.7 Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386 i386"
|
||||
struct utsname un;
|
||||
if(uname(&un) != -1)
|
||||
{
|
||||
mOSString = mOSStringSimple;
|
||||
mOSString.append(" ");
|
||||
mOSString.append(un.sysname);
|
||||
mOSString.append(" ");
|
||||
mOSString.append(un.release);
|
||||
mOSString.append(" ");
|
||||
mOSString.append(un.version);
|
||||
mOSString.append(" ");
|
||||
mOSString.append(un.machine);
|
||||
}
|
||||
else
|
||||
{
|
||||
mOSString = mOSStringSimple;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct utsname un;
|
||||
if(uname(&un) != -1)
|
||||
{
|
||||
@@ -341,15 +392,7 @@ LLOSInfo::LLOSInfo() :
|
||||
|
||||
// Simplify 'Simple'
|
||||
std::string ostype = mOSStringSimple.substr(0, mOSStringSimple.find_first_of(" ", 0));
|
||||
if (ostype == "Darwin")
|
||||
{
|
||||
// Only care about major Darwin versions, truncate at first '.'
|
||||
S32 idx1 = mOSStringSimple.find_first_of(".", 0);
|
||||
std::string simple = mOSStringSimple.substr(0, idx1);
|
||||
if (simple.length() > 0)
|
||||
mOSStringSimple = simple;
|
||||
}
|
||||
else if (ostype == "Linux")
|
||||
if (ostype == "Linux")
|
||||
{
|
||||
// Only care about major and minor Linux versions, truncate at second '.'
|
||||
std::string::size_type idx1 = mOSStringSimple.find_first_of(".", 0);
|
||||
@@ -513,71 +556,21 @@ U32 LLOSInfo::getProcessResidentSizeKB()
|
||||
LLCPUInfo::LLCPUInfo()
|
||||
{
|
||||
std::ostringstream out;
|
||||
CProcessor proc;
|
||||
const ProcessorInfo* info = proc.GetCPUInfo();
|
||||
LLProcessorInfo proc;
|
||||
// proc.WriteInfoTextFile("procInfo.txt");
|
||||
mHasSSE = info->_Ext.SSE_StreamingSIMD_Extensions;
|
||||
mHasSSE2 = info->_Ext.SSE2_StreamingSIMD2_Extensions;
|
||||
mHasAltivec = info->_Ext.Altivec_Extensions;
|
||||
mCPUMHz = (F64)(proc.GetCPUFrequency(50)/1000000.0);
|
||||
mFamily.assign( info->strFamily );
|
||||
mHasSSE = proc.hasSSE();
|
||||
mHasSSE2 = proc.hasSSE2();
|
||||
mHasAltivec = proc.hasAltivec();
|
||||
mCPUMHz = (F64)proc.getCPUFrequency();
|
||||
mFamily = proc.getCPUFamilyName();
|
||||
mCPUString = "Unknown";
|
||||
|
||||
#if LL_WINDOWS || LL_DARWIN || LL_SOLARIS
|
||||
out << proc.strCPUName;
|
||||
out << proc.getCPUBrandName();
|
||||
if (200 < mCPUMHz && mCPUMHz < 10000) // *NOTE: cpu speed is often way wrong, do a sanity check
|
||||
{
|
||||
out << " (" << mCPUMHz << " MHz)";
|
||||
}
|
||||
mCPUString = out.str();
|
||||
|
||||
#elif LL_LINUX
|
||||
std::map< std::string, std::string > cpuinfo;
|
||||
LLFILE* cpuinfo_fp = LLFile::fopen(CPUINFO_FILE, "rb");
|
||||
if(cpuinfo_fp)
|
||||
{
|
||||
char line[MAX_STRING];
|
||||
memset(line, 0, MAX_STRING);
|
||||
while(fgets(line, MAX_STRING, cpuinfo_fp))
|
||||
{
|
||||
// /proc/cpuinfo on Linux looks like:
|
||||
// name\t*: value\n
|
||||
char* tabspot = strchr( line, '\t' );
|
||||
if (tabspot == NULL)
|
||||
continue;
|
||||
char* colspot = strchr( tabspot, ':' );
|
||||
if (colspot == NULL)
|
||||
continue;
|
||||
char* spacespot = strchr( colspot, ' ' );
|
||||
if (spacespot == NULL)
|
||||
continue;
|
||||
char* nlspot = strchr( line, '\n' );
|
||||
if (nlspot == NULL)
|
||||
nlspot = line + strlen( line ); // Fallback to terminating NUL
|
||||
std::string linename( line, tabspot );
|
||||
std::string llinename(linename);
|
||||
LLStringUtil::toLower(llinename);
|
||||
std::string lineval( spacespot + 1, nlspot );
|
||||
cpuinfo[ llinename ] = lineval;
|
||||
}
|
||||
fclose(cpuinfo_fp);
|
||||
}
|
||||
# if LL_X86
|
||||
std::string flags = " " + cpuinfo["flags"] + " ";
|
||||
LLStringUtil::toLower(flags);
|
||||
mHasSSE = ( flags.find( " sse " ) != std::string::npos );
|
||||
mHasSSE2 = ( flags.find( " sse2 " ) != std::string::npos );
|
||||
|
||||
F64 mhz;
|
||||
if (LLStringUtil::convertToF64(cpuinfo["cpu mhz"], mhz)
|
||||
&& 200.0 < mhz && mhz < 10000.0)
|
||||
{
|
||||
mCPUMHz = (F64)llrint(mhz);
|
||||
}
|
||||
if (!cpuinfo["model name"].empty())
|
||||
mCPUString = cpuinfo["model name"];
|
||||
# endif // LL_X86
|
||||
#endif // LL_LINUX
|
||||
}
|
||||
|
||||
bool LLCPUInfo::hasAltivec() const
|
||||
@@ -607,38 +600,9 @@ std::string LLCPUInfo::getCPUString() const
|
||||
|
||||
void LLCPUInfo::stream(std::ostream& s) const
|
||||
{
|
||||
#if LL_WINDOWS || LL_DARWIN || LL_SOLARIS
|
||||
// gather machine information.
|
||||
char proc_buf[CPUINFO_BUFFER_SIZE]; /* Flawfinder: ignore */
|
||||
CProcessor proc;
|
||||
if(proc.CPUInfoToText(proc_buf, CPUINFO_BUFFER_SIZE))
|
||||
{
|
||||
s << proc_buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
s << "Unable to collect processor information" << std::endl;
|
||||
}
|
||||
#else
|
||||
// *NOTE: This works on linux. What will it do on other systems?
|
||||
LLFILE* cpuinfo = LLFile::fopen(CPUINFO_FILE, "rb");
|
||||
if(cpuinfo)
|
||||
{
|
||||
char line[MAX_STRING];
|
||||
memset(line, 0, MAX_STRING);
|
||||
while(fgets(line, MAX_STRING, cpuinfo))
|
||||
{
|
||||
line[strlen(line)-1] = ' ';
|
||||
s << line;
|
||||
}
|
||||
fclose(cpuinfo);
|
||||
s << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
s << "Unable to collect processor information" << std::endl;
|
||||
}
|
||||
#endif
|
||||
s << LLProcessorInfo().getCPUFeatureDescription();
|
||||
|
||||
// These are interesting as they reflect our internal view of the
|
||||
// CPU's attributes regardless of platform
|
||||
s << "->mHasSSE: " << (U32)mHasSSE << std::endl;
|
||||
|
||||
@@ -131,10 +131,10 @@ LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLCPUInfo& info);
|
||||
LL_COMMON_API std::ostream& operator<<(std::ostream& s, const LLMemoryInfo& info);
|
||||
|
||||
// gunzip srcfile into dstfile. Returns FALSE on error.
|
||||
LL_COMMON_API BOOL gunzip_file(const std::string& srcfile, const std::string& dstfile);
|
||||
BOOL LL_COMMON_API gunzip_file(const std::string& srcfile, const std::string& dstfile);
|
||||
// gzip srcfile into dstfile. Returns FALSE on error.
|
||||
LL_COMMON_API BOOL gzip_file(const std::string& srcfile, const std::string& dstfile);
|
||||
BOOL LL_COMMON_API gzip_file(const std::string& srcfile, const std::string& dstfile);
|
||||
|
||||
LL_COMMON_API extern LLCPUInfo gSysCPU;
|
||||
extern LL_COMMON_API LLCPUInfo gSysCPU;
|
||||
|
||||
#endif // LL_LLSYS_H
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "lltimer.h"
|
||||
#include "timing.h" // totalTime prototype.
|
||||
|
||||
#include "u64.h"
|
||||
|
||||
@@ -52,6 +51,9 @@
|
||||
//
|
||||
// Locally used constants
|
||||
//
|
||||
const U32 SEC_PER_DAY = 86400;
|
||||
const F64 SEC_TO_MICROSEC = 1000000.f;
|
||||
const U64 SEC_TO_MICROSEC_U64 = 1000000;
|
||||
const F64 USEC_TO_SEC_F64 = 0.000001;
|
||||
|
||||
|
||||
@@ -571,59 +573,6 @@ void timeStructToFormattedString(struct tm * time, std::string format, std::stri
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// LLEventTimer Implementation
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::list<LLEventTimer*> LLEventTimer::sActiveList;
|
||||
|
||||
LLEventTimer::LLEventTimer(F32 period)
|
||||
: mEventTimer()
|
||||
{
|
||||
mPeriod = period;
|
||||
sActiveList.push_back(this);
|
||||
}
|
||||
|
||||
LLEventTimer::LLEventTimer(const LLDate& time)
|
||||
: mEventTimer()
|
||||
{
|
||||
mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch());
|
||||
sActiveList.push_back(this);
|
||||
}
|
||||
|
||||
|
||||
LLEventTimer::~LLEventTimer()
|
||||
{
|
||||
sActiveList.remove(this);
|
||||
}
|
||||
|
||||
void LLEventTimer::updateClass()
|
||||
{
|
||||
std::list<LLEventTimer*> completed_timers;
|
||||
for (std::list<LLEventTimer*>::iterator iter = sActiveList.begin(); iter != sActiveList.end(); )
|
||||
{
|
||||
LLEventTimer* timer = *iter++;
|
||||
F32 et = timer->mEventTimer.getElapsedTimeF32();
|
||||
if (timer->mEventTimer.getStarted() && et > timer->mPeriod) {
|
||||
timer->mEventTimer.reset();
|
||||
if ( timer->tick() )
|
||||
{
|
||||
completed_timers.push_back( timer );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( completed_timers.size() > 0 )
|
||||
{
|
||||
for (std::list<LLEventTimer*>::iterator completed_iter = completed_timers.begin();
|
||||
completed_iter != completed_timers.end();
|
||||
completed_iter++ )
|
||||
{
|
||||
delete *completed_iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@ const U32 USEC_PER_HOUR = USEC_PER_MIN * MIN_PER_HOUR;
|
||||
const U32 SEC_PER_HOUR = SEC_PER_MIN * MIN_PER_HOUR;
|
||||
const F64 SEC_PER_USEC = 1.0 / (F64) USEC_PER_SEC;
|
||||
|
||||
LL_COMMON_API U64 totalTime(); // Returns current system time in microseconds
|
||||
|
||||
class LL_COMMON_API LLTimer
|
||||
{
|
||||
public:
|
||||
@@ -155,7 +157,7 @@ static inline time_t time_max()
|
||||
}
|
||||
|
||||
// Correction factor used by time_corrected() above.
|
||||
LL_COMMON_API extern S32 gUTCOffset;
|
||||
extern LL_COMMON_API S32 gUTCOffset;
|
||||
|
||||
// Is the current computer (in its current time zone)
|
||||
// observing daylight savings time?
|
||||
@@ -173,27 +175,4 @@ LL_COMMON_API void secondsToTimecodeString(F32 current_time, std::string& tcstri
|
||||
LL_COMMON_API void timeToFormattedString(time_t time, std::string format, std::string ×tr);
|
||||
LL_COMMON_API void timeStructToFormattedString(struct tm * time, std::string format, std::string ×tr);
|
||||
|
||||
// class for scheduling a function to be called at a given frequency (approximate, inprecise)
|
||||
class LL_COMMON_API LLEventTimer
|
||||
{
|
||||
public:
|
||||
LLEventTimer(F32 period); // period is the amount of time between each call to tick() in seconds
|
||||
LLEventTimer(const LLDate& time);
|
||||
virtual ~LLEventTimer();
|
||||
|
||||
//function to be called at the supplied frequency
|
||||
// Normally return FALSE; TRUE will delete the timer after the function returns.
|
||||
virtual BOOL tick() = 0;
|
||||
|
||||
static void updateClass();
|
||||
|
||||
protected:
|
||||
LLTimer mEventTimer;
|
||||
F32 mPeriod;
|
||||
|
||||
private:
|
||||
//list of active timers
|
||||
static std::list<LLEventTimer*> sActiveList; // TODO should this be a vector
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -43,7 +43,6 @@ const F32 SEC_TO_MICROSEC = 1000000.f;
|
||||
const U64 SEC_TO_MICROSEC_U64 = 1000000;
|
||||
const U32 SEC_PER_DAY = 86400;
|
||||
|
||||
// This is just a stub, implementation in lltimer.cpp. This file will be deprecated in the future.
|
||||
LL_COMMON_API U64 totalTime(); // Returns current system time in microseconds
|
||||
// functionality has been moved lltimer.{cpp,h}. This file will be deprecated in the future.
|
||||
|
||||
#endif
|
||||
|
||||
@@ -45,7 +45,8 @@ LLCamera::LLCamera() :
|
||||
mNearPlane(DEFAULT_NEAR_PLANE),
|
||||
mFarPlane(DEFAULT_FAR_PLANE),
|
||||
mFixedDistance(-1.f),
|
||||
mPlaneCount(6)
|
||||
mPlaneCount(6),
|
||||
mFrustumCornerDist(0.f)
|
||||
{
|
||||
calculateFrustumPlanes();
|
||||
}
|
||||
@@ -55,7 +56,8 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p
|
||||
LLCoordFrame(),
|
||||
mViewHeightInPixels(view_height_in_pixels),
|
||||
mFixedDistance(-1.f),
|
||||
mPlaneCount(6)
|
||||
mPlaneCount(6),
|
||||
mFrustumCornerDist(0.f)
|
||||
{
|
||||
mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
|
||||
mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE);
|
||||
@@ -65,6 +67,10 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p
|
||||
setView(vertical_fov_rads);
|
||||
}
|
||||
|
||||
LLCamera::~LLCamera()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// ---------------- LLCamera::getFoo() member functions ----------------
|
||||
|
||||
@@ -86,11 +92,11 @@ F32 LLCamera::getMaxView() const
|
||||
|
||||
// ---------------- LLCamera::setFoo() member functions ----------------
|
||||
|
||||
void LLCamera::setUserClipPlane(LLPlane plane)
|
||||
void LLCamera::setUserClipPlane(LLPlane const& plane)
|
||||
{
|
||||
mPlaneCount = 7;
|
||||
mAgentPlanes[6].p = plane;
|
||||
mAgentPlanes[6].mask = calcPlaneMask(plane);
|
||||
mAgentPlanes[6] = plane;
|
||||
mPlaneMask[6] = plane.calcPlaneMask();
|
||||
}
|
||||
|
||||
void LLCamera::disableUserClipPlane()
|
||||
@@ -178,7 +184,7 @@ S32 LLCamera::AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius)
|
||||
U8 mask = 0;
|
||||
S32 result = 2;
|
||||
|
||||
if (radius.magVecSquared() > mFrustumCornerDist * mFrustumCornerDist)
|
||||
/*if (radius.magVecSquared() > mFrustumCornerDist * mFrustumCornerDist)
|
||||
{ //box is larger than frustum, check frustum quads against box planes
|
||||
|
||||
static const LLVector3 dir[] =
|
||||
@@ -241,12 +247,16 @@ S32 LLCamera::AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius)
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
else*/
|
||||
{
|
||||
for (U32 i = 0; i < mPlaneCount; i++)
|
||||
{
|
||||
mask = mAgentPlanes[i].mask;
|
||||
LLPlane p = mAgentPlanes[i].p;
|
||||
mask = mPlaneMask[i];
|
||||
if (mask == 0xff)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
LLPlane p = mAgentPlanes[i];
|
||||
LLVector3 n = LLVector3(p);
|
||||
float d = p.mV[3];
|
||||
LLVector3 rscale = radius.scaledVec(scaler[mask]);
|
||||
@@ -293,8 +303,12 @@ S32 LLCamera::AABBInFrustumNoFarClip(const LLVector3 ¢er, const LLVector3& r
|
||||
continue;
|
||||
}
|
||||
|
||||
mask = mAgentPlanes[i].mask;
|
||||
LLPlane p = mAgentPlanes[i].p;
|
||||
mask = mPlaneMask[i];
|
||||
if (mask == 0xff)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
LLPlane p = mAgentPlanes[i];
|
||||
LLVector3 n = LLVector3(p);
|
||||
float d = p.mV[3];
|
||||
LLVector3 rscale = radius.scaledVec(scaler[mask]);
|
||||
@@ -434,23 +448,22 @@ int LLCamera::sphereInFrustumOld(const LLVector3 &sphere_center, const F32 radiu
|
||||
int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) const
|
||||
{
|
||||
// Returns 1 if sphere is in frustum, 0 if not.
|
||||
int res = 2;
|
||||
bool res = false;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
float d = mAgentPlanes[i].p.dist(sphere_center);
|
||||
|
||||
if (d > radius)
|
||||
if (mPlaneMask[i] != 0xff)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
float d = mAgentPlanes[i].dist(sphere_center);
|
||||
|
||||
if (d > -radius)
|
||||
{
|
||||
res = 1;
|
||||
if (d > radius)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
res = res || (d > -radius);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
return res?1:2;
|
||||
}
|
||||
|
||||
|
||||
@@ -602,29 +615,20 @@ LLPlane planeFromPoints(LLVector3 p1, LLVector3 p2, LLVector3 p3)
|
||||
return LLPlane(p1, n);
|
||||
}
|
||||
|
||||
U8 LLCamera::calcPlaneMask(const LLPlane& plane)
|
||||
|
||||
void LLCamera::ignoreAgentFrustumPlane(S32 idx)
|
||||
{
|
||||
U8 mask = 0;
|
||||
|
||||
if (plane.mV[0] >= 0)
|
||||
if (idx < 0 || idx > (S32) mPlaneCount)
|
||||
{
|
||||
mask |= 1;
|
||||
}
|
||||
if (plane.mV[1] >= 0)
|
||||
{
|
||||
mask |= 2;
|
||||
}
|
||||
if (plane.mV[2] >= 0)
|
||||
{
|
||||
mask |= 4;
|
||||
return;
|
||||
}
|
||||
|
||||
return mask;
|
||||
mPlaneMask[idx] = 0xff;
|
||||
mAgentPlanes[idx].clear();
|
||||
}
|
||||
|
||||
void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
|
||||
{
|
||||
|
||||
for (int i = 0; i < 8; i++)
|
||||
{
|
||||
mAgentFrustum[i] = frust[i];
|
||||
@@ -637,27 +641,27 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
|
||||
//order of planes is important, keep most likely to fail in the front of the list
|
||||
|
||||
//near - frust[0], frust[1], frust[2]
|
||||
mAgentPlanes[2].p = planeFromPoints(frust[0], frust[1], frust[2]);
|
||||
mAgentPlanes[2] = planeFromPoints(frust[0], frust[1], frust[2]);
|
||||
|
||||
//far
|
||||
mAgentPlanes[5].p = planeFromPoints(frust[5], frust[4], frust[6]);
|
||||
mAgentPlanes[5] = planeFromPoints(frust[5], frust[4], frust[6]);
|
||||
|
||||
//left
|
||||
mAgentPlanes[0].p = planeFromPoints(frust[4], frust[0], frust[7]);
|
||||
mAgentPlanes[0] = planeFromPoints(frust[4], frust[0], frust[7]);
|
||||
|
||||
//right
|
||||
mAgentPlanes[1].p = planeFromPoints(frust[1], frust[5], frust[6]);
|
||||
mAgentPlanes[1] = planeFromPoints(frust[1], frust[5], frust[6]);
|
||||
|
||||
//top
|
||||
mAgentPlanes[4].p = planeFromPoints(frust[3], frust[2], frust[6]);
|
||||
mAgentPlanes[4] = planeFromPoints(frust[3], frust[2], frust[6]);
|
||||
|
||||
//bottom
|
||||
mAgentPlanes[3].p = planeFromPoints(frust[1], frust[0], frust[4]);
|
||||
mAgentPlanes[3] = planeFromPoints(frust[1], frust[0], frust[4]);
|
||||
|
||||
//cache plane octant facing mask for use in AABBInFrustum
|
||||
for (U32 i = 0; i < mPlaneCount; i++)
|
||||
{
|
||||
mAgentPlanes[i].mask = calcPlaneMask(mAgentPlanes[i].p);
|
||||
mPlaneMask[i] = mAgentPlanes[i].calcPlaneMask();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,12 @@ class LLCamera
|
||||
: public LLCoordFrame
|
||||
{
|
||||
public:
|
||||
|
||||
LLCamera(const LLCamera& rhs)
|
||||
{
|
||||
*this = rhs;
|
||||
}
|
||||
|
||||
enum {
|
||||
PLANE_LEFT = 0,
|
||||
PLANE_RIGHT = 1,
|
||||
@@ -84,6 +90,17 @@ public:
|
||||
PLANE_TOP_MASK = (1<<PLANE_TOP),
|
||||
PLANE_ALL_MASK = 0xf
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
AGENT_PLANE_LEFT = 0,
|
||||
AGENT_PLANE_RIGHT,
|
||||
AGENT_PLANE_NEAR,
|
||||
AGENT_PLANE_BOTTOM,
|
||||
AGENT_PLANE_TOP,
|
||||
AGENT_PLANE_FAR,
|
||||
};
|
||||
|
||||
enum {
|
||||
HORIZ_PLANE_LEFT = 0,
|
||||
HORIZ_PLANE_RIGHT = 1,
|
||||
@@ -96,6 +113,9 @@ public:
|
||||
};
|
||||
|
||||
private:
|
||||
LLPlane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
|
||||
U8 mPlaneMask[8]; // 8 for alignment
|
||||
|
||||
F32 mView; // angle between top and bottom frustum planes in radians.
|
||||
F32 mAspect; // width/height
|
||||
S32 mViewHeightInPixels; // for ViewHeightInPixels() only
|
||||
@@ -109,29 +129,22 @@ private:
|
||||
LLPlane mWorldPlanes[PLANE_NUM];
|
||||
LLPlane mHorizPlanes[HORIZ_PLANE_NUM];
|
||||
|
||||
struct frustum_plane
|
||||
{
|
||||
frustum_plane() : mask(0) {}
|
||||
LLPlane p;
|
||||
U8 mask;
|
||||
};
|
||||
frustum_plane mAgentPlanes[7]; //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
|
||||
|
||||
U32 mPlaneCount; //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in
|
||||
|
||||
LLVector3 mWorldPlanePos; // Position of World Planes (may be offset from camera)
|
||||
public:
|
||||
LLVector3 mAgentFrustum[8]; //8 corners of 6-plane frustum
|
||||
F32 mFrustumCornerDist; //distance to corner of frustum against far clip plane
|
||||
|
||||
LLPlane& getAgentPlane(U32 idx) { return mAgentPlanes[idx]; }
|
||||
|
||||
public:
|
||||
LLCamera();
|
||||
LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane);
|
||||
virtual ~LLCamera(){} // no-op virtual destructor
|
||||
virtual ~LLCamera();
|
||||
|
||||
|
||||
void setUserClipPlane(LLPlane plane);
|
||||
void setUserClipPlane(LLPlane const& plane);
|
||||
void disableUserClipPlane();
|
||||
U8 calcPlaneMask(const LLPlane& plane);
|
||||
virtual void setView(F32 vertical_fov_rads);
|
||||
void setViewHeightInPixels(S32 height);
|
||||
void setAspect(F32 new_aspect);
|
||||
@@ -170,6 +183,8 @@ public:
|
||||
// Return number of bytes copied.
|
||||
size_t readFrustumFromBuffer(const char *buffer);
|
||||
void calcAgentFrustumPlanes(LLVector3* frust);
|
||||
void ignoreAgentFrustumPlane(S32 idx);
|
||||
|
||||
// Returns 1 if partly in, 2 if fully in.
|
||||
// NOTE: 'center' is in absolute frame.
|
||||
S32 sphereInFrustumOld(const LLVector3 ¢er, const F32 radius) const;
|
||||
|
||||
@@ -384,11 +384,14 @@ inline F32 snap_to_sig_figs(F32 foo, S32 sig_figs)
|
||||
bar *= 10.f;
|
||||
}
|
||||
|
||||
foo = (F32)llround(foo * bar);
|
||||
//F32 new_foo = (F32)llround(foo * bar);
|
||||
// the llround() implementation sucks. Don't us it.
|
||||
|
||||
// shift back
|
||||
foo /= bar;
|
||||
return foo;
|
||||
F32 sign = (foo > 0.f) ? 1.f : -1.f;
|
||||
F32 new_foo = F32( S64(foo * bar + sign * 0.5f));
|
||||
new_foo /= bar;
|
||||
|
||||
return new_foo;
|
||||
}
|
||||
|
||||
inline F32 lerp(F32 a, F32 b, F32 u)
|
||||
@@ -522,4 +525,41 @@ inline F32 llgaussian(F32 x, F32 o)
|
||||
return 1.f/(F_SQRT_TWO_PI*o)*powf(F_E, -(x*x)/(2*o*o));
|
||||
}
|
||||
|
||||
//helper function for removing outliers
|
||||
template <class VEC_TYPE>
|
||||
inline void ll_remove_outliers(std::vector<VEC_TYPE>& data, F32 k)
|
||||
{
|
||||
if (data.size() < 100)
|
||||
{ //not enough samples
|
||||
return;
|
||||
}
|
||||
|
||||
VEC_TYPE Q1 = data[data.size()/4];
|
||||
VEC_TYPE Q3 = data[data.size()-data.size()/4-1];
|
||||
|
||||
VEC_TYPE min = (VEC_TYPE) ((F32) Q1-k * (F32) (Q3-Q1));
|
||||
VEC_TYPE max = (VEC_TYPE) ((F32) Q3+k * (F32) (Q3-Q1));
|
||||
|
||||
U32 i = 0;
|
||||
while (i < data.size() && data[i] < min)
|
||||
{
|
||||
i++;
|
||||
}
|
||||
|
||||
S32 j = data.size()-1;
|
||||
while (j > 0 && data[j] > max)
|
||||
{
|
||||
j--;
|
||||
}
|
||||
|
||||
if (j < data.size()-1)
|
||||
{
|
||||
data.erase(data.begin()+j, data.end());
|
||||
}
|
||||
|
||||
if (i > 0)
|
||||
{
|
||||
data.erase(data.begin(), data.begin()+i);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -73,6 +73,13 @@ public:
|
||||
virtual void visit(const LLOctreeNode<T>* branch) = 0;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class LLOctreeTravelerDepthFirst : public LLOctreeTraveler<T>
|
||||
{
|
||||
public:
|
||||
virtual void traverse(const LLOctreeNode<T>* node);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class LLOctreeNode : public LLTreeNode<T>
|
||||
{
|
||||
@@ -124,11 +131,10 @@ public:
|
||||
inline void setParent(BaseType* parent) { mParent = (oct_node*) parent; }
|
||||
inline const LLVector3d& getCenter() const { return mCenter; }
|
||||
inline const LLVector3d& getSize() const { return mSize; }
|
||||
inline void setCenter(LLVector3d center) { mCenter = center; }
|
||||
inline void setSize(LLVector3d size) { mSize = size; }
|
||||
inline oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); }
|
||||
inline U8 getOctant() const { return mOctant; }
|
||||
inline void setOctant(U8 octant) { mOctant = octant; }
|
||||
inline void setCenter(const LLVector3d center) { mCenter = center; }
|
||||
inline void setSize(const LLVector3d size) { mSize = size; }
|
||||
inline oct_node* getNodeAt(T* data) { return getNodeAt(data->getPositionGroup(), data->getBinRadius()); }
|
||||
inline U8 getOctant() const { return mOctant; }
|
||||
inline const oct_node* getOctParent() const { return (const oct_node*) getParent(); }
|
||||
inline oct_node* getOctParent() { return (oct_node*) getParent(); }
|
||||
|
||||
@@ -197,17 +203,17 @@ public:
|
||||
return contains(xform->getBinRadius());
|
||||
}
|
||||
|
||||
bool contains(F64 radius)
|
||||
bool contains(F32 radius)
|
||||
{
|
||||
if (mParent == NULL)
|
||||
{ //root node contains nothing
|
||||
return false;
|
||||
}
|
||||
|
||||
F64 size = mSize.mdV[0];
|
||||
F64 p_size = size * 2.0;
|
||||
F32 size = mSize[0];
|
||||
F32 p_size = size * 2.f;
|
||||
|
||||
return (radius <= 0.001 && size <= 0.001) ||
|
||||
return (radius <= 0.001f && size <= 0.001f) ||
|
||||
(radius <= p_size && radius > size);
|
||||
}
|
||||
|
||||
@@ -243,7 +249,30 @@ public:
|
||||
void accept(tree_traveler* visitor) const { visitor->visit(this); }
|
||||
void accept(oct_traveler* visitor) const { visitor->visit(this); }
|
||||
|
||||
oct_node* getNodeAt(const LLVector3d& pos, const F64& rad)
|
||||
void validateChildMap()
|
||||
{
|
||||
for (U32 i = 0; i < 8; i++)
|
||||
{
|
||||
U8 idx = mChildMap[i];
|
||||
if (idx != 255)
|
||||
{
|
||||
LLOctreeNode<T>* child = mChild[idx];
|
||||
|
||||
if (child->getOctant() != i)
|
||||
{
|
||||
llerrs << "Invalid child map, bad octant data." << llendl;
|
||||
}
|
||||
|
||||
if (getOctant(child->getCenter()) != child->getOctant())
|
||||
{
|
||||
llerrs << "Invalid child octant compared to position data." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
oct_node* getNodeAt(const LLVector3d& pos, const F32& rad)
|
||||
{
|
||||
LLOctreeNode<T>* node = this;
|
||||
|
||||
@@ -251,24 +280,18 @@ public:
|
||||
{
|
||||
//do a quick search by octant
|
||||
U8 octant = node->getOctant(pos.mdV);
|
||||
BOOL keep_going = TRUE;
|
||||
|
||||
|
||||
//traverse the tree until we find a node that has no node
|
||||
//at the appropriate octant or is smaller than the object.
|
||||
//by definition, that node is the smallest node that contains
|
||||
// the data
|
||||
while (keep_going && node->getSize().mdV[0] >= rad)
|
||||
U8 next_node = node->mChildMap[octant];
|
||||
|
||||
while (next_node != 255 && node->getSize()[0] >= rad)
|
||||
{
|
||||
keep_going = FALSE;
|
||||
for (U32 i = 0; i < node->getChildCount() && !keep_going; i++)
|
||||
{
|
||||
if (node->getChild(i)->getOctant() == octant)
|
||||
{
|
||||
node = node->getChild(i);
|
||||
octant = node->getOctant(pos.mdV);
|
||||
keep_going = TRUE;
|
||||
}
|
||||
}
|
||||
node = node->getChild(next_node);
|
||||
octant = node->getOctant(pos.mdV);
|
||||
next_node = node->mChildMap[octant];
|
||||
}
|
||||
}
|
||||
else if (!node->contains(rad) && node->getParent())
|
||||
@@ -444,6 +467,9 @@ public:
|
||||
void clearChildren()
|
||||
{
|
||||
mChild.clear();
|
||||
|
||||
U32* foo = (U32*) mChildMap;
|
||||
foo[0] = foo[1] = 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
void validate()
|
||||
@@ -477,6 +503,12 @@ public:
|
||||
void addChild(oct_node* child, BOOL silent = FALSE)
|
||||
{
|
||||
#if LL_OCTREE_PARANOIA_CHECK
|
||||
|
||||
if (child->getSize() == getSize())
|
||||
{
|
||||
OCT_ERRS << "Child size is same as parent size!" << llendl;
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < getChildCount(); i++)
|
||||
{
|
||||
if(mChild[i]->getSize() != child->getSize())
|
||||
@@ -495,6 +527,8 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
mChildMap[child->getOctant()] = (U8) mChild.size();
|
||||
|
||||
mChild.push_back(child);
|
||||
child->setParent(this);
|
||||
|
||||
@@ -508,7 +542,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void removeChild(U8 index, BOOL destroy = FALSE)
|
||||
void removeChild(S32 index, BOOL destroy = FALSE)
|
||||
{
|
||||
for (U32 i = 0; i < this->getListenerCount(); i++)
|
||||
{
|
||||
@@ -516,6 +550,8 @@ public:
|
||||
listener->handleChildRemoval(this, getChild(index));
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (destroy)
|
||||
{
|
||||
mChild[index]->destroy();
|
||||
@@ -523,6 +559,15 @@ public:
|
||||
}
|
||||
mChild.erase(mChild.begin() + index);
|
||||
|
||||
//rebuild child map
|
||||
U32* foo = (U32*) mChildMap;
|
||||
foo[0] = foo[1] = 0xFFFFFFFF;
|
||||
|
||||
for (U32 i = 0; i < mChild.size(); ++i)
|
||||
{
|
||||
mChildMap[mChild[i]->getOctant()] = i;
|
||||
}
|
||||
|
||||
checkAlive();
|
||||
}
|
||||
|
||||
@@ -553,14 +598,27 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
child_list mChild;
|
||||
element_list mData;
|
||||
oct_node* mParent;
|
||||
typedef enum
|
||||
{
|
||||
CENTER = 0,
|
||||
SIZE = 1,
|
||||
MAX = 2,
|
||||
MIN = 3
|
||||
} eDName;
|
||||
|
||||
LLVector3d mCenter;
|
||||
LLVector3d mSize;
|
||||
LLVector3d mMax;
|
||||
LLVector3d mMin;
|
||||
|
||||
oct_node* mParent;
|
||||
U8 mOctant;
|
||||
|
||||
child_list mChild;
|
||||
U8 mChildMap[8];
|
||||
|
||||
element_list mData;
|
||||
|
||||
};
|
||||
|
||||
//just like a regular node, except it might expand on insert and compress on balance
|
||||
@@ -571,8 +629,8 @@ public:
|
||||
typedef LLOctreeNode<T> BaseType;
|
||||
typedef LLOctreeNode<T> oct_node;
|
||||
|
||||
LLOctreeRoot( LLVector3d center,
|
||||
LLVector3d size,
|
||||
LLOctreeRoot( const LLVector3d ¢er,
|
||||
const LLVector3d &size,
|
||||
BaseType* parent)
|
||||
: BaseType(center, size, parent)
|
||||
{
|
||||
@@ -604,6 +662,8 @@ public:
|
||||
//destroy child
|
||||
child->clearChildren();
|
||||
delete child;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -700,7 +760,6 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//========================
|
||||
// LLOctreeTraveler
|
||||
//========================
|
||||
@@ -714,4 +773,14 @@ void LLOctreeTraveler<T>::traverse(const LLOctreeNode<T>* node)
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void LLOctreeTravelerDepthFirst<T>::traverse(const LLOctreeNode<T>* node)
|
||||
{
|
||||
for (U32 i = 0; i < node->getChildCount(); i++)
|
||||
{
|
||||
traverse(node->getChild(i));
|
||||
}
|
||||
node->accept(this);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -48,13 +48,13 @@ public:
|
||||
LLPlane() {}; // no default constructor
|
||||
LLPlane(const LLVector3 &p0, F32 d) { setVec(p0, d); }
|
||||
LLPlane(const LLVector3 &p0, const LLVector3 &n) { setVec(p0, n); }
|
||||
void setVec(const LLVector3 &p0, F32 d) { LLVector4::setVec(p0[0], p0[1], p0[2], d); }
|
||||
void setVec(const LLVector3 &p0, const LLVector3 &n)
|
||||
inline void setVec(const LLVector3 &p0, F32 d) { LLVector4::setVec(p0[0], p0[1], p0[2], d); }
|
||||
inline void setVec(const LLVector3 &p0, const LLVector3 &n)
|
||||
{
|
||||
F32 d = -(p0 * n);
|
||||
setVec(n, d);
|
||||
}
|
||||
void setVec(const LLVector3 &p0, const LLVector3 &p1, const LLVector3 &p2)
|
||||
inline void setVec(const LLVector3 &p0, const LLVector3 &p1, const LLVector3 &p2)
|
||||
{
|
||||
LLVector3 u, v, w;
|
||||
u = p1 - p0;
|
||||
@@ -64,8 +64,39 @@ public:
|
||||
F32 d = -(w * p0);
|
||||
setVec(w, d);
|
||||
}
|
||||
LLPlane& operator=(const LLVector4& v2) { LLVector4::setVec(v2[0],v2[1],v2[2],v2[3]); return *this;}
|
||||
|
||||
inline LLPlane& operator=(const LLVector4& v2) { LLVector4::setVec(v2[0],v2[1],v2[2],v2[3]); return *this;}
|
||||
|
||||
inline void set(const LLPlane& p2) { LLVector4::setVec(p2); }
|
||||
|
||||
//
|
||||
F32 dist(const LLVector3 &v2) const { return mV[0]*v2[0] + mV[1]*v2[1] + mV[2]*v2[2] + mV[3]; }
|
||||
|
||||
// reset the vector to 0, 0, 0, 1
|
||||
inline void clear() { LLVector4::setVec(0, 0, 0, 1); }
|
||||
|
||||
inline void getVector3(LLVector3& vec) const { vec.set(mV[0], mV[1], mV[2]); }
|
||||
|
||||
// Retrieve the mask indicating which of the x, y, or z axis are greater or equal to zero.
|
||||
inline U8 calcPlaneMask() const
|
||||
{
|
||||
U8 mask = 0;
|
||||
|
||||
if (mV[0] >= 0)
|
||||
{
|
||||
mask |= 1;
|
||||
}
|
||||
if (mV[1] >= 0)
|
||||
{
|
||||
mask |= 2;
|
||||
}
|
||||
if (mV[2] >= 0)
|
||||
{
|
||||
mask |= 4;
|
||||
}
|
||||
|
||||
return mask;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -32,9 +32,10 @@
|
||||
|
||||
#include "linden_common.h"
|
||||
|
||||
#include "llmath.h" // for F_PI
|
||||
|
||||
#include "llquaternion.h"
|
||||
|
||||
#include "llmath.h" // for F_PI
|
||||
//#include "vmath.h"
|
||||
#include "v3math.h"
|
||||
#include "v3dmath.h"
|
||||
|
||||
@@ -33,7 +33,11 @@
|
||||
#ifndef LLQUATERNION_H
|
||||
#define LLQUATERNION_H
|
||||
|
||||
#include "llmath.h"
|
||||
#include <iostream>
|
||||
|
||||
#ifndef LLMATH_H //enforce specific include order to avoid tangling inline dependencies
|
||||
#error "Please include llmath.h first."
|
||||
#endif
|
||||
|
||||
class LLVector4;
|
||||
class LLVector3;
|
||||
|
||||
@@ -103,27 +103,33 @@ BOOL check_same_clock_dir( const LLVector3& pt1, const LLVector3& pt2, const LLV
|
||||
|
||||
BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size)
|
||||
{
|
||||
float fAWdU[3];
|
||||
LLVector3 dir;
|
||||
LLVector3 diff;
|
||||
return LLLineSegmentBoxIntersect(start.mV, end.mV, center.mV, size.mV);
|
||||
}
|
||||
|
||||
BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size)
|
||||
{
|
||||
F32 fAWdU[3];
|
||||
F32 dir[3];
|
||||
F32 diff[3];
|
||||
|
||||
for (U32 i = 0; i < 3; i++)
|
||||
{
|
||||
dir.mV[i] = 0.5f * (end.mV[i] - start.mV[i]);
|
||||
diff.mV[i] = (0.5f * (end.mV[i] + start.mV[i])) - center.mV[i];
|
||||
fAWdU[i] = fabsf(dir.mV[i]);
|
||||
if(fabsf(diff.mV[i])>size.mV[i] + fAWdU[i]) return false;
|
||||
dir[i] = 0.5f * (end[i] - start[i]);
|
||||
diff[i] = (0.5f * (end[i] + start[i])) - center[i];
|
||||
fAWdU[i] = fabsf(dir[i]);
|
||||
if(fabsf(diff[i])>size[i] + fAWdU[i]) return false;
|
||||
}
|
||||
|
||||
float f;
|
||||
f = dir.mV[1] * diff.mV[2] - dir.mV[2] * diff.mV[1]; if(fabsf(f)>size.mV[1]*fAWdU[2] + size.mV[2]*fAWdU[1]) return false;
|
||||
f = dir.mV[2] * diff.mV[0] - dir.mV[0] * diff.mV[2]; if(fabsf(f)>size.mV[0]*fAWdU[2] + size.mV[2]*fAWdU[0]) return false;
|
||||
f = dir.mV[0] * diff.mV[1] - dir.mV[1] * diff.mV[0]; if(fabsf(f)>size.mV[0]*fAWdU[1] + size.mV[1]*fAWdU[0]) return false;
|
||||
f = dir[1] * diff[2] - dir[2] * diff[1]; if(fabsf(f)>size[1]*fAWdU[2] + size[2]*fAWdU[1]) return false;
|
||||
f = dir[2] * diff[0] - dir[0] * diff[2]; if(fabsf(f)>size[0]*fAWdU[2] + size[2]*fAWdU[0]) return false;
|
||||
f = dir[0] * diff[1] - dir[1] * diff[0]; if(fabsf(f)>size[0]*fAWdU[1] + size[1]*fAWdU[0]) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// intersect test between triangle vert0, vert1, vert2 and a ray from orig in direction dir.
|
||||
// returns TRUE if intersecting and returns barycentric coordinates in intersection_a, intersection_b,
|
||||
// and returns the intersection point along dir in intersection_t.
|
||||
@@ -1688,7 +1694,8 @@ LLVolume::LLVolume(const LLVolumeParams ¶ms, const F32 detail, const BOOL ge
|
||||
mGenerateSingleFace = generate_single_face;
|
||||
|
||||
generate();
|
||||
if (mParams.getSculptID().isNull() && params.getSculptType() == LL_SCULPT_TYPE_NONE)
|
||||
|
||||
if (mParams.getSculptID().isNull() && mParams.getSculptType() == LL_SCULPT_TYPE_NONE)
|
||||
{
|
||||
createVolumeFaces();
|
||||
}
|
||||
|
||||
@@ -984,6 +984,7 @@ LLVector3 calc_binormal_from_triangle(
|
||||
const LLVector3& pos2,
|
||||
const LLVector2& tex2);
|
||||
|
||||
BOOL LLLineSegmentBoxIntersect(const F32* start, const F32* end, const F32* center, const F32* size);
|
||||
BOOL LLLineSegmentBoxIntersect(const LLVector3& start, const LLVector3& end, const LLVector3& center, const LLVector3& size);
|
||||
BOOL LLTriangleRayIntersect(const LLVector3& vert0, const LLVector3& vert1, const LLVector3& vert2, const LLVector3& orig, const LLVector3& dir,
|
||||
F32* intersection_a, F32* intersection_b, F32* intersection_t, BOOL two_sided);
|
||||
|
||||
@@ -221,8 +221,33 @@ const LLMatrix4& LLMatrix4::transpose()
|
||||
|
||||
F32 LLMatrix4::determinant() const
|
||||
{
|
||||
llerrs << "Not implemented!" << llendl;
|
||||
return 0.f;
|
||||
F32 value =
|
||||
mMatrix[0][3] * mMatrix[1][2] * mMatrix[2][1] * mMatrix[3][0] -
|
||||
mMatrix[0][2] * mMatrix[1][3] * mMatrix[2][1] * mMatrix[3][0] -
|
||||
mMatrix[0][3] * mMatrix[1][1] * mMatrix[2][2] * mMatrix[3][0] +
|
||||
mMatrix[0][1] * mMatrix[1][3] * mMatrix[2][2] * mMatrix[3][0] +
|
||||
mMatrix[0][2] * mMatrix[1][1] * mMatrix[2][3] * mMatrix[3][0] -
|
||||
mMatrix[0][1] * mMatrix[1][2] * mMatrix[2][3] * mMatrix[3][0] -
|
||||
mMatrix[0][3] * mMatrix[1][2] * mMatrix[2][0] * mMatrix[3][1] +
|
||||
mMatrix[0][2] * mMatrix[1][3] * mMatrix[2][0] * mMatrix[3][1] +
|
||||
mMatrix[0][3] * mMatrix[1][0] * mMatrix[2][2] * mMatrix[3][1] -
|
||||
mMatrix[0][0] * mMatrix[1][3] * mMatrix[2][2] * mMatrix[3][1] -
|
||||
mMatrix[0][2] * mMatrix[1][0] * mMatrix[2][3] * mMatrix[3][1] +
|
||||
mMatrix[0][0] * mMatrix[1][2] * mMatrix[2][3] * mMatrix[3][1] +
|
||||
mMatrix[0][3] * mMatrix[1][1] * mMatrix[2][0] * mMatrix[3][2] -
|
||||
mMatrix[0][1] * mMatrix[1][3] * mMatrix[2][0] * mMatrix[3][2] -
|
||||
mMatrix[0][3] * mMatrix[1][0] * mMatrix[2][1] * mMatrix[3][2] +
|
||||
mMatrix[0][0] * mMatrix[1][3] * mMatrix[2][1] * mMatrix[3][2] +
|
||||
mMatrix[0][1] * mMatrix[1][0] * mMatrix[2][3] * mMatrix[3][2] -
|
||||
mMatrix[0][0] * mMatrix[1][1] * mMatrix[2][3] * mMatrix[3][2] -
|
||||
mMatrix[0][2] * mMatrix[1][1] * mMatrix[2][0] * mMatrix[3][3] +
|
||||
mMatrix[0][1] * mMatrix[1][2] * mMatrix[2][0] * mMatrix[3][3] +
|
||||
mMatrix[0][2] * mMatrix[1][0] * mMatrix[2][1] * mMatrix[3][3] -
|
||||
mMatrix[0][0] * mMatrix[1][2] * mMatrix[2][1] * mMatrix[3][3] -
|
||||
mMatrix[0][1] * mMatrix[1][0] * mMatrix[2][2] * mMatrix[3][3] +
|
||||
mMatrix[0][0] * mMatrix[1][1] * mMatrix[2][2] * mMatrix[3][3];
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
// Only works for pure orthonormal, homogeneous transform matrices.
|
||||
@@ -428,6 +453,17 @@ const LLMatrix4& LLMatrix4::initRotTrans(const LLQuaternion &q, const LLVector
|
||||
return (*this);
|
||||
}
|
||||
|
||||
const LLMatrix4& LLMatrix4::initScale(const LLVector3 &scale)
|
||||
{
|
||||
setIdentity();
|
||||
|
||||
mMatrix[VX][VX] = scale.mV[VX];
|
||||
mMatrix[VY][VY] = scale.mV[VY];
|
||||
mMatrix[VZ][VZ] = scale.mV[VZ];
|
||||
|
||||
return (*this);
|
||||
}
|
||||
|
||||
const LLMatrix4& LLMatrix4::initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos)
|
||||
{
|
||||
F32 sx, sy, sz;
|
||||
@@ -774,6 +810,23 @@ bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool operator<(const LLMatrix4& a, const LLMatrix4 &b)
|
||||
{
|
||||
U32 i, j;
|
||||
for (i = 0; i < NUM_VALUES_IN_MAT4; i++)
|
||||
{
|
||||
for (j = 0; j < NUM_VALUES_IN_MAT4; j++)
|
||||
{
|
||||
if (a.mMatrix[i][j] != b.mMatrix[i][j])
|
||||
{
|
||||
return a.mMatrix[i][j] < b.mMatrix[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const LLMatrix4& operator*=(LLMatrix4 &a, F32 k)
|
||||
{
|
||||
U32 i, j;
|
||||
@@ -813,4 +866,54 @@ std::ostream& operator<<(std::ostream& s, const LLMatrix4 &a)
|
||||
return s;
|
||||
}
|
||||
|
||||
LLSD LLMatrix4::getValue() const
|
||||
{
|
||||
LLSD ret;
|
||||
|
||||
ret[0] = mMatrix[0][0];
|
||||
ret[1] = mMatrix[0][1];
|
||||
ret[2] = mMatrix[0][2];
|
||||
ret[3] = mMatrix[0][3];
|
||||
|
||||
ret[4] = mMatrix[1][0];
|
||||
ret[5] = mMatrix[1][1];
|
||||
ret[6] = mMatrix[1][2];
|
||||
ret[7] = mMatrix[1][3];
|
||||
|
||||
ret[8] = mMatrix[2][0];
|
||||
ret[9] = mMatrix[2][1];
|
||||
ret[10] = mMatrix[2][2];
|
||||
ret[11] = mMatrix[2][3];
|
||||
|
||||
ret[12] = mMatrix[3][0];
|
||||
ret[13] = mMatrix[3][1];
|
||||
ret[14] = mMatrix[3][2];
|
||||
ret[15] = mMatrix[3][3];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LLMatrix4::setValue(const LLSD& data)
|
||||
{
|
||||
mMatrix[0][0] = data[0].asReal();
|
||||
mMatrix[0][1] = data[1].asReal();
|
||||
mMatrix[0][2] = data[2].asReal();
|
||||
mMatrix[0][3] = data[3].asReal();
|
||||
|
||||
mMatrix[1][0] = data[4].asReal();
|
||||
mMatrix[1][1] = data[5].asReal();
|
||||
mMatrix[1][2] = data[6].asReal();
|
||||
mMatrix[1][3] = data[7].asReal();
|
||||
|
||||
mMatrix[2][0] = data[8].asReal();
|
||||
mMatrix[2][1] = data[9].asReal();
|
||||
mMatrix[2][2] = data[10].asReal();
|
||||
mMatrix[2][3] = data[11].asReal();
|
||||
|
||||
mMatrix[3][0] = data[12].asReal();
|
||||
mMatrix[3][1] = data[13].asReal();
|
||||
mMatrix[3][2] = data[14].asReal();
|
||||
mMatrix[3][3] = data[15].asReal();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -125,6 +125,8 @@ public:
|
||||
|
||||
~LLMatrix4(void); // Destructor
|
||||
|
||||
LLSD getValue() const;
|
||||
void setValue(const LLSD&);
|
||||
|
||||
//////////////////////////////
|
||||
//
|
||||
@@ -138,6 +140,7 @@ public:
|
||||
|
||||
// various useful matrix functions
|
||||
const LLMatrix4& setIdentity(); // Load identity matrix
|
||||
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)
|
||||
@@ -159,6 +162,7 @@ public:
|
||||
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
|
||||
|
||||
const LLMatrix4& initScale(const LLVector3 &scale);
|
||||
|
||||
// Set all
|
||||
const LLMatrix4& initAll(const LLVector3 &scale, const LLQuaternion &q, const LLVector3 &pos);
|
||||
@@ -236,6 +240,7 @@ public:
|
||||
|
||||
friend bool operator==(const LLMatrix4 &a, const LLMatrix4 &b); // Return a == b
|
||||
friend bool operator!=(const LLMatrix4 &a, const LLMatrix4 &b); // Return a != b
|
||||
friend bool operator<(const LLMatrix4 &a, const LLMatrix4& b); // Return a < b
|
||||
|
||||
friend const LLMatrix4& operator+=(LLMatrix4 &a, const LLMatrix4 &b); // Return a + b
|
||||
friend const LLMatrix4& operator-=(LLMatrix4 &a, const LLMatrix4 &b); // Return a - b
|
||||
@@ -269,6 +274,30 @@ inline const LLMatrix4& LLMatrix4::setIdentity()
|
||||
return (*this);
|
||||
}
|
||||
|
||||
inline bool LLMatrix4::isIdentity() const
|
||||
{
|
||||
return
|
||||
mMatrix[0][0] == 1.f &&
|
||||
mMatrix[0][1] == 0.f &&
|
||||
mMatrix[0][2] == 0.f &&
|
||||
mMatrix[0][3] == 0.f &&
|
||||
|
||||
mMatrix[1][0] == 0.f &&
|
||||
mMatrix[1][1] == 1.f &&
|
||||
mMatrix[1][2] == 0.f &&
|
||||
mMatrix[1][3] == 0.f &&
|
||||
|
||||
mMatrix[2][0] == 0.f &&
|
||||
mMatrix[2][1] == 0.f &&
|
||||
mMatrix[2][2] == 1.f &&
|
||||
mMatrix[2][3] == 0.f &&
|
||||
|
||||
mMatrix[3][0] == 0.f &&
|
||||
mMatrix[3][1] == 0.f &&
|
||||
mMatrix[3][2] == 0.f &&
|
||||
mMatrix[3][3] == 1.f;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
inline LLMatrix4 operator*(const LLMatrix4 &a, const LLMatrix4 &b)
|
||||
|
||||
@@ -115,3 +115,18 @@ LLVector2 lerp(const LLVector2 &a, const LLVector2 &b, F32 u)
|
||||
a.mV[VX] + (b.mV[VX] - a.mV[VX]) * u,
|
||||
a.mV[VY] + (b.mV[VY] - a.mV[VY]) * u );
|
||||
}
|
||||
|
||||
LLSD LLVector2::getValue() const
|
||||
{
|
||||
LLSD ret;
|
||||
ret[0] = mV[0];
|
||||
ret[1] = mV[1];
|
||||
return ret;
|
||||
}
|
||||
|
||||
void LLVector2::setValue(LLSD& sd)
|
||||
{
|
||||
mV[0] = (F32) sd[0].asReal();
|
||||
mV[1] = (F32) sd[1].asReal();
|
||||
}
|
||||
|
||||
|
||||
@@ -66,6 +66,9 @@ class LLVector2
|
||||
void set(const LLVector2 &vec); // Sets LLVector2 to vec
|
||||
void set(const F32 *vec); // Sets LLVector2 to vec
|
||||
|
||||
LLSD getValue() const;
|
||||
void setValue(LLSD& sd);
|
||||
|
||||
void setVec(F32 x, F32 y); // deprecated
|
||||
void setVec(const LLVector2 &vec); // deprecated
|
||||
void setVec(const F32 *vec); // deprecated
|
||||
|
||||
@@ -140,6 +140,21 @@ BOOL LLVector3::clampLength( F32 length_limit )
|
||||
return changed;
|
||||
}
|
||||
|
||||
BOOL LLVector3::clamp(const LLVector3 &min_vec, const LLVector3 &max_vec)
|
||||
{
|
||||
BOOL ret = FALSE;
|
||||
|
||||
if (mV[0] < min_vec[0]) { mV[0] = min_vec[0]; ret = TRUE; }
|
||||
if (mV[1] < min_vec[1]) { mV[1] = min_vec[1]; ret = TRUE; }
|
||||
if (mV[2] < min_vec[2]) { mV[2] = min_vec[2]; ret = TRUE; }
|
||||
|
||||
if (mV[0] > max_vec[0]) { mV[0] = max_vec[0]; ret = TRUE; }
|
||||
if (mV[1] > max_vec[1]) { mV[1] = max_vec[1]; ret = TRUE; }
|
||||
if (mV[2] > max_vec[2]) { mV[2] = max_vec[2]; ret = TRUE; }
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Sets all values to absolute value of their original values
|
||||
// Returns TRUE if data changed
|
||||
@@ -197,6 +212,28 @@ const LLVector3& LLVector3::rotVec(const LLQuaternion &q)
|
||||
return *this;
|
||||
}
|
||||
|
||||
const LLVector3& LLVector3::transVec(const LLMatrix4& mat)
|
||||
{
|
||||
setVec(
|
||||
mV[VX] * mat.mMatrix[VX][VX] +
|
||||
mV[VY] * mat.mMatrix[VX][VY] +
|
||||
mV[VZ] * mat.mMatrix[VX][VZ] +
|
||||
mat.mMatrix[VX][VW],
|
||||
|
||||
mV[VX] * mat.mMatrix[VY][VX] +
|
||||
mV[VY] * mat.mMatrix[VY][VY] +
|
||||
mV[VZ] * mat.mMatrix[VY][VZ] +
|
||||
mat.mMatrix[VY][VW],
|
||||
|
||||
mV[VX] * mat.mMatrix[VZ][VX] +
|
||||
mV[VY] * mat.mMatrix[VZ][VY] +
|
||||
mV[VZ] * mat.mMatrix[VZ][VZ] +
|
||||
mat.mMatrix[VZ][VW]);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
const LLVector3& LLVector3::rotVec(F32 angle, const LLVector3 &vec)
|
||||
{
|
||||
if ( !vec.isExactlyZero() && angle )
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
class LLVector2;
|
||||
class LLVector4;
|
||||
class LLMatrix3;
|
||||
class LLMatrix4;
|
||||
class LLVector3d;
|
||||
class LLQuaternion;
|
||||
|
||||
@@ -75,6 +76,7 @@ class LLVector3
|
||||
|
||||
inline BOOL isFinite() const; // checks to see if all values of LLVector3 are finite
|
||||
BOOL clamp(F32 min, F32 max); // Clamps all values to (min,max), returns TRUE if data changed
|
||||
BOOL clamp(const LLVector3 &min_vec, const LLVector3 &max_vec); // Scales vector by another vector
|
||||
BOOL clampLength( F32 length_limit ); // Scales vector to limit length to a value
|
||||
|
||||
void quantize16(F32 lowerxy, F32 upperxy, F32 lowerz, F32 upperz); // changes the vector to reflect quatization
|
||||
@@ -115,6 +117,7 @@ class LLVector3
|
||||
const LLVector3& rotVec(F32 angle, F32 x, F32 y, F32 z); // Rotates about x,y,z by angle radians
|
||||
const LLVector3& rotVec(const LLMatrix3 &mat); // Rotates by LLMatrix4 mat
|
||||
const LLVector3& rotVec(const LLQuaternion &q); // Rotates by LLQuaternion q
|
||||
const LLVector3& transVec(const LLMatrix4& mat); // Transforms by LLMatrix4 mat (mat * v)
|
||||
|
||||
const LLVector3& scaleVec(const LLVector3& vec); // scales per component by vec
|
||||
LLVector3 scaledVec(const LLVector3& vec) const; // get a copy of this vector scaled by vec
|
||||
@@ -162,6 +165,8 @@ F32 dist_vec(const LLVector3 &a, const LLVector3 &b); // Returns distance betwe
|
||||
F32 dist_vec_squared(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b
|
||||
F32 dist_vec_squared2D(const LLVector3 &a, const LLVector3 &b);// Returns distance squared between a and b ignoring Z component
|
||||
LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b
|
||||
LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b); // Returns vector a projected on vector b (same as projected_vec)
|
||||
LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b); // Returns component of vector a not parallel to vector b (same as projected_vec)
|
||||
LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u); // Returns a vector that is a linear interpolation between a and b
|
||||
|
||||
inline LLVector3::LLVector3(void)
|
||||
@@ -496,6 +501,17 @@ inline LLVector3 projected_vec(const LLVector3 &a, const LLVector3 &b)
|
||||
return project_axis * (a * project_axis);
|
||||
}
|
||||
|
||||
inline LLVector3 parallel_component(const LLVector3 &a, const LLVector3 &b)
|
||||
{
|
||||
return projected_vec(a, b);
|
||||
}
|
||||
|
||||
inline LLVector3 orthogonal_component(const LLVector3 &a, const LLVector3 &b)
|
||||
{
|
||||
return a - projected_vec(a, b);
|
||||
}
|
||||
|
||||
|
||||
inline LLVector3 lerp(const LLVector3 &a, const LLVector3 &b, F32 u)
|
||||
{
|
||||
return LLVector3(
|
||||
@@ -529,6 +545,21 @@ inline void update_min_max(LLVector3& min, LLVector3& max, const LLVector3& pos)
|
||||
}
|
||||
}
|
||||
|
||||
inline void update_min_max(LLVector3& min, LLVector3& max, const F32* pos)
|
||||
{
|
||||
for (U32 i = 0; i < 3; i++)
|
||||
{
|
||||
if (min.mV[i] > pos[i])
|
||||
{
|
||||
min.mV[i] = pos[i];
|
||||
}
|
||||
if (max.mV[i] < pos[i])
|
||||
{
|
||||
max.mV[i] = pos[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline F32 angle_between(const LLVector3& a, const LLVector3& b)
|
||||
{
|
||||
LLVector3 an = a;
|
||||
|
||||
@@ -114,6 +114,7 @@ class LLColor4
|
||||
|
||||
const LLColor4& operator=(const LLColor3 &a); // Assigns vec3 to vec4 and returns vec4
|
||||
|
||||
bool operator<(const LLColor4& rhs) const;
|
||||
friend std::ostream& operator<<(std::ostream& s, const LLColor4 &a); // Print a
|
||||
friend LLColor4 operator+(const LLColor4 &a, const LLColor4 &b); // Return vector a + b
|
||||
friend LLColor4 operator-(const LLColor4 &a, const LLColor4 &b); // Return vector a minus b
|
||||
@@ -595,6 +596,23 @@ inline LLColor4 lerp(const LLColor4 &a, const LLColor4 &b, F32 u)
|
||||
a.mV[VW] + (b.mV[VW] - a.mV[VW]) * u);
|
||||
}
|
||||
|
||||
inline bool LLColor4::operator<(const LLColor4& rhs) const
|
||||
{
|
||||
if (mV[0] != rhs.mV[0])
|
||||
{
|
||||
return mV[0] < rhs.mV[0];
|
||||
}
|
||||
if (mV[1] != rhs.mV[1])
|
||||
{
|
||||
return mV[1] < rhs.mV[1];
|
||||
}
|
||||
if (mV[2] != rhs.mV[2])
|
||||
{
|
||||
return mV[2] < rhs.mV[2];
|
||||
}
|
||||
|
||||
return mV[3] < rhs.mV[3];
|
||||
}
|
||||
|
||||
void LLColor4::clamp()
|
||||
{
|
||||
|
||||
@@ -55,8 +55,8 @@
|
||||
#include "llstl.h"
|
||||
#include "llsdserialize.h"
|
||||
#include "llthread.h"
|
||||
|
||||
#include "llsocks5.h"
|
||||
#include "lltimer.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
@@ -92,6 +92,26 @@ std::vector<LLMutex*> LLCurl::sSSLMutex;
|
||||
std::string LLCurl::sCAPath;
|
||||
std::string LLCurl::sCAFile;
|
||||
|
||||
void check_curl_code(CURLcode code)
|
||||
{
|
||||
if (code != CURLE_OK)
|
||||
{
|
||||
// linux appears to throw a curl error once per session for a bad initialization
|
||||
// at a pretty random time (when enabling cookies).
|
||||
llinfos << "curl error detected: " << curl_easy_strerror(code) << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
void check_curl_multi_code(CURLMcode code)
|
||||
{
|
||||
if (code != CURLM_OK)
|
||||
{
|
||||
// linux appears to throw a curl error once per session for a bad initialization
|
||||
// at a pretty random time (when enabling cookies).
|
||||
llinfos << "curl multi error detected: " << curl_multi_strerror(code) << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLCurl::setCAPath(const std::string& path)
|
||||
{
|
||||
@@ -241,7 +261,12 @@ public:
|
||||
|
||||
void resetState();
|
||||
|
||||
static CURL* allocEasyHandle();
|
||||
static void releaseEasyHandle(CURL* handle);
|
||||
|
||||
private:
|
||||
friend class LLCurl;
|
||||
|
||||
CURL* mCurlEasyHandle;
|
||||
struct curl_slist* mHeaders;
|
||||
|
||||
@@ -256,8 +281,62 @@ private:
|
||||
std::vector<char*> mStrings;
|
||||
|
||||
ResponderPtr mResponder;
|
||||
|
||||
static std::set<CURL*> sFreeHandles;
|
||||
static std::set<CURL*> sActiveHandles;
|
||||
static LLMutex* sHandleMutex;
|
||||
};
|
||||
|
||||
std::set<CURL*> LLCurl::Easy::sFreeHandles;
|
||||
std::set<CURL*> LLCurl::Easy::sActiveHandles;
|
||||
LLMutex* LLCurl::Easy::sHandleMutex = NULL;
|
||||
|
||||
|
||||
//static
|
||||
CURL* LLCurl::Easy::allocEasyHandle()
|
||||
{
|
||||
CURL* ret = NULL;
|
||||
LLMutexLock lock(sHandleMutex);
|
||||
if (sFreeHandles.empty())
|
||||
{
|
||||
ret = curl_easy_init();
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = *(sFreeHandles.begin());
|
||||
sFreeHandles.erase(ret);
|
||||
curl_easy_reset(ret);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
{
|
||||
sActiveHandles.insert(ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//static
|
||||
void LLCurl::Easy::releaseEasyHandle(CURL* handle)
|
||||
{
|
||||
if (!handle)
|
||||
{
|
||||
llerrs << "handle cannot be NULL!" << llendl;
|
||||
}
|
||||
|
||||
LLMutexLock lock(sHandleMutex);
|
||||
|
||||
if (sActiveHandles.find(handle) != sActiveHandles.end())
|
||||
{
|
||||
sActiveHandles.erase(handle);
|
||||
sFreeHandles.insert(handle);
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Invalid handle." << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
LLCurl::Easy::Easy()
|
||||
: mHeaders(NULL),
|
||||
mCurlEasyHandle(NULL)
|
||||
@@ -268,18 +347,20 @@ LLCurl::Easy::Easy()
|
||||
LLCurl::Easy* LLCurl::Easy::getEasy()
|
||||
{
|
||||
Easy* easy = new Easy();
|
||||
easy->mCurlEasyHandle = curl_easy_init();
|
||||
easy->mCurlEasyHandle = allocEasyHandle();
|
||||
|
||||
if (!easy->mCurlEasyHandle)
|
||||
{
|
||||
// this can happen if we have too many open files (fails in c-ares/ares_init.c)
|
||||
llwarns << "curl_multi_init() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl;
|
||||
llwarns << "allocEasyHandle() returned NULL! Easy handles: " << gCurlEasyCount << " Multi handles: " << gCurlMultiCount << llendl;
|
||||
delete easy;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// set no DMS caching as default for all easy handles. This prevents them adopting a
|
||||
// set no DNS caching as default for all easy handles. This prevents them adopting a
|
||||
// multi handles cache if they are added to one.
|
||||
curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0);
|
||||
CURLcode result = curl_easy_setopt(easy->mCurlEasyHandle, CURLOPT_DNS_CACHE_TIMEOUT, 0);
|
||||
check_curl_code(result);
|
||||
|
||||
if (LLSocks::getInstance()->isHttpProxyEnabled())
|
||||
{
|
||||
@@ -305,7 +386,7 @@ LLCurl::Easy* LLCurl::Easy::getEasy()
|
||||
|
||||
LLCurl::Easy::~Easy()
|
||||
{
|
||||
curl_easy_cleanup(mCurlEasyHandle);
|
||||
releaseEasyHandle(mCurlEasyHandle);
|
||||
--gCurlEasyCount;
|
||||
curl_slist_free_all(mHeaders);
|
||||
for_each(mStrings.begin(), mStrings.end(), DeletePointerArray());
|
||||
@@ -364,9 +445,9 @@ void LLCurl::Easy::setHeaders()
|
||||
|
||||
void LLCurl::Easy::getTransferInfo(LLCurl::TransferInfo* info)
|
||||
{
|
||||
curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SIZE_DOWNLOAD, &info->mSizeDownload);
|
||||
curl_easy_getinfo(mCurlEasyHandle, CURLINFO_TOTAL_TIME, &info->mTotalTime);
|
||||
curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SPEED_DOWNLOAD, &info->mSpeedDownload);
|
||||
check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SIZE_DOWNLOAD, &info->mSizeDownload));
|
||||
check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_TOTAL_TIME, &info->mTotalTime));
|
||||
check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_SPEED_DOWNLOAD, &info->mSpeedDownload));
|
||||
}
|
||||
|
||||
U32 LLCurl::Easy::report(CURLcode code)
|
||||
@@ -376,13 +457,14 @@ U32 LLCurl::Easy::report(CURLcode code)
|
||||
|
||||
if (code == CURLE_OK)
|
||||
{
|
||||
curl_easy_getinfo(mCurlEasyHandle, CURLINFO_RESPONSE_CODE, &responseCode);
|
||||
check_curl_code(curl_easy_getinfo(mCurlEasyHandle, CURLINFO_RESPONSE_CODE, &responseCode));
|
||||
//*TODO: get reason from first line of mHeaderOutput
|
||||
}
|
||||
else
|
||||
{
|
||||
responseCode = 499;
|
||||
responseReason = strerror(code) + " : " + mErrorBuffer;
|
||||
setopt(CURLOPT_FRESH_CONNECT, TRUE);
|
||||
}
|
||||
|
||||
if (mResponder)
|
||||
@@ -398,17 +480,20 @@ U32 LLCurl::Easy::report(CURLcode code)
|
||||
// Note: these all assume the caller tracks the value (i.e. keeps it persistant)
|
||||
void LLCurl::Easy::setopt(CURLoption option, S32 value)
|
||||
{
|
||||
curl_easy_setopt(mCurlEasyHandle, option, value);
|
||||
CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, value);
|
||||
check_curl_code(result);
|
||||
}
|
||||
|
||||
void LLCurl::Easy::setopt(CURLoption option, void* value)
|
||||
{
|
||||
curl_easy_setopt(mCurlEasyHandle, option, value);
|
||||
CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, value);
|
||||
check_curl_code(result);
|
||||
}
|
||||
|
||||
void LLCurl::Easy::setopt(CURLoption option, char* value)
|
||||
{
|
||||
curl_easy_setopt(mCurlEasyHandle, option, value);
|
||||
CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, value);
|
||||
check_curl_code(result);
|
||||
}
|
||||
|
||||
// Note: this copies the string so that the caller does not have to keep it around
|
||||
@@ -417,7 +502,8 @@ void LLCurl::Easy::setoptString(CURLoption option, const std::string& value)
|
||||
char* tstring = new char[value.length()+1];
|
||||
strcpy(tstring, value.c_str());
|
||||
mStrings.push_back(tstring);
|
||||
curl_easy_setopt(mCurlEasyHandle, option, tstring);
|
||||
CURLcode result = curl_easy_setopt(mCurlEasyHandle, option, tstring);
|
||||
check_curl_code(result);
|
||||
}
|
||||
|
||||
void LLCurl::Easy::slist_append(const char* str)
|
||||
@@ -510,6 +596,9 @@ void LLCurl::Easy::prepRequest(const std::string& url,
|
||||
setCA();
|
||||
|
||||
setopt(CURLOPT_SSL_VERIFYPEER, true);
|
||||
|
||||
//don't verify host name so urls with scrubbed host names will work (improves DNS performance)
|
||||
setopt(CURLOPT_SSL_VERIFYHOST, 0);
|
||||
setopt(CURLOPT_TIMEOUT, CURL_REQUEST_TIMEOUT);
|
||||
|
||||
setoptString(CURLOPT_URL, url);
|
||||
@@ -586,7 +675,7 @@ LLCurl::Multi::~Multi()
|
||||
iter != mEasyActiveList.end(); ++iter)
|
||||
{
|
||||
Easy* easy = *iter;
|
||||
curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle());
|
||||
check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));
|
||||
delete easy;
|
||||
}
|
||||
mEasyActiveList.clear();
|
||||
@@ -596,7 +685,7 @@ LLCurl::Multi::~Multi()
|
||||
for_each(mEasyFreeList.begin(), mEasyFreeList.end(), DeletePointer());
|
||||
mEasyFreeList.clear();
|
||||
|
||||
curl_multi_cleanup(mCurlMultiHandle);
|
||||
check_curl_multi_code(curl_multi_cleanup(mCurlMultiHandle));
|
||||
--gCurlMultiCount;
|
||||
}
|
||||
|
||||
@@ -617,8 +706,10 @@ S32 LLCurl::Multi::perform()
|
||||
CURLMcode code = curl_multi_perform(mCurlMultiHandle, &q);
|
||||
if (CURLM_CALL_MULTI_PERFORM != code || q == 0)
|
||||
{
|
||||
check_curl_multi_code(code);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
mQueued = q;
|
||||
return q;
|
||||
@@ -685,11 +776,12 @@ LLCurl::Easy* LLCurl::Multi::allocEasy()
|
||||
bool LLCurl::Multi::addEasy(Easy* easy)
|
||||
{
|
||||
CURLMcode mcode = curl_multi_add_handle(mCurlMultiHandle, easy->getCurlHandle());
|
||||
if (mcode != CURLM_OK)
|
||||
{
|
||||
llwarns << "Curl Error: " << curl_multi_strerror(mcode) << llendl;
|
||||
return false;
|
||||
}
|
||||
check_curl_multi_code(mcode);
|
||||
//if (mcode != CURLM_OK)
|
||||
//{
|
||||
// llwarns << "Curl Error: " << curl_multi_strerror(mcode) << llendl;
|
||||
// return false;
|
||||
//}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -710,22 +802,14 @@ void LLCurl::Multi::easyFree(Easy* easy)
|
||||
|
||||
void LLCurl::Multi::removeEasy(Easy* easy)
|
||||
{
|
||||
curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle());
|
||||
check_curl_multi_code(curl_multi_remove_handle(mCurlMultiHandle, easy->getCurlHandle()));
|
||||
easyFree(easy);
|
||||
}
|
||||
|
||||
//static
|
||||
std::string LLCurl::strerror(CURLcode errorcode)
|
||||
{
|
||||
#if LL_DARWIN
|
||||
// curl_easy_strerror was added in libcurl 7.12.0. Unfortunately, the version in the Mac OS X 10.3.9 SDK is 7.10.2...
|
||||
// There's a problem with the custom curl headers in our build that keeps me from #ifdefing this on the libcurl version number
|
||||
// (the correct check would be #if LIBCURL_VERSION_NUM >= 0x070c00). We'll fix the header problem soon, but for now
|
||||
// just punt and print the numeric error code on the Mac.
|
||||
return llformat("%d", errorcode);
|
||||
#else // LL_DARWIN
|
||||
return std::string(curl_easy_strerror(errorcode));
|
||||
#endif // LL_DARWIN
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -737,6 +821,7 @@ LLCurlRequest::LLCurlRequest() :
|
||||
mActiveRequestCount(0)
|
||||
{
|
||||
mThreadID = LLThread::currentID();
|
||||
mProcessing = FALSE;
|
||||
}
|
||||
|
||||
LLCurlRequest::~LLCurlRequest()
|
||||
@@ -771,6 +856,11 @@ LLCurl::Easy* LLCurlRequest::allocEasy()
|
||||
bool LLCurlRequest::addEasy(LLCurl::Easy* easy)
|
||||
{
|
||||
llassert_always(mActiveMulti);
|
||||
|
||||
if (mProcessing)
|
||||
{
|
||||
llerrs << "Posting to a LLCurlRequest instance from within a responder is not allowed (causes DNS timeouts)." << llendl;
|
||||
}
|
||||
bool res = mActiveMulti->addEasy(easy);
|
||||
return res;
|
||||
}
|
||||
@@ -828,12 +918,41 @@ bool LLCurlRequest::post(const std::string& url,
|
||||
bool res = addEasy(easy);
|
||||
return res;
|
||||
}
|
||||
|
||||
bool LLCurlRequest::post(const std::string& url,
|
||||
const headers_t& headers,
|
||||
const std::string& data,
|
||||
LLCurl::ResponderPtr responder)
|
||||
{
|
||||
LLCurl::Easy* easy = allocEasy();
|
||||
if (!easy)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
easy->prepRequest(url, headers, responder);
|
||||
|
||||
easy->getInput().write(data.data(), data.size());
|
||||
S32 bytes = easy->getInput().str().length();
|
||||
|
||||
easy->setopt(CURLOPT_POST, 1);
|
||||
easy->setopt(CURLOPT_POSTFIELDS, (void*)NULL);
|
||||
easy->setopt(CURLOPT_POSTFIELDSIZE, bytes);
|
||||
|
||||
easy->slist_append("Content-Type: application/octet-stream");
|
||||
easy->setHeaders();
|
||||
|
||||
lldebugs << "POSTING: " << bytes << " bytes." << llendl;
|
||||
bool res = addEasy(easy);
|
||||
return res;
|
||||
}
|
||||
|
||||
// Note: call once per frame
|
||||
S32 LLCurlRequest::process()
|
||||
{
|
||||
llassert_always(mThreadID == LLThread::currentID());
|
||||
S32 res = 0;
|
||||
|
||||
mProcessing = TRUE;
|
||||
for (curlmulti_set_t::iterator iter = mMultiSet.begin();
|
||||
iter != mMultiSet.end(); )
|
||||
{
|
||||
@@ -847,6 +966,7 @@ S32 LLCurlRequest::process()
|
||||
delete multi;
|
||||
}
|
||||
}
|
||||
mProcessing = FALSE;
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -1076,8 +1196,12 @@ void LLCurl::initClass()
|
||||
// Do not change this "unless you are familiar with and mean to control
|
||||
// internal operations of libcurl"
|
||||
// - http://curl.haxx.se/libcurl/c/curl_global_init.html
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
|
||||
|
||||
check_curl_code(code);
|
||||
|
||||
Easy::sHandleMutex = new LLMutex;
|
||||
|
||||
#if SAFE_SSL
|
||||
S32 mutex_count = CRYPTO_num_locks();
|
||||
for (S32 i=0; i<mutex_count; i++)
|
||||
@@ -1095,7 +1219,19 @@ void LLCurl::cleanupClass()
|
||||
CRYPTO_set_locking_callback(NULL);
|
||||
for_each(sSSLMutex.begin(), sSSLMutex.end(), DeletePointer());
|
||||
#endif
|
||||
curl_global_cleanup();
|
||||
|
||||
delete Easy::sHandleMutex;
|
||||
Easy::sHandleMutex = NULL;
|
||||
|
||||
for (std::set<CURL*>::iterator iter = Easy::sFreeHandles.begin(); iter != Easy::sFreeHandles.end(); ++iter)
|
||||
{
|
||||
CURL* curl = *iter;
|
||||
curl_easy_cleanup(curl);
|
||||
}
|
||||
|
||||
Easy::sFreeHandles.clear();
|
||||
|
||||
llassert(Easy::sActiveHandles.empty());
|
||||
}
|
||||
|
||||
const unsigned int LLCurl::MAX_REDIRECTS = 5;
|
||||
|
||||
@@ -207,6 +207,8 @@ public:
|
||||
void get(const std::string& url, LLCurl::ResponderPtr responder);
|
||||
bool getByteRange(const std::string& url, const headers_t& headers, S32 offset, S32 length, LLCurl::ResponderPtr responder);
|
||||
bool post(const std::string& url, const headers_t& headers, const LLSD& data, LLCurl::ResponderPtr responder);
|
||||
bool post(const std::string& url, const headers_t& headers, const std::string& data, LLCurl::ResponderPtr responder);
|
||||
|
||||
S32 process();
|
||||
S32 getQueued();
|
||||
|
||||
@@ -220,6 +222,7 @@ private:
|
||||
curlmulti_set_t mMultiSet;
|
||||
LLCurl::Multi* mActiveMulti;
|
||||
S32 mActiveRequestCount;
|
||||
BOOL mProcessing;
|
||||
U32 mThreadID; // debug
|
||||
};
|
||||
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "llsdmessagebuilder.h"
|
||||
|
||||
#include "llmessagetemplate.h"
|
||||
#include "llmath.h"
|
||||
#include "llquaternion.h"
|
||||
#include "llsdutil.h"
|
||||
#include "llsdutil_math.h"
|
||||
|
||||
@@ -94,7 +94,7 @@ bool starts_with(const std::string& text, const char* prefix)
|
||||
|
||||
// TODO: Build a real services.xml for windows development.
|
||||
// and remove the base_url logic below.
|
||||
std::string LLServiceBuilder::buildServiceURI(const std::string& service_name)
|
||||
std::string LLServiceBuilder::buildServiceURI(const std::string& service_name) const
|
||||
{
|
||||
std::ostringstream service_url;
|
||||
// Find the service builder
|
||||
@@ -132,7 +132,7 @@ std::string LLServiceBuilder::buildServiceURI(const std::string& service_name)
|
||||
|
||||
std::string LLServiceBuilder::buildServiceURI(
|
||||
const std::string& service_name,
|
||||
const LLSD& option_map)
|
||||
const LLSD& option_map) const
|
||||
{
|
||||
return russ_format(buildServiceURI(service_name), option_map);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ public:
|
||||
*
|
||||
* @param service_name The name of the service you want to call.
|
||||
*/
|
||||
std::string buildServiceURI(const std::string& service_name);
|
||||
std::string buildServiceURI(const std::string& service_name) const;
|
||||
|
||||
/**
|
||||
* @brief Build a service url if the url with construction parameters.
|
||||
@@ -88,7 +88,7 @@ public:
|
||||
*/
|
||||
std::string buildServiceURI(
|
||||
const std::string& service_name,
|
||||
const LLSD& option_map);
|
||||
const LLSD& option_map) const;
|
||||
|
||||
public:
|
||||
/**
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
#include "lltemplatemessagebuilder.h"
|
||||
|
||||
#include "llmessagetemplate.h"
|
||||
#include "llmath.h"
|
||||
#include "llquaternion.h"
|
||||
#include "u64.h"
|
||||
#include "v3dmath.h"
|
||||
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "llfasttimer.h"
|
||||
#include "llmessagebuilder.h"
|
||||
#include "llmessagetemplate.h"
|
||||
#include "llmath.h"
|
||||
#include "llquaternion.h"
|
||||
#include "message.h"
|
||||
#include "u64.h"
|
||||
|
||||
@@ -2469,12 +2469,12 @@ void dump_prehash_files()
|
||||
" * Generated from message template version number %.3f\n"
|
||||
" */\n",
|
||||
gMessageSystem->mMessageFileVersionNumber);
|
||||
fprintf(fp, "\n\nextern F32 gPrehashVersionNumber;\n\n");
|
||||
fprintf(fp, "\n\nextern F32 const gPrehashVersionNumber;\n\n");
|
||||
for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++)
|
||||
{
|
||||
if (!LLMessageStringTable::getInstance()->mEmpty[i] && LLMessageStringTable::getInstance()->mString[i][0] != '.')
|
||||
{
|
||||
fprintf(fp, "extern char * _PREHASH_%s;\n", LLMessageStringTable::getInstance()->mString[i]);
|
||||
fprintf(fp, "extern char const* const _PREHASH_%s;\n", LLMessageStringTable::getInstance()->mString[i]);
|
||||
}
|
||||
}
|
||||
fprintf(fp, "\n\n#endif\n");
|
||||
@@ -2499,12 +2499,12 @@ void dump_prehash_files()
|
||||
gMessageSystem->mMessageFileVersionNumber);
|
||||
fprintf(fp, "#include \"linden_common.h\"\n");
|
||||
fprintf(fp, "#include \"message.h\"\n\n");
|
||||
fprintf(fp, "\n\nF32 gPrehashVersionNumber = %.3ff;\n\n", gMessageSystem->mMessageFileVersionNumber);
|
||||
fprintf(fp, "\n\nF32 const gPrehashVersionNumber = %.3ff;\n\n", gMessageSystem->mMessageFileVersionNumber);
|
||||
for (i = 0; i < MESSAGE_NUMBER_OF_HASH_BUCKETS; i++)
|
||||
{
|
||||
if (!LLMessageStringTable::getInstance()->mEmpty[i] && LLMessageStringTable::getInstance()->mString[i][0] != '.')
|
||||
{
|
||||
fprintf(fp, "char * _PREHASH_%s = LLMessageStringTable::getInstance()->getString(\"%s\");\n", LLMessageStringTable::getInstance()->mString[i], LLMessageStringTable::getInstance()->mString[i]);
|
||||
fprintf(fp, "char const* const _PREHASH_%s = LLMessageStringTable::getInstance()->getString(\"%s\");\n", LLMessageStringTable::getInstance()->mString[i], LLMessageStringTable::getInstance()->mString[i]);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
@@ -34,259 +34,281 @@
|
||||
|
||||
#include "lluuid.h"
|
||||
|
||||
LLUUID const SND_NULL = LLUUID::null;
|
||||
LLUUID const SND_RIDE ("00000000-0000-0000-0000-000000000100");
|
||||
LLUUID const SND_SHOT ("00000000-0000-0000-0000-000000000101");
|
||||
LLUUID const SND_MORTAR ("00000000-0000-0000-0000-000000000102");
|
||||
LLUUID const SND_HIT ("00000000-0000-0000-0000-000000000103");
|
||||
LLUUID const SND_EXPLOSION ("00000000-0000-0000-0000-000000000104");
|
||||
LLUUID const SND_BOING ("00000000-0000-0000-0000-000000000105");
|
||||
LLUUID const SND_OBJECT_CREATE ("9f1bc096-3592-411e-9b0b-c447a9ff054c");
|
||||
const LLUUID SND_NULL = LLUUID::null;
|
||||
const LLUUID SND_RIDE ("00000000-0000-0000-0000-000000000100");
|
||||
const LLUUID SND_SHOT ("00000000-0000-0000-0000-000000000101");
|
||||
const LLUUID SND_MORTAR ("00000000-0000-0000-0000-000000000102");
|
||||
const LLUUID SND_HIT ("00000000-0000-0000-0000-000000000103");
|
||||
const LLUUID SND_EXPLOSION ("00000000-0000-0000-0000-000000000104");
|
||||
const LLUUID SND_BOING ("00000000-0000-0000-0000-000000000105");
|
||||
const LLUUID SND_OBJECT_CREATE ("9f1bc096-3592-411e-9b0b-c447a9ff054c");
|
||||
|
||||
//
|
||||
// Different bird sounds for different states
|
||||
//
|
||||
|
||||
LLUUID const SND_CHIRP ("00000000-0000-0000-0000-000000000106"); // Flying random chirp
|
||||
LLUUID const SND_CHIRP2 ("828a9526-175b-455d-8af0-0e3c0fb602b2"); // Spooked by user
|
||||
LLUUID const SND_CHIRP3 ("f99772d6-1ce6-4a39-a28b-06d26c94c9e3"); // Spooked by object
|
||||
LLUUID const SND_CHIRP4 ("54472ca4-7fc9-42cb-b7d5-99ad5b12bd50"); // Chasing other bird
|
||||
LLUUID const SND_CHIRP5 ("2929964f-fac5-40d7-9179-2864a8fa9ace"); // Hopping random chirp
|
||||
LLUUID const SND_CHIRPDEAD ("9abff1d3-863a-4e04-bd83-3834fd7fcff4"); // Hit by grenade - dead!
|
||||
const LLUUID SND_CHIRP ("00000000-0000-0000-0000-000000000106"); // Flying random chirp
|
||||
const LLUUID SND_CHIRP2 ("828a9526-175b-455d-8af0-0e3c0fb602b2"); // Spooked by user
|
||||
const LLUUID SND_CHIRP3 ("f99772d6-1ce6-4a39-a28b-06d26c94c9e3"); // Spooked by object
|
||||
const LLUUID SND_CHIRP4 ("54472ca4-7fc9-42cb-b7d5-99ad5b12bd50"); // Chasing other bird
|
||||
const LLUUID SND_CHIRP5 ("2929964f-fac5-40d7-9179-2864a8fa9ace"); // Hopping random chirp
|
||||
const LLUUID SND_CHIRPDEAD ("9abff1d3-863a-4e04-bd83-3834fd7fcff4"); // Hit by grenade - dead!
|
||||
|
||||
|
||||
LLUUID const SND_MUNCH ("00000000-0000-0000-0000-000000000107");
|
||||
LLUUID const SND_PUNCH ("00000000-0000-0000-0000-000000000108");
|
||||
LLUUID const SND_SPLASH ("00000000-0000-0000-0000-000000000109");
|
||||
LLUUID const SND_CLICK ("00000000-0000-0000-0000-000000000110");
|
||||
LLUUID const SND_WHISTLE ("ab858f9a-1f44-4d39-9b33-351543d03ccb");
|
||||
LLUUID const SND_TYPING ("5e191c7b-8996-9ced-a177-b2ac32bfea06");
|
||||
const LLUUID SND_MUNCH ("00000000-0000-0000-0000-000000000107");
|
||||
const LLUUID SND_PUNCH ("00000000-0000-0000-0000-000000000108");
|
||||
const LLUUID SND_SPLASH ("00000000-0000-0000-0000-000000000109");
|
||||
const LLUUID SND_CLICK ("00000000-0000-0000-0000-000000000110");
|
||||
const LLUUID SND_WHISTLE ("ab858f9a-1f44-4d39-9b33-351543d03ccb");
|
||||
const LLUUID SND_TYPING ("5e191c7b-8996-9ced-a177-b2ac32bfea06");
|
||||
|
||||
LLUUID const SND_ARROW_SHOT ("00000000-0000-0000-0000-000000000111");
|
||||
LLUUID const SND_ARROW_THUD ("00000000-0000-0000-0000-000000000112");
|
||||
LLUUID const SND_LASER_SHOT ("00000000-0000-0000-0000-000000000113");
|
||||
LLUUID const SND_JET_THRUST ("67f5e4f0-0534-4d97-bc01-f297648d20e0");
|
||||
const LLUUID SND_ARROW_SHOT ("00000000-0000-0000-0000-000000000111");
|
||||
const LLUUID SND_ARROW_THUD ("00000000-0000-0000-0000-000000000112");
|
||||
const LLUUID SND_LASER_SHOT ("00000000-0000-0000-0000-000000000113");
|
||||
const LLUUID SND_JET_THRUST ("67f5e4f0-0534-4d97-bc01-f297648d20e0");
|
||||
|
||||
LLUUID const SND_SILENCE ("00000000-0000-0000-0000-000000000114");
|
||||
LLUUID const SND_BUBBLES ("00000000-0000-0000-0000-000000000115");
|
||||
LLUUID const SND_WELCOME ("00000000-0000-0000-0000-000000000116");
|
||||
LLUUID const SND_SQUISH ("00000000-0000-0000-0000-000000000117");
|
||||
LLUUID const SND_SUBPOD ("00000000-0000-0000-0000-000000000118");
|
||||
LLUUID const SND_FOOTSTEPS ("00000000-0000-0000-0000-000000000119");
|
||||
LLUUID const SND_STEP_LEFT ("00000000-0000-0000-0000-000000000124");
|
||||
LLUUID const SND_STEP_RIGHT ("00000000-0000-0000-0000-000000000125");
|
||||
const LLUUID SND_SILENCE ("00000000-0000-0000-0000-000000000114");
|
||||
const LLUUID SND_BUBBLES ("00000000-0000-0000-0000-000000000115");
|
||||
const LLUUID SND_WELCOME ("00000000-0000-0000-0000-000000000116");
|
||||
const LLUUID SND_SQUISH ("00000000-0000-0000-0000-000000000117");
|
||||
const LLUUID SND_SUBPOD ("00000000-0000-0000-0000-000000000118");
|
||||
const LLUUID SND_FOOTSTEPS ("00000000-0000-0000-0000-000000000119");
|
||||
const LLUUID SND_STEP_LEFT ("00000000-0000-0000-0000-000000000124");
|
||||
const LLUUID SND_STEP_RIGHT ("00000000-0000-0000-0000-000000000125");
|
||||
|
||||
LLUUID const SND_BALL_COLLISION ("00000000-0000-0000-0000-000000000120");
|
||||
const LLUUID SND_BALL_COLLISION ("00000000-0000-0000-0000-000000000120");
|
||||
|
||||
LLUUID const SND_OOOH_SCARE_ME ("00000000-0000-0000-0000-000000000121");
|
||||
LLUUID const SND_PAYBACK_TIME ("00000000-0000-0000-0000-000000000122");
|
||||
LLUUID const SND_READY_FOR_BATTLE ("00000000-0000-0000-0000-000000000123");
|
||||
const LLUUID SND_OOOH_SCARE_ME ("00000000-0000-0000-0000-000000000121");
|
||||
const LLUUID SND_PAYBACK_TIME ("00000000-0000-0000-0000-000000000122");
|
||||
const LLUUID SND_READY_FOR_BATTLE ("00000000-0000-0000-0000-000000000123");
|
||||
|
||||
LLUUID const SND_FLESH_FLESH ("dce5fdd4-afe4-4ea1-822f-dd52cac46b08");
|
||||
LLUUID const SND_FLESH_PLASTIC ("51011582-fbca-4580-ae9e-1a5593f094ec");
|
||||
LLUUID const SND_FLESH_RUBBER ("68d62208-e257-4d0c-bbe2-20c9ea9760bb");
|
||||
LLUUID const SND_GLASS_FLESH ("75872e8c-bc39-451b-9b0b-042d7ba36cba");
|
||||
LLUUID const SND_GLASS_GLASS ("6a45ba0b-5775-4ea8-8513-26008a17f873");
|
||||
LLUUID const SND_GLASS_PLASTIC ("992a6d1b-8c77-40e0-9495-4098ce539694");
|
||||
LLUUID const SND_GLASS_RUBBER ("2de4da5a-faf8-46be-bac6-c4d74f1e5767");
|
||||
LLUUID const SND_GLASS_WOOD ("6e3fb0f7-6d9c-42ca-b86b-1122ff562d7d");
|
||||
LLUUID const SND_METAL_FLESH ("14209133-4961-4acc-9649-53fc38ee1667");
|
||||
LLUUID const SND_METAL_GLASS ("bc4a4348-cfcc-4e5e-908e-8a52a8915fe6");
|
||||
LLUUID const SND_METAL_METAL ("9e5c1297-6eed-40c0-825a-d9bcd86e3193");
|
||||
LLUUID const SND_METAL_PLASTIC ("e534761c-1894-4b61-b20c-658a6fb68157");
|
||||
LLUUID const SND_METAL_RUBBER ("8761f73f-6cf9-4186-8aaa-0948ed002db1");
|
||||
LLUUID const SND_METAL_WOOD ("874a26fd-142f-4173-8c5b-890cd846c74d");
|
||||
LLUUID const SND_PLASTIC_PLASTIC ("0e24a717-b97e-4b77-9c94-b59a5a88b2da");
|
||||
LLUUID const SND_RUBBER_PLASTIC ("75cf3ade-9a5b-4c4d-bb35-f9799bda7fb2");
|
||||
LLUUID const SND_RUBBER_RUBBER ("153c8bf7-fb89-4d89-b263-47e58b1b4774");
|
||||
LLUUID const SND_STONE_FLESH ("55c3e0ce-275a-46fa-82ff-e0465f5e8703");
|
||||
LLUUID const SND_STONE_GLASS ("24babf58-7156-4841-9a3f-761bdbb8e237");
|
||||
LLUUID const SND_STONE_METAL ("aca261d8-e145-4610-9e20-9eff990f2c12");
|
||||
LLUUID const SND_STONE_PLASTIC ("0642fba6-5dcf-4d62-8e7b-94dbb529d117");
|
||||
LLUUID const SND_STONE_RUBBER ("25a863e8-dc42-4e8a-a357-e76422ace9b5");
|
||||
LLUUID const SND_STONE_STONE ("9538f37c-456e-4047-81be-6435045608d4");
|
||||
LLUUID const SND_STONE_WOOD ("8c0f84c3-9afd-4396-b5f5-9bca2c911c20");
|
||||
LLUUID const SND_WOOD_FLESH ("be582e5d-b123-41a2-a150-454c39e961c8");
|
||||
LLUUID const SND_WOOD_PLASTIC ("c70141d4-ba06-41ea-bcbc-35ea81cb8335");
|
||||
LLUUID const SND_WOOD_RUBBER ("7d1826f4-24c4-4aac-8c2e-eff45df37783");
|
||||
LLUUID const SND_WOOD_WOOD ("063c97d3-033a-4e9b-98d8-05c8074922cb");
|
||||
const LLUUID SND_FLESH_FLESH ("dce5fdd4-afe4-4ea1-822f-dd52cac46b08");
|
||||
const LLUUID SND_FLESH_PLASTIC ("51011582-fbca-4580-ae9e-1a5593f094ec");
|
||||
const LLUUID SND_FLESH_RUBBER ("68d62208-e257-4d0c-bbe2-20c9ea9760bb");
|
||||
const LLUUID SND_GLASS_FLESH ("75872e8c-bc39-451b-9b0b-042d7ba36cba");
|
||||
const LLUUID SND_GLASS_GLASS ("6a45ba0b-5775-4ea8-8513-26008a17f873");
|
||||
const LLUUID SND_GLASS_PLASTIC ("992a6d1b-8c77-40e0-9495-4098ce539694");
|
||||
const LLUUID SND_GLASS_RUBBER ("2de4da5a-faf8-46be-bac6-c4d74f1e5767");
|
||||
const LLUUID SND_GLASS_WOOD ("6e3fb0f7-6d9c-42ca-b86b-1122ff562d7d");
|
||||
const LLUUID SND_METAL_FLESH ("14209133-4961-4acc-9649-53fc38ee1667");
|
||||
const LLUUID SND_METAL_GLASS ("bc4a4348-cfcc-4e5e-908e-8a52a8915fe6");
|
||||
const LLUUID SND_METAL_METAL ("9e5c1297-6eed-40c0-825a-d9bcd86e3193");
|
||||
const LLUUID SND_METAL_PLASTIC ("e534761c-1894-4b61-b20c-658a6fb68157");
|
||||
const LLUUID SND_METAL_RUBBER ("8761f73f-6cf9-4186-8aaa-0948ed002db1");
|
||||
const LLUUID SND_METAL_WOOD ("874a26fd-142f-4173-8c5b-890cd846c74d");
|
||||
const LLUUID SND_PLASTIC_PLASTIC ("0e24a717-b97e-4b77-9c94-b59a5a88b2da");
|
||||
const LLUUID SND_RUBBER_PLASTIC ("75cf3ade-9a5b-4c4d-bb35-f9799bda7fb2");
|
||||
const LLUUID SND_RUBBER_RUBBER ("153c8bf7-fb89-4d89-b263-47e58b1b4774");
|
||||
const LLUUID SND_STONE_FLESH ("55c3e0ce-275a-46fa-82ff-e0465f5e8703");
|
||||
const LLUUID SND_STONE_GLASS ("24babf58-7156-4841-9a3f-761bdbb8e237");
|
||||
const LLUUID SND_STONE_METAL ("aca261d8-e145-4610-9e20-9eff990f2c12");
|
||||
const LLUUID SND_STONE_PLASTIC ("0642fba6-5dcf-4d62-8e7b-94dbb529d117");
|
||||
const LLUUID SND_STONE_RUBBER ("25a863e8-dc42-4e8a-a357-e76422ace9b5");
|
||||
const LLUUID SND_STONE_STONE ("9538f37c-456e-4047-81be-6435045608d4");
|
||||
const LLUUID SND_STONE_WOOD ("8c0f84c3-9afd-4396-b5f5-9bca2c911c20");
|
||||
const LLUUID SND_WOOD_FLESH ("be582e5d-b123-41a2-a150-454c39e961c8");
|
||||
const LLUUID SND_WOOD_PLASTIC ("c70141d4-ba06-41ea-bcbc-35ea81cb8335");
|
||||
const LLUUID SND_WOOD_RUBBER ("7d1826f4-24c4-4aac-8c2e-eff45df37783");
|
||||
const LLUUID SND_WOOD_WOOD ("063c97d3-033a-4e9b-98d8-05c8074922cb");
|
||||
|
||||
|
||||
LLUUID const SND_SLIDE_FLESH_FLESH ("614eec22-f73d-4fdc-8691-a37dc5c58333");
|
||||
LLUUID const SND_SLIDE_FLESH_PLASTIC (SND_NULL);
|
||||
LLUUID const SND_SLIDE_FLESH_RUBBER (SND_NULL);
|
||||
LLUUID const SND_SLIDE_FLESH_FABRIC ("3678b9b9-2a0c-42b5-9c83-80b64ad6e898");
|
||||
LLUUID const SND_SLIDE_FLESH_GRAVEL ("02eaa42a-ce1a-4b6b-9c38-cd7ad0e8f4a6");
|
||||
LLUUID const SND_SLIDE_FLESH_GRAVEL_02 ("e7d3b501-79f8-4419-b842-ab6843e0f840");
|
||||
LLUUID const SND_SLIDE_FLESH_GRAVEL_03 ("4c3e8b52-6244-4e44-85a6-f4ab994418ed");
|
||||
LLUUID const SND_SLIDE_GLASS_GRAVEL ("ca491e77-5c47-4ea1-8021-b3ebbf636cab");
|
||||
LLUUID const SND_SLIDE_GLASS_GRAVEL_02 ("30794d49-91ce-48e3-a527-c06f67bd6cbe");
|
||||
LLUUID const SND_SLIDE_GLASS_GRAVEL_03 ("04c78e54-fd8d-46b6-8ab9-7678b5d6e5cb");
|
||||
LLUUID const SND_SLIDE_GLASS_FLESH (SND_NULL);
|
||||
LLUUID const SND_SLIDE_GLASS_GLASS (SND_NULL);
|
||||
LLUUID const SND_SLIDE_GLASS_PLASTIC (SND_NULL);
|
||||
LLUUID const SND_SLIDE_GLASS_RUBBER (SND_NULL);
|
||||
LLUUID const SND_SLIDE_GLASS_WOOD (SND_NULL);
|
||||
LLUUID const SND_SLIDE_METAL_FABRIC ("18b66e81-2958-42d4-a373-7a5054919adc");
|
||||
LLUUID const SND_SLIDE_METAL_FLESH ("dde65837-633c-4841-af2f-62ec471bf61e");
|
||||
LLUUID const SND_SLIDE_METAL_FLESH_02 ("f3cc2cbe-1a1a-4db7-a8d2-e9c8f8fa1f4f");
|
||||
LLUUID const SND_SLIDE_METAL_GLASS ("4188be39-7b1f-4495-bf2b-83ddd82eea05");
|
||||
LLUUID const SND_SLIDE_METAL_GLASS_02 ("336faa2b-9d96-4e14-93ad-b63b60074379");
|
||||
LLUUID const SND_SLIDE_METAL_GLASS_03 ("34d912aa-cf73-4462-b7d0-dcba2c66caba");
|
||||
LLUUID const SND_SLIDE_METAL_GLASS_04 ("97ffc063-e872-4469-8e95-1450ac6bad2b");
|
||||
LLUUID const SND_SLIDE_METAL_GRAVEL ("2bbff37d-009a-4cfc-9a0d-817652c08fbe");
|
||||
LLUUID const SND_SLIDE_METAL_GRAVEL_02 ("a906a228-783b-49e7-9f0a-e20a41d0e39f");
|
||||
LLUUID const SND_SLIDE_METAL_METAL ("09461277-c691-45de-b2c5-89dfd3712f79");
|
||||
LLUUID const SND_SLIDE_METAL_METAL_02 ("e00a5d97-8fdc-46c1-bd53-7e312727466c");
|
||||
LLUUID const SND_SLIDE_METAL_METAL_03 ("8ebfa780-c440-4b52-ab65-5edf3bc15bf1");
|
||||
LLUUID const SND_SLIDE_METAL_METAL_04 ("d6d03cb2-5b16-4e31-b7d4-2a81d2a0909b");
|
||||
LLUUID const SND_SLIDE_METAL_METAL_05 ("3a46f447-916e-47de-a1e5-95d1af46bd0f");
|
||||
LLUUID const SND_SLIDE_METAL_METAL_06 ("cd423231-e70d-4fd2-ad26-f1c6cf5f0610");
|
||||
LLUUID const SND_SLIDE_METAL_PLASTIC (SND_NULL);
|
||||
LLUUID const SND_SLIDE_METAL_RUBBER ("12d97bc0-3c15-4744-b6bd-77d1316eb4f0");
|
||||
LLUUID const SND_SLIDE_METAL_WOOD ("4afb6926-a73f-4cb7-85d5-0f9a40107434");
|
||||
LLUUID const SND_SLIDE_METAL_WOOD_02 ("349970bf-187d-4bcb-b2cf-e7bb6581590f");
|
||||
LLUUID const SND_SLIDE_METAL_WOOD_03 ("64bf6e87-73d4-4cb4-84f7-55cecfd97cd3");
|
||||
LLUUID const SND_SLIDE_METAL_WOOD_04 ("0dc670a9-dbe8-41bc-b8ee-4d96d99219d5");
|
||||
LLUUID const SND_SLIDE_METAL_WOOD_05 ("6e3cc57b-c9aa-4829-86a1-8e82aeaccb47");
|
||||
LLUUID const SND_SLIDE_METAL_WOOD_06 ("c1237f4c-8c88-4da1-bfbc-2af26a8d9e5a");
|
||||
LLUUID const SND_SLIDE_METAL_WOOD_07 ("0e1ec243-063b-4dcb-a903-52b8dffed3d2");
|
||||
LLUUID const SND_SLIDE_METAL_WOOD_08 ("66736d0f-533d-4007-a8ee-0f27c2034126");
|
||||
LLUUID const SND_SLIDE_PLASTIC_GRAVEL ("35092c21-5c48-4b4d-a818-3cf240af2348");
|
||||
LLUUID const SND_SLIDE_PLASTIC_GRAVEL_02("c37f5776-0020-47e8-89a0-c74cc6f5742d");
|
||||
LLUUID const SND_SLIDE_PLASTIC_GRAVEL_03("d2fc8db6-2e66-464a-8ccb-f99b61ee4987");
|
||||
LLUUID const SND_SLIDE_PLASTIC_GRAVEL_04("93cbdb10-6e82-4c0b-a547-7b3b79ac25f6");
|
||||
LLUUID const SND_SLIDE_PLASTIC_GRAVEL_05("2f6d0542-fcd1-4264-a17b-f57bf5ebf402");
|
||||
LLUUID const SND_SLIDE_PLASTIC_GRAVEL_06("5b8887d4-3be2-45a0-b25d-85af3b1e6392");
|
||||
LLUUID const SND_SLIDE_PLASTIC_PLASTIC (SND_NULL);
|
||||
LLUUID const SND_SLIDE_PLASTIC_PLASTIC_02 (SND_NULL);
|
||||
LLUUID const SND_SLIDE_PLASTIC_PLASTIC_03 (SND_NULL);
|
||||
LLUUID const SND_SLIDE_PLASTIC_FABRIC ("7294d9ad-3e41-4373-992c-a9f21d5d66ad");
|
||||
LLUUID const SND_SLIDE_PLASTIC_FABRIC_02("58608ce1-f524-472f-b447-bbe6ce4a46e0");
|
||||
LLUUID const SND_SLIDE_PLASTIC_FABRIC_03("06ae285e-0b34-4ea6-84ab-9c6c31b414fc");
|
||||
LLUUID const SND_SLIDE_PLASTIC_FABRIC_04("211613db-0461-49bd-9554-5c14ad8b31f6");
|
||||
LLUUID const SND_SLIDE_RUBBER_PLASTIC ("a98ffa5a-e48e-4f9d-9242-b9a3210ad84a");
|
||||
LLUUID const SND_SLIDE_RUBBER_PLASTIC_02 ("d4136c40-eeaa-49c6-a982-8e5a16f5d93a");
|
||||
LLUUID const SND_SLIDE_RUBBER_PLASTIC_03 ("29ec0fb2-0b23-47b2-835b-c83cc7cf9fb0");
|
||||
LLUUID const SND_SLIDE_RUBBER_RUBBER (SND_NULL);
|
||||
LLUUID const SND_SLIDE_STONE_FLESH (SND_NULL);
|
||||
LLUUID const SND_SLIDE_STONE_GLASS (SND_NULL);
|
||||
LLUUID const SND_SLIDE_STONE_METAL (SND_NULL);
|
||||
LLUUID const SND_SLIDE_STONE_PLASTIC ("afd0bcc3-d41a-4572-9e7f-08a29eeb0b8a");
|
||||
LLUUID const SND_SLIDE_STONE_PLASTIC_02 ("881b720a-96cf-4128-bb98-5d87e03e93c7");
|
||||
LLUUID const SND_SLIDE_STONE_PLASTIC_03 ("293dac42-658a-4c5a-a7a2-6d4c5e5658b0");
|
||||
LLUUID const SND_SLIDE_STONE_RUBBER ("0724b946-6a3f-4eeb-bb50-0a3b33120974");
|
||||
LLUUID const SND_SLIDE_STONE_RUBBER_02 ("ada93d00-76e2-4bf1-9ad9-493727630717");
|
||||
LLUUID const SND_SLIDE_STONE_STONE ("ade766dc-2e75-4699-9b41-7c8e53d2b3f2");
|
||||
LLUUID const SND_SLIDE_STONE_STONE_02 ("66698375-6594-47b0-8046-c3973de1291d");
|
||||
LLUUID const SND_SLIDE_STONE_WOOD ("174ef324-ed50-4f65-9479-b4da580aeb3c");
|
||||
LLUUID const SND_SLIDE_STONE_WOOD_02 ("33d517fd-ff11-4d01-a7b5-0e3abf818dcf");
|
||||
LLUUID const SND_SLIDE_STONE_WOOD_03 ("1bac4b63-e6fd-4659-9761-991284cf4582");
|
||||
LLUUID const SND_SLIDE_STONE_WOOD_04 ("a7d28564-6821-4c01-a378-cde98fba7ba9");
|
||||
LLUUID const SND_SLIDE_WOOD_FABRIC ("22c58e74-22cd-4960-9ab7-5bf08ab824e5");
|
||||
LLUUID const SND_SLIDE_WOOD_FABRIC_02 ("0b0ed22e-4a0f-4617-a4cf-20d0f2b78ccc");
|
||||
LLUUID const SND_SLIDE_WOOD_FABRIC_03 ("42b80abb-9823-4b74-a210-326ccf23636a");
|
||||
LLUUID const SND_SLIDE_WOOD_FABRIC_04 ("8538298a-1e6b-4b69-a9ee-5e01e4a02b35");
|
||||
LLUUID const SND_SLIDE_WOOD_FLESH ("84b026f3-a11c-4366-aa7c-07edcd89b2bb");
|
||||
LLUUID const SND_SLIDE_WOOD_FLESH_02 ("2644191f-4848-47ba-8ba7-bddc0bfcb3da");
|
||||
LLUUID const SND_SLIDE_WOOD_FLESH_03 ("edb978e4-9be9-456f-b2fc-e8502bfe25be");
|
||||
LLUUID const SND_SLIDE_WOOD_FLESH_04 ("bf2b972e-f42a-46d7-b53e-5fca38f5bc61");
|
||||
LLUUID const SND_SLIDE_WOOD_GRAVEL ("d063bb4d-0eff-4403-a6cc-c6c6c073e624");
|
||||
LLUUID const SND_SLIDE_WOOD_GRAVEL_02 ("511eb679-6d93-47fa-9141-c3ef9261c919");
|
||||
LLUUID const SND_SLIDE_WOOD_GRAVEL_03 ("4ed1fd43-4707-4e5c-b7b7-21ec4e72c1ac");
|
||||
LLUUID const SND_SLIDE_WOOD_GRAVEL_04 ("99ea89b3-aa76-4b87-99c8-670365c6d8c3");
|
||||
LLUUID const SND_SLIDE_WOOD_PLASTIC ("505ca3c4-94a0-4e28-8fc1-ea72a428396b");
|
||||
LLUUID const SND_SLIDE_WOOD_PLASTIC_02 ("fc404011-df71-4ed0-8f22-b72bdd18f63c");
|
||||
LLUUID const SND_SLIDE_WOOD_PLASTIC_03 ("67dbe225-26df-4efa-8c8b-f1ef669fec45");
|
||||
LLUUID const SND_SLIDE_WOOD_RUBBER (SND_NULL);
|
||||
LLUUID const SND_SLIDE_WOOD_WOOD ("3079d569-b3e8-4df4-9e09-f0d4611213ef");
|
||||
LLUUID const SND_SLIDE_WOOD_WOOD_02 ("276b093d-dbcb-4279-a89e-a54b0b416af6");
|
||||
LLUUID const SND_SLIDE_WOOD_WOOD_03 ("c3f3ca5e-2768-4081-847f-247139310fdb");
|
||||
LLUUID const SND_SLIDE_WOOD_WOOD_04 ("f08d44b8-ff87-4a98-9561-c72f1f2fec81");
|
||||
LLUUID const SND_SLIDE_WOOD_WOOD_05 ("2d8a58cf-f139-4238-8503-27d334d05c85");
|
||||
LLUUID const SND_SLIDE_WOOD_WOOD_06 ("e157ebbd-b12d-4225-aa7c-d47b026a7687");
|
||||
LLUUID const SND_SLIDE_WOOD_WOOD_07 ("35e17956-e7b4-478c-b274-e37db8a166b2");
|
||||
LLUUID const SND_SLIDE_WOOD_WOOD_08 ("e606fc65-0643-4964-9979-ff964fa6a62c");
|
||||
const LLUUID SND_SLIDE_FLESH_FLESH ("614eec22-f73d-4fdc-8691-a37dc5c58333");
|
||||
const LLUUID SND_SLIDE_FLESH_PLASTIC (SND_NULL);
|
||||
const LLUUID SND_SLIDE_FLESH_RUBBER (SND_NULL);
|
||||
const LLUUID SND_SLIDE_FLESH_FABRIC ("3678b9b9-2a0c-42b5-9c83-80b64ad6e898");
|
||||
const LLUUID SND_SLIDE_FLESH_GRAVEL ("02eaa42a-ce1a-4b6b-9c38-cd7ad0e8f4a6");
|
||||
const LLUUID SND_SLIDE_FLESH_GRAVEL_02 ("e7d3b501-79f8-4419-b842-ab6843e0f840");
|
||||
const LLUUID SND_SLIDE_FLESH_GRAVEL_03 ("4c3e8b52-6244-4e44-85a6-f4ab994418ed");
|
||||
const LLUUID SND_SLIDE_GLASS_GRAVEL ("ca491e77-5c47-4ea1-8021-b3ebbf636cab");
|
||||
const LLUUID SND_SLIDE_GLASS_GRAVEL_02 ("30794d49-91ce-48e3-a527-c06f67bd6cbe");
|
||||
const LLUUID SND_SLIDE_GLASS_GRAVEL_03 ("04c78e54-fd8d-46b6-8ab9-7678b5d6e5cb");
|
||||
const LLUUID SND_SLIDE_GLASS_FLESH (SND_NULL);
|
||||
const LLUUID SND_SLIDE_GLASS_GLASS (SND_NULL);
|
||||
const LLUUID SND_SLIDE_GLASS_PLASTIC (SND_NULL);
|
||||
const LLUUID SND_SLIDE_GLASS_RUBBER (SND_NULL);
|
||||
const LLUUID SND_SLIDE_GLASS_WOOD (SND_NULL);
|
||||
const LLUUID SND_SLIDE_METAL_FABRIC ("18b66e81-2958-42d4-a373-7a5054919adc");
|
||||
const LLUUID SND_SLIDE_METAL_FLESH ("dde65837-633c-4841-af2f-62ec471bf61e");
|
||||
const LLUUID SND_SLIDE_METAL_FLESH_02 ("f3cc2cbe-1a1a-4db7-a8d2-e9c8f8fa1f4f");
|
||||
const LLUUID SND_SLIDE_METAL_GLASS ("4188be39-7b1f-4495-bf2b-83ddd82eea05");
|
||||
const LLUUID SND_SLIDE_METAL_GLASS_02 ("336faa2b-9d96-4e14-93ad-b63b60074379");
|
||||
const LLUUID SND_SLIDE_METAL_GLASS_03 ("34d912aa-cf73-4462-b7d0-dcba2c66caba");
|
||||
const LLUUID SND_SLIDE_METAL_GLASS_04 ("97ffc063-e872-4469-8e95-1450ac6bad2b");
|
||||
const LLUUID SND_SLIDE_METAL_GRAVEL ("2bbff37d-009a-4cfc-9a0d-817652c08fbe");
|
||||
const LLUUID SND_SLIDE_METAL_GRAVEL_02 ("a906a228-783b-49e7-9f0a-e20a41d0e39f");
|
||||
const LLUUID SND_SLIDE_METAL_METAL ("09461277-c691-45de-b2c5-89dfd3712f79");
|
||||
const LLUUID SND_SLIDE_METAL_METAL_02 ("e00a5d97-8fdc-46c1-bd53-7e312727466c");
|
||||
const LLUUID SND_SLIDE_METAL_METAL_03 ("8ebfa780-c440-4b52-ab65-5edf3bc15bf1");
|
||||
const LLUUID SND_SLIDE_METAL_METAL_04 ("d6d03cb2-5b16-4e31-b7d4-2a81d2a0909b");
|
||||
const LLUUID SND_SLIDE_METAL_METAL_05 ("3a46f447-916e-47de-a1e5-95d1af46bd0f");
|
||||
const LLUUID SND_SLIDE_METAL_METAL_06 ("cd423231-e70d-4fd2-ad26-f1c6cf5f0610");
|
||||
const LLUUID SND_SLIDE_METAL_PLASTIC (SND_NULL);
|
||||
const LLUUID SND_SLIDE_METAL_RUBBER ("12d97bc0-3c15-4744-b6bd-77d1316eb4f0");
|
||||
const LLUUID SND_SLIDE_METAL_WOOD ("4afb6926-a73f-4cb7-85d5-0f9a40107434");
|
||||
const LLUUID SND_SLIDE_METAL_WOOD_02 ("349970bf-187d-4bcb-b2cf-e7bb6581590f");
|
||||
const LLUUID SND_SLIDE_METAL_WOOD_03 ("64bf6e87-73d4-4cb4-84f7-55cecfd97cd3");
|
||||
const LLUUID SND_SLIDE_METAL_WOOD_04 ("0dc670a9-dbe8-41bc-b8ee-4d96d99219d5");
|
||||
const LLUUID SND_SLIDE_METAL_WOOD_05 ("6e3cc57b-c9aa-4829-86a1-8e82aeaccb47");
|
||||
const LLUUID SND_SLIDE_METAL_WOOD_06 ("c1237f4c-8c88-4da1-bfbc-2af26a8d9e5a");
|
||||
const LLUUID SND_SLIDE_METAL_WOOD_07 ("0e1ec243-063b-4dcb-a903-52b8dffed3d2");
|
||||
const LLUUID SND_SLIDE_METAL_WOOD_08 ("66736d0f-533d-4007-a8ee-0f27c2034126");
|
||||
const LLUUID SND_SLIDE_PLASTIC_GRAVEL ("35092c21-5c48-4b4d-a818-3cf240af2348");
|
||||
const LLUUID SND_SLIDE_PLASTIC_GRAVEL_02("c37f5776-0020-47e8-89a0-c74cc6f5742d");
|
||||
const LLUUID SND_SLIDE_PLASTIC_GRAVEL_03("d2fc8db6-2e66-464a-8ccb-f99b61ee4987");
|
||||
const LLUUID SND_SLIDE_PLASTIC_GRAVEL_04("93cbdb10-6e82-4c0b-a547-7b3b79ac25f6");
|
||||
const LLUUID SND_SLIDE_PLASTIC_GRAVEL_05("2f6d0542-fcd1-4264-a17b-f57bf5ebf402");
|
||||
const LLUUID SND_SLIDE_PLASTIC_GRAVEL_06("5b8887d4-3be2-45a0-b25d-85af3b1e6392");
|
||||
const LLUUID SND_SLIDE_PLASTIC_PLASTIC (SND_NULL);
|
||||
const LLUUID SND_SLIDE_PLASTIC_PLASTIC_02 (SND_NULL);
|
||||
const LLUUID SND_SLIDE_PLASTIC_PLASTIC_03 (SND_NULL);
|
||||
const LLUUID SND_SLIDE_PLASTIC_FABRIC ("7294d9ad-3e41-4373-992c-a9f21d5d66ad");
|
||||
const LLUUID SND_SLIDE_PLASTIC_FABRIC_02("58608ce1-f524-472f-b447-bbe6ce4a46e0");
|
||||
const LLUUID SND_SLIDE_PLASTIC_FABRIC_03("06ae285e-0b34-4ea6-84ab-9c6c31b414fc");
|
||||
const LLUUID SND_SLIDE_PLASTIC_FABRIC_04("211613db-0461-49bd-9554-5c14ad8b31f6");
|
||||
const LLUUID SND_SLIDE_RUBBER_PLASTIC ("a98ffa5a-e48e-4f9d-9242-b9a3210ad84a");
|
||||
const LLUUID SND_SLIDE_RUBBER_PLASTIC_02 ("d4136c40-eeaa-49c6-a982-8e5a16f5d93a");
|
||||
const LLUUID SND_SLIDE_RUBBER_PLASTIC_03 ("29ec0fb2-0b23-47b2-835b-c83cc7cf9fb0");
|
||||
const LLUUID SND_SLIDE_RUBBER_RUBBER (SND_NULL);
|
||||
const LLUUID SND_SLIDE_STONE_FLESH (SND_NULL);
|
||||
const LLUUID SND_SLIDE_STONE_GLASS (SND_NULL);
|
||||
const LLUUID SND_SLIDE_STONE_METAL (SND_NULL);
|
||||
const LLUUID SND_SLIDE_STONE_PLASTIC ("afd0bcc3-d41a-4572-9e7f-08a29eeb0b8a");
|
||||
const LLUUID SND_SLIDE_STONE_PLASTIC_02 ("881b720a-96cf-4128-bb98-5d87e03e93c7");
|
||||
const LLUUID SND_SLIDE_STONE_PLASTIC_03 ("293dac42-658a-4c5a-a7a2-6d4c5e5658b0");
|
||||
const LLUUID SND_SLIDE_STONE_RUBBER ("0724b946-6a3f-4eeb-bb50-0a3b33120974");
|
||||
const LLUUID SND_SLIDE_STONE_RUBBER_02 ("ada93d00-76e2-4bf1-9ad9-493727630717");
|
||||
const LLUUID SND_SLIDE_STONE_STONE ("ade766dc-2e75-4699-9b41-7c8e53d2b3f2");
|
||||
const LLUUID SND_SLIDE_STONE_STONE_02 ("66698375-6594-47b0-8046-c3973de1291d");
|
||||
const LLUUID SND_SLIDE_STONE_WOOD ("174ef324-ed50-4f65-9479-b4da580aeb3c");
|
||||
const LLUUID SND_SLIDE_STONE_WOOD_02 ("33d517fd-ff11-4d01-a7b5-0e3abf818dcf");
|
||||
const LLUUID SND_SLIDE_STONE_WOOD_03 ("1bac4b63-e6fd-4659-9761-991284cf4582");
|
||||
const LLUUID SND_SLIDE_STONE_WOOD_04 ("a7d28564-6821-4c01-a378-cde98fba7ba9");
|
||||
const LLUUID SND_SLIDE_WOOD_FABRIC ("22c58e74-22cd-4960-9ab7-5bf08ab824e5");
|
||||
const LLUUID SND_SLIDE_WOOD_FABRIC_02 ("0b0ed22e-4a0f-4617-a4cf-20d0f2b78ccc");
|
||||
const LLUUID SND_SLIDE_WOOD_FABRIC_03 ("42b80abb-9823-4b74-a210-326ccf23636a");
|
||||
const LLUUID SND_SLIDE_WOOD_FABRIC_04 ("8538298a-1e6b-4b69-a9ee-5e01e4a02b35");
|
||||
const LLUUID SND_SLIDE_WOOD_FLESH ("84b026f3-a11c-4366-aa7c-07edcd89b2bb");
|
||||
const LLUUID SND_SLIDE_WOOD_FLESH_02 ("2644191f-4848-47ba-8ba7-bddc0bfcb3da");
|
||||
const LLUUID SND_SLIDE_WOOD_FLESH_03 ("edb978e4-9be9-456f-b2fc-e8502bfe25be");
|
||||
const LLUUID SND_SLIDE_WOOD_FLESH_04 ("bf2b972e-f42a-46d7-b53e-5fca38f5bc61");
|
||||
const LLUUID SND_SLIDE_WOOD_GRAVEL ("d063bb4d-0eff-4403-a6cc-c6c6c073e624");
|
||||
const LLUUID SND_SLIDE_WOOD_GRAVEL_02 ("511eb679-6d93-47fa-9141-c3ef9261c919");
|
||||
const LLUUID SND_SLIDE_WOOD_GRAVEL_03 ("4ed1fd43-4707-4e5c-b7b7-21ec4e72c1ac");
|
||||
const LLUUID SND_SLIDE_WOOD_GRAVEL_04 ("99ea89b3-aa76-4b87-99c8-670365c6d8c3");
|
||||
const LLUUID SND_SLIDE_WOOD_PLASTIC ("505ca3c4-94a0-4e28-8fc1-ea72a428396b");
|
||||
const LLUUID SND_SLIDE_WOOD_PLASTIC_02 ("fc404011-df71-4ed0-8f22-b72bdd18f63c");
|
||||
const LLUUID SND_SLIDE_WOOD_PLASTIC_03 ("67dbe225-26df-4efa-8c8b-f1ef669fec45");
|
||||
const LLUUID SND_SLIDE_WOOD_RUBBER (SND_NULL);
|
||||
const LLUUID SND_SLIDE_WOOD_WOOD ("3079d569-b3e8-4df4-9e09-f0d4611213ef");
|
||||
const LLUUID SND_SLIDE_WOOD_WOOD_02 ("276b093d-dbcb-4279-a89e-a54b0b416af6");
|
||||
const LLUUID SND_SLIDE_WOOD_WOOD_03 ("c3f3ca5e-2768-4081-847f-247139310fdb");
|
||||
const LLUUID SND_SLIDE_WOOD_WOOD_04 ("f08d44b8-ff87-4a98-9561-c72f1f2fec81");
|
||||
const LLUUID SND_SLIDE_WOOD_WOOD_05 ("2d8a58cf-f139-4238-8503-27d334d05c85");
|
||||
const LLUUID SND_SLIDE_WOOD_WOOD_06 ("e157ebbd-b12d-4225-aa7c-d47b026a7687");
|
||||
const LLUUID SND_SLIDE_WOOD_WOOD_07 ("35e17956-e7b4-478c-b274-e37db8a166b2");
|
||||
const LLUUID SND_SLIDE_WOOD_WOOD_08 ("e606fc65-0643-4964-9979-ff964fa6a62c");
|
||||
|
||||
|
||||
LLUUID const SND_ROLL_FLESH_FLESH (SND_NULL);
|
||||
LLUUID const SND_ROLL_FLESH_PLASTIC ("89a0be4c-848d-4a6e-8886-298f56c2cff4");
|
||||
LLUUID const SND_ROLL_FLESH_PLASTIC_02 ("beb06343-1aa1-4af2-b320-5d2ec31c53b1");
|
||||
LLUUID const SND_ROLL_FLESH_RUBBER (SND_NULL);
|
||||
LLUUID const SND_ROLL_GLASS_GRAVEL ("ba795c74-7e09-4572-b495-e09886a46b86");
|
||||
LLUUID const SND_ROLL_GLASS_GRAVEL_02 ("4c93c3b7-14cb-4d9b-a7df-628ad935f1f2");
|
||||
LLUUID const SND_ROLL_GLASS_FLESH (SND_NULL);
|
||||
LLUUID const SND_ROLL_GLASS_GLASS (SND_NULL);
|
||||
LLUUID const SND_ROLL_GLASS_PLASTIC (SND_NULL);
|
||||
LLUUID const SND_ROLL_GLASS_RUBBER (SND_NULL);
|
||||
LLUUID const SND_ROLL_GLASS_WOOD ("d40b1f48-a061-4f6e-b18f-4326a3dd5c29");
|
||||
LLUUID const SND_ROLL_GLASS_WOOD_02 ("78cd407a-bb36-4163-ba09-20f2e6d9d44b");
|
||||
LLUUID const SND_ROLL_GRAVEL_GRAVEL ("c7354cc3-6df5-4738-8dbb-b28a6ac46a05");
|
||||
LLUUID const SND_ROLL_GRAVEL_GRAVEL_02 ("01d194c4-72a6-47df-81a5-8db430faff87");
|
||||
LLUUID const SND_ROLL_METAL_FABRIC ("ce6e6564-20fd-48e4-81e2-cd3f81c00a3e");
|
||||
LLUUID const SND_ROLL_METAL_FABRIC_02 ("fc4d0065-32f6-4bb0-9f3f-f4737eb27163");
|
||||
LLUUID const SND_ROLL_METAL_FLESH (SND_NULL);
|
||||
LLUUID const SND_ROLL_METAL_GLASS ("63d530bb-a41f-402b-aa1f-be6b11959809");
|
||||
LLUUID const SND_ROLL_METAL_GLASS_02 ("f62642c2-6db5-4faa-8b77-939067d837c3");
|
||||
LLUUID const SND_ROLL_METAL_GLASS_03 ("db5b5a15-2817-4cd7-9f0b-9ad49b5e52c8");
|
||||
LLUUID const SND_ROLL_METAL_GRAVEL ("447164e3-9646-4c1a-a16d-606892891466");
|
||||
LLUUID const SND_ROLL_METAL_METAL ("c3c22cf3-5d1f-4cc3-b4b5-708b9f65979c");
|
||||
LLUUID const SND_ROLL_METAL_METAL_02 ("d8386277-a1ea-460e-b6fd-bb285c323bf1");
|
||||
LLUUID const SND_ROLL_METAL_METAL_03 ("69ee1f02-f9cd-4c8b-aedd-39a2d6705680");
|
||||
LLUUID const SND_ROLL_METAL_METAL_04 ("5cc6b5fd-26ce-47ad-b21d-3a7c190dd375");
|
||||
LLUUID const SND_ROLL_METAL_PLASTIC ("c6a9bbf6-df15-4713-9f84-7237fce4051e");
|
||||
LLUUID const SND_ROLL_METAL_PLASTIC_01 ("0fedb59b-2dbb-4cec-b6cc-8559ec027749");
|
||||
LLUUID const SND_ROLL_METAL_RUBBER (SND_NULL);
|
||||
LLUUID const SND_ROLL_METAL_WOOD ("1d76af57-01b1-4c73-9a1d-69523bfa50ea");
|
||||
LLUUID const SND_ROLL_METAL_WOOD_02 ("78aa4e71-8e7c-4b90-a561-3ebdc639f99b");
|
||||
LLUUID const SND_ROLL_METAL_WOOD_03 ("777d95bf-962f-48fa-93bf-8c1806557d72");
|
||||
LLUUID const SND_ROLL_METAL_WOOD_04 ("1833da76-45e2-4a8b-97da-d17413e056c9");
|
||||
LLUUID const SND_ROLL_METAL_WOOD_05 ("b13e1232-3d8d-42e9-92ec-b30f9f823962");
|
||||
LLUUID const SND_ROLL_PLASTIC_FABRIC ("616a1f03-209f-4c55-b264-83a000b6ef0a");
|
||||
LLUUID const SND_ROLL_PLASTIC_PLASTIC ("873f3d82-00b2-4082-9c69-7aef3461dba1");
|
||||
LLUUID const SND_ROLL_PLASTIC_PLASTIC_02 ("cc39879f-ebc8-4405-a4fc-8342f5bed31e");
|
||||
LLUUID const SND_ROLL_RUBBER_PLASTIC (SND_NULL);
|
||||
LLUUID const SND_ROLL_RUBBER_RUBBER (SND_NULL);
|
||||
LLUUID const SND_ROLL_STONE_FLESH (SND_NULL);
|
||||
LLUUID const SND_ROLL_STONE_GLASS (SND_NULL);
|
||||
LLUUID const SND_ROLL_STONE_METAL (SND_NULL);
|
||||
LLUUID const SND_ROLL_STONE_PLASTIC ("155f65a8-cae7-476e-a58b-fd362be7fd0e");
|
||||
LLUUID const SND_ROLL_STONE_RUBBER (SND_NULL);
|
||||
LLUUID const SND_ROLL_STONE_STONE ("67d56e3f-6ed5-4658-9418-14f020c38b11");
|
||||
LLUUID const SND_ROLL_STONE_STONE_02 ("43d99d10-d75b-4246-accf-4ceb2c909aa7");
|
||||
LLUUID const SND_ROLL_STONE_STONE_03 ("f04e83ff-eed7-4e99-8f45-eb97e4e1d3b7");
|
||||
LLUUID const SND_ROLL_STONE_STONE_04 ("10fcc5ad-fa89-48d6-b774-986b580c1efc");
|
||||
LLUUID const SND_ROLL_STONE_STONE_05 ("3d86f5a3-1a91-49d9-b99f-8521a7422497");
|
||||
LLUUID const SND_ROLL_STONE_WOOD ("53e46fb7-6c21-4fe1-bffe-0567475d48fa");
|
||||
LLUUID const SND_ROLL_STONE_WOOD_02 ("5eba8c9a-a014-4299-87f1-315c45ec795b");
|
||||
LLUUID const SND_ROLL_STONE_WOOD_03 ("ea6c05fc-6e9c-4526-8a20-bc47810bb549");
|
||||
LLUUID const SND_ROLL_STONE_WOOD_04 ("64618cbf-3f42-4728-8094-e77807545efb");
|
||||
LLUUID const SND_ROLL_WOOD_FLESH ("26ee185d-6fc3-49f8-89ba-51cab04cfc42");
|
||||
LLUUID const SND_ROLL_WOOD_FLESH_02 ("334faa25-1e80-4c99-b29f-4c9c2a3d079d");
|
||||
LLUUID const SND_ROLL_WOOD_FLESH_03 ("2f876626-4dce-4f71-a91e-a25302edfab7");
|
||||
LLUUID const SND_ROLL_WOOD_FLESH_04 ("d6877aac-07fc-4931-bcde-585f223802ad");
|
||||
LLUUID const SND_ROLL_WOOD_GRAVEL ("2a23ebb5-a4a2-4f1f-8d75-7384239354aa");
|
||||
LLUUID const SND_ROLL_WOOD_GRAVEL_02 ("208bf26d-f097-450c-95c4-9d26317c613c");
|
||||
LLUUID const SND_ROLL_WOOD_GRAVEL_03 ("a26ecaf4-92c6-4e32-9864-56b7c70cab8e");
|
||||
LLUUID const SND_ROLL_WOOD_PLASTIC ("71c1000a-9f16-4cc3-8ede-ec4aa3bf5723");
|
||||
LLUUID const SND_ROLL_WOOD_PLASTIC_02 ("7bc20ba6-1e6d-4eea-83ad-c5cc3ae0e409");
|
||||
LLUUID const SND_ROLL_WOOD_RUBBER (SND_NULL);
|
||||
LLUUID const SND_ROLL_WOOD_WOOD ("2cc8eec4-bb4a-4ba8-b783-71526ec708e8");
|
||||
LLUUID const SND_ROLL_WOOD_WOOD_02 ("0a1f8070-a11a-4b4c-b260-5ffb6acb0a5d");
|
||||
LLUUID const SND_ROLL_WOOD_WOOD_03 ("160bef64-da9c-4be8-b07b-a5060b501700");
|
||||
LLUUID const SND_ROLL_WOOD_WOOD_04 ("1c62ea16-cc60-48ed-829a-68b8f4cf0c1c");
|
||||
LLUUID const SND_ROLL_WOOD_WOOD_05 ("be9cc8fe-b920-4bf5-8924-453088cbc03f");
|
||||
LLUUID const SND_ROLL_WOOD_WOOD_06 ("a76cfe60-56b0-43b1-8f31-93e56947d78b");
|
||||
LLUUID const SND_ROLL_WOOD_WOOD_07 ("0c6aa481-b5bc-4573-ae83-8e16ff27e750");
|
||||
LLUUID const SND_ROLL_WOOD_WOOD_08 ("214ab2c7-871a-451b-b0db-4c5677199011");
|
||||
LLUUID const SND_ROLL_WOOD_WOOD_09 ("0086e4db-3ac6-4545-b414-6f359bedd9a5");
|
||||
const LLUUID SND_ROLL_FLESH_FLESH (SND_NULL);
|
||||
const LLUUID SND_ROLL_FLESH_PLASTIC ("89a0be4c-848d-4a6e-8886-298f56c2cff4");
|
||||
const LLUUID SND_ROLL_FLESH_PLASTIC_02 ("beb06343-1aa1-4af2-b320-5d2ec31c53b1");
|
||||
const LLUUID SND_ROLL_FLESH_RUBBER (SND_NULL);
|
||||
const LLUUID SND_ROLL_GLASS_GRAVEL ("ba795c74-7e09-4572-b495-e09886a46b86");
|
||||
const LLUUID SND_ROLL_GLASS_GRAVEL_02 ("4c93c3b7-14cb-4d9b-a7df-628ad935f1f2");
|
||||
const LLUUID SND_ROLL_GLASS_FLESH (SND_NULL);
|
||||
const LLUUID SND_ROLL_GLASS_GLASS (SND_NULL);
|
||||
const LLUUID SND_ROLL_GLASS_PLASTIC (SND_NULL);
|
||||
const LLUUID SND_ROLL_GLASS_RUBBER (SND_NULL);
|
||||
const LLUUID SND_ROLL_GLASS_WOOD ("d40b1f48-a061-4f6e-b18f-4326a3dd5c29");
|
||||
const LLUUID SND_ROLL_GLASS_WOOD_02 ("78cd407a-bb36-4163-ba09-20f2e6d9d44b");
|
||||
const LLUUID SND_ROLL_GRAVEL_GRAVEL ("c7354cc3-6df5-4738-8dbb-b28a6ac46a05");
|
||||
const LLUUID SND_ROLL_GRAVEL_GRAVEL_02 ("01d194c4-72a6-47df-81a5-8db430faff87");
|
||||
const LLUUID SND_ROLL_METAL_FABRIC ("ce6e6564-20fd-48e4-81e2-cd3f81c00a3e");
|
||||
const LLUUID SND_ROLL_METAL_FABRIC_02 ("fc4d0065-32f6-4bb0-9f3f-f4737eb27163");
|
||||
const LLUUID SND_ROLL_METAL_FLESH (SND_NULL);
|
||||
const LLUUID SND_ROLL_METAL_GLASS ("63d530bb-a41f-402b-aa1f-be6b11959809");
|
||||
const LLUUID SND_ROLL_METAL_GLASS_02 ("f62642c2-6db5-4faa-8b77-939067d837c3");
|
||||
const LLUUID SND_ROLL_METAL_GLASS_03 ("db5b5a15-2817-4cd7-9f0b-9ad49b5e52c8");
|
||||
const LLUUID SND_ROLL_METAL_GRAVEL ("447164e3-9646-4c1a-a16d-606892891466");
|
||||
const LLUUID SND_ROLL_METAL_METAL ("c3c22cf3-5d1f-4cc3-b4b5-708b9f65979c");
|
||||
const LLUUID SND_ROLL_METAL_METAL_02 ("d8386277-a1ea-460e-b6fd-bb285c323bf1");
|
||||
const LLUUID SND_ROLL_METAL_METAL_03 ("69ee1f02-f9cd-4c8b-aedd-39a2d6705680");
|
||||
const LLUUID SND_ROLL_METAL_METAL_04 ("5cc6b5fd-26ce-47ad-b21d-3a7c190dd375");
|
||||
const LLUUID SND_ROLL_METAL_PLASTIC ("c6a9bbf6-df15-4713-9f84-7237fce4051e");
|
||||
const LLUUID SND_ROLL_METAL_PLASTIC_01 ("0fedb59b-2dbb-4cec-b6cc-8559ec027749");
|
||||
const LLUUID SND_ROLL_METAL_RUBBER (SND_NULL);
|
||||
const LLUUID SND_ROLL_METAL_WOOD ("1d76af57-01b1-4c73-9a1d-69523bfa50ea");
|
||||
const LLUUID SND_ROLL_METAL_WOOD_02 ("78aa4e71-8e7c-4b90-a561-3ebdc639f99b");
|
||||
const LLUUID SND_ROLL_METAL_WOOD_03 ("777d95bf-962f-48fa-93bf-8c1806557d72");
|
||||
const LLUUID SND_ROLL_METAL_WOOD_04 ("1833da76-45e2-4a8b-97da-d17413e056c9");
|
||||
const LLUUID SND_ROLL_METAL_WOOD_05 ("b13e1232-3d8d-42e9-92ec-b30f9f823962");
|
||||
const LLUUID SND_ROLL_PLASTIC_FABRIC ("616a1f03-209f-4c55-b264-83a000b6ef0a");
|
||||
const LLUUID SND_ROLL_PLASTIC_PLASTIC ("873f3d82-00b2-4082-9c69-7aef3461dba1");
|
||||
const LLUUID SND_ROLL_PLASTIC_PLASTIC_02 ("cc39879f-ebc8-4405-a4fc-8342f5bed31e");
|
||||
const LLUUID SND_ROLL_RUBBER_PLASTIC (SND_NULL);
|
||||
const LLUUID SND_ROLL_RUBBER_RUBBER (SND_NULL);
|
||||
const LLUUID SND_ROLL_STONE_FLESH (SND_NULL);
|
||||
const LLUUID SND_ROLL_STONE_GLASS (SND_NULL);
|
||||
const LLUUID SND_ROLL_STONE_METAL (SND_NULL);
|
||||
const LLUUID SND_ROLL_STONE_PLASTIC ("155f65a8-cae7-476e-a58b-fd362be7fd0e");
|
||||
const LLUUID SND_ROLL_STONE_RUBBER (SND_NULL);
|
||||
const LLUUID SND_ROLL_STONE_STONE ("67d56e3f-6ed5-4658-9418-14f020c38b11");
|
||||
const LLUUID SND_ROLL_STONE_STONE_02 ("43d99d10-d75b-4246-accf-4ceb2c909aa7");
|
||||
const LLUUID SND_ROLL_STONE_STONE_03 ("f04e83ff-eed7-4e99-8f45-eb97e4e1d3b7");
|
||||
const LLUUID SND_ROLL_STONE_STONE_04 ("10fcc5ad-fa89-48d6-b774-986b580c1efc");
|
||||
const LLUUID SND_ROLL_STONE_STONE_05 ("3d86f5a3-1a91-49d9-b99f-8521a7422497");
|
||||
const LLUUID SND_ROLL_STONE_WOOD ("53e46fb7-6c21-4fe1-bffe-0567475d48fa");
|
||||
const LLUUID SND_ROLL_STONE_WOOD_02 ("5eba8c9a-a014-4299-87f1-315c45ec795b");
|
||||
const LLUUID SND_ROLL_STONE_WOOD_03 ("ea6c05fc-6e9c-4526-8a20-bc47810bb549");
|
||||
const LLUUID SND_ROLL_STONE_WOOD_04 ("64618cbf-3f42-4728-8094-e77807545efb");
|
||||
const LLUUID SND_ROLL_WOOD_FLESH ("26ee185d-6fc3-49f8-89ba-51cab04cfc42");
|
||||
const LLUUID SND_ROLL_WOOD_FLESH_02 ("334faa25-1e80-4c99-b29f-4c9c2a3d079d");
|
||||
const LLUUID SND_ROLL_WOOD_FLESH_03 ("2f876626-4dce-4f71-a91e-a25302edfab7");
|
||||
const LLUUID SND_ROLL_WOOD_FLESH_04 ("d6877aac-07fc-4931-bcde-585f223802ad");
|
||||
const LLUUID SND_ROLL_WOOD_GRAVEL ("2a23ebb5-a4a2-4f1f-8d75-7384239354aa");
|
||||
const LLUUID SND_ROLL_WOOD_GRAVEL_02 ("208bf26d-f097-450c-95c4-9d26317c613c");
|
||||
const LLUUID SND_ROLL_WOOD_GRAVEL_03 ("a26ecaf4-92c6-4e32-9864-56b7c70cab8e");
|
||||
const LLUUID SND_ROLL_WOOD_PLASTIC ("71c1000a-9f16-4cc3-8ede-ec4aa3bf5723");
|
||||
const LLUUID SND_ROLL_WOOD_PLASTIC_02 ("7bc20ba6-1e6d-4eea-83ad-c5cc3ae0e409");
|
||||
const LLUUID SND_ROLL_WOOD_RUBBER (SND_NULL);
|
||||
const LLUUID SND_ROLL_WOOD_WOOD ("2cc8eec4-bb4a-4ba8-b783-71526ec708e8");
|
||||
const LLUUID SND_ROLL_WOOD_WOOD_02 ("0a1f8070-a11a-4b4c-b260-5ffb6acb0a5d");
|
||||
const LLUUID SND_ROLL_WOOD_WOOD_03 ("160bef64-da9c-4be8-b07b-a5060b501700");
|
||||
const LLUUID SND_ROLL_WOOD_WOOD_04 ("1c62ea16-cc60-48ed-829a-68b8f4cf0c1c");
|
||||
const LLUUID SND_ROLL_WOOD_WOOD_05 ("be9cc8fe-b920-4bf5-8924-453088cbc03f");
|
||||
const LLUUID SND_ROLL_WOOD_WOOD_06 ("a76cfe60-56b0-43b1-8f31-93e56947d78b");
|
||||
const LLUUID SND_ROLL_WOOD_WOOD_07 ("0c6aa481-b5bc-4573-ae83-8e16ff27e750");
|
||||
const LLUUID SND_ROLL_WOOD_WOOD_08 ("214ab2c7-871a-451b-b0db-4c5677199011");
|
||||
const LLUUID SND_ROLL_WOOD_WOOD_09 ("0086e4db-3ac6-4545-b414-6f359bedd9a5");
|
||||
|
||||
LLUUID const SND_SLIDE_STONE_STONE_01 ("2a7dcbd1-d3e6-4767-8432-8322648e7b9d");
|
||||
const LLUUID SND_SLIDE_STONE_STONE_01 ("2a7dcbd1-d3e6-4767-8432-8322648e7b9d");
|
||||
|
||||
LLUUID const SND_STONE_DIRT_01 ("97727335-392c-4338-ac4b-23a7883279c2");
|
||||
LLUUID const SND_STONE_DIRT_02 ("cbe75eb2-3375-41d8-9e3f-2ae46b4164ed");
|
||||
LLUUID const SND_STONE_DIRT_03 ("31e236ee-001b-4c8e-ad6c-c2074cb64357");
|
||||
LLUUID const SND_STONE_DIRT_04 ("c8091652-e04b-4a11-84ba-15dba06e7a1b");
|
||||
const LLUUID SND_STONE_DIRT_01 ("97727335-392c-4338-ac4b-23a7883279c2");
|
||||
const LLUUID SND_STONE_DIRT_02 ("cbe75eb2-3375-41d8-9e3f-2ae46b4164ed");
|
||||
const LLUUID SND_STONE_DIRT_03 ("31e236ee-001b-4c8e-ad6c-c2074cb64357");
|
||||
const LLUUID SND_STONE_DIRT_04 ("c8091652-e04b-4a11-84ba-15dba06e7a1b");
|
||||
|
||||
LLUUID const SND_STONE_STONE_02 ("ba4ef5ac-7435-4240-b826-c24ba8fa5a78");
|
||||
LLUUID const SND_STONE_STONE_04 ("ea296329-0f09-4993-af1b-e6784bab1dc9");
|
||||
const LLUUID SND_STONE_STONE_02 ("ba4ef5ac-7435-4240-b826-c24ba8fa5a78");
|
||||
const LLUUID SND_STONE_STONE_04 ("ea296329-0f09-4993-af1b-e6784bab1dc9");
|
||||
|
||||
|
||||
|
||||
// extra guids
|
||||
#if 0
|
||||
const LLUUID SND_ ("a839b8ac-b0af-4ba9-9fde-188754744e02");
|
||||
const LLUUID SND_ ("20165fa8-836f-4993-85dc-1529172dcd14");
|
||||
const LLUUID SND_ ("fba8e17b-a4b3-4693-9fce-c14800f8a349");
|
||||
const LLUUID SND_ ("2d48db8b-7260-4b02-ad2a-b2c6bee60e94");
|
||||
const LLUUID SND_ ("956d344b-1808-4d8b-88b1-cbc82b7a96a1");
|
||||
const LLUUID SND_ ("b8303cc6-f0b4-4c6f-a199-81f87aba342e");
|
||||
const LLUUID SND_ ("fbf7cd0c-bc8f-4cba-9c19-11f4dd03a06b");
|
||||
const LLUUID SND_ ("85047f7d-933a-4ce5-a7b5-34670243e1ab");
|
||||
const LLUUID SND_ ("0f81acf7-6a2e-4490-957f-c7b0eda00559");
|
||||
const LLUUID SND_ ("5631a6a1-79b4-4de8-bccf-1880b6882da1");
|
||||
const LLUUID SND_ ("43c87a6b-ffb2-437b-89a0-9deba890a4fc");
|
||||
const LLUUID SND_ ("58878d1d-3156-4d01-ac3c-0c4fb99f4d53");
|
||||
const LLUUID SND_ ("9a83f321-44bf-40f6-b006-46c085515345");
|
||||
const LLUUID SND_ ("ff144533-33ab-40f2-bac8-39c34699ecc4");
|
||||
const LLUUID SND_ ("09018e87-d52c-4cd5-9805-015f413319e7");
|
||||
const LLUUID SND_ ("17d4c057-7edd-401e-9589-d5b9fe981bf2");
|
||||
#endif
|
||||
|
||||
@@ -39,9 +39,9 @@
|
||||
class LLUUID;
|
||||
|
||||
extern const LLUUID SND_NULL;
|
||||
extern LLUUID const SND_RIDE;
|
||||
extern LLUUID const SND_SHOT;
|
||||
extern LLUUID const SND_MORTAR;
|
||||
extern const LLUUID SND_RIDE;
|
||||
extern const LLUUID SND_SHOT;
|
||||
extern const LLUUID SND_MORTAR;
|
||||
extern const LLUUID SND_HIT;
|
||||
extern const LLUUID SND_EXPLOSION;
|
||||
extern const LLUUID SND_BOING;
|
||||
@@ -58,237 +58,238 @@ extern const LLUUID SND_CHIRPDEAD; // Hit by grenade - dead!
|
||||
|
||||
extern const LLUUID SND_MUNCH;
|
||||
extern const LLUUID SND_PUNCH;
|
||||
extern LLUUID const SND_SPLASH;
|
||||
extern LLUUID const SND_CLICK;
|
||||
extern LLUUID const SND_WHISTLE;
|
||||
extern LLUUID const SND_TYPING;
|
||||
extern const LLUUID SND_SPLASH;
|
||||
extern const LLUUID SND_CLICK;
|
||||
extern const LLUUID SND_WHISTLE;
|
||||
extern const LLUUID SND_TYPING;
|
||||
|
||||
extern LLUUID const SND_ARROW_SHOT;
|
||||
extern LLUUID const SND_ARROW_THUD;
|
||||
extern LLUUID const SND_LASER_SHOT;
|
||||
extern LLUUID const SND_JET_THRUST;
|
||||
extern const LLUUID SND_ARROW_SHOT;
|
||||
extern const LLUUID SND_ARROW_THUD;
|
||||
extern const LLUUID SND_LASER_SHOT;
|
||||
extern const LLUUID SND_JET_THRUST;
|
||||
|
||||
extern LLUUID const SND_SILENCE;
|
||||
extern LLUUID const SND_BUBBLES;
|
||||
extern LLUUID const SND_WELCOME;
|
||||
extern LLUUID const SND_SQUISH;
|
||||
extern LLUUID const SND_SUBPOD;
|
||||
extern LLUUID const SND_FOOTSTEPS;
|
||||
extern LLUUID const SND_STEP_LEFT;
|
||||
extern LLUUID const SND_STEP_RIGHT;
|
||||
extern const LLUUID SND_SILENCE;
|
||||
extern const LLUUID SND_BUBBLES;
|
||||
extern const LLUUID SND_WELCOME;
|
||||
extern const LLUUID SND_SQUISH;
|
||||
extern const LLUUID SND_SUBPOD;
|
||||
extern const LLUUID SND_FOOTSTEPS;
|
||||
extern const LLUUID SND_STEP_LEFT;
|
||||
extern const LLUUID SND_STEP_RIGHT;
|
||||
|
||||
extern LLUUID const SND_BALL_COLLISION;
|
||||
extern const LLUUID SND_BALL_COLLISION;
|
||||
|
||||
extern LLUUID const SND_OOOH_SCARE_ME;
|
||||
extern LLUUID const SND_PAYBACK_TIME;
|
||||
extern LLUUID const SND_READY_FOR_BATTLE;
|
||||
extern const LLUUID SND_OOOH_SCARE_ME;
|
||||
extern const LLUUID SND_PAYBACK_TIME;
|
||||
extern const LLUUID SND_READY_FOR_BATTLE;
|
||||
|
||||
extern LLUUID const SND_FLESH_FLESH;
|
||||
extern LLUUID const SND_FLESH_PLASTIC;
|
||||
extern LLUUID const SND_FLESH_RUBBER;
|
||||
extern LLUUID const SND_GLASS_FLESH;
|
||||
extern LLUUID const SND_GLASS_GLASS;
|
||||
extern LLUUID const SND_GLASS_PLASTIC;
|
||||
extern LLUUID const SND_GLASS_RUBBER;
|
||||
extern LLUUID const SND_GLASS_WOOD;
|
||||
extern LLUUID const SND_METAL_FLESH;
|
||||
extern LLUUID const SND_METAL_GLASS;
|
||||
extern LLUUID const SND_METAL_METAL;
|
||||
extern LLUUID const SND_METAL_PLASTIC;
|
||||
extern LLUUID const SND_METAL_RUBBER;
|
||||
extern LLUUID const SND_METAL_WOOD;
|
||||
extern LLUUID const SND_PLASTIC_PLASTIC;
|
||||
extern LLUUID const SND_RUBBER_PLASTIC;
|
||||
extern LLUUID const SND_RUBBER_RUBBER;
|
||||
extern LLUUID const SND_STONE_FLESH;
|
||||
extern LLUUID const SND_STONE_GLASS;
|
||||
extern LLUUID const SND_STONE_METAL;
|
||||
extern LLUUID const SND_STONE_PLASTIC;
|
||||
extern LLUUID const SND_STONE_RUBBER;
|
||||
extern LLUUID const SND_STONE_STONE;
|
||||
extern LLUUID const SND_STONE_WOOD;
|
||||
extern LLUUID const SND_WOOD_FLESH;
|
||||
extern LLUUID const SND_WOOD_PLASTIC;
|
||||
extern LLUUID const SND_WOOD_RUBBER;
|
||||
extern LLUUID const SND_WOOD_WOOD;
|
||||
|
||||
extern LLUUID const SND_SLIDE_FLESH_FLESH;
|
||||
extern LLUUID const SND_SLIDE_FLESH_PLASTIC;
|
||||
extern LLUUID const SND_SLIDE_FLESH_RUBBER;
|
||||
extern LLUUID const SND_SLIDE_FLESH_FABRIC;
|
||||
extern LLUUID const SND_SLIDE_FLESH_GRAVEL;
|
||||
extern LLUUID const SND_SLIDE_FLESH_GRAVEL_02;
|
||||
extern LLUUID const SND_SLIDE_FLESH_GRAVEL_03;
|
||||
extern LLUUID const SND_SLIDE_GLASS_GRAVEL;
|
||||
extern LLUUID const SND_SLIDE_GLASS_GRAVEL_02;
|
||||
extern LLUUID const SND_SLIDE_GLASS_GRAVEL_03;
|
||||
extern LLUUID const SND_SLIDE_GLASS_FLESH;
|
||||
extern LLUUID const SND_SLIDE_GLASS_GLASS;
|
||||
extern LLUUID const SND_SLIDE_GLASS_PLASTIC;
|
||||
extern LLUUID const SND_SLIDE_GLASS_RUBBER;
|
||||
extern LLUUID const SND_SLIDE_GLASS_WOOD;
|
||||
extern LLUUID const SND_SLIDE_METAL_FABRIC;
|
||||
extern LLUUID const SND_SLIDE_METAL_FLESH;
|
||||
extern LLUUID const SND_SLIDE_METAL_FLESH_02;
|
||||
extern LLUUID const SND_SLIDE_METAL_GLASS;
|
||||
extern LLUUID const SND_SLIDE_METAL_GLASS_02;
|
||||
extern LLUUID const SND_SLIDE_METAL_GLASS_03;
|
||||
extern LLUUID const SND_SLIDE_METAL_GLASS_04;
|
||||
extern LLUUID const SND_SLIDE_METAL_GRAVEL;
|
||||
extern LLUUID const SND_SLIDE_METAL_GRAVEL_02;
|
||||
extern LLUUID const SND_SLIDE_METAL_METAL;
|
||||
extern LLUUID const SND_SLIDE_METAL_METAL_02;
|
||||
extern LLUUID const SND_SLIDE_METAL_METAL_03;
|
||||
extern LLUUID const SND_SLIDE_METAL_METAL_04;
|
||||
extern LLUUID const SND_SLIDE_METAL_METAL_05;
|
||||
extern LLUUID const SND_SLIDE_METAL_METAL_06;
|
||||
extern LLUUID const SND_SLIDE_METAL_PLASTIC;
|
||||
extern LLUUID const SND_SLIDE_METAL_RUBBER;
|
||||
extern LLUUID const SND_SLIDE_METAL_WOOD;
|
||||
extern LLUUID const SND_SLIDE_METAL_WOOD_02;
|
||||
extern LLUUID const SND_SLIDE_METAL_WOOD_03;
|
||||
extern LLUUID const SND_SLIDE_METAL_WOOD_04;
|
||||
extern LLUUID const SND_SLIDE_METAL_WOOD_05;
|
||||
extern LLUUID const SND_SLIDE_METAL_WOOD_06;
|
||||
extern LLUUID const SND_SLIDE_METAL_WOOD_07;
|
||||
extern LLUUID const SND_SLIDE_METAL_WOOD_08;
|
||||
extern LLUUID const SND_SLIDE_PLASTIC_GRAVEL;
|
||||
extern LLUUID const SND_SLIDE_PLASTIC_GRAVEL_02;
|
||||
extern LLUUID const SND_SLIDE_PLASTIC_GRAVEL_03;
|
||||
extern LLUUID const SND_SLIDE_PLASTIC_GRAVEL_04;
|
||||
extern LLUUID const SND_SLIDE_PLASTIC_GRAVEL_05;
|
||||
extern LLUUID const SND_SLIDE_PLASTIC_GRAVEL_06;
|
||||
extern LLUUID const SND_SLIDE_PLASTIC_PLASTIC;
|
||||
extern LLUUID const SND_SLIDE_PLASTIC_PLASTIC_02;
|
||||
extern LLUUID const SND_SLIDE_PLASTIC_PLASTIC_03;
|
||||
extern LLUUID const SND_SLIDE_PLASTIC_FABRIC;
|
||||
extern LLUUID const SND_SLIDE_PLASTIC_FABRIC_02;
|
||||
extern LLUUID const SND_SLIDE_PLASTIC_FABRIC_03;
|
||||
extern LLUUID const SND_SLIDE_PLASTIC_FABRIC_04;
|
||||
extern LLUUID const SND_SLIDE_RUBBER_PLASTIC;
|
||||
extern LLUUID const SND_SLIDE_RUBBER_PLASTIC_02;
|
||||
extern LLUUID const SND_SLIDE_RUBBER_PLASTIC_03;
|
||||
extern LLUUID const SND_SLIDE_RUBBER_RUBBER;
|
||||
extern LLUUID const SND_SLIDE_STONE_FLESH;
|
||||
extern LLUUID const SND_SLIDE_STONE_GLASS;
|
||||
extern LLUUID const SND_SLIDE_STONE_METAL;
|
||||
extern LLUUID const SND_SLIDE_STONE_PLASTIC;
|
||||
extern LLUUID const SND_SLIDE_STONE_PLASTIC_02;
|
||||
extern LLUUID const SND_SLIDE_STONE_PLASTIC_03;
|
||||
extern LLUUID const SND_SLIDE_STONE_RUBBER;
|
||||
extern LLUUID const SND_SLIDE_STONE_RUBBER_02;
|
||||
extern LLUUID const SND_SLIDE_STONE_STONE;
|
||||
extern LLUUID const SND_SLIDE_STONE_STONE_02;
|
||||
extern LLUUID const SND_SLIDE_STONE_WOOD;
|
||||
extern LLUUID const SND_SLIDE_STONE_WOOD_02;
|
||||
extern LLUUID const SND_SLIDE_STONE_WOOD_03;
|
||||
extern LLUUID const SND_SLIDE_STONE_WOOD_04;
|
||||
extern LLUUID const SND_SLIDE_WOOD_FABRIC;
|
||||
extern LLUUID const SND_SLIDE_WOOD_FABRIC_02;
|
||||
extern LLUUID const SND_SLIDE_WOOD_FABRIC_03;
|
||||
extern LLUUID const SND_SLIDE_WOOD_FABRIC_04;
|
||||
extern LLUUID const SND_SLIDE_WOOD_FLESH;
|
||||
extern LLUUID const SND_SLIDE_WOOD_FLESH_02;
|
||||
extern LLUUID const SND_SLIDE_WOOD_FLESH_03;
|
||||
extern LLUUID const SND_SLIDE_WOOD_FLESH_04;
|
||||
extern LLUUID const SND_SLIDE_WOOD_GRAVEL;
|
||||
extern LLUUID const SND_SLIDE_WOOD_GRAVEL_02;
|
||||
extern LLUUID const SND_SLIDE_WOOD_GRAVEL_03;
|
||||
extern LLUUID const SND_SLIDE_WOOD_GRAVEL_04;
|
||||
extern LLUUID const SND_SLIDE_WOOD_PLASTIC;
|
||||
extern LLUUID const SND_SLIDE_WOOD_PLASTIC_02;
|
||||
extern LLUUID const SND_SLIDE_WOOD_PLASTIC_03;
|
||||
extern LLUUID const SND_SLIDE_WOOD_RUBBER;
|
||||
extern LLUUID const SND_SLIDE_WOOD_WOOD;
|
||||
extern LLUUID const SND_SLIDE_WOOD_WOOD_02;
|
||||
extern LLUUID const SND_SLIDE_WOOD_WOOD_03;
|
||||
extern LLUUID const SND_SLIDE_WOOD_WOOD_04;
|
||||
extern LLUUID const SND_SLIDE_WOOD_WOOD_05;
|
||||
extern LLUUID const SND_SLIDE_WOOD_WOOD_06;
|
||||
extern LLUUID const SND_SLIDE_WOOD_WOOD_07;
|
||||
extern LLUUID const SND_SLIDE_WOOD_WOOD_08;
|
||||
extern const LLUUID SND_FLESH_FLESH;
|
||||
extern const LLUUID SND_FLESH_PLASTIC;
|
||||
extern const LLUUID SND_FLESH_RUBBER;
|
||||
extern const LLUUID SND_GLASS_FLESH;
|
||||
extern const LLUUID SND_GLASS_GLASS;
|
||||
extern const LLUUID SND_GLASS_PLASTIC;
|
||||
extern const LLUUID SND_GLASS_RUBBER;
|
||||
extern const LLUUID SND_GLASS_WOOD;
|
||||
extern const LLUUID SND_METAL_FLESH;
|
||||
extern const LLUUID SND_METAL_GLASS;
|
||||
extern const LLUUID SND_METAL_METAL;
|
||||
extern const LLUUID SND_METAL_PLASTIC;
|
||||
extern const LLUUID SND_METAL_RUBBER;
|
||||
extern const LLUUID SND_METAL_WOOD;
|
||||
extern const LLUUID SND_PLASTIC_PLASTIC;
|
||||
extern const LLUUID SND_RUBBER_PLASTIC;
|
||||
extern const LLUUID SND_RUBBER_RUBBER;
|
||||
extern const LLUUID SND_STONE_FLESH;
|
||||
extern const LLUUID SND_STONE_GLASS;
|
||||
extern const LLUUID SND_STONE_METAL;
|
||||
extern const LLUUID SND_STONE_PLASTIC;
|
||||
extern const LLUUID SND_STONE_RUBBER;
|
||||
extern const LLUUID SND_STONE_STONE;
|
||||
extern const LLUUID SND_STONE_WOOD;
|
||||
extern const LLUUID SND_WOOD_FLESH;
|
||||
extern const LLUUID SND_WOOD_PLASTIC;
|
||||
extern const LLUUID SND_WOOD_RUBBER;
|
||||
extern const LLUUID SND_WOOD_WOOD;
|
||||
|
||||
|
||||
extern LLUUID const SND_ROLL_FLESH_FLESH;
|
||||
extern LLUUID const SND_ROLL_FLESH_PLASTIC;
|
||||
extern LLUUID const SND_ROLL_FLESH_PLASTIC_02;
|
||||
extern LLUUID const SND_ROLL_FLESH_RUBBER;
|
||||
extern LLUUID const SND_ROLL_GLASS_GRAVEL;
|
||||
extern LLUUID const SND_ROLL_GLASS_GRAVEL_02;
|
||||
extern LLUUID const SND_ROLL_GLASS_FLESH;
|
||||
extern LLUUID const SND_ROLL_GLASS_GLASS;
|
||||
extern LLUUID const SND_ROLL_GLASS_PLASTIC;
|
||||
extern LLUUID const SND_ROLL_GLASS_RUBBER;
|
||||
extern LLUUID const SND_ROLL_GLASS_WOOD;
|
||||
extern LLUUID const SND_ROLL_GLASS_WOOD_02;
|
||||
extern LLUUID const SND_ROLL_GRAVEL_GRAVEL;
|
||||
extern LLUUID const SND_ROLL_GRAVEL_GRAVEL_02;
|
||||
extern LLUUID const SND_ROLL_METAL_FABRIC;
|
||||
extern LLUUID const SND_ROLL_METAL_FABRIC_02;
|
||||
extern LLUUID const SND_ROLL_METAL_FLESH;
|
||||
extern LLUUID const SND_ROLL_METAL_GLASS;
|
||||
extern LLUUID const SND_ROLL_METAL_GLASS_02;
|
||||
extern LLUUID const SND_ROLL_METAL_GLASS_03;
|
||||
extern LLUUID const SND_ROLL_METAL_GRAVEL;
|
||||
extern LLUUID const SND_ROLL_METAL_METAL;
|
||||
extern LLUUID const SND_ROLL_METAL_METAL_02;
|
||||
extern LLUUID const SND_ROLL_METAL_METAL_03;
|
||||
extern LLUUID const SND_ROLL_METAL_METAL_04;
|
||||
extern LLUUID const SND_ROLL_METAL_PLASTIC;
|
||||
extern LLUUID const SND_ROLL_METAL_PLASTIC_01;
|
||||
extern LLUUID const SND_ROLL_METAL_RUBBER;
|
||||
extern LLUUID const SND_ROLL_METAL_WOOD;
|
||||
extern LLUUID const SND_ROLL_METAL_WOOD_02;
|
||||
extern LLUUID const SND_ROLL_METAL_WOOD_03;
|
||||
extern LLUUID const SND_ROLL_METAL_WOOD_04;
|
||||
extern LLUUID const SND_ROLL_METAL_WOOD_05;
|
||||
extern LLUUID const SND_ROLL_PLASTIC_FABRIC;
|
||||
extern LLUUID const SND_ROLL_PLASTIC_PLASTIC;
|
||||
extern LLUUID const SND_ROLL_PLASTIC_PLASTIC_02;
|
||||
extern LLUUID const SND_ROLL_RUBBER_PLASTIC;
|
||||
extern LLUUID const SND_ROLL_RUBBER_RUBBER;
|
||||
extern LLUUID const SND_ROLL_STONE_FLESH;
|
||||
extern LLUUID const SND_ROLL_STONE_GLASS;
|
||||
extern LLUUID const SND_ROLL_STONE_METAL;
|
||||
extern LLUUID const SND_ROLL_STONE_PLASTIC;
|
||||
extern LLUUID const SND_ROLL_STONE_RUBBER;
|
||||
extern LLUUID const SND_ROLL_STONE_STONE;
|
||||
extern LLUUID const SND_ROLL_STONE_STONE_02;
|
||||
extern LLUUID const SND_ROLL_STONE_STONE_03;
|
||||
extern LLUUID const SND_ROLL_STONE_STONE_04;
|
||||
extern LLUUID const SND_ROLL_STONE_STONE_05;
|
||||
extern LLUUID const SND_ROLL_STONE_WOOD;
|
||||
extern LLUUID const SND_ROLL_STONE_WOOD_02;
|
||||
extern LLUUID const SND_ROLL_STONE_WOOD_03;
|
||||
extern LLUUID const SND_ROLL_STONE_WOOD_04;
|
||||
extern LLUUID const SND_ROLL_WOOD_FLESH;
|
||||
extern LLUUID const SND_ROLL_WOOD_FLESH_02;
|
||||
extern LLUUID const SND_ROLL_WOOD_FLESH_03;
|
||||
extern LLUUID const SND_ROLL_WOOD_FLESH_04;
|
||||
extern LLUUID const SND_ROLL_WOOD_GRAVEL;
|
||||
extern LLUUID const SND_ROLL_WOOD_GRAVEL_02;
|
||||
extern LLUUID const SND_ROLL_WOOD_GRAVEL_03;
|
||||
extern LLUUID const SND_ROLL_WOOD_PLASTIC;
|
||||
extern LLUUID const SND_ROLL_WOOD_PLASTIC_02;
|
||||
extern LLUUID const SND_ROLL_WOOD_RUBBER;
|
||||
extern LLUUID const SND_ROLL_WOOD_WOOD;
|
||||
extern LLUUID const SND_ROLL_WOOD_WOOD_02;
|
||||
extern LLUUID const SND_ROLL_WOOD_WOOD_03;
|
||||
extern LLUUID const SND_ROLL_WOOD_WOOD_04;
|
||||
extern LLUUID const SND_ROLL_WOOD_WOOD_05;
|
||||
extern LLUUID const SND_ROLL_WOOD_WOOD_06;
|
||||
extern LLUUID const SND_ROLL_WOOD_WOOD_07;
|
||||
extern LLUUID const SND_ROLL_WOOD_WOOD_08;
|
||||
extern LLUUID const SND_ROLL_WOOD_WOOD_09;
|
||||
extern const LLUUID SND_SLIDE_FLESH_FLESH;
|
||||
extern const LLUUID SND_SLIDE_FLESH_PLASTIC;
|
||||
extern const LLUUID SND_SLIDE_FLESH_RUBBER;
|
||||
extern const LLUUID SND_SLIDE_FLESH_FABRIC;
|
||||
extern const LLUUID SND_SLIDE_FLESH_GRAVEL;
|
||||
extern const LLUUID SND_SLIDE_FLESH_GRAVEL_02;
|
||||
extern const LLUUID SND_SLIDE_FLESH_GRAVEL_03;
|
||||
extern const LLUUID SND_SLIDE_GLASS_GRAVEL;
|
||||
extern const LLUUID SND_SLIDE_GLASS_GRAVEL_02;
|
||||
extern const LLUUID SND_SLIDE_GLASS_GRAVEL_03;
|
||||
extern const LLUUID SND_SLIDE_GLASS_FLESH;
|
||||
extern const LLUUID SND_SLIDE_GLASS_GLASS;
|
||||
extern const LLUUID SND_SLIDE_GLASS_PLASTIC;
|
||||
extern const LLUUID SND_SLIDE_GLASS_RUBBER;
|
||||
extern const LLUUID SND_SLIDE_GLASS_WOOD;
|
||||
extern const LLUUID SND_SLIDE_METAL_FABRIC;
|
||||
extern const LLUUID SND_SLIDE_METAL_FLESH;
|
||||
extern const LLUUID SND_SLIDE_METAL_FLESH_02;
|
||||
extern const LLUUID SND_SLIDE_METAL_GLASS;
|
||||
extern const LLUUID SND_SLIDE_METAL_GLASS_02;
|
||||
extern const LLUUID SND_SLIDE_METAL_GLASS_03;
|
||||
extern const LLUUID SND_SLIDE_METAL_GLASS_04;
|
||||
extern const LLUUID SND_SLIDE_METAL_GRAVEL;
|
||||
extern const LLUUID SND_SLIDE_METAL_GRAVEL_02;
|
||||
extern const LLUUID SND_SLIDE_METAL_METAL;
|
||||
extern const LLUUID SND_SLIDE_METAL_METAL_02;
|
||||
extern const LLUUID SND_SLIDE_METAL_METAL_03;
|
||||
extern const LLUUID SND_SLIDE_METAL_METAL_04;
|
||||
extern const LLUUID SND_SLIDE_METAL_METAL_05;
|
||||
extern const LLUUID SND_SLIDE_METAL_METAL_06;
|
||||
extern const LLUUID SND_SLIDE_METAL_PLASTIC;
|
||||
extern const LLUUID SND_SLIDE_METAL_RUBBER;
|
||||
extern const LLUUID SND_SLIDE_METAL_WOOD;
|
||||
extern const LLUUID SND_SLIDE_METAL_WOOD_02;
|
||||
extern const LLUUID SND_SLIDE_METAL_WOOD_03;
|
||||
extern const LLUUID SND_SLIDE_METAL_WOOD_04;
|
||||
extern const LLUUID SND_SLIDE_METAL_WOOD_05;
|
||||
extern const LLUUID SND_SLIDE_METAL_WOOD_06;
|
||||
extern const LLUUID SND_SLIDE_METAL_WOOD_07;
|
||||
extern const LLUUID SND_SLIDE_METAL_WOOD_08;
|
||||
extern const LLUUID SND_SLIDE_PLASTIC_GRAVEL;
|
||||
extern const LLUUID SND_SLIDE_PLASTIC_GRAVEL_02;
|
||||
extern const LLUUID SND_SLIDE_PLASTIC_GRAVEL_03;
|
||||
extern const LLUUID SND_SLIDE_PLASTIC_GRAVEL_04;
|
||||
extern const LLUUID SND_SLIDE_PLASTIC_GRAVEL_05;
|
||||
extern const LLUUID SND_SLIDE_PLASTIC_GRAVEL_06;
|
||||
extern const LLUUID SND_SLIDE_PLASTIC_PLASTIC;
|
||||
extern const LLUUID SND_SLIDE_PLASTIC_PLASTIC_02;
|
||||
extern const LLUUID SND_SLIDE_PLASTIC_PLASTIC_03;
|
||||
extern const LLUUID SND_SLIDE_PLASTIC_FABRIC;
|
||||
extern const LLUUID SND_SLIDE_PLASTIC_FABRIC_02;
|
||||
extern const LLUUID SND_SLIDE_PLASTIC_FABRIC_03;
|
||||
extern const LLUUID SND_SLIDE_PLASTIC_FABRIC_04;
|
||||
extern const LLUUID SND_SLIDE_RUBBER_PLASTIC;
|
||||
extern const LLUUID SND_SLIDE_RUBBER_PLASTIC_02;
|
||||
extern const LLUUID SND_SLIDE_RUBBER_PLASTIC_03;
|
||||
extern const LLUUID SND_SLIDE_RUBBER_RUBBER;
|
||||
extern const LLUUID SND_SLIDE_STONE_FLESH;
|
||||
extern const LLUUID SND_SLIDE_STONE_GLASS;
|
||||
extern const LLUUID SND_SLIDE_STONE_METAL;
|
||||
extern const LLUUID SND_SLIDE_STONE_PLASTIC;
|
||||
extern const LLUUID SND_SLIDE_STONE_PLASTIC_02;
|
||||
extern const LLUUID SND_SLIDE_STONE_PLASTIC_03;
|
||||
extern const LLUUID SND_SLIDE_STONE_RUBBER;
|
||||
extern const LLUUID SND_SLIDE_STONE_RUBBER_02;
|
||||
extern const LLUUID SND_SLIDE_STONE_STONE;
|
||||
extern const LLUUID SND_SLIDE_STONE_STONE_02;
|
||||
extern const LLUUID SND_SLIDE_STONE_WOOD;
|
||||
extern const LLUUID SND_SLIDE_STONE_WOOD_02;
|
||||
extern const LLUUID SND_SLIDE_STONE_WOOD_03;
|
||||
extern const LLUUID SND_SLIDE_STONE_WOOD_04;
|
||||
extern const LLUUID SND_SLIDE_WOOD_FABRIC;
|
||||
extern const LLUUID SND_SLIDE_WOOD_FABRIC_02;
|
||||
extern const LLUUID SND_SLIDE_WOOD_FABRIC_03;
|
||||
extern const LLUUID SND_SLIDE_WOOD_FABRIC_04;
|
||||
extern const LLUUID SND_SLIDE_WOOD_FLESH;
|
||||
extern const LLUUID SND_SLIDE_WOOD_FLESH_02;
|
||||
extern const LLUUID SND_SLIDE_WOOD_FLESH_03;
|
||||
extern const LLUUID SND_SLIDE_WOOD_FLESH_04;
|
||||
extern const LLUUID SND_SLIDE_WOOD_GRAVEL;
|
||||
extern const LLUUID SND_SLIDE_WOOD_GRAVEL_02;
|
||||
extern const LLUUID SND_SLIDE_WOOD_GRAVEL_03;
|
||||
extern const LLUUID SND_SLIDE_WOOD_GRAVEL_04;
|
||||
extern const LLUUID SND_SLIDE_WOOD_PLASTIC;
|
||||
extern const LLUUID SND_SLIDE_WOOD_PLASTIC_02;
|
||||
extern const LLUUID SND_SLIDE_WOOD_PLASTIC_03;
|
||||
extern const LLUUID SND_SLIDE_WOOD_RUBBER;
|
||||
extern const LLUUID SND_SLIDE_WOOD_WOOD;
|
||||
extern const LLUUID SND_SLIDE_WOOD_WOOD_02;
|
||||
extern const LLUUID SND_SLIDE_WOOD_WOOD_03;
|
||||
extern const LLUUID SND_SLIDE_WOOD_WOOD_04;
|
||||
extern const LLUUID SND_SLIDE_WOOD_WOOD_05;
|
||||
extern const LLUUID SND_SLIDE_WOOD_WOOD_06;
|
||||
extern const LLUUID SND_SLIDE_WOOD_WOOD_07;
|
||||
extern const LLUUID SND_SLIDE_WOOD_WOOD_08;
|
||||
|
||||
extern LLUUID const SND_SLIDE_STONE_STONE_01;
|
||||
|
||||
extern LLUUID const SND_STONE_DIRT_01;
|
||||
extern LLUUID const SND_STONE_DIRT_02;
|
||||
extern LLUUID const SND_STONE_DIRT_03;
|
||||
extern LLUUID const SND_STONE_DIRT_04;
|
||||
extern const LLUUID SND_ROLL_FLESH_FLESH;
|
||||
extern const LLUUID SND_ROLL_FLESH_PLASTIC;
|
||||
extern const LLUUID SND_ROLL_FLESH_PLASTIC_02;
|
||||
extern const LLUUID SND_ROLL_FLESH_RUBBER;
|
||||
extern const LLUUID SND_ROLL_GLASS_GRAVEL;
|
||||
extern const LLUUID SND_ROLL_GLASS_GRAVEL_02;
|
||||
extern const LLUUID SND_ROLL_GLASS_FLESH;
|
||||
extern const LLUUID SND_ROLL_GLASS_GLASS;
|
||||
extern const LLUUID SND_ROLL_GLASS_PLASTIC;
|
||||
extern const LLUUID SND_ROLL_GLASS_RUBBER;
|
||||
extern const LLUUID SND_ROLL_GLASS_WOOD;
|
||||
extern const LLUUID SND_ROLL_GLASS_WOOD_02;
|
||||
extern const LLUUID SND_ROLL_GRAVEL_GRAVEL;
|
||||
extern const LLUUID SND_ROLL_GRAVEL_GRAVEL_02;
|
||||
extern const LLUUID SND_ROLL_METAL_FABRIC;
|
||||
extern const LLUUID SND_ROLL_METAL_FABRIC_02;
|
||||
extern const LLUUID SND_ROLL_METAL_FLESH;
|
||||
extern const LLUUID SND_ROLL_METAL_GLASS;
|
||||
extern const LLUUID SND_ROLL_METAL_GLASS_02;
|
||||
extern const LLUUID SND_ROLL_METAL_GLASS_03;
|
||||
extern const LLUUID SND_ROLL_METAL_GRAVEL;
|
||||
extern const LLUUID SND_ROLL_METAL_METAL;
|
||||
extern const LLUUID SND_ROLL_METAL_METAL_02;
|
||||
extern const LLUUID SND_ROLL_METAL_METAL_03;
|
||||
extern const LLUUID SND_ROLL_METAL_METAL_04;
|
||||
extern const LLUUID SND_ROLL_METAL_PLASTIC;
|
||||
extern const LLUUID SND_ROLL_METAL_PLASTIC_01;
|
||||
extern const LLUUID SND_ROLL_METAL_RUBBER;
|
||||
extern const LLUUID SND_ROLL_METAL_WOOD;
|
||||
extern const LLUUID SND_ROLL_METAL_WOOD_02;
|
||||
extern const LLUUID SND_ROLL_METAL_WOOD_03;
|
||||
extern const LLUUID SND_ROLL_METAL_WOOD_04;
|
||||
extern const LLUUID SND_ROLL_METAL_WOOD_05;
|
||||
extern const LLUUID SND_ROLL_PLASTIC_FABRIC;
|
||||
extern const LLUUID SND_ROLL_PLASTIC_PLASTIC;
|
||||
extern const LLUUID SND_ROLL_PLASTIC_PLASTIC_02;
|
||||
extern const LLUUID SND_ROLL_RUBBER_PLASTIC;
|
||||
extern const LLUUID SND_ROLL_RUBBER_RUBBER;
|
||||
extern const LLUUID SND_ROLL_STONE_FLESH;
|
||||
extern const LLUUID SND_ROLL_STONE_GLASS;
|
||||
extern const LLUUID SND_ROLL_STONE_METAL;
|
||||
extern const LLUUID SND_ROLL_STONE_PLASTIC;
|
||||
extern const LLUUID SND_ROLL_STONE_RUBBER;
|
||||
extern const LLUUID SND_ROLL_STONE_STONE;
|
||||
extern const LLUUID SND_ROLL_STONE_STONE_02;
|
||||
extern const LLUUID SND_ROLL_STONE_STONE_03;
|
||||
extern const LLUUID SND_ROLL_STONE_STONE_04;
|
||||
extern const LLUUID SND_ROLL_STONE_STONE_05;
|
||||
extern const LLUUID SND_ROLL_STONE_WOOD;
|
||||
extern const LLUUID SND_ROLL_STONE_WOOD_02;
|
||||
extern const LLUUID SND_ROLL_STONE_WOOD_03;
|
||||
extern const LLUUID SND_ROLL_STONE_WOOD_04;
|
||||
extern const LLUUID SND_ROLL_WOOD_FLESH;
|
||||
extern const LLUUID SND_ROLL_WOOD_FLESH_02;
|
||||
extern const LLUUID SND_ROLL_WOOD_FLESH_03;
|
||||
extern const LLUUID SND_ROLL_WOOD_FLESH_04;
|
||||
extern const LLUUID SND_ROLL_WOOD_GRAVEL;
|
||||
extern const LLUUID SND_ROLL_WOOD_GRAVEL_02;
|
||||
extern const LLUUID SND_ROLL_WOOD_GRAVEL_03;
|
||||
extern const LLUUID SND_ROLL_WOOD_PLASTIC;
|
||||
extern const LLUUID SND_ROLL_WOOD_PLASTIC_02;
|
||||
extern const LLUUID SND_ROLL_WOOD_RUBBER;
|
||||
extern const LLUUID SND_ROLL_WOOD_WOOD;
|
||||
extern const LLUUID SND_ROLL_WOOD_WOOD_02;
|
||||
extern const LLUUID SND_ROLL_WOOD_WOOD_03;
|
||||
extern const LLUUID SND_ROLL_WOOD_WOOD_04;
|
||||
extern const LLUUID SND_ROLL_WOOD_WOOD_05;
|
||||
extern const LLUUID SND_ROLL_WOOD_WOOD_06;
|
||||
extern const LLUUID SND_ROLL_WOOD_WOOD_07;
|
||||
extern const LLUUID SND_ROLL_WOOD_WOOD_08;
|
||||
extern const LLUUID SND_ROLL_WOOD_WOOD_09;
|
||||
|
||||
extern LLUUID const SND_STONE_STONE_02;
|
||||
extern LLUUID const SND_STONE_STONE_04;
|
||||
extern const LLUUID SND_SLIDE_STONE_STONE_01;
|
||||
|
||||
extern const LLUUID SND_STONE_DIRT_01;
|
||||
extern const LLUUID SND_STONE_DIRT_02;
|
||||
extern const LLUUID SND_STONE_DIRT_03;
|
||||
extern const LLUUID SND_STONE_DIRT_04;
|
||||
|
||||
extern const LLUUID SND_STONE_STONE_02;
|
||||
extern const LLUUID SND_STONE_STONE_04;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1236,12 +1236,12 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name)
|
||||
S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name)
|
||||
{
|
||||
return(unpackTEMessage(mesgsys,block_name,-1));
|
||||
}
|
||||
|
||||
S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, const S32 block_num)
|
||||
S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num)
|
||||
{
|
||||
// use a negative block_num to indicate a single-block read (a non-variable block)
|
||||
S32 retval = 0;
|
||||
@@ -1515,6 +1515,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size)
|
||||
return (size == 16);
|
||||
case PARAMS_SCULPT:
|
||||
return (size == 17);
|
||||
case PARAMS_LIGHT_IMAGE:
|
||||
return (size == 28);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
@@ -1847,3 +1849,78 @@ bool LLSculptParams::fromLLSD(LLSD& sd)
|
||||
return false;
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
LLLightImageParams::LLLightImageParams()
|
||||
{
|
||||
mType = PARAMS_LIGHT_IMAGE;
|
||||
mParams.setVec(F_PI*0.5f, 0.f, 0.f);
|
||||
}
|
||||
|
||||
BOOL LLLightImageParams::pack(LLDataPacker &dp) const
|
||||
{
|
||||
dp.packUUID(mLightTexture, "texture");
|
||||
dp.packVector3(mParams, "params");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL LLLightImageParams::unpack(LLDataPacker &dp)
|
||||
{
|
||||
dp.unpackUUID(mLightTexture, "texture");
|
||||
dp.unpackVector3(mParams, "params");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
bool LLLightImageParams::operator==(const LLNetworkData& data) const
|
||||
{
|
||||
if (data.mType != PARAMS_LIGHT_IMAGE)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const LLLightImageParams *param = (const LLLightImageParams*)&data;
|
||||
if ( (param->mLightTexture != mLightTexture) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( (param->mParams != mParams ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void LLLightImageParams::copy(const LLNetworkData& data)
|
||||
{
|
||||
const LLLightImageParams *param = (LLLightImageParams*)&data;
|
||||
mLightTexture = param->mLightTexture;
|
||||
mParams = param->mParams;
|
||||
}
|
||||
|
||||
|
||||
|
||||
LLSD LLLightImageParams::asLLSD() const
|
||||
{
|
||||
LLSD sd;
|
||||
|
||||
sd["texture"] = mLightTexture;
|
||||
sd["params"] = mParams.getValue();
|
||||
|
||||
return sd;
|
||||
}
|
||||
|
||||
bool LLLightImageParams::fromLLSD(LLSD& sd)
|
||||
{
|
||||
if (sd.has("texture"))
|
||||
{
|
||||
setLightTexture( sd["texture"] );
|
||||
setParams( LLVector3( sd["params"] ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -107,7 +107,8 @@ public:
|
||||
{
|
||||
PARAMS_FLEXIBLE = 0x10,
|
||||
PARAMS_LIGHT = 0x20,
|
||||
PARAMS_SCULPT = 0x30
|
||||
PARAMS_SCULPT = 0x30,
|
||||
PARAMS_LIGHT_IMAGE = 0x40,
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -267,6 +268,29 @@ public:
|
||||
U8 getSculptType() const { return mSculptType; }
|
||||
};
|
||||
|
||||
class LLLightImageParams : public LLNetworkData
|
||||
{
|
||||
protected:
|
||||
LLUUID mLightTexture;
|
||||
LLVector3 mParams;
|
||||
|
||||
public:
|
||||
LLLightImageParams();
|
||||
/*virtual*/ BOOL pack(LLDataPacker &dp) const;
|
||||
/*virtual*/ BOOL unpack(LLDataPacker &dp);
|
||||
/*virtual*/ bool operator==(const LLNetworkData& data) const;
|
||||
/*virtual*/ void copy(const LLNetworkData& data);
|
||||
LLSD asLLSD() const;
|
||||
operator LLSD() const { return asLLSD(); }
|
||||
bool fromLLSD(LLSD& sd);
|
||||
|
||||
void setLightTexture(const LLUUID& id) { mLightTexture = id; }
|
||||
LLUUID getLightTexture() const { return mLightTexture; }
|
||||
bool isLightSpotlight() const { return mLightTexture.notNull(); }
|
||||
void setParams(const LLVector3& params) { mParams = params; }
|
||||
LLVector3 getParams() const { return mParams; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
class LLPrimitive : public LLXform
|
||||
@@ -340,8 +364,8 @@ public:
|
||||
S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type);
|
||||
BOOL packTEMessage(LLMessageSystem *mesgsys, int shield = 0, std::string client_str = "") const;
|
||||
BOOL packTEMessage(LLDataPacker &dp) const;
|
||||
S32 unpackTEMessage(LLMessageSystem *mesgsys, char *block_name);
|
||||
S32 unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, const S32 block_num); // Variable num of blocks
|
||||
S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name);
|
||||
S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks
|
||||
BOOL unpackTEMessage(LLDataPacker &dp);
|
||||
|
||||
#ifdef CHECK_FOR_FINITE
|
||||
|
||||
@@ -100,7 +100,7 @@ bool LLVolumeMessage::packProfileParams(
|
||||
bool LLVolumeMessage::unpackProfileParams(
|
||||
LLProfileParams* params,
|
||||
LLMessageSystem* mesgsys,
|
||||
char* block_name,
|
||||
char const* block_name,
|
||||
S32 block_num)
|
||||
{
|
||||
bool ok = true;
|
||||
@@ -328,7 +328,7 @@ bool LLVolumeMessage::packPathParams(
|
||||
bool LLVolumeMessage::unpackPathParams(
|
||||
LLPathParams* params,
|
||||
LLMessageSystem* mesgsys,
|
||||
char* block_name,
|
||||
char const* block_name,
|
||||
S32 block_num)
|
||||
{
|
||||
U8 curve;
|
||||
@@ -528,7 +528,7 @@ bool LLVolumeMessage::packVolumeParams(const LLVolumeParams* params, LLDataPacke
|
||||
bool LLVolumeMessage::unpackVolumeParams(
|
||||
LLVolumeParams* params,
|
||||
LLMessageSystem* mesgsys,
|
||||
char* block_name,
|
||||
char const* block_name,
|
||||
S32 block_num)
|
||||
{
|
||||
bool ok = true;
|
||||
|
||||
@@ -55,7 +55,7 @@ protected:
|
||||
static bool unpackProfileParams(
|
||||
LLProfileParams* params,
|
||||
LLMessageSystem* mesgsys,
|
||||
char* block_name,
|
||||
char const* block_name,
|
||||
S32 block_num = 0);
|
||||
static bool unpackProfileParams(LLProfileParams* params, LLDataPacker& dp);
|
||||
|
||||
@@ -66,7 +66,7 @@ protected:
|
||||
static bool unpackPathParams(
|
||||
LLPathParams* params,
|
||||
LLMessageSystem* mesgsys,
|
||||
char* block_name,
|
||||
char const* block_name,
|
||||
S32 block_num = 0);
|
||||
static bool unpackPathParams(LLPathParams* params, LLDataPacker& dp);
|
||||
|
||||
@@ -89,7 +89,7 @@ public:
|
||||
static bool unpackVolumeParams(
|
||||
LLVolumeParams* params,
|
||||
LLMessageSystem* mesgsys,
|
||||
char* block_name,
|
||||
char const* block_name,
|
||||
S32 block_num = 0);
|
||||
static bool unpackVolumeParams(LLVolumeParams* params, LLDataPacker &dp);
|
||||
};
|
||||
|
||||
@@ -45,10 +45,12 @@
|
||||
#include "llrender.h"
|
||||
|
||||
#include "llerror.h"
|
||||
#include "llerrorcontrol.h"
|
||||
#include "llquaternion.h"
|
||||
#include "llmath.h"
|
||||
#include "m4math.h"
|
||||
#include "llstring.h"
|
||||
#include "llstacktrace.h"
|
||||
|
||||
#include "llglheaders.h"
|
||||
|
||||
@@ -56,15 +58,53 @@
|
||||
//#define GL_STATE_VERIFY
|
||||
#endif
|
||||
|
||||
|
||||
BOOL gDebugSession = FALSE;
|
||||
BOOL gDebugGL = FALSE;
|
||||
BOOL gClothRipple = FALSE;
|
||||
BOOL gNoRender = FALSE;
|
||||
BOOL gGLActive = FALSE;
|
||||
|
||||
std::ofstream gFailLog;
|
||||
|
||||
void ll_init_fail_log(std::string filename)
|
||||
{
|
||||
gFailLog.open(filename.c_str());
|
||||
}
|
||||
|
||||
|
||||
void ll_fail(std::string msg)
|
||||
{
|
||||
|
||||
if (gDebugSession)
|
||||
{
|
||||
std::vector<std::string> lines;
|
||||
|
||||
gFailLog << LLError::utcTime() << " " << msg << std::endl;
|
||||
|
||||
gFailLog << "Stack Trace:" << std::endl;
|
||||
|
||||
ll_get_stack_trace(lines);
|
||||
|
||||
for(size_t i = 0; i < lines.size(); ++i)
|
||||
{
|
||||
gFailLog << lines[i] << std::endl;
|
||||
}
|
||||
|
||||
gFailLog << "End of Stack Trace." << std::endl << std::endl;
|
||||
|
||||
gFailLog.flush();
|
||||
}
|
||||
};
|
||||
|
||||
void ll_close_fail_log()
|
||||
{
|
||||
gFailLog.close();
|
||||
}
|
||||
LLMatrix4 gGLObliqueProjectionInverse;
|
||||
|
||||
#define LL_GL_NAME_POOLING 0
|
||||
|
||||
LLGLNamePool::pool_list_t LLGLNamePool::sInstances;
|
||||
std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
|
||||
|
||||
#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
|
||||
@@ -134,12 +174,9 @@ PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT = NULL;
|
||||
PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT = NULL;
|
||||
PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT = NULL;
|
||||
PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT = NULL;
|
||||
|
||||
// GL_EXT_framebuffer_multisample
|
||||
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT = NULL;
|
||||
|
||||
// GL_EXT_framebuffer_blit
|
||||
PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT = NULL;
|
||||
PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT = NULL;
|
||||
PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glFramebufferTextureLayerEXT = NULL;
|
||||
|
||||
// GL_EXT_blend_func_separate
|
||||
PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT = NULL;
|
||||
@@ -278,6 +315,8 @@ LLGLManager::LLGLManager() :
|
||||
mIsDisabled(FALSE),
|
||||
|
||||
mHasMultitexture(FALSE),
|
||||
mHasATIMemInfo(FALSE),
|
||||
mHasNVXMemInfo(FALSE),
|
||||
mNumTextureUnits(1),
|
||||
mHasMipMapGeneration(FALSE),
|
||||
mHasCompressedTextures(FALSE),
|
||||
@@ -290,7 +329,9 @@ LLGLManager::LLGLManager() :
|
||||
mHasShaderObjects(FALSE),
|
||||
mHasVertexShader(FALSE),
|
||||
mHasFragmentShader(FALSE),
|
||||
mNumTextureImageUnits(0),
|
||||
mHasOcclusionQuery(FALSE),
|
||||
mHasOcclusionQuery2(FALSE),
|
||||
mHasPointParameters(FALSE),
|
||||
mHasDrawBuffers(FALSE),
|
||||
mHasTextureRectangle(FALSE),
|
||||
@@ -460,6 +501,20 @@ bool LLGLManager::initGL()
|
||||
// This is called here because it depends on the setting of mIsGF2or4MX, and sets up mHasMultitexture.
|
||||
initExtensions();
|
||||
|
||||
if (mHasATIMemInfo)
|
||||
{ //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;
|
||||
}
|
||||
else if (mHasNVXMemInfo)
|
||||
{
|
||||
S32 dedicated_memory;
|
||||
glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated_memory);
|
||||
mVRAM = dedicated_memory/1024;
|
||||
}
|
||||
|
||||
if (mHasMultitexture)
|
||||
{
|
||||
GLint num_tex_units;
|
||||
@@ -479,6 +534,12 @@ bool LLGLManager::initGL()
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mHasFragmentShader)
|
||||
{
|
||||
GLint num_tex_image_units;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units);
|
||||
mNumTextureImageUnits = num_tex_image_units;
|
||||
}
|
||||
|
||||
initGLStates();
|
||||
return true;
|
||||
@@ -504,14 +565,13 @@ void LLGLManager::getGLInfo(LLSD& info)
|
||||
std::string LLGLManager::getGLInfoString()
|
||||
{
|
||||
std::string info_str;
|
||||
std::string all_exts, line;
|
||||
|
||||
info_str += std::string("GL_VENDOR ") + ll_safe_string((const char *)glGetString(GL_VENDOR)) + std::string("\n");
|
||||
info_str += std::string("GL_RENDERER ") + ll_safe_string((const char *)glGetString(GL_RENDERER)) + std::string("\n");
|
||||
info_str += std::string("GL_VERSION ") + ll_safe_string((const char *)glGetString(GL_VERSION)) + std::string("\n");
|
||||
|
||||
#if !LL_MESA_HEADLESS
|
||||
all_exts = (const char *)gGLHExts.mSysExts;
|
||||
std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
|
||||
LLStringUtil::replaceChar(all_exts, ' ', '\n');
|
||||
info_str += std::string("GL_EXTENSIONS:\n") + all_exts + std::string("\n");
|
||||
#endif
|
||||
@@ -522,14 +582,13 @@ std::string LLGLManager::getGLInfoString()
|
||||
void LLGLManager::printGLInfoString()
|
||||
{
|
||||
std::string info_str;
|
||||
std::string all_exts, line;
|
||||
|
||||
LL_INFOS("RenderInit") << "GL_VENDOR: " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_RENDERER: " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
|
||||
LL_INFOS("RenderInit") << "GL_VERSION: " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL;
|
||||
|
||||
#if !LL_MESA_HEADLESS
|
||||
all_exts = std::string(gGLHExts.mSysExts);
|
||||
std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
|
||||
LLStringUtil::replaceChar(all_exts, ' ', '\n');
|
||||
LL_DEBUGS("RenderInit") << "GL_EXTENSIONS:\n" << all_exts << LL_ENDL;
|
||||
#endif
|
||||
@@ -615,6 +674,8 @@ void LLGLManager::initExtensions()
|
||||
mHasTextureRectangle = FALSE;
|
||||
#else // LL_MESA_HEADLESS
|
||||
mHasMultitexture = glh_init_extensions("GL_ARB_multitexture");
|
||||
mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts);
|
||||
mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts);
|
||||
mHasMipMapGeneration = glh_init_extensions("GL_SGIS_generate_mipmap");
|
||||
mHasSeparateSpecularColor = glh_init_extensions("GL_EXT_separate_specular_color");
|
||||
mHasAnisotropic = glh_init_extensions("GL_EXT_texture_filter_anisotropic");
|
||||
@@ -623,11 +684,18 @@ void LLGLManager::initExtensions()
|
||||
mHasARBEnvCombine = ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts);
|
||||
mHasCompressedTextures = glh_init_extensions("GL_ARB_texture_compression");
|
||||
mHasOcclusionQuery = ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts);
|
||||
mHasOcclusionQuery2 = ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts);
|
||||
mHasVertexBufferObject = ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts);
|
||||
mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts);
|
||||
// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
|
||||
mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts)
|
||||
&& ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
|
||||
// mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad
|
||||
#ifdef GL_ARB_framebuffer_object
|
||||
mHasFramebufferObject = ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts);
|
||||
#else
|
||||
mHasFramebufferObject = ExtensionExists("GL_EXT_framebuffer_object", gGLHExts.mSysExts) &&
|
||||
ExtensionExists("GL_EXT_framebuffer_blit", gGLHExts.mSysExts) &&
|
||||
ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts) &&
|
||||
ExtensionExists("GL_EXT_packed_depth_stencil", gGLHExts.mSysExts);
|
||||
#endif
|
||||
mHasFramebufferMultisample = mHasFramebufferObject && ExtensionExists("GL_EXT_framebuffer_multisample", gGLHExts.mSysExts);
|
||||
mHasDrawBuffers = ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts);
|
||||
mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts);
|
||||
@@ -741,6 +809,10 @@ void LLGLManager::initExtensions()
|
||||
{
|
||||
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query" << LL_ENDL;
|
||||
}
|
||||
if (!mHasOcclusionQuery2)
|
||||
{
|
||||
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query2" << LL_ENDL;
|
||||
}
|
||||
if (!mHasPointParameters)
|
||||
{
|
||||
LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL;
|
||||
@@ -827,11 +899,9 @@ void LLGLManager::initExtensions()
|
||||
glFramebufferRenderbufferEXT = (PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferRenderbufferEXT");
|
||||
glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameterivEXT");
|
||||
glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenerateMipmapEXT");
|
||||
}
|
||||
if (mHasFramebufferMultisample)
|
||||
{
|
||||
glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorageMultisampleEXT");
|
||||
glBlitFramebufferEXT = (PFNGLBLITFRAMEBUFFEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glBlitFramebufferEXT");
|
||||
glRenderbufferStorageMultisampleEXT = (PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glRenderbufferStorageMultisampleEXT");
|
||||
glFramebufferTextureLayerEXT = (PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) GLH_EXT_GET_PROC_ADDRESS("glFramebufferTextureLayerEXT");
|
||||
}
|
||||
if (mHasDrawBuffers)
|
||||
{
|
||||
@@ -1003,12 +1073,35 @@ void flush_glerror()
|
||||
glGetError();
|
||||
}
|
||||
|
||||
void assert_glerror()
|
||||
//this function outputs gl error to the log file, does not crash the code.
|
||||
void log_glerror()
|
||||
{
|
||||
if (gNoRender || !gDebugGL)
|
||||
if (LL_UNLIKELY(!gGLManager.mInited))
|
||||
{
|
||||
return;
|
||||
return ;
|
||||
}
|
||||
// Create or update texture to be used with this data
|
||||
GLenum error;
|
||||
error = glGetError();
|
||||
while (LL_UNLIKELY(error))
|
||||
{
|
||||
GLubyte const * gl_error_msg = gluErrorString(error);
|
||||
if (NULL != gl_error_msg)
|
||||
{
|
||||
llwarns << "GL Error: " << error << " GL Error String: " << gl_error_msg << llendl ;
|
||||
}
|
||||
else
|
||||
{
|
||||
// gluErrorString returns NULL for some extensions' error codes.
|
||||
// you'll probably have to grep for the number in glext.h.
|
||||
llwarns << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << llendl;
|
||||
}
|
||||
error = glGetError();
|
||||
}
|
||||
}
|
||||
|
||||
void do_assert_glerror()
|
||||
{
|
||||
if (LL_UNLIKELY(!gGLManager.mInited))
|
||||
{
|
||||
LL_ERRS("RenderInit") << "GL not initialized" << LL_ENDL;
|
||||
@@ -1020,29 +1113,65 @@ void assert_glerror()
|
||||
while (LL_UNLIKELY(error))
|
||||
{
|
||||
quit = TRUE;
|
||||
#ifndef LL_LINUX // *FIX: ! This should be an error for linux as well.
|
||||
GLubyte const * gl_error_msg = gluErrorString(error);
|
||||
if (NULL != gl_error_msg)
|
||||
{
|
||||
LL_WARNS("RenderState") << "GL Error:" << error<< LL_ENDL;
|
||||
LL_WARNS("RenderState") << "GL Error String:" << gl_error_msg << LL_ENDL;
|
||||
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL Error:" << gl_error_msg << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// gluErrorString returns NULL for some extensions' error codes.
|
||||
// you'll probably have to grep for the number in glext.h.
|
||||
LL_WARNS("RenderState") << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << LL_ENDL;
|
||||
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL Error: UNKNOWN 0x" << std::hex << error << std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
error = glGetError();
|
||||
#endif
|
||||
}
|
||||
|
||||
if (quit)
|
||||
{
|
||||
llerrs << "One or more unhandled GL errors." << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
ll_fail("assert_glerror failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "One or more unhandled GL errors." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void assert_glerror()
|
||||
{
|
||||
if (gNoRender)
|
||||
return;
|
||||
if (!gGLActive)
|
||||
{
|
||||
//llwarns << "GL used while not active!" << llendl;
|
||||
|
||||
if (gDebugSession)
|
||||
{
|
||||
//ll_fail("GL used while not active");
|
||||
}
|
||||
}
|
||||
|
||||
if (gDebugGL)
|
||||
{
|
||||
do_assert_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void clear_glerror()
|
||||
{
|
||||
// Create or update texture to be used with this data
|
||||
@@ -1125,9 +1254,19 @@ void LLGLState::checkStates(const std::string& msg)
|
||||
glGetIntegerv(GL_BLEND_SRC, &src);
|
||||
glGetIntegerv(GL_BLEND_DST, &dst);
|
||||
|
||||
BOOL error = FALSE;
|
||||
|
||||
if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA)
|
||||
{
|
||||
LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << std::endl;
|
||||
error = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL;
|
||||
}
|
||||
}
|
||||
|
||||
for (boost::unordered_map<LLGLenum, LLGLboolean>::iterator iter = sStateMap.begin();
|
||||
@@ -1139,10 +1278,22 @@ void LLGLState::checkStates(const std::string& msg)
|
||||
if(cur_state != gl_state)
|
||||
{
|
||||
dumpStates();
|
||||
LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << llformat("LLGLState error. State: 0x%04x",state) << std::endl;
|
||||
error = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
ll_fail("LLGLState::checkStates failed.");
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
@@ -1153,9 +1304,12 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
||||
return;
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
GLint activeTexture;
|
||||
glGetIntegerv(GL_ACTIVE_TEXTURE_ARB, &activeTexture);
|
||||
|
||||
stop_glerror();
|
||||
|
||||
BOOL error = FALSE;
|
||||
|
||||
if (activeTexture == GL_TEXTURE0_ARB)
|
||||
@@ -1163,15 +1317,22 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
||||
GLint tex_env_mode = 0;
|
||||
|
||||
glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &tex_env_mode);
|
||||
stop_glerror();
|
||||
|
||||
if (tex_env_mode != GL_MODULATE)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << std::dec << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << std::dec << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GLint maxTextureUnits = 0;
|
||||
glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &maxTextureUnits);
|
||||
stop_glerror();
|
||||
|
||||
static const char* label[] =
|
||||
{
|
||||
@@ -1200,35 +1361,44 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
||||
};
|
||||
|
||||
GLint stackDepth = 0;
|
||||
|
||||
glh::matrix4f mat;
|
||||
glh::matrix4f identity;
|
||||
identity.identity();
|
||||
// LLMatrix4 identity;
|
||||
// LLMatrix4 matrix;
|
||||
|
||||
for (GLint i = 1; i < maxTextureUnits; i++)
|
||||
{
|
||||
gGL.getTexUnit(i)->activate();
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB+i);
|
||||
|
||||
stop_glerror();
|
||||
glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth);
|
||||
stop_glerror();
|
||||
|
||||
if (stackDepth != 1)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL;
|
||||
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture matrix stack corrupted." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
//glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) matrix.mMatrix);
|
||||
glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.m);
|
||||
stop_glerror();
|
||||
|
||||
//if (matrix != identity)
|
||||
if (mat != identity)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture matrix in channel " << i << " corrupt." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (S32 j = (i == 0 ? 1 : 0);
|
||||
j < (gGLManager.mHasTextureRectangle ? 9 : 8); j++)
|
||||
{
|
||||
@@ -1236,24 +1406,42 @@ void LLGLState::checkTextureChannels(const std::string& msg)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture channel " << i << " still has " << label[j] << " enabled." << std::endl;
|
||||
}
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
glGetFloatv(GL_TEXTURE_MATRIX, mat.m);
|
||||
stop_glerror();
|
||||
|
||||
if (mat != identity)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "Texture matrix " << i << " is not identity." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture matrix " << i << " is not identity." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gGL.getTexUnit(0)->activate();
|
||||
glClientActiveTextureARB(GL_TEXTURE0_ARB);
|
||||
stop_glerror();
|
||||
|
||||
if (error)
|
||||
{
|
||||
LL_GL_ERRS << "GL texture state corruption detected. " << msg << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
ll_fail("LLGLState::checkTextureChannels failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_GL_ERRS << "GL texture state corruption detected. " << msg << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1273,6 +1461,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
if (active_texture != GL_TEXTURE0_ARB)
|
||||
{
|
||||
llwarns << "Client active texture corrupted: " << active_texture << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Client active texture corrupted: " << active_texture << std::endl;
|
||||
}
|
||||
error = TRUE;
|
||||
}
|
||||
|
||||
@@ -1280,6 +1472,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
if (active_texture != GL_TEXTURE0_ARB)
|
||||
{
|
||||
llwarns << "Active texture corrupted: " << active_texture << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Active texture corrupted: " << active_texture << std::endl;
|
||||
}
|
||||
error = TRUE;
|
||||
}
|
||||
|
||||
@@ -1316,6 +1512,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL still has " << label[j] << " enabled." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL still has " << label[j] << " enabled." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1324,6 +1524,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL does not have " << label[j] << " enabled." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL does not have " << label[j] << " enabled." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1336,6 +1540,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL still has GL_TEXTURE_COORD_ARRAY enabled on channel 1." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1344,6 +1552,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL does not have GL_TEXTURE_COORD_ARRAY enabled on channel 1." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1353,6 +1565,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL still has GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL still has GL_TEXTURE_2D enabled on channel 1." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1361,6 +1577,10 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL does not have GL_TEXTURE_2D enabled on channel 1." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL does not have GL_TEXTURE_2D enabled on channel 1." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1379,13 +1599,24 @@ void LLGLState::checkClientArrays(const std::string& msg, U32 data_mask)
|
||||
{
|
||||
error = TRUE;
|
||||
LL_WARNS("RenderState") << "GL still has vertex attrib array " << i << " enabled." << LL_ENDL;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "GL still has vertex attrib array " << i << " enabled." << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
if (gDebugSession)
|
||||
{
|
||||
ll_fail("LLGLState::checkClientArrays failed.");
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_GL_ERRS << "GL client array corruption detected. " << msg << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1436,7 +1667,17 @@ LLGLState::~LLGLState()
|
||||
{
|
||||
if (gDebugGL)
|
||||
{
|
||||
if (!gDebugSession)
|
||||
{
|
||||
llassert_always(sStateMap[mState] == glIsEnabled(mState));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sStateMap[mState] != glIsEnabled(mState))
|
||||
{
|
||||
ll_fail("GL enabled state does not match expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mIsEnabled != mWasEnabled)
|
||||
@@ -1620,12 +1861,17 @@ void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor
|
||||
}
|
||||
}
|
||||
|
||||
LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection)
|
||||
LLGLUserClipPlane::LLGLUserClipPlane(const LLPlane& p, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply)
|
||||
{
|
||||
mModelview = modelview;
|
||||
mProjection = projection;
|
||||
mApply = apply;
|
||||
|
||||
setPlane(p.mV[0], p.mV[1], p.mV[2], p.mV[3]);
|
||||
if (mApply)
|
||||
{
|
||||
mModelview = modelview;
|
||||
mProjection = projection;
|
||||
|
||||
setPlane(p[0], p[1], p[2], p[3]);
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
|
||||
@@ -1656,31 +1902,20 @@ void LLGLUserClipPlane::setPlane(F32 a, F32 b, F32 c, F32 d)
|
||||
|
||||
LLGLUserClipPlane::~LLGLUserClipPlane()
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
if (mApply)
|
||||
{
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glPopMatrix();
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
}
|
||||
}
|
||||
|
||||
LLGLNamePool::LLGLNamePool()
|
||||
{
|
||||
}
|
||||
|
||||
void LLGLNamePool::registerPool(LLGLNamePool* pool)
|
||||
{
|
||||
pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), pool);
|
||||
if (iter == sInstances.end())
|
||||
{
|
||||
sInstances.push_back(pool);
|
||||
}
|
||||
}
|
||||
|
||||
LLGLNamePool::~LLGLNamePool()
|
||||
{
|
||||
pool_list_t::iterator iter = std::find(sInstances.begin(), sInstances.end(), this);
|
||||
if (iter != sInstances.end())
|
||||
{
|
||||
sInstances.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLNamePool::upkeep()
|
||||
@@ -1748,20 +1983,22 @@ void LLGLNamePool::release(GLuint name)
|
||||
//static
|
||||
void LLGLNamePool::upkeepPools()
|
||||
{
|
||||
for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
|
||||
tracker_t::LLInstanceTrackerScopedGuard guard;
|
||||
for (tracker_t::instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ++iter)
|
||||
{
|
||||
LLGLNamePool* pool = *iter;
|
||||
pool->upkeep();
|
||||
LLGLNamePool & pool = *iter;
|
||||
pool.upkeep();
|
||||
}
|
||||
}
|
||||
|
||||
//static
|
||||
void LLGLNamePool::cleanupPools()
|
||||
{
|
||||
for (pool_list_t::iterator iter = sInstances.begin(); iter != sInstances.end(); ++iter)
|
||||
tracker_t::LLInstanceTrackerScopedGuard guard;
|
||||
for (tracker_t::instance_iter iter = guard.beginInstances(); iter != guard.endInstances(); ++iter)
|
||||
{
|
||||
LLGLNamePool* pool = *iter;
|
||||
pool->cleanup();
|
||||
LLGLNamePool & pool = *iter;
|
||||
pool.cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1838,17 +2075,26 @@ void LLGLDepthTest::checkState()
|
||||
sWriteEnabled != mask ||
|
||||
sDepthFunc != func)
|
||||
{
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Unexpected depth testing state." << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_GL_ERRS << "Unexpected depth testing state." << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P)
|
||||
|
||||
LLGLSquashToFarClip::LLGLSquashToFarClip(glh::matrix4f P, U32 layer)
|
||||
{
|
||||
|
||||
F32 depth = 0.99999f - 0.0001f * layer;
|
||||
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
P.element(2, i) = P.element(3, i) * 0.99999f;
|
||||
P.element(2, i) = P.element(3, i) * depth;
|
||||
}
|
||||
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#include <string>
|
||||
#include <boost/unordered_map.hpp>
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
#include "llerror.h"
|
||||
#include "v4color.h"
|
||||
@@ -46,14 +46,23 @@
|
||||
#include "v4math.h"
|
||||
#include "llplane.h"
|
||||
#include "llgltypes.h"
|
||||
#include "llinstancetracker.h"
|
||||
|
||||
#include "llglheaders.h"
|
||||
#include "glh/glh_linear.h"
|
||||
|
||||
extern BOOL gDebugGL;
|
||||
extern BOOL gDebugSession;
|
||||
extern std::ofstream gFailLog;
|
||||
|
||||
#define LL_GL_ERRS LL_ERRS("RenderState")
|
||||
|
||||
void ll_init_fail_log(std::string filename);
|
||||
|
||||
void ll_fail(std::string msg);
|
||||
|
||||
void ll_close_fail_log();
|
||||
|
||||
class LLSD;
|
||||
|
||||
// Manage GL extensions...
|
||||
@@ -74,6 +83,8 @@ public:
|
||||
|
||||
// Extensions used by everyone
|
||||
BOOL mHasMultitexture;
|
||||
BOOL mHasATIMemInfo;
|
||||
BOOL mHasNVXMemInfo;
|
||||
S32 mNumTextureUnits;
|
||||
BOOL mHasMipMapGeneration;
|
||||
BOOL mHasCompressedTextures;
|
||||
@@ -87,7 +98,9 @@ public:
|
||||
BOOL mHasShaderObjects;
|
||||
BOOL mHasVertexShader;
|
||||
BOOL mHasFragmentShader;
|
||||
S32 mNumTextureImageUnits;
|
||||
BOOL mHasOcclusionQuery;
|
||||
BOOL mHasOcclusionQuery2;
|
||||
BOOL mHasPointParameters;
|
||||
BOOL mHasDrawBuffers;
|
||||
BOOL mHasDepthClamp;
|
||||
@@ -152,6 +165,7 @@ void rotate_quat(LLQuaternion& rotation);
|
||||
|
||||
void flush_glerror(); // Flush GL errors when we know we're handling them correctly.
|
||||
|
||||
void log_glerror();
|
||||
void assert_glerror();
|
||||
|
||||
void clear_glerror();
|
||||
@@ -292,12 +306,14 @@ class LLGLUserClipPlane
|
||||
{
|
||||
public:
|
||||
|
||||
LLGLUserClipPlane(const LLPlane& plane, const glh::matrix4f& modelview, const glh::matrix4f& projection);
|
||||
LLGLUserClipPlane(const LLPlane& plane, const glh::matrix4f& modelview, const glh::matrix4f& projection, bool apply = true);
|
||||
~LLGLUserClipPlane();
|
||||
|
||||
void setPlane(F32 a, F32 b, F32 c, F32 d);
|
||||
|
||||
private:
|
||||
bool mApply;
|
||||
|
||||
glh::matrix4f mProjection;
|
||||
glh::matrix4f mModelview;
|
||||
};
|
||||
@@ -313,7 +329,7 @@ private:
|
||||
class LLGLSquashToFarClip
|
||||
{
|
||||
public:
|
||||
LLGLSquashToFarClip(glh::matrix4f projection);
|
||||
LLGLSquashToFarClip(glh::matrix4f projection, U32 layer = 0);
|
||||
~LLGLSquashToFarClip();
|
||||
};
|
||||
|
||||
@@ -321,9 +337,11 @@ public:
|
||||
Generic pooling scheme for things which use GL names (used for occlusion queries and vertex buffer objects).
|
||||
Prevents thrashing of GL name caches by avoiding calls to glGenFoo and glDeleteFoo.
|
||||
*/
|
||||
class LLGLNamePool
|
||||
class LLGLNamePool : public LLInstanceTracker<LLGLNamePool>
|
||||
{
|
||||
public:
|
||||
typedef LLInstanceTracker<LLGLNamePool> tracker_t;
|
||||
|
||||
struct NameEntry
|
||||
{
|
||||
GLuint name;
|
||||
@@ -350,13 +368,11 @@ public:
|
||||
GLuint allocate();
|
||||
void release(GLuint name);
|
||||
|
||||
static void registerPool(LLGLNamePool* pool);
|
||||
static void upkeepPools();
|
||||
static void cleanupPools();
|
||||
|
||||
protected:
|
||||
typedef std::vector<LLGLNamePool*> pool_list_t;
|
||||
static pool_list_t sInstances;
|
||||
|
||||
virtual GLuint allocateName() = 0;
|
||||
virtual void releaseName(GLuint name) = 0;
|
||||
@@ -411,4 +427,66 @@ extern BOOL gClothRipple;
|
||||
extern BOOL gNoRender;
|
||||
extern BOOL gGLActive;
|
||||
|
||||
// Deal with changing glext.h definitions for newer SDK versions, specifically
|
||||
// with MAC OSX 10.5 -> 10.6
|
||||
|
||||
|
||||
#ifndef GL_DEPTH_ATTACHMENT
|
||||
#define GL_DEPTH_ATTACHMENT GL_DEPTH_ATTACHMENT_EXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_STENCIL_ATTACHMENT
|
||||
#define GL_STENCIL_ATTACHMENT GL_STENCIL_ATTACHMENT_EXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_FRAMEBUFFER
|
||||
#define GL_FRAMEBUFFER GL_FRAMEBUFFER_EXT
|
||||
#define GL_DRAW_FRAMEBUFFER GL_DRAW_FRAMEBUFFER_EXT
|
||||
#define GL_READ_FRAMEBUFFER GL_READ_FRAMEBUFFER_EXT
|
||||
#define GL_FRAMEBUFFER_COMPLETE GL_FRAMEBUFFER_COMPLETE_EXT
|
||||
#define GL_FRAMEBUFFER_UNSUPPORTED GL_FRAMEBUFFER_UNSUPPORTED_EXT
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT
|
||||
#define GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT
|
||||
#define glGenFramebuffers glGenFramebuffersEXT
|
||||
#define glBindFramebuffer glBindFramebufferEXT
|
||||
#define glCheckFramebufferStatus glCheckFramebufferStatusEXT
|
||||
#define glBlitFramebuffer glBlitFramebufferEXT
|
||||
#define glDeleteFramebuffers glDeleteFramebuffersEXT
|
||||
#define glFramebufferRenderbuffer glFramebufferRenderbufferEXT
|
||||
#define glFramebufferTexture2D glFramebufferTexture2DEXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_RENDERBUFFER
|
||||
#define GL_RENDERBUFFER GL_RENDERBUFFER_EXT
|
||||
#define glGenRenderbuffers glGenRenderbuffersEXT
|
||||
#define glBindRenderbuffer glBindRenderbufferEXT
|
||||
#define glRenderbufferStorage glRenderbufferStorageEXT
|
||||
#define glRenderbufferStorageMultisample glRenderbufferStorageMultisampleEXT
|
||||
#define glDeleteRenderbuffers glDeleteRenderbuffersEXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_COLOR_ATTACHMENT
|
||||
#define GL_COLOR_ATTACHMENT GL_COLOR_ATTACHMENT_EXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_COLOR_ATTACHMENT0
|
||||
#define GL_COLOR_ATTACHMENT0 GL_COLOR_ATTACHMENT0_EXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_COLOR_ATTACHMENT1
|
||||
#define GL_COLOR_ATTACHMENT1 GL_COLOR_ATTACHMENT1_EXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_COLOR_ATTACHMENT2
|
||||
#define GL_COLOR_ATTACHMENT2 GL_COLOR_ATTACHMENT2_EXT
|
||||
#endif
|
||||
|
||||
#ifndef GL_COLOR_ATTACHMENT3
|
||||
#define GL_COLOR_ATTACHMENT3 GL_COLOR_ATTACHMENT3_EXT
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef GL_DEPTH24_STENCIL8
|
||||
#define GL_DEPTH24_STENCIL8 GL_DEPTH24_STENCIL8_EXT
|
||||
#endif
|
||||
#endif // LL_LLGL_H
|
||||
|
||||
@@ -473,17 +473,17 @@ extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT;
|
||||
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
|
||||
extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
|
||||
extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
|
||||
|
||||
// GL_EXT_framebuffer_multisample
|
||||
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
|
||||
|
||||
// GL_EXT_framebuffer_blit
|
||||
extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;
|
||||
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
|
||||
extern PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glFramebufferTextureLayerEXT;
|
||||
|
||||
//GL_ARB_draw_buffers
|
||||
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
|
||||
|
||||
|
||||
#elif LL_WINDOWS
|
||||
//----------------------------------------------------------------------------
|
||||
// LL_WINDOWS
|
||||
|
||||
// windows gl headers depend on things like APIENTRY, so include windows.
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
@@ -672,12 +672,9 @@ extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT;
|
||||
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
|
||||
extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
|
||||
extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
|
||||
|
||||
// GL_EXT_framebuffer_multisample
|
||||
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
|
||||
|
||||
// GL_EXT_framebuffer_blit
|
||||
extern PFNGLBLITFRAMEBUFFEREXTPROC glBlitFramebufferEXT;
|
||||
extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXTPROC glRenderbufferStorageMultisampleEXT;
|
||||
extern PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC glFramebufferTextureLayerEXT;
|
||||
|
||||
//GL_ARB_draw_buffers
|
||||
extern PFNGLDRAWBUFFERSARBPROC glDrawBuffersARB;
|
||||
@@ -720,6 +717,9 @@ extern void glFramebufferRenderbufferEXT(GLenum target, GLenum attachment, GLenu
|
||||
extern void glGetFramebufferAttachmentParameterivEXT(GLenum target, GLenum attachment, GLenum pname, GLint *params) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
|
||||
extern void glGenerateMipmapEXT(GLenum target) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
|
||||
|
||||
#ifndef GL_ARB_framebuffer_object
|
||||
#define glGenerateMipmap glGenerateMipmapEXT
|
||||
#endif
|
||||
// GL_ARB_draw_buffers
|
||||
extern void glDrawBuffersARB(GLsizei n, const GLenum* bufs) AVAILABLE_MAC_OS_X_VERSION_10_4_AND_LATER;
|
||||
|
||||
@@ -842,4 +842,21 @@ extern void glGetBufferPointervARB (GLenum, GLenum, GLvoid* *);
|
||||
#define GL_DEPTH_CLAMP 0x864F
|
||||
#endif
|
||||
|
||||
//GL_NVX_gpu_memory_info constants
|
||||
#ifndef GL_NVX_gpu_memory_info
|
||||
#define GL_NVX_gpu_memory_info
|
||||
#define GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX 0x9047
|
||||
#define GL_GPU_MEMORY_INFO_TOTAL_AVAILABLE_MEMORY_NVX 0x9048
|
||||
#define GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX 0x9049
|
||||
#define GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX 0x904A
|
||||
#define GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX 0x904B
|
||||
#endif
|
||||
|
||||
//GL_ATI_meminfo constants
|
||||
#ifndef GL_ATI_meminfo
|
||||
#define GL_ATI_meminfo
|
||||
#define GL_VBO_FREE_MEMORY_ATI 0x87FB
|
||||
#define GL_TEXTURE_FREE_MEMORY_ATI 0x87FC
|
||||
#define GL_RENDERBUFFER_FREE_MEMORY_ATI 0x87FD
|
||||
#endif
|
||||
#endif // LL_LLGLHEADERS_H
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
#error This file has been renamed llrender.cpp
|
||||
@@ -1 +0,0 @@
|
||||
#error This file has been renamed llrender.h
|
||||
@@ -420,7 +420,15 @@ S32 LLGLSLShader::disableTexture(S32 uniform, LLTexUnit::eTextureType mode)
|
||||
{
|
||||
if (gDebugGL && gGL.getTexUnit(index)->getCurrType() != mode)
|
||||
{
|
||||
llerrs << "Texture channel " << index << " texture type corrupted." << llendl;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Texture channel " << index << " texture type corrupted." << std::endl;
|
||||
ll_fail("LLGLSLShader::disableTexture failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Texture channel " << index << " texture type corrupted." << llendl;
|
||||
}
|
||||
}
|
||||
gGL.getTexUnit(index)->disable();
|
||||
}
|
||||
@@ -708,17 +716,46 @@ void LLGLSLShader::uniformMatrix4fv(U32 index, U32 count, GLboolean transpose, c
|
||||
|
||||
GLint LLGLSLShader::getUniformLocation(const string& uniform)
|
||||
{
|
||||
GLint ret = -1;
|
||||
if (mProgramObject > 0)
|
||||
{
|
||||
std::map<string, GLint>::iterator iter = mUniformMap.find(uniform);
|
||||
if (iter != mUniformMap.end())
|
||||
{
|
||||
llassert(iter->second == glGetUniformLocationARB(mProgramObject, uniform.c_str()));
|
||||
return iter->second;
|
||||
if (gDebugGL)
|
||||
{
|
||||
stop_glerror();
|
||||
if (iter->second != glGetUniformLocationARB(mProgramObject, uniform.c_str()))
|
||||
{
|
||||
llerrs << "Uniform does not match." << llendl;
|
||||
}
|
||||
stop_glerror();
|
||||
}
|
||||
ret = iter->second;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
/*if (gDebugGL)
|
||||
{
|
||||
if (ret == -1 && ret != glGetUniformLocationARB(mProgramObject, uniform.c_str()))
|
||||
{
|
||||
llerrs << "Uniform map invalid." << llendl;
|
||||
}
|
||||
}*/
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
GLint LLGLSLShader::getAttribLocation(U32 attrib)
|
||||
{
|
||||
if (attrib < mAttribute.size())
|
||||
{
|
||||
return mAttribute[attrib];
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void LLGLSLShader::uniform1i(const string& uniform, GLint v)
|
||||
@@ -892,7 +929,9 @@ void LLGLSLShader::uniformMatrix4fv(const string& uniform, U32 count, GLboolean
|
||||
|
||||
if (location >= 0)
|
||||
{
|
||||
stop_glerror();
|
||||
glUniformMatrix4fvARB(location, count, transpose, v);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ public:
|
||||
void vertexAttrib4fv(U32 index, GLfloat* v);
|
||||
|
||||
GLint getUniformLocation(const std::string& uniform);
|
||||
|
||||
GLint getAttribLocation(U32 attrib);
|
||||
GLint mapUniformTextureChannel(GLint location, GLenum type);
|
||||
|
||||
|
||||
|
||||
@@ -262,25 +262,4 @@ public:
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
class LLGLSBlendFunc : public LLGLSPipeline {
|
||||
protected:
|
||||
GLint mSavedSrc, mSavedDst;
|
||||
LLGLEnable mBlend;
|
||||
|
||||
public:
|
||||
LLGLSBlendFunc(GLenum srcFunc, GLenum dstFunc) :
|
||||
mBlend(GL_BLEND)
|
||||
{
|
||||
glGetIntegerv(GL_BLEND_SRC, &mSavedSrc);
|
||||
glGetIntegerv(GL_BLEND_DST, &mSavedDst);
|
||||
glBlendFunc(srcFunc, dstFunc);
|
||||
}
|
||||
|
||||
~LLGLSBlendFunc(void) {
|
||||
glBlendFunc(mSavedSrc, mSavedDst);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -110,24 +110,58 @@ void LLImageGL::checkTexSize(bool forced) const
|
||||
{
|
||||
if ((forced || gDebugGL) && mTarget == GL_TEXTURE_2D)
|
||||
{
|
||||
{
|
||||
//check viewport
|
||||
GLint vp[4] ;
|
||||
glGetIntegerv(GL_VIEWPORT, vp) ;
|
||||
llcallstacks << "viewport: " << vp[0] << " : " << vp[1] << " : " << vp[2] << " : " << vp[3] << llcallstacksendl ;
|
||||
}
|
||||
GLint texname;
|
||||
glGetIntegerv(GL_TEXTURE_BINDING_2D, &texname);
|
||||
BOOL error = FALSE;
|
||||
if (texname != mTexName)
|
||||
{
|
||||
llerrs << "Invalid texture bound!" << llendl;
|
||||
llinfos << "Bound: " << texname << " Should bind: " << mTexName << " Default: " << LLImageGL::sDefaultGLTexture->getTexName() << llendl;
|
||||
|
||||
error = TRUE;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "Invalid texture bound!" << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "Invalid texture bound!" << llendl;
|
||||
}
|
||||
}
|
||||
stop_glerror() ;
|
||||
LLGLint x = 0, y = 0 ;
|
||||
glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_WIDTH, (GLint*)&x);
|
||||
glGetTexLevelParameteriv(mTarget, 0, GL_TEXTURE_HEIGHT, (GLint*)&y) ;
|
||||
stop_glerror() ;
|
||||
llcallstacks << "w: " << x << " h: " << y << llcallstacksendl ;
|
||||
|
||||
if(!x || !y)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
if(x != (mWidth >> mCurrentDiscardLevel) || y != (mHeight >> mCurrentDiscardLevel))
|
||||
{
|
||||
llerrs << "wrong texture size and discard level!" << llendl ;
|
||||
error = TRUE;
|
||||
if (gDebugSession)
|
||||
{
|
||||
gFailLog << "wrong texture size and discard level!" <<
|
||||
mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
llerrs << "wrong texture size and discard level: width: " <<
|
||||
mWidth << " Height: " << mHeight << " Current Level: " << (S32)mCurrentDiscardLevel << llendl ;
|
||||
}
|
||||
}
|
||||
|
||||
if (error)
|
||||
{
|
||||
ll_fail("LLImageGL::checkTexSize failed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -649,7 +683,7 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
|
||||
}
|
||||
|
||||
// LLFastTimer t2(LLFastTimer::FTM_TEMP2);
|
||||
gGL.getTexUnit(0)->bind(this);
|
||||
llverify(gGL.getTexUnit(0)->bind(this));
|
||||
|
||||
if (mUseMipMaps)
|
||||
{
|
||||
@@ -864,12 +898,14 @@ BOOL LLImageGL::setSubImage(const U8* datap, S32 data_width, S32 data_height, S3
|
||||
}
|
||||
if (mTexName == 0)
|
||||
{
|
||||
llwarns << "Setting subimage on image without GL texture" << llendl;
|
||||
// *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
|
||||
//llwarns << "Setting subimage on image without GL texture" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
if (datap == NULL)
|
||||
{
|
||||
llwarns << "Setting subimage on image with NULL datap" << llendl;
|
||||
// *TODO: Re-enable warning? Ran into thread locking issues? DK 2011-02-18
|
||||
//llwarns << "Setting subimage on image with NULL datap" << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@@ -991,6 +1027,7 @@ void LLImageGL::deleteTextures(S32 numTextures, U32 *textures)
|
||||
void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels)
|
||||
{
|
||||
glTexImage2D(target, miplevel, intformat, width, height, 0, pixformat, pixtype, pixels);
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
//create an empty GL texture: just create a texture name
|
||||
@@ -1143,6 +1180,13 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_
|
||||
if (mUseMipMaps)
|
||||
{
|
||||
mAutoGenMips = gGLManager.mHasMipMapGeneration;
|
||||
#if LL_DARWIN
|
||||
// On the Mac GF2 and GF4MX drivers, auto mipmap generation doesn't work right with alpha-only textures.
|
||||
if(gGLManager.mIsGF2or4MX && (mFormatInternal == GL_ALPHA8) && (mFormatPrimary == GL_ALPHA))
|
||||
{
|
||||
mAutoGenMips = FALSE;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
mCurrentDiscardLevel = discard_level;
|
||||
|
||||
@@ -45,10 +45,12 @@ LLRender gGL;
|
||||
// Handy copies of last good GL matrices
|
||||
F64 gGLModelView[16];
|
||||
F64 gGLLastModelView[16];
|
||||
F64 gGLLastProjection[16];
|
||||
F64 gGLProjection[16];
|
||||
S32 gGLViewport[4];
|
||||
|
||||
static const U32 LL_NUM_TEXTURE_LAYERS = 8;
|
||||
static const U32 LL_NUM_LIGHT_UNITS = 8;
|
||||
|
||||
static GLenum sGLTextureType[] =
|
||||
{
|
||||
@@ -118,14 +120,29 @@ void LLTexUnit::refreshState(void)
|
||||
// and we reset the cached tex unit state
|
||||
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
|
||||
|
||||
//
|
||||
// Per apple spec, don't call glEnable/glDisable when index exceeds max texture units
|
||||
// http://www.mailinglistarchive.com/html/mac-opengl@lists.apple.com/2008-07/msg00653.html
|
||||
//
|
||||
bool enableDisable = (mIndex < gGLManager.mNumTextureUnits);
|
||||
|
||||
if (mCurrTexType != TT_NONE)
|
||||
{
|
||||
glEnable(sGLTextureType[mCurrTexType]);
|
||||
if (enableDisable)
|
||||
{
|
||||
glEnable(sGLTextureType[mCurrTexType]);
|
||||
}
|
||||
|
||||
glBindTexture(sGLTextureType[mCurrTexType], mCurrTexture);
|
||||
}
|
||||
else
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if (enableDisable)
|
||||
{
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
}
|
||||
|
||||
@@ -144,7 +161,7 @@ void LLTexUnit::activate(void)
|
||||
{
|
||||
if (mIndex < 0) return;
|
||||
|
||||
if (gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty)
|
||||
if ((S32)gGL.mCurrTextureUnitIndex != mIndex || gGL.mDirty)
|
||||
{
|
||||
glActiveTextureARB(GL_TEXTURE0_ARB + mIndex);
|
||||
gGL.mCurrTextureUnitIndex = mIndex;
|
||||
@@ -163,7 +180,10 @@ void LLTexUnit::enable(eTextureType type)
|
||||
disable(); // Force a disable of a previous texture type if it's enabled.
|
||||
}
|
||||
mCurrTexType = type;
|
||||
glEnable(sGLTextureType[type]);
|
||||
if (mIndex < gGLManager.mNumTextureUnits)
|
||||
{
|
||||
glEnable(sGLTextureType[type]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +195,11 @@ void LLTexUnit::disable(void)
|
||||
{
|
||||
activate();
|
||||
unbind(mCurrTexType);
|
||||
glDisable(sGLTextureType[mCurrTexType]);
|
||||
if (mIndex < gGLManager.mNumTextureUnits)
|
||||
{
|
||||
glDisable(sGLTextureType[mCurrTexType]);
|
||||
}
|
||||
|
||||
mCurrTexType = TT_NONE;
|
||||
}
|
||||
}
|
||||
@@ -729,6 +753,130 @@ void LLTexUnit::debugTextureUnit(void)
|
||||
}
|
||||
}
|
||||
|
||||
LLLightState::LLLightState(S32 index)
|
||||
: mIndex(index),
|
||||
mEnabled(false),
|
||||
mConstantAtten(1.f),
|
||||
mLinearAtten(0.f),
|
||||
mQuadraticAtten(0.f),
|
||||
mSpotExponent(0.f),
|
||||
mSpotCutoff(180.f)
|
||||
{
|
||||
if (mIndex == 0)
|
||||
{
|
||||
mDiffuse.set(1,1,1,1);
|
||||
mSpecular.set(1,1,1,1);
|
||||
}
|
||||
|
||||
mAmbient.set(0,0,0,1);
|
||||
mPosition.set(0,0,1,0);
|
||||
mSpotDirection.set(0,0,-1);
|
||||
|
||||
}
|
||||
|
||||
void LLLightState::enable()
|
||||
{
|
||||
if (!mEnabled)
|
||||
{
|
||||
glEnable(GL_LIGHT0+mIndex);
|
||||
mEnabled = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LLLightState::disable()
|
||||
{
|
||||
if (mEnabled)
|
||||
{
|
||||
glDisable(GL_LIGHT0+mIndex);
|
||||
mEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
void LLLightState::setDiffuse(const LLColor4& diffuse)
|
||||
{
|
||||
if (mDiffuse != diffuse)
|
||||
{
|
||||
mDiffuse = diffuse;
|
||||
glLightfv(GL_LIGHT0+mIndex, GL_DIFFUSE, mDiffuse.mV);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLightState::setAmbient(const LLColor4& ambient)
|
||||
{
|
||||
if (mAmbient != ambient)
|
||||
{
|
||||
mAmbient = ambient;
|
||||
glLightfv(GL_LIGHT0+mIndex, GL_AMBIENT, mAmbient.mV);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLightState::setSpecular(const LLColor4& specular)
|
||||
{
|
||||
if (mSpecular != specular)
|
||||
{
|
||||
mSpecular = specular;
|
||||
glLightfv(GL_LIGHT0+mIndex, GL_SPECULAR, mSpecular.mV);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLightState::setPosition(const LLVector4& position)
|
||||
{
|
||||
//always set position because modelview matrix may have changed
|
||||
mPosition = position;
|
||||
glLightfv(GL_LIGHT0+mIndex, GL_POSITION, mPosition.mV);
|
||||
}
|
||||
|
||||
void LLLightState::setConstantAttenuation(const F32& atten)
|
||||
{
|
||||
if (mConstantAtten != atten)
|
||||
{
|
||||
mConstantAtten = atten;
|
||||
glLightf(GL_LIGHT0+mIndex, GL_CONSTANT_ATTENUATION, atten);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLightState::setLinearAttenuation(const F32& atten)
|
||||
{
|
||||
if (mLinearAtten != atten)
|
||||
{
|
||||
mLinearAtten = atten;
|
||||
glLightf(GL_LIGHT0+mIndex, GL_LINEAR_ATTENUATION, atten);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLightState::setQuadraticAttenuation(const F32& atten)
|
||||
{
|
||||
if (mQuadraticAtten != atten)
|
||||
{
|
||||
mQuadraticAtten = atten;
|
||||
glLightf(GL_LIGHT0+mIndex, GL_QUADRATIC_ATTENUATION, atten);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLightState::setSpotExponent(const F32& exponent)
|
||||
{
|
||||
if (mSpotExponent != exponent)
|
||||
{
|
||||
mSpotExponent = exponent;
|
||||
glLightf(GL_LIGHT0+mIndex, GL_SPOT_EXPONENT, exponent);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLightState::setSpotCutoff(const F32& cutoff)
|
||||
{
|
||||
if (mSpotCutoff != cutoff)
|
||||
{
|
||||
mSpotCutoff = cutoff;
|
||||
glLightf(GL_LIGHT0+mIndex, GL_SPOT_CUTOFF, cutoff);
|
||||
}
|
||||
}
|
||||
|
||||
void LLLightState::setSpotDirection(const LLVector3& direction)
|
||||
{
|
||||
//always set direction because modelview matrix may have changed
|
||||
mSpotDirection = direction;
|
||||
glLightfv(GL_LIGHT0+mIndex, GL_SPOT_DIRECTION, direction.mV);
|
||||
}
|
||||
|
||||
LLRender::LLRender()
|
||||
: mDirty(false),
|
||||
@@ -750,6 +898,11 @@ LLRender::LLRender()
|
||||
}
|
||||
mDummyTexUnit = new LLTexUnit(-1);
|
||||
|
||||
for (U32 i = 0; i < LL_NUM_LIGHT_UNITS; ++i)
|
||||
{
|
||||
mLightState.push_back(new LLLightState(i));
|
||||
}
|
||||
|
||||
for (U32 i = 0; i < 4; i++)
|
||||
{
|
||||
mCurrColorMask[i] = true;
|
||||
@@ -777,6 +930,12 @@ void LLRender::shutdown()
|
||||
mTexUnits.clear();
|
||||
delete mDummyTexUnit;
|
||||
mDummyTexUnit = NULL;
|
||||
|
||||
for (U32 i = 0; i < mLightState.size(); ++i)
|
||||
{
|
||||
delete mLightState[i];
|
||||
}
|
||||
mLightState.clear();
|
||||
}
|
||||
|
||||
void LLRender::refreshState(void)
|
||||
@@ -941,6 +1100,7 @@ void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
|
||||
sGLBlendFactor[alpha_sfactor], sGLBlendFactor[alpha_dfactor]);
|
||||
}
|
||||
}
|
||||
|
||||
LLTexUnit* LLRender::getTexUnit(U32 index)
|
||||
{
|
||||
if ((index >= 0) && (index < mTexUnits.size()))
|
||||
@@ -954,6 +1114,16 @@ LLTexUnit* LLRender::getTexUnit(U32 index)
|
||||
}
|
||||
}
|
||||
|
||||
LLLightState* LLRender::getLight(U32 index)
|
||||
{
|
||||
if (index < mLightState.size())
|
||||
{
|
||||
return mLightState[index];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool LLRender::verifyTexUnitActive(U32 unitToVerify)
|
||||
{
|
||||
if (mCurrTextureUnitIndex == unitToVerify)
|
||||
@@ -1058,6 +1228,34 @@ void LLRender::flush()
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
if (gDebugGL)
|
||||
{
|
||||
if (mMode == LLRender::QUADS)
|
||||
{
|
||||
if (mCount%4 != 0)
|
||||
{
|
||||
llerrs << "Incomplete quad rendered." << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
if (mMode == LLRender::TRIANGLES)
|
||||
{
|
||||
if (mCount%3 != 0)
|
||||
{
|
||||
llerrs << "Incomplete triangle rendered." << llendl;
|
||||
}
|
||||
}
|
||||
|
||||
if (mMode == LLRender::LINES)
|
||||
{
|
||||
if (mCount%2 != 0)
|
||||
{
|
||||
llerrs << "Incomplete line rendered." << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mBuffer->setBuffer(immediate_mask);
|
||||
mBuffer->drawArrays(mMode, 0, mCount);
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
#include "v2math.h"
|
||||
#include "v3math.h"
|
||||
#include "v4coloru.h"
|
||||
#include "v4math.h"
|
||||
#include "llstrider.h"
|
||||
#include "llmemory.h"
|
||||
#include "llglheaders.h"
|
||||
@@ -218,6 +219,40 @@ protected:
|
||||
void setTextureCombiner(eTextureBlendOp op, eTextureBlendSrc src1, eTextureBlendSrc src2, bool isAlpha = false);
|
||||
};
|
||||
|
||||
class LLLightState
|
||||
{
|
||||
public:
|
||||
LLLightState(S32 index);
|
||||
|
||||
void enable();
|
||||
void disable();
|
||||
void setDiffuse(const LLColor4& diffuse);
|
||||
void setAmbient(const LLColor4& ambient);
|
||||
void setSpecular(const LLColor4& specular);
|
||||
void setPosition(const LLVector4& position);
|
||||
void setConstantAttenuation(const F32& atten);
|
||||
void setLinearAttenuation(const F32& atten);
|
||||
void setQuadraticAttenuation(const F32& atten);
|
||||
void setSpotExponent(const F32& exponent);
|
||||
void setSpotCutoff(const F32& cutoff);
|
||||
void setSpotDirection(const LLVector3& direction);
|
||||
|
||||
protected:
|
||||
S32 mIndex;
|
||||
bool mEnabled;
|
||||
LLColor4 mDiffuse;
|
||||
LLColor4 mAmbient;
|
||||
LLColor4 mSpecular;
|
||||
LLVector4 mPosition;
|
||||
LLVector3 mSpotDirection;
|
||||
|
||||
F32 mConstantAtten;
|
||||
F32 mLinearAtten;
|
||||
F32 mQuadraticAtten;
|
||||
|
||||
F32 mSpotExponent;
|
||||
F32 mSpotCutoff;
|
||||
};
|
||||
class LLRender
|
||||
{
|
||||
friend class LLTexUnit;
|
||||
@@ -324,6 +359,8 @@ public:
|
||||
void blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor,
|
||||
eBlendFactor alpha_sfactor, eBlendFactor alpha_dfactor);
|
||||
|
||||
LLLightState* getLight(U32 index);
|
||||
|
||||
LLTexUnit* getTexUnit(U32 index);
|
||||
|
||||
U32 getCurrentTexUnitIndex(void) const { return mCurrTextureUnitIndex; }
|
||||
@@ -358,6 +395,7 @@ private:
|
||||
LLStrider<LLColor4U> mColorsp;
|
||||
std::vector<LLTexUnit*> mTexUnits;
|
||||
LLTexUnit* mDummyTexUnit;
|
||||
std::vector<LLLightState*> mLightState;
|
||||
|
||||
eBlendFactor mCurrBlendColorSFactor;
|
||||
eBlendFactor mCurrBlendColorDFactor;
|
||||
@@ -369,6 +407,7 @@ private:
|
||||
|
||||
extern F64 gGLModelView[16];
|
||||
extern F64 gGLLastModelView[16];
|
||||
extern F64 gGLLastProjection[16];
|
||||
extern F64 gGLProjection[16];
|
||||
extern S32 gGLViewport[4];
|
||||
|
||||
|
||||
@@ -68,45 +68,6 @@ void drawSolidSphere(GLdouble radius, GLint slices, GLint stacks)
|
||||
}
|
||||
|
||||
|
||||
// lat = 0 is Z-axis
|
||||
// lon = 0, lat = 90 at X-axis
|
||||
void lat2xyz(LLVector3 * result, F32 lat, F32 lon)
|
||||
{
|
||||
// Convert a latitude and longitude to x,y,z on a normal sphere and return it in result
|
||||
F32 r;
|
||||
result->mV[VX] = (F32) (cos(lon * DEG_TO_RAD) * sin(lat * DEG_TO_RAD));
|
||||
result->mV[VY] = (F32) (sin(lon * DEG_TO_RAD) * sin(lat * DEG_TO_RAD));
|
||||
r = (F32) pow(result->mV[VX] * result->mV[VX] + result->mV[VY] * result->mV[VY], 0.5f);
|
||||
if (r == 1.0f)
|
||||
{
|
||||
result->mV[VZ] = 0.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
result->mV[VZ] = (F32) pow(1 - r*r, 0.5f);
|
||||
if (lat > 90.01)
|
||||
{
|
||||
result->mV[VZ] *= -1.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void lat2xyz_rad(LLVector3 * result, F32 lat, F32 lon)
|
||||
{
|
||||
// Convert a latitude and longitude to x,y,z on a normal sphere and return it in result
|
||||
F32 r;
|
||||
result->mV[VX] = (F32) (cos(lon) * sin(lat));
|
||||
result->mV[VY] = (F32) (sin(lon) * sin(lat));
|
||||
r = (F32) pow(result->mV[VX] * result->mV[VX] + result->mV[VY] * result->mV[VY], 0.5f);
|
||||
if (r == 1.0f)
|
||||
result->mV[VZ] = 0.0f;
|
||||
else
|
||||
{
|
||||
result->mV[VZ] = (F32) pow(1 - r*r, 0.5f);
|
||||
if (lat > F_PI_BY_TWO) result->mV[VZ] *= -1.0;
|
||||
}
|
||||
}
|
||||
|
||||
// A couple thoughts on sphere drawing:
|
||||
// 1) You need more slices than stacks, but little less than 2:1
|
||||
// 2) At low LOD, setting stacks to an odd number avoids a "band" around the equator, making things look smoother
|
||||
@@ -181,3 +142,50 @@ void LLRenderSphere::render()
|
||||
{
|
||||
glCallList(mDList[0]);
|
||||
}
|
||||
|
||||
inline LLVector3 polar_to_cart(F32 latitude, F32 longitude)
|
||||
{
|
||||
return LLVector3(sin(F_TWO_PI * latitude) * cos(F_TWO_PI * longitude),
|
||||
sin(F_TWO_PI * latitude) * sin(F_TWO_PI * longitude),
|
||||
cos(F_TWO_PI * latitude));
|
||||
}
|
||||
|
||||
|
||||
void LLRenderSphere::renderGGL()
|
||||
{
|
||||
S32 const LATITUDE_SLICES = 20;
|
||||
S32 const LONGITUDE_SLICES = 30;
|
||||
|
||||
if (mSpherePoints.empty())
|
||||
{
|
||||
mSpherePoints.resize(LATITUDE_SLICES + 1);
|
||||
for (S32 lat_i = 0; lat_i < LATITUDE_SLICES + 1; lat_i++)
|
||||
{
|
||||
mSpherePoints[lat_i].resize(LONGITUDE_SLICES + 1);
|
||||
for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES + 1; lon_i++)
|
||||
{
|
||||
F32 lat = (F32)lat_i / LATITUDE_SLICES;
|
||||
F32 lon = (F32)lon_i / LONGITUDE_SLICES;
|
||||
|
||||
mSpherePoints[lat_i][lon_i] = polar_to_cart(lat, lon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gGL.begin(LLRender::TRIANGLES);
|
||||
|
||||
for (S32 lat_i = 0; lat_i < LATITUDE_SLICES; lat_i++)
|
||||
{
|
||||
for (S32 lon_i = 0; lon_i < LONGITUDE_SLICES; lon_i++)
|
||||
{
|
||||
gGL.vertex3fv(mSpherePoints[lat_i][lon_i].mV);
|
||||
gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV);
|
||||
gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV);
|
||||
|
||||
gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i].mV);
|
||||
gGL.vertex3fv(mSpherePoints[lat_i][lon_i+1].mV);
|
||||
gGL.vertex3fv(mSpherePoints[lat_i+1][lon_i+1].mV);
|
||||
}
|
||||
}
|
||||
gGL.end();
|
||||
}
|
||||
|
||||
@@ -52,6 +52,10 @@ public:
|
||||
void cleanupGL();
|
||||
void render(F32 pixel_area); // of a box of size 1.0 at that position
|
||||
void render(); // render at highest LOD
|
||||
void renderGGL(); // render using LLRender
|
||||
|
||||
private:
|
||||
std::vector< std::vector<LLVector3> > mSpherePoints;
|
||||
};
|
||||
|
||||
extern LLRenderSphere gSphere;
|
||||
|
||||
@@ -36,6 +36,9 @@
|
||||
#include "llrender.h"
|
||||
#include "llgl.h"
|
||||
|
||||
LLRenderTarget* LLRenderTarget::sBoundTarget = NULL;
|
||||
|
||||
|
||||
|
||||
void check_framebuffer_status()
|
||||
{
|
||||
@@ -46,16 +49,14 @@ void check_framebuffer_status()
|
||||
{
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
llerrs << "WTF?" << llendl;
|
||||
break;
|
||||
default:
|
||||
llerrs << "WTF?" << llendl;
|
||||
llerrs <<"check_framebuffer_status failed" << llendl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLRenderTarget::sUseFBO = FALSE;
|
||||
bool LLRenderTarget::sUseFBO = false;
|
||||
|
||||
LLRenderTarget::LLRenderTarget() :
|
||||
mResX(0),
|
||||
@@ -64,8 +65,8 @@ LLRenderTarget::LLRenderTarget() :
|
||||
mFBO(0),
|
||||
mDepth(0),
|
||||
mStencil(0),
|
||||
mUseDepth(FALSE),
|
||||
mRenderDepth(FALSE),
|
||||
mUseDepth(false),
|
||||
mRenderDepth(false),
|
||||
mUsage(LLTexUnit::TT_TEXTURE),
|
||||
mSamples(0),
|
||||
mSampleBuffer(NULL)
|
||||
@@ -83,7 +84,7 @@ void LLRenderTarget::setSampleBuffer(LLMultisampleBuffer* buffer)
|
||||
mSampleBuffer = buffer;
|
||||
}
|
||||
|
||||
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo)
|
||||
void LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo)
|
||||
{
|
||||
stop_glerror();
|
||||
mResX = resx;
|
||||
@@ -214,6 +215,16 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
|
||||
llerrs << "Cannot share depth buffer between non FBO render targets." << llendl;
|
||||
}
|
||||
|
||||
if (target.mDepth)
|
||||
{
|
||||
llerrs << "Attempting to override existing depth buffer. Detach existing buffer first." << llendl;
|
||||
}
|
||||
|
||||
if (target.mUseDepth)
|
||||
{
|
||||
llerrs << "Attempting to override existing shared depth buffer. Detach existing buffer first." << llendl;
|
||||
}
|
||||
|
||||
if (mDepth)
|
||||
{
|
||||
stop_glerror();
|
||||
@@ -226,16 +237,12 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
|
||||
stop_glerror();
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);
|
||||
stop_glerror();
|
||||
target.mStencil = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
|
||||
stop_glerror();
|
||||
if (mStencil)
|
||||
{
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), mDepth, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
@@ -245,18 +252,6 @@ void LLRenderTarget::shareDepthBuffer(LLRenderTarget& target)
|
||||
|
||||
void LLRenderTarget::release()
|
||||
{
|
||||
if (mFBO)
|
||||
{
|
||||
glDeleteFramebuffersEXT(1, (GLuint *) &mFBO);
|
||||
mFBO = 0;
|
||||
}
|
||||
|
||||
if (mTex.size() > 0)
|
||||
{
|
||||
LLImageGL::deleteTextures(mTex.size(), &mTex[0]);
|
||||
mTex.clear();
|
||||
}
|
||||
|
||||
if (mDepth)
|
||||
{
|
||||
if (mStencil)
|
||||
@@ -271,8 +266,36 @@ void LLRenderTarget::release()
|
||||
}
|
||||
mDepth = 0;
|
||||
}
|
||||
else if (mUseDepth && mFBO)
|
||||
{ //detach shared depth buffer
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, mFBO);
|
||||
if (mStencil)
|
||||
{ //attached as a renderbuffer
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0);
|
||||
mStencil = false;
|
||||
}
|
||||
else
|
||||
{ //attached as a texture
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, LLTexUnit::getInternalType(mUsage), 0, 0);
|
||||
}
|
||||
mUseDepth = false;
|
||||
}
|
||||
|
||||
if (mFBO)
|
||||
{
|
||||
glDeleteFramebuffersEXT(1, (GLuint *) &mFBO);
|
||||
mFBO = 0;
|
||||
}
|
||||
|
||||
if (mTex.size() > 0)
|
||||
{
|
||||
LLImageGL::deleteTextures(mTex.size(), &mTex[0]);
|
||||
mTex.clear();
|
||||
}
|
||||
|
||||
mSampleBuffer = NULL;
|
||||
sBoundTarget = NULL;
|
||||
}
|
||||
|
||||
void LLRenderTarget::bindTarget()
|
||||
@@ -311,6 +334,7 @@ void LLRenderTarget::bindTarget()
|
||||
}
|
||||
|
||||
glViewport(0, 0, mResX, mResY);
|
||||
sBoundTarget = this;
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -320,6 +344,7 @@ void LLRenderTarget::unbindTarget()
|
||||
{
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
sBoundTarget = NULL;
|
||||
}
|
||||
|
||||
void LLRenderTarget::clear(U32 mask_in)
|
||||
@@ -351,19 +376,19 @@ U32 LLRenderTarget::getTexture(U32 attachment) const
|
||||
{
|
||||
llerrs << "Invalid attachment index." << llendl;
|
||||
}
|
||||
if (mTex.empty())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
return mTex[attachment];
|
||||
}
|
||||
|
||||
void LLRenderTarget::bindTexture(U32 index, S32 channel)
|
||||
{
|
||||
if (index > mTex.size()-1)
|
||||
{
|
||||
llerrs << "Invalid attachment index." << llendl;
|
||||
}
|
||||
gGL.getTexUnit(channel)->bindManual(mUsage, mTex[index]);
|
||||
gGL.getTexUnit(channel)->bindManual(mUsage, getTexture(index));
|
||||
}
|
||||
|
||||
void LLRenderTarget::flush(BOOL fetch_depth)
|
||||
void LLRenderTarget::flush(bool fetch_depth)
|
||||
{
|
||||
gGL.flush();
|
||||
if (!mFBO)
|
||||
@@ -386,7 +411,11 @@ void LLRenderTarget::flush(BOOL fetch_depth)
|
||||
}
|
||||
else
|
||||
{
|
||||
stop_glerror();
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
stop_glerror();
|
||||
|
||||
if (mSampleBuffer)
|
||||
{
|
||||
@@ -439,6 +468,10 @@ void LLRenderTarget::flush(BOOL fetch_depth)
|
||||
void LLRenderTarget::copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
|
||||
S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter)
|
||||
{
|
||||
GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
|
||||
|
||||
LLGLDepthTest depth(write_depth, write_depth);
|
||||
|
||||
gGL.flush();
|
||||
if (!source.mFBO || !mFBO)
|
||||
{
|
||||
@@ -494,6 +527,10 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0
|
||||
llerrs << "Cannot copy framebuffer contents for non FBO render targets." << llendl;
|
||||
}
|
||||
{
|
||||
GLboolean write_depth = mask & GL_DEPTH_BUFFER_BIT ? TRUE : FALSE;
|
||||
|
||||
LLGLDepthTest depth(write_depth, write_depth);
|
||||
|
||||
glBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, source.mSampleBuffer ? source.mSampleBuffer->mFBO : source.mFBO);
|
||||
stop_glerror();
|
||||
glBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, 0);
|
||||
@@ -513,9 +550,9 @@ void LLRenderTarget::copyContentsToFramebuffer(LLRenderTarget& source, S32 srcX0
|
||||
}
|
||||
}
|
||||
|
||||
BOOL LLRenderTarget::isComplete() const
|
||||
bool LLRenderTarget::isComplete() const
|
||||
{
|
||||
return (!mTex.empty() || mDepth) ? TRUE : FALSE;
|
||||
return (!mTex.empty() || mDepth) ? true : false;
|
||||
}
|
||||
|
||||
void LLRenderTarget::getViewport(S32* viewport)
|
||||
@@ -536,10 +573,10 @@ LLMultisampleBuffer::LLMultisampleBuffer()
|
||||
|
||||
LLMultisampleBuffer::~LLMultisampleBuffer()
|
||||
{
|
||||
releaseSampleBuffer();
|
||||
release();
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::releaseSampleBuffer()
|
||||
void LLMultisampleBuffer::release()
|
||||
{
|
||||
if (mFBO)
|
||||
{
|
||||
@@ -586,14 +623,15 @@ void LLMultisampleBuffer::bindTarget(LLRenderTarget* ref)
|
||||
|
||||
glViewport(0, 0, mResX, mResY);
|
||||
|
||||
sBoundTarget = this;
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo )
|
||||
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo )
|
||||
{
|
||||
allocate(resx,resy,color_fmt,depth,stencil,usage,use_fbo,2);
|
||||
}
|
||||
|
||||
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo, U32 samples )
|
||||
void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples )
|
||||
{
|
||||
stop_glerror();
|
||||
mResX = resx;
|
||||
@@ -603,7 +641,7 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth
|
||||
mUseDepth = depth;
|
||||
mStencil = stencil;
|
||||
|
||||
releaseSampleBuffer();
|
||||
release();
|
||||
|
||||
if (!gGLManager.mHasFramebufferMultisample)
|
||||
{
|
||||
@@ -640,11 +678,9 @@ void LLMultisampleBuffer::allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth
|
||||
{
|
||||
glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, mDepth);
|
||||
}
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
|
||||
stop_glerror();
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
stop_glerror();
|
||||
}
|
||||
@@ -683,11 +719,9 @@ void LLMultisampleBuffer::addColorAttachment(U32 color_fmt)
|
||||
{
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
break;
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
llerrs << "WTF?" << llendl;
|
||||
break;
|
||||
default:
|
||||
llerrs << "WTF?" << llendl;
|
||||
llerrs << "WTF? " << std::hex << status << llendl;
|
||||
break;
|
||||
}
|
||||
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
|
||||
@@ -69,7 +69,7 @@ class LLRenderTarget
|
||||
{
|
||||
public:
|
||||
//whether or not to use FBO implementation
|
||||
static BOOL sUseFBO;
|
||||
static bool sUseFBO;
|
||||
|
||||
LLRenderTarget();
|
||||
virtual ~LLRenderTarget();
|
||||
@@ -77,7 +77,7 @@ public:
|
||||
//allocate resources for rendering
|
||||
//must be called before use
|
||||
//multiple calls will release previously allocated resources
|
||||
void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, BOOL use_fbo = FALSE);
|
||||
void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage = LLTexUnit::TT_TEXTURE, bool use_fbo = FALSE);
|
||||
|
||||
//provide this render target with a multisample resource.
|
||||
void setSampleBuffer(LLMultisampleBuffer* buffer);
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
|
||||
//free any allocated resources
|
||||
//safe to call redundantly
|
||||
void release();
|
||||
virtual void release();
|
||||
|
||||
//bind target for rendering
|
||||
//applies appropriate viewport
|
||||
@@ -121,7 +121,7 @@ public:
|
||||
U32 getTexture(U32 attachment = 0) const;
|
||||
|
||||
U32 getDepth(void) const { return mDepth; }
|
||||
BOOL hasStencil() const { return mStencil; }
|
||||
bool hasStencil() const { return mStencil; }
|
||||
|
||||
void bindTexture(U32 index, S32 channel);
|
||||
|
||||
@@ -131,7 +131,7 @@ public:
|
||||
// call bindTarget once, do all your rendering, call flush once
|
||||
// if fetch_depth is TRUE, every effort will be made to copy the depth buffer into
|
||||
// the current depth texture. A depth texture will be allocated if needed.
|
||||
void flush(BOOL fetch_depth = FALSE);
|
||||
void flush(bool fetch_depth = FALSE);
|
||||
|
||||
void copyContents(LLRenderTarget& source, S32 srcX0, S32 srcY0, S32 srcX1, S32 srcY1,
|
||||
S32 dstX0, S32 dstY0, S32 dstX1, S32 dstY1, U32 mask, U32 filter);
|
||||
@@ -142,7 +142,9 @@ public:
|
||||
//Returns TRUE if target is ready to be rendered into.
|
||||
//That is, if the target has been allocated with at least
|
||||
//one renderable attachment (i.e. color buffer, depth buffer).
|
||||
BOOL isComplete() const;
|
||||
bool isComplete() const;
|
||||
|
||||
static LLRenderTarget* getCurrentBoundTarget() { return sBoundTarget; }
|
||||
|
||||
protected:
|
||||
friend class LLMultisampleBuffer;
|
||||
@@ -151,12 +153,14 @@ protected:
|
||||
std::vector<U32> mTex;
|
||||
U32 mFBO;
|
||||
U32 mDepth;
|
||||
BOOL mStencil;
|
||||
BOOL mUseDepth;
|
||||
BOOL mRenderDepth;
|
||||
bool mStencil;
|
||||
bool mUseDepth;
|
||||
bool mRenderDepth;
|
||||
LLTexUnit::eTextureType mUsage;
|
||||
U32 mSamples;
|
||||
LLMultisampleBuffer* mSampleBuffer;
|
||||
|
||||
static LLRenderTarget* sBoundTarget;
|
||||
|
||||
};
|
||||
|
||||
@@ -166,12 +170,12 @@ public:
|
||||
LLMultisampleBuffer();
|
||||
virtual ~LLMultisampleBuffer();
|
||||
|
||||
void releaseSampleBuffer();
|
||||
virtual void release();
|
||||
|
||||
virtual void bindTarget();
|
||||
void bindTarget(LLRenderTarget* ref);
|
||||
virtual void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo);
|
||||
void allocate(U32 resx, U32 resy, U32 color_fmt, BOOL depth, BOOL stencil, LLTexUnit::eTextureType usage, BOOL use_fbo, U32 samples);
|
||||
virtual void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo);
|
||||
void allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, U32 samples);
|
||||
virtual void addColorAttachment(U32 color_fmt);
|
||||
virtual void allocateDepth();
|
||||
};
|
||||
|
||||
@@ -226,7 +226,14 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader)
|
||||
else if (features->isFullbright)
|
||||
{
|
||||
|
||||
if (features->hasWaterFog)
|
||||
if (features->isShiny && features->hasWaterFog)
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightShinyWaterF.glsl"))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else if (features->hasWaterFog)
|
||||
{
|
||||
if (!shader->attachObject("lighting/lightFullbrightWaterF.glsl"))
|
||||
{
|
||||
@@ -306,7 +313,7 @@ void LLShaderMgr::dumpObjectLog(GLhandleARB ret, BOOL warns)
|
||||
}
|
||||
else
|
||||
{
|
||||
LL_DEBUGS("ShaderLoading") << log << LL_ENDL;
|
||||
LL_INFOS("ShaderLoading") << log << LL_ENDL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user