Merge branch 'V2Renderer'

This commit is contained in:
Aleric Inglewood
2011-06-03 22:56:18 +02:00
395 changed files with 16018 additions and 7142 deletions

View File

@@ -673,9 +673,6 @@
<key>FetchInventoryDescendents</key>
<boolean>false</boolean>
<key>WebFetchInventoryDescendents</key>
<boolean>true</boolean>
<key>FetchInventory</key>
<boolean>true</boolean>

View File

@@ -42,6 +42,7 @@ if (WINDOWS)
wldap32
gdi32
user32
dbghelp
)
else (WINDOWS)
set(WINDOWS_LIBRARIES "")

View File

@@ -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++;

View File

@@ -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);

View File

@@ -47,7 +47,6 @@
#include "llquaternion.h"
#include "v3dmath.h"
#include "v3math.h"
#include "llapr.h"
#include "llbvhconsts.h"
class LLKeyframeDataCache;

View File

@@ -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)

View File

@@ -36,12 +36,12 @@
//-----------------------------------------------------------------------------
// Header Files
//-----------------------------------------------------------------------------
#include <string>
#include "llmap.h"
#include "lljointstate.h"
#include "lljoint.h"
#include "llmap.h"
#include <map>
#include <string>
//-----------------------------------------------------------------------------

View File

@@ -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

View File

@@ -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;

View File

@@ -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)

View File

@@ -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:

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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

View File

@@ -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;

View File

@@ -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.

View File

@@ -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

View File

@@ -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

View File

@@ -34,7 +34,7 @@
#ifndef LL_LLERRORLEGACY_H
#define LL_LLERRORLEGACY_H
#include "llpreprocessor.h"
/*
LEGACY -- DO NOT USE THIS STUFF ANYMORE

View File

@@ -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"),

View 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;
}
}
}

View 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

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View 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];
}

View 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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -33,7 +33,7 @@
#include "lllivefile.h"
#include "llframetimer.h"
#include "lltimer.h"
#include "lleventtimer.h"
const F32 DEFAULT_CONFIG_FILE_REFRESH = 5.0f;

View File

@@ -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;

View File

@@ -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:

View File

@@ -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:

View File

@@ -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();

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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.

View File

@@ -38,8 +38,6 @@
#include <vector>
#include <boost/shared_ptr.hpp>
#include "llpreprocessor.h"
class LLRunnable;
/**

View 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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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)
{

View File

@@ -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; }

View File

@@ -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;

View File

@@ -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

View File

@@ -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;
}
}
}

View File

@@ -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 &timestr);
LL_COMMON_API void timeStructToFormattedString(struct tm * time, std::string format, std::string &timestr);
// 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

View File

@@ -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

View File

@@ -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 &center, 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 &center, 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 &center, 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();
}
}

View File

@@ -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 &center, const F32 radius) const;

View File

@@ -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

View File

@@ -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 &center,
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

View File

@@ -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;
}
};

View File

@@ -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"

View File

@@ -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;

View File

@@ -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 &params, 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();
}

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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)

View File

@@ -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();
}

View File

@@ -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

View File

@@ -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 )

View File

@@ -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;

View File

@@ -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()
{

View File

@@ -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;

View File

@@ -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
};

View File

@@ -35,6 +35,7 @@
#include "llsdmessagebuilder.h"
#include "llmessagetemplate.h"
#include "llmath.h"
#include "llquaternion.h"
#include "llsdutil.h"
#include "llsdutil_math.h"

View File

@@ -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);
}

View File

@@ -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:
/**

View File

@@ -35,6 +35,7 @@
#include "lltemplatemessagebuilder.h"
#include "llmessagetemplate.h"
#include "llmath.h"
#include "llquaternion.h"
#include "u64.h"
#include "v3dmath.h"

View File

@@ -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"

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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);
};

View File

@@ -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);

View File

@@ -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

View File

@@ -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

View File

@@ -1 +0,0 @@
#error This file has been renamed llrender.cpp

View File

@@ -1 +0,0 @@
#error This file has been renamed llrender.h

View File

@@ -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();
}
}

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -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);

View File

@@ -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];

View File

@@ -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();
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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();
};

View File

@@ -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