Added Alpha Layer support and Additional Attachments, plus I reverted my
localhost on outgoing log hack and added the original values back in.
This commit is contained in:
@@ -279,7 +279,7 @@ S32 LLPacketRing::receivePacket (S32 socket, char *datap)
|
||||
BOOL LLPacketRing::sendPacket(int h_socket, char * send_buffer, S32 buf_size, LLHost host)
|
||||
{
|
||||
//<edit>
|
||||
LLMessageLog::log(LLHost("127.0.0.1", gMessageSystem->getListenPort()), host, (U8*)send_buffer, buf_size);
|
||||
LLMessageLog::log(LLHost(16777343, gMessageSystem->getListenPort()), host, (U8*)send_buffer, buf_size);
|
||||
//</edit>
|
||||
BOOL status = TRUE;
|
||||
|
||||
|
||||
@@ -799,6 +799,9 @@ void LLRender::setSceneBlendType(eBlendType type)
|
||||
case BT_MULT:
|
||||
glBlendFunc(GL_DST_COLOR, GL_ZERO);
|
||||
break;
|
||||
case BT_MULT_ALPHA:
|
||||
glBlendFunc(GL_DST_ALPHA, GL_ZERO);
|
||||
break;
|
||||
case BT_MULT_X2:
|
||||
glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR);
|
||||
break;
|
||||
|
||||
@@ -252,6 +252,7 @@ public:
|
||||
BT_ADD,
|
||||
BT_ADD_WITH_ALPHA, // Additive blend modulated by the fragment's alpha.
|
||||
BT_MULT,
|
||||
BT_MULT_ALPHA,
|
||||
BT_MULT_X2,
|
||||
BT_REPLACE
|
||||
} eBlendType;
|
||||
|
||||
@@ -11346,6 +11346,28 @@
|
||||
<key>Value</key>
|
||||
<string>5748decc-f629-461c-9a36-a35a221fe21f</string>
|
||||
</map>
|
||||
<key>UIImgDefaultAlphaUUID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string />
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>5748decc-f629-461c-9a36-a35a221fe21f</string>
|
||||
</map>
|
||||
<key>UIImgDefaultAlphaUUID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
<string />
|
||||
<key>Persist</key>
|
||||
<integer>0</integer>
|
||||
<key>Type</key>
|
||||
<string>String</string>
|
||||
<key>Value</key>
|
||||
<string>5748decc-f629-461c-9a36-a35a221fe21f</string>
|
||||
</map>
|
||||
<key>UIImgDefaultUnderwearUUID</key>
|
||||
<map>
|
||||
<key>Comment</key>
|
||||
|
||||
376
indra/newview/character/avatar_lad.xml
Normal file → Executable file
376
indra/newview/character/avatar_lad.xml
Normal file → Executable file
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
|
||||
<?xml version="1.0" encoding="US-ASCII" standalone="yes"?>
|
||||
<linden_avatar
|
||||
version="1.0"
|
||||
wearable_definition_version="22">
|
||||
@@ -393,7 +393,307 @@
|
||||
hud="true"
|
||||
max_attachment_offset="2.0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
|
||||
<attachment_point
|
||||
id="39"
|
||||
group="6"
|
||||
pie_slice="2"
|
||||
name="Chest 2"
|
||||
joint="mChest"
|
||||
position="0.15 0 -0.1"
|
||||
rotation="0 90 90"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="40"
|
||||
group="2"
|
||||
pie_slice="2"
|
||||
name="Skull 2"
|
||||
joint="mHead"
|
||||
position="0 0 0.15"
|
||||
rotation="0 0 90"
|
||||
visible_in_first_person="false" />
|
||||
|
||||
<attachment_point
|
||||
id="41"
|
||||
group="3"
|
||||
pie_slice="3"
|
||||
name="Left Shoulder 2"
|
||||
joint="mCollarLeft"
|
||||
position="0 0 0.08"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="42"
|
||||
group="1"
|
||||
pie_slice="1"
|
||||
name="Right Shoulder 2"
|
||||
joint="mCollarRight"
|
||||
position="0 0 0.08"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true"/>
|
||||
|
||||
<attachment_point
|
||||
id="43"
|
||||
group="4"
|
||||
name="Left Hand 2"
|
||||
joint="mWristLeft"
|
||||
position="0 0.08 -0.02"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true"
|
||||
max_attachment_offset="1.5" />
|
||||
|
||||
<attachment_point
|
||||
id="44"
|
||||
group="0"
|
||||
name="Right Hand 2"
|
||||
joint="mWristRight"
|
||||
position="0 -0.08 -0.02"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true"
|
||||
max_attachment_offset="1.5" />
|
||||
|
||||
<attachment_point
|
||||
id="45"
|
||||
group="5"
|
||||
pie_slice="6"
|
||||
name="Left Foot 2"
|
||||
joint="mFootLeft"
|
||||
position="0 0.0 0.0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true"/>
|
||||
|
||||
<attachment_point
|
||||
id="46"
|
||||
group="7"
|
||||
pie_slice="6"
|
||||
name="Right Foot 2"
|
||||
joint="mFootRight"
|
||||
position="0 0.0 0.0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true"/>
|
||||
|
||||
<attachment_point
|
||||
id="47"
|
||||
group="6"
|
||||
pie_slice="7"
|
||||
name="Spine 2"
|
||||
joint="mChest"
|
||||
position="-0.15 0 -0.1"
|
||||
rotation="0 -90 90"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="48"
|
||||
group="6"
|
||||
pie_slice="6"
|
||||
name="Pelvis 2"
|
||||
joint="mPelvis"
|
||||
position="0 0 -0.15"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="49"
|
||||
group="2"
|
||||
pie_slice="6"
|
||||
name="Mouth 2"
|
||||
joint="mHead"
|
||||
position="0.12 0 0.001"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false"/>
|
||||
|
||||
<attachment_point
|
||||
id="50"
|
||||
group="2"
|
||||
pie_slice="7"
|
||||
name="Chin 2"
|
||||
joint="mHead"
|
||||
position="0.12 0 -0.04"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false" />
|
||||
|
||||
<attachment_point
|
||||
id="51"
|
||||
group="2"
|
||||
pie_slice="4"
|
||||
name="Left Ear 2"
|
||||
joint="mHead"
|
||||
position="0.015 0.08 0.017"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false" />
|
||||
|
||||
<attachment_point
|
||||
id="52"
|
||||
group="2"
|
||||
pie_slice="0"
|
||||
name="Right Ear 2"
|
||||
joint="mHead"
|
||||
position="0.015 -0.08 0.017"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false" />
|
||||
|
||||
<attachment_point
|
||||
id="53"
|
||||
group="2"
|
||||
pie_slice="3"
|
||||
name="Left Eyeball 2"
|
||||
joint="mEyeLeft"
|
||||
position="0 0 0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false"/>
|
||||
|
||||
<attachment_point
|
||||
id="54"
|
||||
group="2"
|
||||
pie_slice="1"
|
||||
name="Right Eyeball 2"
|
||||
joint="mEyeRight"
|
||||
position="0 0 0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false" />
|
||||
|
||||
<attachment_point
|
||||
id="55"
|
||||
group="2"
|
||||
pie_slice="5"
|
||||
name="Nose 2"
|
||||
joint="mHead"
|
||||
position="0.1 0 0.05"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="false"/>
|
||||
|
||||
<attachment_point
|
||||
id="56"
|
||||
group="1"
|
||||
pie_slice="0"
|
||||
name="R Upper Arm 2"
|
||||
joint="mShoulderRight"
|
||||
position="0.01 -0.13 0.01"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="57"
|
||||
group="1"
|
||||
pie_slice="7"
|
||||
name="R Forearm 2"
|
||||
joint="mElbowRight"
|
||||
position="0 -0.12 0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true"/>
|
||||
|
||||
<attachment_point
|
||||
id="58"
|
||||
group="3"
|
||||
pie_slice="4"
|
||||
name="L Upper Arm 2"
|
||||
joint="mShoulderLeft"
|
||||
position="0.01 0.15 -0.01"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="59"
|
||||
group="3"
|
||||
pie_slice="5"
|
||||
name="L Forearm 2"
|
||||
joint="mElbowLeft"
|
||||
position="0 0.113 0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="60"
|
||||
group="7"
|
||||
pie_slice="1"
|
||||
name="Right Hip 2"
|
||||
joint="mHipRight"
|
||||
position="0 0 0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="61"
|
||||
group="7"
|
||||
pie_slice="0"
|
||||
name="R Upper Leg 2"
|
||||
joint="mHipRight"
|
||||
position="-0.017 0.041 -0.310"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="62"
|
||||
group="7"
|
||||
pie_slice="7"
|
||||
name="R Lower Leg 2"
|
||||
joint="mKneeRight"
|
||||
position="-0.044 -0.007 -0.262"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="63"
|
||||
group="5"
|
||||
pie_slice="3"
|
||||
name="Left Hip 2"
|
||||
joint="mHipLeft"
|
||||
position="0 0 0"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="64"
|
||||
group="5"
|
||||
pie_slice="4"
|
||||
name="L Upper Leg 2"
|
||||
joint="mHipLeft"
|
||||
position="-0.019 -0.034 -0.310"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true"/>
|
||||
|
||||
<attachment_point
|
||||
id="65"
|
||||
group="5"
|
||||
pie_slice="5"
|
||||
name="L Lower Leg 2"
|
||||
joint="mKneeLeft"
|
||||
position="-0.044 -0.007 -0.261"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="66"
|
||||
group="6"
|
||||
pie_slice="5"
|
||||
name="Stomach 2"
|
||||
joint="mPelvis"
|
||||
position="0.092 0.0 0.088"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="67"
|
||||
group="6"
|
||||
pie_slice="3"
|
||||
name="Left Pec 2"
|
||||
joint="mTorso"
|
||||
position="0.104 0.082 0.247"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<attachment_point
|
||||
id="68"
|
||||
group="6"
|
||||
pie_slice="1"
|
||||
name="Right Pec 2"
|
||||
joint="mTorso"
|
||||
position="0.104 -0.082 0.247"
|
||||
rotation="0 0 0"
|
||||
visible_in_first_person="true" />
|
||||
|
||||
<param
|
||||
id="32"
|
||||
group="1"
|
||||
@@ -5542,15 +5842,27 @@
|
||||
<texture
|
||||
local_texture="hair_grain" />
|
||||
</layer>
|
||||
|
||||
<layer
|
||||
name="hair texture alpha layer"
|
||||
visibility_mask="TRUE">
|
||||
<texture
|
||||
local_texture="hair_grain" />
|
||||
</layer>
|
||||
|
||||
<layer
|
||||
name="hair alpha"
|
||||
visibility_mask="TRUE">
|
||||
<texture
|
||||
local_texture="hair_alpha" />
|
||||
</layer>
|
||||
</layer_set>
|
||||
<!-- =========================================================== -->
|
||||
|
||||
<layer_set
|
||||
body_region="head"
|
||||
width="512"
|
||||
height="512"
|
||||
clear_alpha="false"
|
||||
alpha_tga_file="head_alpha.tga">
|
||||
height="512">
|
||||
<layer
|
||||
name="head bump base"
|
||||
fixed_color = "128,128,128,255"
|
||||
@@ -6544,6 +6856,24 @@
|
||||
<texture
|
||||
local_texture="head_bodypaint" />
|
||||
</layer>
|
||||
<layer
|
||||
name="eyelash alpha"
|
||||
visibility_mask="TRUE">
|
||||
<texture
|
||||
tga_file="head_alpha.tga"
|
||||
file_is_mask="TRUE" />
|
||||
</layer>
|
||||
<layer
|
||||
name="head alpha"
|
||||
visibility_mask="TRUE">
|
||||
<texture
|
||||
local_texture="head_alpha" />
|
||||
</layer>
|
||||
<layer
|
||||
name="head_tattoo">
|
||||
<texture
|
||||
local_texture="head_tattoo" />
|
||||
</layer>
|
||||
</layer_set>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
@@ -6659,6 +6989,12 @@
|
||||
</param>
|
||||
</layer>
|
||||
|
||||
<layer
|
||||
name="upper_tattoo">
|
||||
<texture
|
||||
local_texture="upper_tattoo" />
|
||||
</layer>
|
||||
|
||||
<layer
|
||||
name="upper_undershirt bump"
|
||||
render_pass="bump"
|
||||
@@ -7728,6 +8064,14 @@
|
||||
domain="0.01" />
|
||||
</param>
|
||||
</layer>
|
||||
|
||||
<layer
|
||||
name="upper alpha"
|
||||
visibility_mask="TRUE">
|
||||
<texture
|
||||
local_texture="upper_alpha" />
|
||||
</layer>
|
||||
|
||||
</layer_set>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
@@ -7843,6 +8187,12 @@
|
||||
</param>
|
||||
</layer>
|
||||
|
||||
<layer
|
||||
name="lower_tattoo">
|
||||
<texture
|
||||
local_texture="lower_tattoo" />
|
||||
</layer>
|
||||
|
||||
<layer
|
||||
name="lower_underpants bump"
|
||||
render_pass="bump"
|
||||
@@ -8600,6 +8950,14 @@
|
||||
domain="0.01" />
|
||||
</param>
|
||||
</layer>
|
||||
|
||||
<layer
|
||||
name="lower alpha"
|
||||
visibility_mask="TRUE">
|
||||
<texture
|
||||
local_texture="lower_alpha" />
|
||||
</layer>
|
||||
|
||||
</layer_set>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
@@ -8619,6 +8977,14 @@
|
||||
<texture
|
||||
local_texture="eyes_iris" />
|
||||
</layer>
|
||||
|
||||
<layer
|
||||
name="eyes alpha"
|
||||
visibility_mask="TRUE">
|
||||
<texture
|
||||
local_texture="eyes_alpha" />
|
||||
</layer>
|
||||
|
||||
</layer_set>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
|
||||
@@ -7103,7 +7103,9 @@ void LLAgent::createStandardWearables(BOOL female)
|
||||
FALSE, //WT_GLOVES
|
||||
TRUE, //WT_UNDERSHIRT
|
||||
TRUE, //WT_UNDERPANTS
|
||||
FALSE //WT_SKIRT
|
||||
FALSE, //WT_SKIRT
|
||||
FALSE, //WT_ALPHA
|
||||
FALSE //WT_TATTOO
|
||||
};
|
||||
|
||||
for( S32 i=0; i < WT_COUNT; i++ )
|
||||
@@ -7593,6 +7595,8 @@ void LLAgent::setWearableOutfit(
|
||||
wearables_to_remove[WT_UNDERSHIRT] = (!gAgent.isTeen()) & remove;
|
||||
wearables_to_remove[WT_UNDERPANTS] = (!gAgent.isTeen()) & remove;
|
||||
wearables_to_remove[WT_SKIRT] = remove;
|
||||
wearables_to_remove[WT_ALPHA] = remove;
|
||||
wearables_to_remove[WT_TATTOO] = remove;
|
||||
|
||||
S32 count = wearables.count();
|
||||
llassert( items.count() == count );
|
||||
@@ -7862,6 +7866,8 @@ void LLAgent::userRemoveAllClothesStep2( BOOL proceed, void* userdata )
|
||||
gAgent.removeWearable( WT_UNDERSHIRT );
|
||||
gAgent.removeWearable( WT_UNDERPANTS );
|
||||
gAgent.removeWearable( WT_SKIRT );
|
||||
gAgent.removeWearable( WT_ALPHA );
|
||||
gAgent.removeWearable( WT_TATTOO );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -333,7 +333,9 @@ enum ESubpart {
|
||||
SUBPART_GLOVES,
|
||||
SUBPART_UNDERSHIRT,
|
||||
SUBPART_UNDERPANTS,
|
||||
SUBPART_SKIRT
|
||||
SUBPART_SKIRT,
|
||||
SUBPART_ALPHA,
|
||||
SUBPART_TATTOO
|
||||
};
|
||||
|
||||
struct LLSubpart
|
||||
@@ -362,6 +364,7 @@ public:
|
||||
|
||||
void addSubpart(const std::string& name, ESubpart id, LLSubpart* part );
|
||||
void addTextureDropTarget( ETextureIndex te, const std::string& name, const LLUUID& default_image_id, BOOL allow_no_texture );
|
||||
void addInvisibilityCheckbox(ETextureIndex te, const std::string& name);
|
||||
void addColorSwatch( ETextureIndex te, const std::string& name );
|
||||
|
||||
const std::string& getLabel() { return LLWearable::typeToTypeLabel( mType ); }
|
||||
@@ -375,6 +378,11 @@ public:
|
||||
void setWearable(LLWearable* wearable, U32 perm_mask, BOOL is_complete);
|
||||
|
||||
void setUIPermissions(U32 perm_mask, BOOL is_complete);
|
||||
|
||||
void hideTextureControls();
|
||||
bool textureIsInvisible(ETextureIndex te);
|
||||
void initPreviousTextureList();
|
||||
void initPreviousTextureListEntry(ETextureIndex te);
|
||||
|
||||
virtual void setVisible( BOOL visible );
|
||||
|
||||
@@ -390,6 +398,7 @@ public:
|
||||
static void onBtnTakeOffDialog( S32 option, void* userdata );
|
||||
static void onBtnCreateNew( void* userdata );
|
||||
static void onTextureCommit( LLUICtrl* ctrl, void* userdata );
|
||||
static void onInvisibilityCommit( LLUICtrl* ctrl, void* userdata );
|
||||
static void onColorCommit( LLUICtrl* ctrl, void* userdata );
|
||||
static void onCommitSexChange( LLUICtrl*, void* userdata );
|
||||
static bool onSelectAutoWearOption(const LLSD& notification, const LLSD& response);
|
||||
@@ -400,8 +409,10 @@ private:
|
||||
EWearableType mType;
|
||||
BOOL mCanTakeOff;
|
||||
std::map<std::string, S32> mTextureList;
|
||||
std::map<std::string, S32> mInvisibilityList;
|
||||
std::map<std::string, S32> mColorList;
|
||||
std::map<ESubpart, LLSubpart*> mSubpartList;
|
||||
std::map<S32, LLUUID> mPreviousTextureList;
|
||||
ESubpart mCurrentSubpart;
|
||||
};
|
||||
|
||||
@@ -625,6 +636,71 @@ bool LLPanelEditWearable::onSelectAutoWearOption(const LLSD& notification, const
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLPanelEditWearable::textureIsInvisible(ETextureIndex te)
|
||||
{
|
||||
if (gAgent.getWearable(mType))
|
||||
{
|
||||
LLVOAvatar *avatar = gAgent.getAvatarObject();
|
||||
if (avatar)
|
||||
{
|
||||
const LLTextureEntry* current_te = avatar->getTE(te);
|
||||
return (current_te && current_te->getID() == IMG_INVISIBLE);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LLPanelEditWearable::addInvisibilityCheckbox(ETextureIndex te, const std::string& name)
|
||||
{
|
||||
childSetCommitCallback(name, LLPanelEditWearable::onInvisibilityCommit, this);
|
||||
|
||||
mInvisibilityList[name] = te;
|
||||
}
|
||||
|
||||
// static
|
||||
void LLPanelEditWearable::onInvisibilityCommit(LLUICtrl* ctrl, void* userdata)
|
||||
{
|
||||
LLPanelEditWearable* self = (LLPanelEditWearable*) userdata;
|
||||
LLCheckBoxCtrl* checkbox_ctrl = (LLCheckBoxCtrl*) ctrl;
|
||||
LLVOAvatar *avatar = gAgent.getAvatarObject();
|
||||
if (!avatar)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ETextureIndex te = (ETextureIndex)(self->mInvisibilityList[ctrl->getName()]);
|
||||
|
||||
bool new_invis_state = checkbox_ctrl->get();
|
||||
if (new_invis_state)
|
||||
{
|
||||
LLViewerImage* image = gImageList.getImage(IMG_INVISIBLE);
|
||||
const LLTextureEntry* current_te = avatar->getTE(te);
|
||||
if (current_te)
|
||||
{
|
||||
self->mPreviousTextureList[(S32)te] = current_te->getID();
|
||||
}
|
||||
avatar->setLocTexTE(te, image, TRUE);
|
||||
avatar->wearableUpdated(self->mType, FALSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try to restore previous texture, if any.
|
||||
LLUUID prev_id = self->mPreviousTextureList[(S32)te];
|
||||
if (prev_id.isNull() || (prev_id == IMG_INVISIBLE))
|
||||
{
|
||||
prev_id = LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID"));
|
||||
}
|
||||
if (prev_id.notNull())
|
||||
{
|
||||
LLViewerImage* image = gImageList.getImage(prev_id);
|
||||
avatar->setLocTexTE(te, image, TRUE);
|
||||
avatar->wearableUpdated(self->mType, FALSE);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelEditWearable::addColorSwatch( ETextureIndex te, const std::string& name )
|
||||
{
|
||||
childSetCommitCallback(name, LLPanelEditWearable::onColorCommit, this);
|
||||
@@ -653,11 +729,34 @@ void LLPanelEditWearable::onColorCommit( LLUICtrl* ctrl, void* userdata )
|
||||
avatar->setClothesColor( te, new_color, TRUE );
|
||||
|
||||
LLVisualParamHint::requestHintUpdates();
|
||||
avatar->wearableUpdated(self->mType, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelEditWearable::initPreviousTextureList()
|
||||
{
|
||||
initPreviousTextureListEntry(TEX_LOWER_ALPHA);
|
||||
initPreviousTextureListEntry(TEX_UPPER_ALPHA);
|
||||
initPreviousTextureListEntry(TEX_HEAD_ALPHA);
|
||||
initPreviousTextureListEntry(TEX_EYES_ALPHA);
|
||||
initPreviousTextureListEntry(TEX_LOWER_ALPHA);
|
||||
}
|
||||
|
||||
void LLPanelEditWearable::initPreviousTextureListEntry(ETextureIndex te)
|
||||
{
|
||||
LLVOAvatar* avatar = gAgent.getAvatarObject();
|
||||
if (!avatar)
|
||||
{
|
||||
return;
|
||||
}
|
||||
const LLTextureEntry* current_te = avatar->getTE(te);
|
||||
if (current_te)
|
||||
{
|
||||
mPreviousTextureList[te] = current_te->getID();
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelEditWearable::addTextureDropTarget( ETextureIndex te, const std::string& name,
|
||||
const LLUUID& default_image_id, BOOL allow_no_texture )
|
||||
@@ -673,6 +772,19 @@ void LLPanelEditWearable::addTextureDropTarget( ETextureIndex te, const std::str
|
||||
texture_ctrl->setNonImmediateFilterPermMask(PERM_NONE);//PERM_COPY | PERM_TRANSFER);
|
||||
}
|
||||
mTextureList[name] = te;
|
||||
LLVOAvatar* avatar = gAgent.getAvatarObject();
|
||||
if (avatar)
|
||||
{
|
||||
LLWearable* wearable = gAgent.getWearable(mType);
|
||||
if (wearable && mType == WT_ALPHA)
|
||||
{
|
||||
const LLTextureEntry* current_te = avatar->getTE(te);
|
||||
if (current_te)
|
||||
{
|
||||
mPreviousTextureList[te] = current_te->getID();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
@@ -688,11 +800,20 @@ void LLPanelEditWearable::onTextureCommit( LLUICtrl* ctrl, void* userdata )
|
||||
|
||||
// Set the new version
|
||||
LLViewerImage* image = gImageList.getImage( texture_ctrl->getImageAssetID() );
|
||||
if( image->getID().isNull() )
|
||||
if (image->getID().isNull())
|
||||
{
|
||||
image = gImageList.getImage(IMG_DEFAULT_AVATAR);
|
||||
}
|
||||
avatar->setLocTexTE( te, image, TRUE );
|
||||
self->mTextureList[ctrl->getName()] = te;
|
||||
if (gAgent.getWearable(self->mType))
|
||||
{
|
||||
avatar->setLocTexTE(te, image, TRUE);
|
||||
avatar->wearableUpdated(self->mType, FALSE);
|
||||
}
|
||||
if (self->mType == WT_ALPHA && image->getID() != IMG_INVISIBLE)
|
||||
{
|
||||
self->mPreviousTextureList[te] = image->getID();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -714,6 +835,8 @@ ESubpart LLPanelEditWearable::getDefaultSubpart()
|
||||
case WT_UNDERSHIRT: return SUBPART_UNDERSHIRT;
|
||||
case WT_UNDERPANTS: return SUBPART_UNDERPANTS;
|
||||
case WT_SKIRT: return SUBPART_SKIRT;
|
||||
case WT_ALPHA: return SUBPART_ALPHA;
|
||||
case WT_TATTOO: return SUBPART_TATTOO;
|
||||
|
||||
default: llassert(0); return SUBPART_SHAPE_WHOLE;
|
||||
}
|
||||
@@ -804,16 +927,7 @@ void LLPanelEditWearable::draw()
|
||||
childSetVisible("title_no_modify", TRUE);
|
||||
childSetTextArg("title_no_modify", "[DESC]", std::string(LLWearable::typeToTypeLabel( mType )));
|
||||
|
||||
for( std::map<std::string, S32>::iterator iter = mTextureList.begin();
|
||||
iter != mTextureList.end(); ++iter )
|
||||
{
|
||||
childSetVisible(iter->first, FALSE );
|
||||
}
|
||||
for( std::map<std::string, S32>::iterator iter = mColorList.begin();
|
||||
iter != mColorList.end(); ++iter )
|
||||
{
|
||||
childSetVisible(iter->first, FALSE );
|
||||
}
|
||||
hideTextureControls();
|
||||
}
|
||||
else if(has_wearable && !is_complete)
|
||||
{
|
||||
@@ -827,16 +941,7 @@ void LLPanelEditWearable::draw()
|
||||
childSetVisible("path", TRUE);
|
||||
childSetTextArg("path", "[PATH]", path);
|
||||
|
||||
for( std::map<std::string, S32>::iterator iter = mTextureList.begin();
|
||||
iter != mTextureList.end(); ++iter )
|
||||
{
|
||||
childSetVisible(iter->first, FALSE );
|
||||
}
|
||||
for( std::map<std::string, S32>::iterator iter = mColorList.begin();
|
||||
iter != mColorList.end(); ++iter )
|
||||
{
|
||||
childSetVisible(iter->first, FALSE );
|
||||
}
|
||||
hideTextureControls();
|
||||
}
|
||||
else if(has_wearable && is_modifiable)
|
||||
{
|
||||
@@ -896,6 +1001,34 @@ void LLPanelEditWearable::draw()
|
||||
ctrl->set(avatar->getClothesColor( (ETextureIndex)te_index ) );
|
||||
}
|
||||
}
|
||||
|
||||
for (std::map<std::string, S32>::iterator iter = mInvisibilityList.begin();
|
||||
iter != mInvisibilityList.end(); ++iter)
|
||||
{
|
||||
std::string name = iter->first;
|
||||
ETextureIndex te = (ETextureIndex)iter->second;
|
||||
childSetVisible(name, is_copyable && is_modifiable && is_complete);
|
||||
childSetEnabled(name, is_copyable && is_modifiable && is_complete);
|
||||
LLCheckBoxCtrl* ctrl = getChild<LLCheckBoxCtrl>(name);
|
||||
if (ctrl)
|
||||
{
|
||||
ctrl->set(textureIsInvisible(te));
|
||||
}
|
||||
}
|
||||
|
||||
for (std::map<std::string, S32>::iterator iter = mInvisibilityList.begin();
|
||||
iter != mInvisibilityList.end(); ++iter)
|
||||
{
|
||||
std::string name = iter->first;
|
||||
ETextureIndex te = (ETextureIndex)iter->second;
|
||||
childSetVisible(name, is_copyable && is_modifiable && is_complete);
|
||||
childSetEnabled(name, is_copyable && is_modifiable && is_complete);
|
||||
LLCheckBoxCtrl* ctrl = getChild<LLCheckBoxCtrl>(name);
|
||||
if (ctrl)
|
||||
{
|
||||
ctrl->set(textureIsInvisible(te));
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -903,16 +1036,7 @@ void LLPanelEditWearable::draw()
|
||||
childSetVisible("title_not_worn", TRUE);
|
||||
childSetTextArg("title_not_worn", "[DESC]", std::string(LLWearable::typeToTypeLabel( mType )));
|
||||
|
||||
for( std::map<std::string, S32>::iterator iter = mTextureList.begin();
|
||||
iter != mTextureList.end(); ++iter )
|
||||
{
|
||||
childSetVisible(iter->first, FALSE );
|
||||
}
|
||||
for( std::map<std::string, S32>::iterator iter = mColorList.begin();
|
||||
iter != mColorList.end(); ++iter )
|
||||
{
|
||||
childSetVisible(iter->first, FALSE );
|
||||
}
|
||||
hideTextureControls();
|
||||
}
|
||||
|
||||
childSetVisible("icon", has_wearable && is_modifiable);
|
||||
@@ -920,11 +1044,34 @@ void LLPanelEditWearable::draw()
|
||||
LLPanel::draw();
|
||||
}
|
||||
|
||||
void LLPanelEditWearable::hideTextureControls()
|
||||
{
|
||||
for (std::map<std::string, S32>::iterator iter = mTextureList.begin();
|
||||
iter != mTextureList.end(); ++iter)
|
||||
{
|
||||
childSetVisible(iter->first, FALSE);
|
||||
}
|
||||
for (std::map<std::string, S32>::iterator iter = mColorList.begin();
|
||||
iter != mColorList.end(); ++iter)
|
||||
{
|
||||
childSetVisible(iter->first, FALSE);
|
||||
}
|
||||
for (std::map<std::string, S32>::iterator iter = mInvisibilityList.begin();
|
||||
iter != mInvisibilityList.end(); ++iter)
|
||||
{
|
||||
childSetVisible(iter->first, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void LLPanelEditWearable::setWearable(LLWearable* wearable, U32 perm_mask, BOOL is_complete)
|
||||
{
|
||||
if( wearable )
|
||||
{
|
||||
setUIPermissions(perm_mask, is_complete);
|
||||
if (mType == WT_ALPHA)
|
||||
{
|
||||
initPreviousTextureList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1017,18 +1164,15 @@ void LLPanelEditWearable::setUIPermissions(U32 perm_mask, BOOL is_complete)
|
||||
{
|
||||
childSetVisible(iter->first, is_modifiable && is_complete );
|
||||
}
|
||||
}
|
||||
|
||||
void updateAvatarHeightDisplay()
|
||||
{
|
||||
if (gFloaterCustomize)
|
||||
for (std::map<std::string, S32>::iterator iter = mInvisibilityList.begin();
|
||||
iter != mInvisibilityList.end(); ++iter)
|
||||
{
|
||||
LLVOAvatar* avatar = gAgent.getAvatarObject();
|
||||
F32 avatar_size = (avatar->mBodySize.mV[VZ]) + (F32)0.17; //mBodySize is actually quite a bit off.
|
||||
gFloaterCustomize->getChild<LLTextBox>("HeightTextM")->setValue(llformat("%.2f", avatar_size) + "m");
|
||||
F32 feet = avatar_size / 0.3048;
|
||||
F32 inches = (feet - (F32)((U32)feet)) * 12.0;
|
||||
gFloaterCustomize->getChild<LLTextBox>("HeightTextI")->setValue(llformat("%d'%d\"", (U32)feet, (U32)inches));
|
||||
childSetVisible(iter->first, is_copyable && is_modifiable && is_complete);
|
||||
}
|
||||
for (std::map<std::string, S32>::iterator iter = mInvisibilityList.begin();
|
||||
iter != mInvisibilityList.end(); ++iter)
|
||||
{
|
||||
childSetVisible(iter->first, is_copyable && is_modifiable && is_complete);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1217,6 +1361,19 @@ void LLScrollingPanelParam::draw()
|
||||
drawChild(getChild<LLView>("max param text"), BTN_BORDER, BTN_BORDER);
|
||||
}
|
||||
|
||||
void updateAvatarHeightDisplay()
|
||||
{
|
||||
if (gFloaterCustomize)
|
||||
{
|
||||
LLVOAvatar* avatar = gAgent.getAvatarObject();
|
||||
F32 avatar_size = (avatar->mBodySize.mV[VZ]) + (F32)0.17; //mBodySize is actually quite a bit off.
|
||||
gFloaterCustomize->getChild<LLTextBox>("HeightTextM")->setValue(llformat("%.2f", avatar_size) + "m");
|
||||
F32 feet = avatar_size / 0.3048;
|
||||
F32 inches = (feet - (F32)((U32)feet)) * 12.0;
|
||||
gFloaterCustomize->getChild<LLTextBox>("HeightTextI")->setValue(llformat("%d'%d\"", (U32)feet, (U32)inches));
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLScrollingPanelParam::onSliderMoved(LLUICtrl* ctrl, void* userdata)
|
||||
{
|
||||
@@ -1460,6 +1617,8 @@ LLFloaterCustomize::LLFloaterCustomize()
|
||||
factory_map["Undershirt"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_UNDERSHIRT) ) );
|
||||
factory_map["Underpants"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_UNDERPANTS) ) );
|
||||
factory_map["Skirt"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_SKIRT) ) );
|
||||
factory_map["Alpha"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_ALPHA)));
|
||||
factory_map["Tattoo"] = LLCallbackMap(createWearablePanel, (void*)(new WearablePanelData(this, WT_TATTOO)));
|
||||
|
||||
LLUICtrlFactory::getInstance()->buildFloater(this, "floater_customize.xml", &factory_map);
|
||||
}
|
||||
@@ -1497,6 +1656,8 @@ BOOL LLFloaterCustomize::postBuild()
|
||||
childSetTabChangeCallback("customize tab container", "Undershirt", onTabChanged, (void*)WT_UNDERSHIRT, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Underpants", onTabChanged, (void*)WT_UNDERPANTS, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Skirt", onTabChanged, (void*)WT_SKIRT, onTabPrecommit );
|
||||
childSetTabChangeCallback("customize tab container", "Alpha", onTabChanged, (void*)WT_ALPHA, onTabPrecommit);
|
||||
childSetTabChangeCallback("customize tab container", "Tattoo", onTabChanged, (void*)WT_TATTOO, onTabPrecommit);
|
||||
|
||||
// Remove underwear panels for teens
|
||||
if (gAgent.isTeen())
|
||||
@@ -1523,6 +1684,7 @@ void LLFloaterCustomize::open()
|
||||
LLFloater::open();
|
||||
// childShowTab depends on gFloaterCustomize being defined and therefore must be called after the constructor. - Nyx
|
||||
childShowTab("customize tab container", "Shape", true);
|
||||
setCurrentWearableType(WT_SHAPE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -1976,6 +2138,126 @@ void LLFloaterCustomize::initWearablePanels()
|
||||
|
||||
panel->addColorSwatch( TEX_LOWER_UNDERPANTS, "Color/Tint" );
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Alpha
|
||||
panel = mWearablePanelList[WT_ALPHA];
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "alpha";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-2.5f, 0.5f, 0.8f);
|
||||
panel->addSubpart(LLStringUtil::null, SUBPART_ALPHA, part);
|
||||
|
||||
panel->addTextureDropTarget(TEX_LOWER_ALPHA, "Lower Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_UPPER_ALPHA, "Upper Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_HEAD_ALPHA, "Head Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_EYES_ALPHA, "Eye Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_HAIR_ALPHA, "Hair Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
|
||||
panel->addInvisibilityCheckbox(TEX_LOWER_ALPHA, "lower alpha texture invisible");
|
||||
panel->addInvisibilityCheckbox(TEX_UPPER_ALPHA, "upper alpha texture invisible");
|
||||
panel->addInvisibilityCheckbox(TEX_HEAD_ALPHA, "head alpha texture invisible");
|
||||
panel->addInvisibilityCheckbox(TEX_EYES_ALPHA, "eye alpha texture invisible");
|
||||
panel->addInvisibilityCheckbox(TEX_HAIR_ALPHA, "hair alpha texture invisible");
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Tattoo
|
||||
panel = mWearablePanelList[WT_TATTOO];
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "tattoo";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-2.5f, 0.5f, 0.8f);
|
||||
panel->addSubpart(LLStringUtil::null, SUBPART_TATTOO, part);
|
||||
|
||||
panel->addTextureDropTarget(TEX_LOWER_TATTOO, "Lower Tattoo",
|
||||
LLUUID::null,
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_UPPER_TATTOO, "Upper Tattoo",
|
||||
LLUUID::null,
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_HEAD_TATTOO, "Head Tattoo",
|
||||
LLUUID::null,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Alpha
|
||||
panel = mWearablePanelList[WT_ALPHA];
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "alpha";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-2.5f, 0.5f, 0.8f);
|
||||
panel->addSubpart(LLStringUtil::null, SUBPART_ALPHA, part);
|
||||
|
||||
panel->addTextureDropTarget(TEX_LOWER_ALPHA, "Lower Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_UPPER_ALPHA, "Upper Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_HEAD_ALPHA, "Head Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_EYES_ALPHA, "Eye Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_HAIR_ALPHA, "Hair Alpha",
|
||||
LLUUID(gSavedSettings.getString("UIImgDefaultAlphaUUID")),
|
||||
TRUE);
|
||||
|
||||
panel->addInvisibilityCheckbox(TEX_LOWER_ALPHA, "lower alpha texture invisible");
|
||||
panel->addInvisibilityCheckbox(TEX_UPPER_ALPHA, "upper alpha texture invisible");
|
||||
panel->addInvisibilityCheckbox(TEX_HEAD_ALPHA, "head alpha texture invisible");
|
||||
panel->addInvisibilityCheckbox(TEX_EYES_ALPHA, "eye alpha texture invisible");
|
||||
panel->addInvisibilityCheckbox(TEX_HAIR_ALPHA, "hair alpha texture invisible");
|
||||
}
|
||||
|
||||
/////////////////////////////////////////
|
||||
// Tattoo
|
||||
panel = mWearablePanelList[WT_TATTOO];
|
||||
|
||||
if (panel)
|
||||
{
|
||||
part = new LLSubpart();
|
||||
part->mTargetJoint = "mPelvis";
|
||||
part->mEditGroup = "tattoo";
|
||||
part->mTargetOffset.setVec(0.f, 0.f, 0.1f);
|
||||
part->mCameraOffset.setVec(-2.5f, 0.5f, 0.8f);
|
||||
panel->addSubpart(LLStringUtil::null, SUBPART_TATTOO, part);
|
||||
|
||||
panel->addTextureDropTarget(TEX_LOWER_TATTOO, "Lower Tattoo",
|
||||
LLUUID::null,
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_UPPER_TATTOO, "Upper Tattoo",
|
||||
LLUUID::null,
|
||||
TRUE);
|
||||
panel->addTextureDropTarget(TEX_HEAD_TATTOO, "Head Tattoo",
|
||||
LLUUID::null,
|
||||
TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
@@ -2007,7 +2289,7 @@ void LLFloaterCustomize::draw()
|
||||
// to be called when the tabs change or an inventory item
|
||||
// arrives. Figure out some way to avoid this if possible.
|
||||
updateInventoryUI();
|
||||
|
||||
|
||||
updateAvatarHeightDisplay();
|
||||
|
||||
LLScrollingPanelParam::sUpdateDelayFrames = 0;
|
||||
@@ -2031,7 +2313,8 @@ BOOL LLFloaterCustomize::isDirty() const
|
||||
// static
|
||||
void LLFloaterCustomize::onTabPrecommit( void* userdata, bool from_click )
|
||||
{
|
||||
if (gFloaterCustomize && gFloaterCustomize->getCurrentWearableType() != (EWearableType)(intptr_t) userdata)
|
||||
EWearableType type = (EWearableType)(intptr_t) userdata;
|
||||
if (type != WT_INVALID && gFloaterCustomize && gFloaterCustomize->getCurrentWearableType() != type)
|
||||
{
|
||||
gFloaterCustomize->askToSaveIfDirty(onCommitChangeTab, userdata);
|
||||
}
|
||||
@@ -2046,7 +2329,10 @@ void LLFloaterCustomize::onTabPrecommit( void* userdata, bool from_click )
|
||||
void LLFloaterCustomize::onTabChanged( void* userdata, bool from_click )
|
||||
{
|
||||
EWearableType wearable_type = (EWearableType) (intptr_t)userdata;
|
||||
LLFloaterCustomize::setCurrentWearableType( wearable_type );
|
||||
if (wearable_type != WT_INVALID)
|
||||
{
|
||||
LLFloaterCustomize::setCurrentWearableType(wearable_type);
|
||||
}
|
||||
}
|
||||
|
||||
void LLFloaterCustomize::onClose(bool app_quitting)
|
||||
|
||||
@@ -468,6 +468,16 @@ void do_create(LLInventoryModel *model, LLInventoryPanel *ptr, std::string type,
|
||||
LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
|
||||
LLFolderBridge::createWearable(parent_id, WT_UNDERPANTS);
|
||||
}
|
||||
else if ("alpha" == type)
|
||||
{
|
||||
LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
|
||||
LLFolderBridge::createWearable(parent_id, WT_ALPHA);
|
||||
}
|
||||
else if ("tattoo" == type)
|
||||
{
|
||||
LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_CLOTHING);
|
||||
LLFolderBridge::createWearable(parent_id, WT_TATTOO);
|
||||
}
|
||||
else if ("shape" == type)
|
||||
{
|
||||
LLUUID parent_id = self ? self->getUUID() : gInventory.findCategoryUUIDForType(LLAssetType::AT_BODYPART);
|
||||
|
||||
@@ -164,6 +164,8 @@ std::string ICON_NAME[ICON_NAME_COUNT] =
|
||||
"inv_item_undershirt.tga",
|
||||
"inv_item_underpants.tga",
|
||||
"inv_item_skirt.tga",
|
||||
"inv_item_alpha.tga",
|
||||
"inv_item_tattoo.tga",
|
||||
|
||||
"inv_item_animation.tga",
|
||||
"inv_item_gesture.tga",
|
||||
@@ -2600,6 +2602,16 @@ void LLFolderBridge::createNewUnderpants(void* user_data)
|
||||
LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_UNDERPANTS);
|
||||
}
|
||||
|
||||
void LLFolderBridge::createNewAlpha(void* user_data)
|
||||
{
|
||||
LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_ALPHA);
|
||||
}
|
||||
|
||||
void LLFolderBridge::createNewTattoo(void* user_data)
|
||||
{
|
||||
LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_TATTOO);
|
||||
}
|
||||
|
||||
void LLFolderBridge::createNewShape(void* user_data)
|
||||
{
|
||||
LLFolderBridge::createWearable((LLFolderBridge*)user_data, WT_SHAPE);
|
||||
|
||||
@@ -64,6 +64,8 @@ enum EInventoryIcon
|
||||
CLOTHING_UNDERSHIRT_ICON_NAME,
|
||||
CLOTHING_UNDERPANTS_ICON_NAME,
|
||||
CLOTHING_SKIRT_ICON_NAME,
|
||||
CLOTHING_ALPHA_ICON_NAME,
|
||||
CLOTHING_TATTOO_ICON_NAME,
|
||||
|
||||
ANIMATION_ICON_NAME,
|
||||
GESTURE_ICON_NAME,
|
||||
@@ -314,6 +316,8 @@ protected:
|
||||
static void createNewGloves(void* user_data);
|
||||
static void createNewUndershirt(void* user_data);
|
||||
static void createNewUnderpants(void* user_data);
|
||||
static void createNewAlpha(void* user_data);
|
||||
static void createNewTattoo(void* user_data);
|
||||
static void createNewShape(void* user_data);
|
||||
static void createNewSkin(void* user_data);
|
||||
static void createNewHair(void* user_data);
|
||||
|
||||
@@ -1220,6 +1220,12 @@ std::string get_item_icon_name(LLAssetType::EType asset_type,
|
||||
case WT_SKIRT:
|
||||
idx = CLOTHING_SKIRT_ICON_NAME;
|
||||
break;
|
||||
case WT_ALPHA:
|
||||
idx = CLOTHING_ALPHA_ICON_NAME;
|
||||
break;
|
||||
case WT_TATTOO:
|
||||
idx = CLOTHING_TATTOO_ICON_NAME;
|
||||
break;
|
||||
default:
|
||||
// no-op, go with choice above
|
||||
break;
|
||||
|
||||
@@ -63,7 +63,6 @@ using namespace LLVOAvatarDefines;
|
||||
|
||||
// static
|
||||
S32 LLTexLayerSetBuffer::sGLByteCount = 0;
|
||||
S32 LLTexLayerSetBuffer::sGLBumpByteCount = 0;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLBakedUploadData()
|
||||
@@ -92,7 +91,7 @@ LLBakedUploadData::LLBakedUploadData( LLVOAvatar* avatar,
|
||||
// LLTexLayerSetBuffer
|
||||
// The composite image that a LLTexLayerSet writes to. Each LLTexLayerSet has one.
|
||||
//-----------------------------------------------------------------------------
|
||||
LLTexLayerSetBuffer::LLTexLayerSetBuffer( LLTexLayerSet* owner, S32 width, S32 height, BOOL has_bump )
|
||||
LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* owner, S32 width, S32 height)
|
||||
:
|
||||
// ORDER_LAST => must render these after the hints are created.
|
||||
LLDynamicTexture( width, height, 4, LLDynamicTexture::ORDER_LAST, TRUE ),
|
||||
@@ -102,84 +101,39 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer( LLTexLayerSet* owner, S32 width, S32 h
|
||||
mTexLayerSet( owner )
|
||||
{
|
||||
LLTexLayerSetBuffer::sGLByteCount += getSize();
|
||||
mHasBump = has_bump ;
|
||||
mBumpTex = NULL ;
|
||||
|
||||
createBumpTexture() ;
|
||||
}
|
||||
|
||||
LLTexLayerSetBuffer::~LLTexLayerSetBuffer()
|
||||
{
|
||||
LLTexLayerSetBuffer::sGLByteCount -= getSize();
|
||||
|
||||
if( mBumpTex.notNull())
|
||||
destroyGLTexture();
|
||||
for (S32 order = 0; order < ORDER_COUNT; order++)
|
||||
{
|
||||
mBumpTex = NULL ;
|
||||
LLTexLayerSetBuffer::sGLBumpByteCount -= mWidth * mHeight * 4;
|
||||
LLDynamicTexture::sInstances[order].erase(this); // will fail in all but one case.
|
||||
}
|
||||
if (mTexLayerSet->mComposite == this)
|
||||
{
|
||||
// Destroy the pointer on this now gone buffer.
|
||||
mTexLayerSet->mComposite = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLTexLayerSetBuffer::restoreGLTexture()
|
||||
{
|
||||
createBumpTexture() ;
|
||||
LLDynamicTexture::restoreGLTexture() ;
|
||||
}
|
||||
|
||||
//virtual
|
||||
void LLTexLayerSetBuffer::destroyGLTexture()
|
||||
{
|
||||
if( mBumpTex.notNull() )
|
||||
{
|
||||
mBumpTex = NULL ;
|
||||
//LLImageGL::sGlobalTextureMemoryInBytes -= mWidth * mHeight * 4;
|
||||
LLTexLayerSetBuffer::sGLBumpByteCount -= mWidth * mHeight * 4;
|
||||
}
|
||||
|
||||
LLDynamicTexture::destroyGLTexture() ;
|
||||
}
|
||||
|
||||
void LLTexLayerSetBuffer::createBumpTexture()
|
||||
{
|
||||
if( mHasBump )
|
||||
{
|
||||
LLGLSUIDefault gls_ui;
|
||||
mBumpTex = new LLImageGL(FALSE) ;
|
||||
if(!mBumpTex->createGLTexture())
|
||||
{
|
||||
mBumpTex = NULL ;
|
||||
return ;
|
||||
}
|
||||
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName());
|
||||
stop_glerror();
|
||||
|
||||
gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
|
||||
|
||||
gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_BILINEAR);
|
||||
|
||||
LLImageGL::setManualImage(GL_TEXTURE_2D, 0, GL_RGBA8, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
|
||||
stop_glerror();
|
||||
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
LLImageGL::sGlobalTextureMemoryInBytes += mWidth * mHeight * 4;
|
||||
LLTexLayerSetBuffer::sGLBumpByteCount += mWidth * mHeight * 4;
|
||||
|
||||
if(gAuditTexture)
|
||||
{
|
||||
mBumpTex->setCategory(LLViewerImageBoostLevel::TEXLAYER_BUMP) ;
|
||||
mBumpTex->setTextureSize(mWidth * mHeight * 4) ;
|
||||
mBumpTex->setComponents(4) ;
|
||||
mBumpTex->incTextureCounter() ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// static
|
||||
void LLTexLayerSetBuffer::dumpTotalByteCount()
|
||||
{
|
||||
llinfos << "Composite System GL Buffers: " << (LLTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl;
|
||||
llinfos << "Composite System GL Bump Buffers: " << (LLTexLayerSetBuffer::sGLBumpByteCount/1024) << "KB" << llendl;
|
||||
}
|
||||
|
||||
void LLTexLayerSetBuffer::requestUpdate()
|
||||
@@ -233,8 +187,8 @@ void LLTexLayerSetBuffer::popProjection()
|
||||
BOOL LLTexLayerSetBuffer::needsRender()
|
||||
{
|
||||
LLVOAvatar* avatar = mTexLayerSet->getAvatar();
|
||||
BOOL upload_now = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal();
|
||||
BOOL needs_update = gAgent.mNumPendingQueries == 0 && (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating;
|
||||
BOOL upload_now = mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal() && gAgent.mNumPendingQueries == 0;
|
||||
BOOL needs_update = (mNeedsUpdate || upload_now) && !avatar->mAppearanceAnimating;
|
||||
if (needs_update)
|
||||
{
|
||||
BOOL invalid_skirt = avatar->getBakedTE(mTexLayerSet) == TEX_SKIRT_BAKED && !avatar->isWearingWearableType(WT_SKIRT);
|
||||
@@ -272,8 +226,6 @@ void LLTexLayerSetBuffer::postRender(BOOL success)
|
||||
|
||||
BOOL LLTexLayerSetBuffer::render()
|
||||
{
|
||||
U8* baked_bump_data = NULL;
|
||||
|
||||
// Default color mask for tex layer render
|
||||
gGL.setColorMask(true, true);
|
||||
|
||||
@@ -282,34 +234,6 @@ BOOL LLTexLayerSetBuffer::render()
|
||||
BOOL upload_now = (gAgent.mNumPendingQueries == 0 && mNeedsUpload && mTexLayerSet->isLocalTextureDataFinal());
|
||||
BOOL success = TRUE;
|
||||
|
||||
// Composite bump
|
||||
if( mBumpTex.notNull() )
|
||||
{
|
||||
// Composite the bump data
|
||||
success &= mTexLayerSet->renderBump( mOrigin.mX, mOrigin.mY, mWidth, mHeight );
|
||||
stop_glerror();
|
||||
|
||||
if (success)
|
||||
{
|
||||
LLGLSUIDefault gls_ui;
|
||||
|
||||
// read back into texture (this is done externally for the color data)
|
||||
gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName());
|
||||
stop_glerror();
|
||||
|
||||
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mOrigin.mX, mOrigin.mY, mWidth, mHeight);
|
||||
stop_glerror();
|
||||
|
||||
// if we need to upload the data, read it back into a buffer
|
||||
if( upload_now )
|
||||
{
|
||||
baked_bump_data = new U8[ mWidth * mHeight * 4 ];
|
||||
glReadPixels(mOrigin.mX, mOrigin.mY, mWidth, mHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_bump_data );
|
||||
stop_glerror();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Composite the color data
|
||||
LLGLSUIDefault gls_ui;
|
||||
success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mWidth, mHeight );
|
||||
@@ -319,13 +243,26 @@ BOOL LLTexLayerSetBuffer::render()
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
delete [] baked_bump_data;
|
||||
llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegion() << llendl;
|
||||
mUploadPending = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
readBackAndUpload(baked_bump_data);
|
||||
if (mTexLayerSet->isVisible())
|
||||
{
|
||||
readBackAndUpload();
|
||||
}
|
||||
else
|
||||
{
|
||||
mUploadPending = FALSE;
|
||||
mNeedsUpload = FALSE;
|
||||
LLVOAvatar* avatar = mTexLayerSet->getAvatar();
|
||||
if (avatar)
|
||||
{
|
||||
avatar->setNewBakedTexture(avatar->getBakedTE(mTexLayerSet), IMG_INVISIBLE);
|
||||
llinfos << "Invisible baked texture set for " << mTexLayerSet->getBodyRegion() << llendl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +297,7 @@ BOOL LLTexLayerSetBuffer::updateImmediate()
|
||||
return result;
|
||||
}
|
||||
|
||||
void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)
|
||||
void LLTexLayerSetBuffer::readBackAndUpload()
|
||||
{
|
||||
// pointers for storing data to upload
|
||||
U8* baked_color_data = new U8[ mWidth * mHeight * 4 ];
|
||||
@@ -390,79 +327,23 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)
|
||||
// writes into baked_color_data
|
||||
const char* comment_text = NULL;
|
||||
|
||||
S32 baked_image_components = mBumpTex.notNull() ? 5 : 4; // red green blue [bump] clothing
|
||||
S32 baked_image_components = 5; // red green blue bump clothing
|
||||
LLPointer<LLImageRaw> baked_image = new LLImageRaw( mWidth, mHeight, baked_image_components );
|
||||
U8* baked_image_data = baked_image->getData();
|
||||
|
||||
if( mBumpTex.notNull() )
|
||||
{
|
||||
comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // 5 channels: rgb, heightfield/alpha, mask
|
||||
comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // 5 channels: rgb, heightfield/alpha, mask
|
||||
|
||||
// Hide the alpha for the eyelashes in a corner of the bump map
|
||||
if (mTexLayerSet->getBodyRegion() == "head")
|
||||
S32 i = 0;
|
||||
for (S32 u = 0; u < mWidth; u++)
|
||||
{
|
||||
for (S32 v = 0; v < mHeight; v++)
|
||||
{
|
||||
S32 i = 0;
|
||||
for( S32 u = 0; u < mWidth; u++ )
|
||||
{
|
||||
for( S32 v = 0; v < mHeight; v++ )
|
||||
{
|
||||
baked_image_data[5*i + 0] = baked_color_data[4*i + 0];
|
||||
baked_image_data[5*i + 1] = baked_color_data[4*i + 1];
|
||||
baked_image_data[5*i + 2] = baked_color_data[4*i + 2];
|
||||
baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes.
|
||||
baked_image_data[5*i + 4] = baked_mask_data[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 i = 0;
|
||||
for( S32 u = 0; u < mWidth; u++ )
|
||||
{
|
||||
for( S32 v = 0; v < mHeight; v++ )
|
||||
{
|
||||
baked_image_data[5*i + 0] = baked_color_data[4*i + 0];
|
||||
baked_image_data[5*i + 1] = baked_color_data[4*i + 1];
|
||||
baked_image_data[5*i + 2] = baked_color_data[4*i + 2];
|
||||
baked_image_data[5*i + 3] = 255; // reserve for alpha
|
||||
baked_image_data[5*i + 4] = baked_mask_data[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (mTexLayerSet->getBodyRegion() == "skirt" || mTexLayerSet->getBodyRegion() == "hair")
|
||||
{
|
||||
S32 i = 0;
|
||||
for( S32 u = 0; u < mWidth; u++ )
|
||||
{
|
||||
for( S32 v = 0; v < mHeight; v++ )
|
||||
{
|
||||
baked_image_data[4*i + 0] = baked_color_data[4*i + 0];
|
||||
baked_image_data[4*i + 1] = baked_color_data[4*i + 1];
|
||||
baked_image_data[4*i + 2] = baked_color_data[4*i + 2];
|
||||
baked_image_data[4*i + 3] = baked_color_data[4*i + 3]; // Use alpha, not bump
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
S32 i = 0;
|
||||
for( S32 u = 0; u < mWidth; u++ )
|
||||
{
|
||||
for( S32 v = 0; v < mHeight; v++ )
|
||||
{
|
||||
baked_image_data[4*i + 0] = baked_color_data[4*i + 0];
|
||||
baked_image_data[4*i + 1] = baked_color_data[4*i + 1];
|
||||
baked_image_data[4*i + 2] = baked_color_data[4*i + 2];
|
||||
baked_image_data[4*i + 3] = 255; // eyes should have no mask - reserve for alpha
|
||||
i++;
|
||||
}
|
||||
}
|
||||
baked_image_data[5 * i + 0] = baked_color_data[4 * i + 0];
|
||||
baked_image_data[5 * i + 1] = baked_color_data[4 * i + 1];
|
||||
baked_image_data[5 * i + 2] = baked_color_data[4 * i + 2];
|
||||
baked_image_data[5 * i + 3] = baked_color_data[4 * i + 3]; // alpha should be correct for eyelashes.
|
||||
baked_image_data[5 * i + 4] = baked_mask_data[i];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -543,7 +424,6 @@ void LLTexLayerSetBuffer::readBackAndUpload(U8* baked_bump_data)
|
||||
}
|
||||
|
||||
delete [] baked_color_data;
|
||||
delete [] baked_bump_data;
|
||||
}
|
||||
|
||||
|
||||
@@ -554,88 +434,62 @@ void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid, void* user
|
||||
|
||||
LLVOAvatar* avatar = gAgent.getAvatarObject();
|
||||
|
||||
if (0 == result && avatar && !avatar->isDead())
|
||||
{
|
||||
// Sanity check: only the user's avatar should be uploading textures.
|
||||
if( baked_upload_data->mAvatar == avatar )
|
||||
{
|
||||
// Composite may have changed since the pointer was stored - need to do some checking.
|
||||
LLTexLayerSetBuffer* prev_layerset_buffer = baked_upload_data->mLayerSetBuffer;
|
||||
// Can't just call getComposite() because this will trigger creation if none exists.
|
||||
LLTexLayerSetBuffer* curr_layerset_buffer =
|
||||
baked_upload_data->mLayerSet->hasComposite()?baked_upload_data->mLayerSet->getComposite():NULL;
|
||||
if (0 == result &&
|
||||
avatar && !avatar->isDead() &&
|
||||
baked_upload_data->mAvatar == avatar && // Sanity check: only the user's avatar should be uploading textures.
|
||||
baked_upload_data->mLayerSet->hasComposite())
|
||||
{
|
||||
LLTexLayerSetBuffer* layerset_buffer = baked_upload_data->mLayerSet->getComposite();
|
||||
|
||||
if (prev_layerset_buffer != curr_layerset_buffer)
|
||||
if (layerset_buffer->mUploadID.isNull())
|
||||
{
|
||||
// The upload got canceled, we should be in the
|
||||
// process of baking a new texture so request an
|
||||
// upload with the new data
|
||||
|
||||
// BAP: does this really belong in this callback, as
|
||||
// opposed to where the cancellation takes place?
|
||||
// suspect this does nothing.
|
||||
layerset_buffer->requestUpload();
|
||||
}
|
||||
else if (baked_upload_data->mID == layerset_buffer->mUploadID)
|
||||
{
|
||||
// This is the upload we're currently waiting for.
|
||||
layerset_buffer->mUploadID.setNull();
|
||||
layerset_buffer->mUploadPending = FALSE;
|
||||
|
||||
if (result >= 0)
|
||||
{
|
||||
llinfos << "Baked texture out of date, composite no longer valid, ignored" << llendl;
|
||||
ETextureIndex baked_te = avatar->getBakedTE(layerset_buffer->mTexLayerSet);
|
||||
U64 now = LLFrameTimer::getTotalTime(); // Record starting time
|
||||
llinfos << "Baked texture upload took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl;
|
||||
avatar->setNewBakedTexture(baked_te, uuid);
|
||||
}
|
||||
else
|
||||
{
|
||||
curr_layerset_buffer->mUploadPending = FALSE;
|
||||
|
||||
if (curr_layerset_buffer->mUploadID.isNull())
|
||||
{
|
||||
// The upload got canceled, we should be in the process of baking a new texture
|
||||
// so request an upload with the new data
|
||||
curr_layerset_buffer->requestUpload();
|
||||
}
|
||||
else if( baked_upload_data->mID == curr_layerset_buffer->mUploadID )
|
||||
{
|
||||
// This is the upload we're currently waiting for.
|
||||
curr_layerset_buffer->mUploadID.setNull();
|
||||
|
||||
if( result >= 0 )
|
||||
{
|
||||
ETextureIndex baked_te = avatar->getBakedTE( curr_layerset_buffer->mTexLayerSet );
|
||||
U64 now = LLFrameTimer::getTotalTime(); // Record starting time
|
||||
llinfos << "Baked texture upload took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl;
|
||||
avatar->setNewBakedTexture( baked_te, uuid );
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "Baked upload failed. Reason: " << result << llendl;
|
||||
// *FIX: retry upload after n seconds, asset server could be busy
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
llinfos << "Received baked texture out of date, ignored." << llendl;
|
||||
}
|
||||
|
||||
avatar->dirtyMesh();
|
||||
{
|
||||
// Avatar appearance is changing, ignore the upload results
|
||||
llinfos << "Baked upload failed. Reason: " << result << llendl;
|
||||
// *FIX: retry upload after n seconds, asset server could be busy
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Baked texture failed to upload, but since we didn't set the new baked texture, it means that they'll
|
||||
// try and rebake it at some point in the future (after login?)
|
||||
llwarns << "Baked upload failed" << llendl;
|
||||
}
|
||||
|
||||
delete baked_upload_data;
|
||||
}
|
||||
|
||||
void LLTexLayerSetBuffer::bindBumpTexture( U32 stage )
|
||||
{
|
||||
if( mBumpTex.notNull() )
|
||||
{
|
||||
gGL.getTexUnit(stage)->bindManual(LLTexUnit::TT_TEXTURE, mBumpTex->getTexName());
|
||||
gGL.getTexUnit(0)->activate();
|
||||
|
||||
if( mLastBindTime != LLImageGL::sLastFrameTime )
|
||||
else
|
||||
{
|
||||
mLastBindTime = LLImageGL::sLastFrameTime;
|
||||
mBumpTex->updateBoundTexMem();
|
||||
llinfos << "Received baked texture out of date, ignored." << llendl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.getTexUnit(0)->activate();
|
||||
}
|
||||
}
|
||||
|
||||
avatar->dirtyMesh();
|
||||
}
|
||||
else
|
||||
{
|
||||
// didn't set the new baked texture, it means that they'll try
|
||||
// and rebake it at some point in the future (after login?)),
|
||||
// or this response to upload is out of date, in which case a
|
||||
// current response should be on the way or already processed.
|
||||
llwarns << "Baked upload failed" << llendl;
|
||||
}
|
||||
|
||||
delete baked_upload_data;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexLayerSet
|
||||
@@ -720,15 +574,19 @@ LLTexLayerSet::LLTexLayerSet( LLVOAvatar* avatar )
|
||||
mComposite( NULL ),
|
||||
mAvatar( avatar ),
|
||||
mUpdatesEnabled( FALSE ),
|
||||
mHasBump( FALSE ),
|
||||
mIsVisible(TRUE),
|
||||
mBakedTexIndex(BAKED_HEAD),
|
||||
mInfo( NULL )
|
||||
{
|
||||
}
|
||||
|
||||
LLTexLayerSet::~LLTexLayerSet()
|
||||
{
|
||||
deleteCaches();
|
||||
std::for_each(mLayerList.begin(), mLayerList.end(), DeletePointer());
|
||||
std::for_each(mMaskLayerList.begin(), mMaskLayerList.end(), DeletePointer());
|
||||
delete mComposite;
|
||||
mComposite = NULL;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -751,7 +609,14 @@ BOOL LLTexLayerSet::setInfo(LLTexLayerSetInfo *info)
|
||||
mInfo = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
mLayerList.push_back( layer );
|
||||
if (!layer->isVisibilityMask())
|
||||
{
|
||||
mLayerList.push_back(layer);
|
||||
}
|
||||
else
|
||||
{
|
||||
mMaskLayerList.push_back(layer);
|
||||
}
|
||||
}
|
||||
|
||||
requestUpdate();
|
||||
@@ -791,6 +656,11 @@ void LLTexLayerSet::deleteCaches()
|
||||
LLTexLayer* layer = *iter;
|
||||
layer->deleteCaches();
|
||||
}
|
||||
for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++)
|
||||
{
|
||||
LLTexLayer* layer = *iter;
|
||||
layer->deleteCaches();
|
||||
}
|
||||
}
|
||||
|
||||
// Returns TRUE if at least one packet of data has been received for each of the textures that this layerset depends on.
|
||||
@@ -807,107 +677,134 @@ BOOL LLTexLayerSet::isLocalTextureDataFinal()
|
||||
}
|
||||
|
||||
|
||||
BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
|
||||
void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear)
|
||||
{
|
||||
BOOL success = TRUE;
|
||||
const LLTexLayerSetInfo *info = getInfo();
|
||||
|
||||
LLGLSUIDefault gls_ui;
|
||||
LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE);
|
||||
gGL.setColorMask(true, true);
|
||||
|
||||
// composite color layers
|
||||
for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
|
||||
{
|
||||
LLTexLayer* layer = *iter;
|
||||
if( layer->getRenderPass() == RP_COLOR )
|
||||
{
|
||||
gGL.flush();
|
||||
success &= layer->render( x, y, width, height );
|
||||
gGL.flush();
|
||||
}
|
||||
}
|
||||
gGL.setColorMask(false, true);
|
||||
gGL.setSceneBlendType(LLRender::BT_REPLACE);
|
||||
|
||||
// (Optionally) replace alpha with a single component image from a tga file.
|
||||
if( !getInfo()->mStaticAlphaFileName.empty() )
|
||||
if (!info->mStaticAlphaFileName.empty())
|
||||
{
|
||||
LLGLSNoAlphaTest gls_no_alpha_test;
|
||||
gGL.flush();
|
||||
gGL.setColorMask(false, true);
|
||||
gGL.setSceneBlendType(LLRender::BT_REPLACE);
|
||||
|
||||
{
|
||||
LLImageGL* image_gl = gTexStaticImageList.getImageGL( getInfo()->mStaticAlphaFileName, TRUE );
|
||||
if( image_gl )
|
||||
LLImageGL* image_gl = gTexStaticImageList.getImageGL(info->mStaticAlphaFileName, TRUE);
|
||||
if (image_gl)
|
||||
{
|
||||
LLGLSUIDefault gls_ui;
|
||||
gGL.getTexUnit(0)->bind(image_gl, TRUE);
|
||||
gGL.getTexUnit(0)->setTextureBlendType( LLTexUnit::TB_REPLACE );
|
||||
gl_rect_2d_simple_tex( width, height );
|
||||
}
|
||||
else
|
||||
{
|
||||
success = FALSE;
|
||||
gGL.getTexUnit(0)->bind(image_gl);
|
||||
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_REPLACE);
|
||||
gl_rect_2d_simple_tex(width, height);
|
||||
}
|
||||
}
|
||||
gGL.flush();
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
|
||||
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
|
||||
gGL.setColorMask(true, true);
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
}
|
||||
else
|
||||
if( getInfo()->mClearAlpha )
|
||||
else if (forceClear || info->mClearAlpha || (mMaskLayerList.size() > 0))
|
||||
{
|
||||
// Set the alpha channel to one (clean up after previous blending)
|
||||
gGL.flush();
|
||||
LLGLDisable no_alpha(GL_ALPHA_TEST);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.color4f( 0.f, 0.f, 0.f, 1.f );
|
||||
gGL.flush();
|
||||
gGL.setColorMask(false, true);
|
||||
|
||||
gl_rect_2d_simple( width, height );
|
||||
|
||||
|
||||
gGL.flush();
|
||||
gGL.setColorMask(true, true);
|
||||
}
|
||||
stop_glerror();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL LLTexLayerSet::renderBump( S32 x, S32 y, S32 width, S32 height )
|
||||
{
|
||||
BOOL success = TRUE;
|
||||
|
||||
LLGLSUIDefault gls_ui;
|
||||
LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE);
|
||||
|
||||
//static S32 bump_layer_count = 1;
|
||||
|
||||
for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
|
||||
}
|
||||
|
||||
// (Optional) Mask out part of the baked texture with alpha masks
|
||||
// will still have an effect even if mClearAlpha is set or the alpha component was replaced
|
||||
if (mMaskLayerList.size() > 0)
|
||||
{
|
||||
LLTexLayer* layer = *iter;
|
||||
if( layer->getRenderPass() == RP_BUMP )
|
||||
gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA);
|
||||
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_REPLACE);
|
||||
for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++)
|
||||
{
|
||||
success &= layer->render( x, y, width, height );
|
||||
LLTexLayer* layer = *iter;
|
||||
gGL.flush();
|
||||
layer->blendAlphaTexture(x, y, width, height);
|
||||
gGL.flush();
|
||||
}
|
||||
}
|
||||
|
||||
// Set the alpha channel to one (clean up after previous blending)
|
||||
LLGLDisable no_alpha(GL_ALPHA_TEST);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.color4f( 0.f, 0.f, 0.f, 1.f );
|
||||
gGL.setColorMask(false, true);
|
||||
|
||||
gl_rect_2d_simple( width, height );
|
||||
|
||||
gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
|
||||
gGL.setColorMask(true, true);
|
||||
stop_glerror();
|
||||
|
||||
return success;
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
}
|
||||
|
||||
BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
|
||||
{
|
||||
BOOL success = TRUE;
|
||||
mIsVisible = TRUE;
|
||||
|
||||
if (mMaskLayerList.size() > 0)
|
||||
{
|
||||
for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++)
|
||||
{
|
||||
LLTexLayer* layer = *iter;
|
||||
if (layer->isInvisibleAlphaMask())
|
||||
{
|
||||
mIsVisible = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LLGLSUIDefault gls_ui;
|
||||
LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE);
|
||||
gGL.setColorMask(true, true);
|
||||
|
||||
// clear buffer area to ensure we don't pick up UI elements
|
||||
{
|
||||
gGL.flush();
|
||||
LLGLDisable no_alpha(GL_ALPHA_TEST);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.color4f( 0.f, 0.f, 0.f, 1.f );
|
||||
|
||||
gl_rect_2d_simple( width, height );
|
||||
|
||||
gGL.flush();
|
||||
}
|
||||
|
||||
if (mIsVisible)
|
||||
{
|
||||
// composite color layers
|
||||
for (layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++)
|
||||
{
|
||||
LLTexLayer* layer = *iter;
|
||||
if (layer->getRenderPass() == RP_COLOR || layer->getRenderPass() == RP_BUMP)
|
||||
{
|
||||
gGL.flush();
|
||||
success &= layer->render(x, y, width, height);
|
||||
gGL.flush();
|
||||
}
|
||||
}
|
||||
|
||||
renderAlphaMaskTextures(x, y, width, height, false);
|
||||
|
||||
stop_glerror();
|
||||
}
|
||||
else
|
||||
{
|
||||
gGL.flush();
|
||||
|
||||
gGL.setSceneBlendType(LLRender::BT_REPLACE);
|
||||
LLGLDisable no_alpha(GL_ALPHA_TEST);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
gGL.color4f( 0.f, 0.f, 0.f, 0.f );
|
||||
|
||||
gl_rect_2d_simple( width, height );
|
||||
gGL.setSceneBlendType(LLRender::BT_ALPHA);
|
||||
|
||||
gGL.flush();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
void LLTexLayerSet::requestUpdate()
|
||||
{
|
||||
if( mUpdatesEnabled )
|
||||
@@ -943,7 +840,7 @@ void LLTexLayerSet::createComposite()
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
}
|
||||
mComposite = new LLTexLayerSetBuffer( this, width, height, mHasBump );
|
||||
mComposite = new LLTexLayerSetBuffer(this, width, height);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1004,6 +901,9 @@ void LLTexLayerSet::gatherAlphaMasks(U8 *data, S32 width, S32 height)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set alpha back to that of our alpha masks.
|
||||
renderAlphaMaskTextures(mComposite->getOriginX(), mComposite->getOriginY(), width, height, true);
|
||||
}
|
||||
|
||||
void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components)
|
||||
@@ -1025,7 +925,8 @@ LLTexLayerInfo::LLTexLayerInfo( )
|
||||
mFixedColor( 0.f, 0.f, 0.f, 0.f ),
|
||||
mLocalTexture( -1 ),
|
||||
mStaticImageIsMask( FALSE ),
|
||||
mUseLocalTextureAlphaOnly( FALSE )
|
||||
mUseLocalTextureAlphaOnly(FALSE),
|
||||
mIsVisibilityMask(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1064,6 +965,14 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
|
||||
static LLStdStringHandle global_color_string = LLXmlTree::addAttributeString("global_color");
|
||||
node->getFastAttributeString( global_color_string, mGlobalColor );
|
||||
|
||||
// Visibility mask (optional)
|
||||
BOOL is_visibility;
|
||||
static LLStdStringHandle visibility_mask_string = LLXmlTree::addAttributeString("visibility_mask");
|
||||
if (node->getFastAttributeBOOL(visibility_mask_string, is_visibility))
|
||||
{
|
||||
mIsVisibilityMask = is_visibility;
|
||||
}
|
||||
|
||||
// color attribute (optional)
|
||||
LLColor4U color4u;
|
||||
static LLStdStringHandle fixed_color_string = LLXmlTree::addAttributeString("fixed_color");
|
||||
@@ -1150,9 +1059,41 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
|
||||
{
|
||||
mLocalTexture = TEX_HAIR;
|
||||
}
|
||||
else if ("hair_alpha" == local_texture)
|
||||
{
|
||||
mLocalTexture = TEX_HAIR_ALPHA;
|
||||
}
|
||||
else if ("head_alpha" == local_texture)
|
||||
{
|
||||
mLocalTexture = TEX_HEAD_ALPHA;
|
||||
}
|
||||
else if ("upper_alpha" == local_texture)
|
||||
{
|
||||
mLocalTexture = TEX_UPPER_ALPHA;
|
||||
}
|
||||
else if ("lower_alpha" == local_texture)
|
||||
{
|
||||
mLocalTexture = TEX_LOWER_ALPHA;
|
||||
}
|
||||
else if ("eyes_alpha" == local_texture)
|
||||
{
|
||||
mLocalTexture = TEX_EYES_ALPHA;
|
||||
}
|
||||
else if ("head_tattoo" == local_texture)
|
||||
{
|
||||
mLocalTexture = TEX_HEAD_TATTOO;
|
||||
}
|
||||
else if ("upper_tattoo" == local_texture)
|
||||
{
|
||||
mLocalTexture = TEX_UPPER_TATTOO;
|
||||
}
|
||||
else if ("lower_tattoo" == local_texture)
|
||||
{
|
||||
mLocalTexture = TEX_LOWER_TATTOO;
|
||||
}
|
||||
else
|
||||
{
|
||||
llwarns << "<texture> element has invalid local_texure attribute: " << mName << " " << local_texture << llendl;
|
||||
llwarns << "<texture> element has invalid local_texture attribute: " << mName << " " << local_texture << llendl;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
@@ -1253,13 +1194,14 @@ LLTexLayer::~LLTexLayer()
|
||||
|
||||
BOOL LLTexLayer::setInfo(LLTexLayerInfo* info)
|
||||
{
|
||||
llassert(mInfo == NULL);
|
||||
//llassert(mInfo == NULL); // nyx says this is probably bogus but needs investigating
|
||||
if (mInfo != NULL) // above llassert(), but softened into a warning
|
||||
{
|
||||
llwarns << "BAD STUFF! mInfo != NULL" << llendl;
|
||||
}
|
||||
mInfo = info;
|
||||
//mID = info->mID; // No ID
|
||||
|
||||
if (info->mRenderPass == RP_BUMP)
|
||||
mTexLayerSet->setBump(TRUE);
|
||||
|
||||
{
|
||||
LLTexLayerInfo::morph_name_list_t::iterator iter;
|
||||
for (iter = mInfo->mMorphNameList.begin(); iter != mInfo->mMorphNameList.end(); iter++)
|
||||
@@ -1351,13 +1293,8 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
|
||||
LLGLEnable color_mat(GL_COLOR_MATERIAL);
|
||||
gPipeline.disableLights();
|
||||
|
||||
BOOL success = TRUE;
|
||||
|
||||
BOOL color_specified = FALSE;
|
||||
BOOL alpha_mask_specified = FALSE;
|
||||
|
||||
LLColor4 net_color;
|
||||
color_specified = findNetColor( &net_color );
|
||||
BOOL color_specified = findNetColor(&net_color);
|
||||
|
||||
if (mTexLayerSet->getAvatar()->mIsDummy)
|
||||
{
|
||||
@@ -1365,18 +1302,21 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
|
||||
net_color = LLVOAvatar::getDummyColor();
|
||||
}
|
||||
|
||||
BOOL success = TRUE;
|
||||
|
||||
// If you can't see the layer, don't render it.
|
||||
if( is_approx_zero( net_color.mV[VW] ) )
|
||||
{
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL alpha_mask_specified = FALSE;
|
||||
alpha_list_t::iterator iter = mParamAlphaList.begin();
|
||||
if( iter != mParamAlphaList.end() )
|
||||
{
|
||||
// If we have alpha masks, but we're skipping all of them, skip the whole layer.
|
||||
// However, we can't do this optimization if we have morph masks that need updating.
|
||||
if( mMaskedMorphs.empty() )
|
||||
/* if( mMaskedMorphs.empty() )
|
||||
{
|
||||
BOOL skip_layer = TRUE;
|
||||
|
||||
@@ -1397,7 +1337,7 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
|
||||
{
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
renderAlphaMasks( x, y, width, height, &net_color );
|
||||
alpha_mask_specified = TRUE;
|
||||
@@ -1412,6 +1352,11 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
|
||||
gGL.flush();
|
||||
gGL.setSceneBlendType(LLRender::BT_REPLACE);
|
||||
}
|
||||
else if (getInfo()->mUseLocalTextureAlphaOnly)
|
||||
{
|
||||
// Use the alpha channel only
|
||||
gGL.setColorMask(false, true);
|
||||
}
|
||||
|
||||
if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly )
|
||||
{
|
||||
@@ -1419,6 +1364,10 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
|
||||
LLImageGL* image_gl = NULL;
|
||||
if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) )
|
||||
{
|
||||
if (mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture) == IMG_DEFAULT_AVATAR)
|
||||
{
|
||||
image_gl = NULL;
|
||||
}
|
||||
if( image_gl )
|
||||
{
|
||||
LLGLDisable alpha_test(getInfo()->mWriteAllChannels ? GL_ALPHA_TEST : 0);
|
||||
@@ -1434,10 +1383,6 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1477,6 +1422,12 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
|
||||
stop_glerror();
|
||||
}
|
||||
|
||||
if (getInfo()->mUseLocalTextureAlphaOnly)
|
||||
{
|
||||
// Restore color + alpha mode.
|
||||
gGL.setColorMask(true, true);
|
||||
}
|
||||
|
||||
if( !success )
|
||||
{
|
||||
llinfos << "LLTexLayer::render() partial: " << getInfo()->mName << llendl;
|
||||
@@ -1484,6 +1435,49 @@ BOOL LLTexLayer::render( S32 x, S32 y, S32 width, S32 height )
|
||||
return success;
|
||||
}
|
||||
|
||||
BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
|
||||
{
|
||||
BOOL success = TRUE;
|
||||
|
||||
gGL.flush();
|
||||
|
||||
if (!getInfo()->mStaticImageFileName.empty())
|
||||
{
|
||||
LLImageGL* image_gl = gTexStaticImageList.getImageGL(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
|
||||
if (image_gl)
|
||||
{
|
||||
LLGLSNoAlphaTest gls_no_alpha_test;
|
||||
gGL.getTexUnit(0)->bind(image_gl, TRUE);
|
||||
gl_rect_2d_simple_tex(width, height);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (getInfo()->mLocalTexture >=0 && getInfo()->mLocalTexture < TEX_NUM_INDICES)
|
||||
{
|
||||
LLImageGL* image_gl = NULL;
|
||||
if (mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl))
|
||||
{
|
||||
if (image_gl)
|
||||
{
|
||||
LLGLSNoAlphaTest gls_no_alpha_test;
|
||||
gGL.getTexUnit(0)->bind(image_gl);
|
||||
gl_rect_2d_simple_tex(width, height);
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
success = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
U8* LLTexLayer::getAlphaData()
|
||||
{
|
||||
LLCRC alpha_mask_crc;
|
||||
@@ -1609,7 +1603,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
|
||||
|
||||
// Approximates a min() function
|
||||
gGL.flush();
|
||||
gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ZERO);
|
||||
gGL.setSceneBlendType(LLRender::BT_MULT_ALPHA);
|
||||
|
||||
// Accumulate the alpha component of the texture
|
||||
if( getInfo()->mLocalTexture != -1 )
|
||||
@@ -1633,10 +1627,6 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1655,10 +1645,6 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
|
||||
gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
success = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1677,7 +1663,7 @@ BOOL LLTexLayer::renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4
|
||||
|
||||
gGL.setColorMask(true, true);
|
||||
|
||||
if (!mMorphMasksValid && !mMaskedMorphs.empty())
|
||||
if (success && !mMorphMasksValid && !mMaskedMorphs.empty())
|
||||
{
|
||||
LLCRC alpha_mask_crc;
|
||||
const LLUUID& uuid = mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)getInfo()->mLocalTexture);
|
||||
@@ -1825,6 +1811,26 @@ void LLTexLayer::invalidateMorphMasks()
|
||||
mMorphMasksValid = FALSE;
|
||||
}
|
||||
|
||||
BOOL LLTexLayer::isVisibilityMask() const
|
||||
{
|
||||
return mInfo->mIsVisibilityMask;
|
||||
}
|
||||
|
||||
BOOL LLTexLayer::isInvisibleAlphaMask()
|
||||
{
|
||||
const LLTexLayerInfo *info = getInfo();
|
||||
|
||||
if (info && info->mLocalTexture >= 0 && info->mLocalTexture < TEX_NUM_INDICES)
|
||||
{
|
||||
if (mTexLayerSet->getAvatar()->getLocalTextureID((ETextureIndex)info->mLocalTexture) == IMG_INVISIBLE)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// LLTexLayerParamAlphaInfo
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#include "lluuid.h"
|
||||
#include "llviewerimage.h"
|
||||
#include "llviewervisualparam.h"
|
||||
#include "llvoavatardefines.h"
|
||||
#include "llwearable.h"
|
||||
#include "v4color.h"
|
||||
#include "llfloater.h"
|
||||
@@ -186,6 +187,7 @@ protected:
|
||||
std::string mStaticImageFileName;
|
||||
BOOL mStaticImageIsMask;
|
||||
BOOL mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture. Use alpha as a mask
|
||||
BOOL mIsVisibilityMask;
|
||||
|
||||
typedef std::vector<std::pair<std::string,BOOL> > morph_name_list_t;
|
||||
morph_name_list_t mMorphNameList;
|
||||
@@ -205,14 +207,13 @@ protected:
|
||||
class LLTexLayerSetBuffer : public LLDynamicTexture
|
||||
{
|
||||
public:
|
||||
LLTexLayerSetBuffer( LLTexLayerSet* owner, S32 width, S32 height, BOOL has_bump );
|
||||
LLTexLayerSetBuffer(LLTexLayerSet* owner, S32 width, S32 height);
|
||||
virtual ~LLTexLayerSetBuffer();
|
||||
|
||||
virtual void preRender(BOOL clear_depth);
|
||||
virtual void postRender(BOOL success);
|
||||
virtual BOOL render();
|
||||
BOOL updateImmediate();
|
||||
void bindBumpTexture( U32 stage );
|
||||
bool isInitialized(void) const;
|
||||
BOOL needsRender();
|
||||
void requestUpdate();
|
||||
@@ -220,8 +221,7 @@ public:
|
||||
void cancelUpload();
|
||||
BOOL uploadPending() { return mUploadPending; }
|
||||
BOOL render( S32 x, S32 y, S32 width, S32 height );
|
||||
void readBackAndUpload(U8* baked_bump_data);
|
||||
void createBumpTexture() ;
|
||||
void readBackAndUpload();
|
||||
|
||||
static void onTextureUploadComplete( const LLUUID& uuid,
|
||||
void* userdata,
|
||||
@@ -236,16 +236,13 @@ private:
|
||||
void popProjection();
|
||||
|
||||
private:
|
||||
BOOL mHasBump ;
|
||||
BOOL mNeedsUpdate;
|
||||
BOOL mNeedsUpload;
|
||||
BOOL mUploadPending;
|
||||
LLUUID mUploadID; // Identifys the current upload process (null if none). Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit)
|
||||
LLTexLayerSet* mTexLayerSet;
|
||||
LLPointer<LLImageGL> mBumpTex; // zero if none
|
||||
|
||||
static S32 sGLByteCount;
|
||||
static S32 sGLBumpByteCount;
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -254,6 +251,7 @@ private:
|
||||
//-----------------------------------------------------------------------------
|
||||
class LLTexLayerSet
|
||||
{
|
||||
friend class LLTexLayerSetBuffer;
|
||||
public:
|
||||
LLTexLayerSet( LLVOAvatar* avatar );
|
||||
~LLTexLayerSet();
|
||||
@@ -264,7 +262,7 @@ public:
|
||||
BOOL setInfo(LLTexLayerSetInfo *info);
|
||||
|
||||
BOOL render( S32 x, S32 y, S32 width, S32 height );
|
||||
BOOL renderBump( S32 x, S32 y, S32 width,S32 height );
|
||||
void renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false);
|
||||
BOOL isBodyRegion( const std::string& region ) { return mInfo->mBodyRegion == region; }
|
||||
LLTexLayerSetBuffer* getComposite();
|
||||
void requestUpdate();
|
||||
@@ -283,8 +281,9 @@ public:
|
||||
void applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
|
||||
const std::string getBodyRegion() { return mInfo->mBodyRegion; }
|
||||
BOOL hasComposite() { return (mComposite != NULL); }
|
||||
void setBump( BOOL b ) { mHasBump = b; }
|
||||
BOOL hasBump() { return mHasBump; }
|
||||
LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; }
|
||||
void setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
|
||||
BOOL isVisible() const { return mIsVisible; }
|
||||
|
||||
public:
|
||||
static BOOL sHasCaches;
|
||||
@@ -292,11 +291,14 @@ public:
|
||||
protected:
|
||||
typedef std::vector<LLTexLayer *> layer_list_t;
|
||||
layer_list_t mLayerList;
|
||||
layer_list_t mMaskLayerList;
|
||||
LLTexLayerSetBuffer* mComposite;
|
||||
// Backlink only; don't make this an LLPointer.
|
||||
LLVOAvatar* mAvatar;
|
||||
BOOL mUpdatesEnabled;
|
||||
BOOL mHasBump;
|
||||
BOOL mIsVisible;
|
||||
|
||||
LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex;
|
||||
|
||||
LLTexLayerSetInfo *mInfo;
|
||||
};
|
||||
@@ -348,6 +350,9 @@ public:
|
||||
BOOL renderImageRaw( U8* in_data, S32 in_width, S32 in_height, S32 in_components, S32 width, S32 height, BOOL is_mask );
|
||||
BOOL renderAlphaMasks( S32 x, S32 y, S32 width, S32 height, LLColor4* colorp );
|
||||
BOOL hasAlphaParams() { return (!mParamAlphaList.empty());}
|
||||
BOOL blendAlphaTexture(S32 x, S32 y, S32 width, S32 height);
|
||||
BOOL isVisibilityMask() const;
|
||||
BOOL isInvisibleAlphaMask();
|
||||
|
||||
protected:
|
||||
LLTexLayerSet* mTexLayerSet;
|
||||
|
||||
@@ -1342,6 +1342,10 @@ void LLTextureCtrl::draw()
|
||||
mTexturep = gImageList.getImageFromFile(mFallbackImageName);
|
||||
mTexturep->setBoostLevel(LLViewerImageBoostLevel::BOOST_PREVIEW);
|
||||
}
|
||||
else // mImageAssetID == LLUUID::null
|
||||
{
|
||||
mTexturep = NULL;
|
||||
}
|
||||
|
||||
// Border
|
||||
LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
|
||||
|
||||
@@ -7764,6 +7764,14 @@ class LLEditEnableTakeOff : public view_listener_t
|
||||
{
|
||||
new_value = LLAgent::selfHasWearable((void *)WT_SKIRT);
|
||||
}
|
||||
if (clothing == "alpha")
|
||||
{
|
||||
new_value = LLAgent::selfHasWearable((void *)WT_ALPHA);
|
||||
}
|
||||
if (clothing == "tattoo")
|
||||
{
|
||||
new_value = LLAgent::selfHasWearable((void *)WT_TATTOO);
|
||||
}
|
||||
gMenuHolder->findControl(control_name)->setValue(new_value);
|
||||
return true;
|
||||
}
|
||||
@@ -7810,6 +7818,14 @@ class LLEditTakeOff : public view_listener_t
|
||||
{
|
||||
LLAgent::userRemoveWearable((void*)WT_SKIRT);
|
||||
}
|
||||
else if (clothing == "alpha")
|
||||
{
|
||||
LLAgent::userRemoveWearable((void*)WT_ALPHA);
|
||||
}
|
||||
else if (clothing == "tattoo")
|
||||
{
|
||||
LLAgent::userRemoveWearable((void*)WT_TATTOO);
|
||||
}
|
||||
else if (clothing == "all")
|
||||
{
|
||||
LLAgent::userRemoveAllClothes(NULL);
|
||||
|
||||
@@ -753,7 +753,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
|
||||
mNeedsSkin(FALSE),
|
||||
mUpdatePeriod(1),
|
||||
mFullyLoadedInitialized(FALSE),
|
||||
mHasBakedHair( FALSE )
|
||||
mHasBakedHair( FALSE ),
|
||||
mSupportsAlphaLayers(FALSE)
|
||||
// <edit>
|
||||
// mNametagSaysIdle(false),
|
||||
// mIdleForever(true),
|
||||
@@ -4351,15 +4352,9 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
|
||||
|
||||
if (pass == AVATAR_RENDER_PASS_SINGLE)
|
||||
{
|
||||
const bool should_alpha_mask = mHasBakedHair && isTextureDefined(TEX_HEAD_BAKED) && isTextureDefined(TEX_UPPER_BAKED)
|
||||
&& isTextureDefined(TEX_LOWER_BAKED)
|
||||
&& mBakedTextureData[BAKED_HEAD].mIsLoaded
|
||||
&& mBakedTextureData[BAKED_UPPER].mIsLoaded && mBakedTextureData[BAKED_LOWER].mIsLoaded
|
||||
&& mBakedTextureData[BAKED_HEAD].mIsUsed
|
||||
&& mBakedTextureData[BAKED_UPPER].mIsUsed && mBakedTextureData[BAKED_LOWER].mIsUsed
|
||||
&& !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
|
||||
&& !(isSelf() && gAgent.cameraCustomizeAvatar()); // don't alpha mask if in customize mode
|
||||
|
||||
const bool should_alpha_mask = mSupportsAlphaLayers && mHasBakedHair
|
||||
&& !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
|
||||
&& !LLDrawPoolAvatar::sSkipTransparent;
|
||||
LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
|
||||
|
||||
if (should_alpha_mask)
|
||||
@@ -4471,27 +4466,25 @@ U32 LLVOAvatar::renderRigid()
|
||||
return 0;
|
||||
}
|
||||
|
||||
const bool should_alpha_mask = mSupportsAlphaLayers && mHasBakedHair
|
||||
&& !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
|
||||
&& !LLDrawPoolAvatar::sSkipTransparent;
|
||||
|
||||
LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
|
||||
|
||||
if (should_alpha_mask)
|
||||
{
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
|
||||
}
|
||||
|
||||
if (isTextureVisible(TEX_EYES_BAKED) || mIsDummy)
|
||||
{
|
||||
// If the meshes need to be drawn, enable alpha masking but not blending
|
||||
bool should_alpha_mask = mHasBakedHair
|
||||
&& mBakedTextureData[BAKED_EYES].mIsLoaded
|
||||
&& mBakedTextureData[BAKED_EYES].mIsUsed
|
||||
&& !(isSelf() && gAgent.cameraCustomizeAvatar());
|
||||
|
||||
LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
|
||||
|
||||
if (should_alpha_mask)
|
||||
{
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
|
||||
}
|
||||
|
||||
num_indices += mMeshLOD[MESH_ID_EYEBALL_LEFT]->render(mAdjustedPixelArea, TRUE, mIsDummy);
|
||||
num_indices += mMeshLOD[MESH_ID_EYEBALL_RIGHT]->render(mAdjustedPixelArea, TRUE, mIsDummy);
|
||||
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
|
||||
}
|
||||
|
||||
|
||||
gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
|
||||
|
||||
return num_indices;
|
||||
}
|
||||
|
||||
@@ -4664,6 +4657,7 @@ void LLVOAvatar::updateTextures()
|
||||
// Spam if this is a baked texture, not set to default image, without valid host info
|
||||
if (isIndexBakedTexture((ETextureIndex)index)
|
||||
&& imagep->getID() != IMG_DEFAULT_AVATAR
|
||||
&& imagep->getID() != IMG_INVISIBLE
|
||||
&& !imagep->getTargetHost().isOk())
|
||||
{
|
||||
LL_WARNS_ONCE("Texture") << "LLVOAvatar::updateTextures No host for texture "
|
||||
@@ -5457,6 +5451,7 @@ BOOL LLVOAvatar::loadAvatar()
|
||||
if (layer_set->isBodyRegion(baked_dict->mName))
|
||||
{
|
||||
mBakedTextureData[baked_iter->first].mTexLayerSet = layer_set;
|
||||
layer_set->setBakedTexIndex(baked_iter->first);
|
||||
found_baked_entry = true;
|
||||
break;
|
||||
}
|
||||
@@ -7230,6 +7225,9 @@ void LLVOAvatar::updateMeshTextures()
|
||||
|
||||
}
|
||||
|
||||
// Turn on alpha masking correctly for yourself and other avatars on 1.23+
|
||||
mSupportsAlphaLayers = isSelf() || is_layer_baked[BAKED_HAIR];
|
||||
|
||||
// Baked textures should be requested from the sim this avatar is on. JC
|
||||
const LLHost target_host = getObjectHost();
|
||||
if (!target_host.isOk())
|
||||
@@ -7259,7 +7257,7 @@ void LLVOAvatar::updateMeshTextures()
|
||||
else
|
||||
{
|
||||
mBakedTextureData[i].mIsLoaded = FALSE;
|
||||
if ( (i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER) )
|
||||
if ((baked_img->getID() != IMG_INVISIBLE) && (i == BAKED_HEAD || i == BAKED_UPPER || i == BAKED_LOWER))
|
||||
{
|
||||
baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));
|
||||
}
|
||||
@@ -7531,7 +7529,13 @@ void LLVOAvatar::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
|
||||
// Baked textures live on other sims.
|
||||
LLHost target_host = getObjectHost();
|
||||
setTEImage( te, gImageList.getImageFromHost( uuid, target_host ) );
|
||||
updateMeshTextures();
|
||||
if (uuid != IMG_INVISIBLE)
|
||||
{
|
||||
// Do not update textures when setting a new invisible baked texture as
|
||||
// it would result in destroying the calling object (setNewBakedTexture()
|
||||
// is called by LLTexLayerSetBuffer::render()) !
|
||||
updateMeshTextures();
|
||||
}
|
||||
dirtyMesh();
|
||||
|
||||
|
||||
@@ -7544,7 +7548,7 @@ void LLVOAvatar::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
|
||||
if (text_dict->mIsBakedTexture)
|
||||
{
|
||||
llinfos << "New baked texture: " << text_dict->mName << " UUID: " << uuid <<llendl;
|
||||
mBakedTextureData[text_dict->mBakedTextureIndex].mTexLayerSet->requestUpdate();
|
||||
//mBakedTextureData[text_dict->mBakedTextureIndex].mTexLayerSet->requestUpdate();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -7788,6 +7792,10 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context )
|
||||
{
|
||||
llinfos << " " << text_dict->mName << ": IMG_DEFAULT" << llendl;
|
||||
}
|
||||
else if (te_image->getID() == IMG_INVISIBLE)
|
||||
{
|
||||
llinfos << " " << text_dict->mName << ": IMG_INVISIBLE" << llendl;
|
||||
}
|
||||
else if( te_image->getID() == IMG_DEFAULT_AVATAR )
|
||||
{
|
||||
llinfos << " " << text_dict->mName << ": IMG_DEFAULT_AVATAR" << llendl;
|
||||
@@ -7959,11 +7967,11 @@ BOOL LLVOAvatar::isWearingWearableType( EWearableType type )
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// updatedWearable( EWearableType type )
|
||||
// wearableUpdated(EWearableType type, BOOL upload_result)
|
||||
// forces an update to any baked textures relevant to type.
|
||||
// Should be called only on saving the wearable
|
||||
// will force an upload of the resulting bake if the second parameter is TRUE
|
||||
//-----------------------------------------------------------------------------
|
||||
void LLVOAvatar::wearableUpdated( EWearableType type )
|
||||
void LLVOAvatar::wearableUpdated(EWearableType type, BOOL upload_result)
|
||||
{
|
||||
for (LLVOAvatarDictionary::wearable_map_t::const_iterator wearable_iter = LLVOAvatarDictionary::getInstance()->getWearables().begin();
|
||||
wearable_iter != LLVOAvatarDictionary::getInstance()->getWearables().end();
|
||||
@@ -7982,8 +7990,8 @@ void LLVOAvatar::wearableUpdated( EWearableType type )
|
||||
{
|
||||
if (mBakedTextureData[index].mTexLayerSet)
|
||||
{
|
||||
mBakedTextureData[index].mTexLayerSet->requestUpdate();
|
||||
mBakedTextureData[index].mTexLayerSet->requestUpload();
|
||||
invalidateComposite(mBakedTextureData[index].mTexLayerSet, upload_result);
|
||||
updateMeshTextures();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -8082,7 +8090,7 @@ void LLVOAvatar::onFirstTEMessageReceived()
|
||||
LLViewerImage* image = getTEImage( mBakedTextureData[i].mTextureIndex );
|
||||
mBakedTextureData[i].mLastTextureIndex = image->getID();
|
||||
// If we have more than one texture for the other baked layers, we'll want to call this for them too.
|
||||
if ( (i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER) )
|
||||
if ((image->getID() != IMG_INVISIBLE) && (i == BAKED_HEAD || i == BAKED_UPPER || i == BAKED_LOWER))
|
||||
{
|
||||
image->setLoadedCallback( onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ));
|
||||
}
|
||||
@@ -8342,7 +8350,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerImage *src_vi,
|
||||
{
|
||||
const ETextureIndex texture_index = iter->first;
|
||||
const LLViewerImage *baked_img = self->getTEImage(texture_index);
|
||||
if (id == baked_img->getID())
|
||||
if (baked_img && id == baked_img->getID())
|
||||
{
|
||||
const EBakedTextureIndex baked_index = text_dict->mBakedTextureIndex;
|
||||
if (self->mBakedTextureData[baked_index].mTexLayerSet)
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "imageids.h" // IMG_INVISIBLE
|
||||
#include "llchat.h"
|
||||
#include "lldrawpoolalpha.h"
|
||||
#include "llviewerobject.h"
|
||||
@@ -342,7 +343,7 @@ public:
|
||||
BOOL teToColorParams( LLVOAvatarDefines::ETextureIndex te, const char* param_name[3] );
|
||||
|
||||
BOOL isWearingWearableType( EWearableType type );
|
||||
void wearableUpdated( EWearableType type );
|
||||
void wearableUpdated(EWearableType type, BOOL upload_result = TRUE);
|
||||
|
||||
//--------------------------------------------------------------------
|
||||
// texture compositing
|
||||
@@ -550,6 +551,7 @@ private:
|
||||
BOOL mIsBuilt; // state of deferred character building
|
||||
F32 mSpeedAccum; // measures speed (for diagnostics mostly).
|
||||
|
||||
BOOL mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients
|
||||
|
||||
// LLFrameTimer mUpdateLODTimer; // controls frequency of LOD change calculations
|
||||
BOOL mDirtyMesh;
|
||||
@@ -777,7 +779,7 @@ inline BOOL LLVOAvatar::isTextureDefined(U8 te) const
|
||||
|
||||
inline BOOL LLVOAvatar::isTextureVisible(U8 te) const
|
||||
{
|
||||
return ((isTextureDefined(te) || isSelf())
|
||||
return ((isTextureDefined(te) || mIsSelf)
|
||||
&& (getTEImage(te)->getID() != IMG_INVISIBLE
|
||||
|| LLDrawPoolAlpha::sShowDebugAlpha));
|
||||
}
|
||||
|
||||
@@ -60,6 +60,14 @@ void LLVOAvatarDictionary::initData()
|
||||
mTextureMap[TEX_UPPER_UNDERSHIRT] = new TextureDictionaryEntry("undershirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", WT_UNDERSHIRT);
|
||||
mTextureMap[TEX_LOWER_UNDERPANTS] = new TextureDictionaryEntry("underpants", TRUE, BAKED_NUM_INDICES, "UIImgDefaultUnderwearUUID", WT_UNDERPANTS);
|
||||
mTextureMap[TEX_SKIRT] = new TextureDictionaryEntry("skirt", TRUE, BAKED_NUM_INDICES, "UIImgDefaultSkirtUUID", WT_SKIRT);
|
||||
mTextureMap[TEX_LOWER_ALPHA] = new TextureDictionaryEntry("lower_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA);
|
||||
mTextureMap[TEX_UPPER_ALPHA] = new TextureDictionaryEntry("upper_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA);
|
||||
mTextureMap[TEX_HEAD_ALPHA] = new TextureDictionaryEntry("head_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA);
|
||||
mTextureMap[TEX_EYES_ALPHA] = new TextureDictionaryEntry("eyes_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA);
|
||||
mTextureMap[TEX_HAIR_ALPHA] = new TextureDictionaryEntry("hair_alpha", TRUE, BAKED_NUM_INDICES, "UIImgDefaultAlphaUUID", WT_ALPHA);
|
||||
mTextureMap[TEX_HEAD_TATTOO] = new TextureDictionaryEntry("head_tattoo", TRUE, BAKED_NUM_INDICES, "", WT_TATTOO);
|
||||
mTextureMap[TEX_UPPER_TATTOO] = new TextureDictionaryEntry("upper_tattoo", TRUE, BAKED_NUM_INDICES, "", WT_TATTOO);
|
||||
mTextureMap[TEX_LOWER_TATTOO] = new TextureDictionaryEntry("lower_tattoo", TRUE, BAKED_NUM_INDICES, "", WT_TATTOO);
|
||||
mTextureMap[TEX_HEAD_BAKED] = new TextureDictionaryEntry("head-baked", FALSE, BAKED_HEAD);
|
||||
mTextureMap[TEX_UPPER_BAKED] = new TextureDictionaryEntry("upper-baked", FALSE, BAKED_UPPER);
|
||||
mTextureMap[TEX_LOWER_BAKED] = new TextureDictionaryEntry("lower-baked", FALSE, BAKED_LOWER);
|
||||
@@ -68,12 +76,12 @@ void LLVOAvatarDictionary::initData()
|
||||
mTextureMap[TEX_SKIRT_BAKED] = new TextureDictionaryEntry("skirt-baked", FALSE, BAKED_SKIRT);
|
||||
|
||||
// Baked textures
|
||||
mBakedTextureMap[BAKED_HEAD] = new BakedDictionaryEntry(TEX_HEAD_BAKED, "head", 1, TEX_HEAD_BODYPAINT);
|
||||
mBakedTextureMap[BAKED_UPPER] = new BakedDictionaryEntry(TEX_UPPER_BAKED, "upper_body", 5, TEX_UPPER_SHIRT,TEX_UPPER_BODYPAINT,TEX_UPPER_JACKET,TEX_UPPER_GLOVES,TEX_UPPER_UNDERSHIRT);
|
||||
mBakedTextureMap[BAKED_LOWER] = new BakedDictionaryEntry(TEX_LOWER_BAKED, "lower_body", 6, TEX_LOWER_PANTS,TEX_LOWER_BODYPAINT,TEX_LOWER_SHOES,TEX_LOWER_SOCKS,TEX_LOWER_JACKET,TEX_LOWER_UNDERPANTS);
|
||||
mBakedTextureMap[BAKED_EYES] = new BakedDictionaryEntry(TEX_EYES_BAKED, "eyes", 1, TEX_EYES_IRIS);
|
||||
mBakedTextureMap[BAKED_HEAD] = new BakedDictionaryEntry(TEX_HEAD_BAKED, "head", 3, TEX_HEAD_BODYPAINT, TEX_HEAD_TATTOO, TEX_HEAD_ALPHA);
|
||||
mBakedTextureMap[BAKED_UPPER] = new BakedDictionaryEntry(TEX_UPPER_BAKED, "upper_body", 7, TEX_UPPER_SHIRT, TEX_UPPER_BODYPAINT, TEX_UPPER_JACKET, TEX_UPPER_GLOVES, TEX_UPPER_UNDERSHIRT, TEX_UPPER_TATTOO, TEX_UPPER_ALPHA);
|
||||
mBakedTextureMap[BAKED_LOWER] = new BakedDictionaryEntry(TEX_LOWER_BAKED, "lower_body", 8, TEX_LOWER_PANTS, TEX_LOWER_BODYPAINT, TEX_LOWER_SHOES, TEX_LOWER_SOCKS, TEX_LOWER_JACKET, TEX_LOWER_UNDERPANTS, TEX_LOWER_TATTOO, TEX_LOWER_ALPHA);
|
||||
mBakedTextureMap[BAKED_EYES] = new BakedDictionaryEntry(TEX_EYES_BAKED, "eyes", 2, TEX_EYES_IRIS, TEX_EYES_ALPHA);
|
||||
mBakedTextureMap[BAKED_SKIRT] = new BakedDictionaryEntry(TEX_SKIRT_BAKED, "skirt", 1, TEX_SKIRT);
|
||||
mBakedTextureMap[BAKED_HAIR] = new BakedDictionaryEntry(TEX_HAIR_BAKED, "hair", 1, TEX_HAIR);
|
||||
mBakedTextureMap[BAKED_HAIR] = new BakedDictionaryEntry(TEX_HAIR_BAKED, "hair", 2, TEX_HAIR, TEX_HAIR_ALPHA);
|
||||
|
||||
// Meshes
|
||||
mMeshMap[MESH_ID_HAIR] = new MeshDictionaryEntry(BAKED_HAIR, "hairMesh", 6, LLViewerJoint::PN_4);
|
||||
@@ -86,12 +94,12 @@ void LLVOAvatarDictionary::initData()
|
||||
mMeshMap[MESH_ID_SKIRT] = new MeshDictionaryEntry(BAKED_SKIRT, "skirtMesh", 5, LLViewerJoint::PN_5);
|
||||
|
||||
// Wearables
|
||||
mWearableMap[BAKED_HEAD] = new WearableDictionaryEntry("18ded8d6-bcfc-e415-8539-944c0f5ea7a6", 3, WT_SHAPE, WT_SKIN, WT_HAIR);
|
||||
mWearableMap[BAKED_UPPER] = new WearableDictionaryEntry("338c29e3-3024-4dbb-998d-7c04cf4fa88f", 6, WT_SHAPE, WT_SKIN, WT_SHIRT, WT_JACKET, WT_GLOVES, WT_UNDERSHIRT);
|
||||
mWearableMap[BAKED_LOWER] = new WearableDictionaryEntry("91b4a2c7-1b1a-ba16-9a16-1f8f8dcc1c3f", 7, WT_SHAPE, WT_SKIN, WT_PANTS, WT_SHOES, WT_SOCKS, WT_JACKET, WT_UNDERPANTS);
|
||||
mWearableMap[BAKED_EYES] = new WearableDictionaryEntry("b2cf28af-b840-1071-3c6a-78085d8128b5", 1, WT_EYES);
|
||||
mWearableMap[BAKED_HEAD] = new WearableDictionaryEntry("18ded8d6-bcfc-e415-8539-944c0f5ea7a6", 5, WT_SHAPE, WT_SKIN, WT_HAIR, WT_TATTOO, WT_ALPHA);
|
||||
mWearableMap[BAKED_UPPER] = new WearableDictionaryEntry("338c29e3-3024-4dbb-998d-7c04cf4fa88f", 8, WT_SHAPE, WT_SKIN, WT_SHIRT, WT_JACKET, WT_GLOVES, WT_UNDERSHIRT, WT_TATTOO, WT_ALPHA);
|
||||
mWearableMap[BAKED_LOWER] = new WearableDictionaryEntry("91b4a2c7-1b1a-ba16-9a16-1f8f8dcc1c3f", 9, WT_SHAPE, WT_SKIN, WT_PANTS, WT_SHOES, WT_SOCKS, WT_JACKET, WT_UNDERPANTS, WT_TATTOO, WT_ALPHA);
|
||||
mWearableMap[BAKED_EYES] = new WearableDictionaryEntry("b2cf28af-b840-1071-3c6a-78085d8128b5", 2, WT_EYES, WT_ALPHA);
|
||||
mWearableMap[BAKED_SKIRT] = new WearableDictionaryEntry("ea800387-ea1a-14e0-56cb-24f2022f969a", 1, WT_SKIRT);
|
||||
mWearableMap[BAKED_HAIR] = new WearableDictionaryEntry("0af1ef7c-ad24-11dd-8790-001f5bf833e8", 1, WT_HAIR);
|
||||
mWearableMap[BAKED_HAIR] = new WearableDictionaryEntry("0af1ef7c-ad24-11dd-8790-001f5bf833e8", 2, WT_HAIR, WT_ALPHA);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -71,9 +71,16 @@ enum ETextureIndex
|
||||
TEX_SKIRT,
|
||||
TEX_SKIRT_BAKED, // Pre-composited
|
||||
TEX_HAIR_BAKED, // Pre-composited
|
||||
TEX_LOWER_ALPHA,
|
||||
TEX_UPPER_ALPHA,
|
||||
TEX_HEAD_ALPHA,
|
||||
TEX_EYES_ALPHA,
|
||||
TEX_HAIR_ALPHA,
|
||||
TEX_HEAD_TATTOO,
|
||||
TEX_UPPER_TATTOO,
|
||||
TEX_LOWER_TATTOO,
|
||||
TEX_NUM_INDICES
|
||||
}; // "Note: if TEX_NUM_ENTRIES changes, update AGENT_TEXTURES in llagentinfo.h, mTextureIndexBaked, and BAKED_TEXTURE_COUNT"
|
||||
// Seraph - Above comment about order is probably obsolete.
|
||||
};
|
||||
|
||||
typedef std::vector<ETextureIndex> texture_vec_t;
|
||||
|
||||
|
||||
@@ -70,6 +70,8 @@ const std::string LLWearable::sTypeName[ WT_COUNT+1 ] =
|
||||
"undershirt",
|
||||
"underpants",
|
||||
"skirt",
|
||||
"alpha",
|
||||
"tattoo",
|
||||
"invalid"
|
||||
};
|
||||
|
||||
@@ -89,6 +91,8 @@ const std::string LLWearable::sTypeLabel[ WT_COUNT+1 ] =
|
||||
"Undershirt",
|
||||
"Underpants",
|
||||
"Skirt",
|
||||
"Alpha",
|
||||
"Tattoo",
|
||||
"invalid"
|
||||
};
|
||||
|
||||
@@ -112,6 +116,8 @@ LLAssetType::EType LLWearable::typeToAssetType(EWearableType wearable_type)
|
||||
case WT_UNDERSHIRT:
|
||||
case WT_UNDERPANTS:
|
||||
case WT_SKIRT:
|
||||
case WT_ALPHA:
|
||||
case WT_TATTOO:
|
||||
return LLAssetType::AT_CLOTHING;
|
||||
default:
|
||||
return LLAssetType::AT_NONE;
|
||||
|
||||
@@ -56,7 +56,9 @@ enum EWearableType // If you change this, update LLWearable::getTypeName(), get
|
||||
WT_UNDERSHIRT = 10,
|
||||
WT_UNDERPANTS = 11,
|
||||
WT_SKIRT = 12,
|
||||
WT_COUNT = 13,
|
||||
WT_ALPHA = 13,
|
||||
WT_TATTOO = 14,
|
||||
WT_COUNT = 15,
|
||||
WT_INVALID = 255
|
||||
};
|
||||
|
||||
|
||||
@@ -1126,6 +1126,174 @@ scratch and wear it.
|
||||
height="20" label="Revert" label_selected="Revert" left="305"
|
||||
mouse_opaque="true" name="Revert" scale_image="true" width="82" />
|
||||
</panel>
|
||||
<panel name="Tattoo" label="Tattoo" border="true" mouse_opaque="true"
|
||||
follows="left|top|right|bottom" width="389" height="481" left="102" bottom="-482">
|
||||
<icon bottom="-21" color="1 1 1 1" follows="top|right" height="16"
|
||||
image_name="icon_lock.tga" left="333" mouse_opaque="true" name="square"
|
||||
width="16" />
|
||||
<icon bottom="-24" color="1 1 1 1" follows="left|top" height="16" left="8"
|
||||
mouse_opaque="true" name="icon" width="16" />
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-24" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="left" height="16" left="26"
|
||||
mouse_opaque="true" name="title" v_pad="0" width="355">
|
||||
[DESC]
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-24" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="left" height="16" left="26"
|
||||
mouse_opaque="true" name="title_no_modify" v_pad="0" width="355">
|
||||
[DESC]: cannot modify
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-24" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="left" height="16" left="26"
|
||||
mouse_opaque="true" name="title_loading" v_pad="0" width="355">
|
||||
[DESC]: loading...
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-24" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="left" height="16" left="26"
|
||||
mouse_opaque="true" name="title_not_worn" v_pad="0" width="355">
|
||||
[DESC]: not worn
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-38" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="14" left="8"
|
||||
mouse_opaque="true" name="path" v_pad="0" width="373">
|
||||
Located in [PATH]
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-74" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="28" left="8"
|
||||
mouse_opaque="true" name="not worn instructions" v_pad="0" width="373">
|
||||
Put on a new tattoo by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-74" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="28" left="8"
|
||||
mouse_opaque="true" name="no modify instructions" v_pad="0" width="373">
|
||||
You do not have permission to modify this wearable.
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-486" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="right" height="28" right="117"
|
||||
mouse_opaque="true" name="Item Action Label" v_pad="0" width="100">
|
||||
Tattoo:
|
||||
</text>
|
||||
<texture_picker name="Head Tattoo" label="Head Tattoo" tool_tip="Click to choose a picture"
|
||||
can_apply_immediately="true" default_image_name="Default" allow_no_texture="true"
|
||||
follows="left|top" width="70" height="80" left="14" bottom="-145"/>
|
||||
<texture_picker name="Upper Tattoo" label="Upper Tattoo" tool_tip="Click to choose a picture"
|
||||
can_apply_immediately="true" default_image_name="Default" allow_no_texture="true"
|
||||
follows="left|top" width="70" height="80" left="14" bottom="-235"/>
|
||||
<texture_picker name="Lower Tattoo" label="Lower Tattoo" tool_tip="Click to choose a picture"
|
||||
can_apply_immediately="true" default_image_name="Default" allow_no_texture="true"
|
||||
follows="left|top" width="70" height="80" left="14" bottom="-325"/>
|
||||
<button name="Create New" label="Create New Tattoo" label_selected="Create New Tattoo"
|
||||
follows="left|top" halign="center" width="170" height="24" left="8" bottom="-128"
|
||||
mouse_opaque="true" scale_image="true"/>
|
||||
<button name="Take Off" label="Take Off" label_selected="Take Off"
|
||||
follows="left|top" width="82" height="20" left="8" bottom="-365"/>
|
||||
<button name="Save" label="Save" label_selected="Save"
|
||||
follows="right|bottom" width="82" height="20" left="123" bottom="-478"/>
|
||||
<button name="Save As" label="Save As..." label_selected="Save As..."
|
||||
follows="right|bottom" width="92" height="20" left="209" bottom="-478"/>
|
||||
<button name="Revert" label="Revert" label_selected="Revert"
|
||||
follows="right|bottom" width="82" height="20" left="305" bottom="-478"/>
|
||||
</panel>
|
||||
<panel name="Alpha" label="Alpha" border="true" mouse_opaque="true"
|
||||
follows="left|top|right|bottom" width="389" height="481" left="102" bottom="-482">
|
||||
<icon bottom="-21" color="1 1 1 1" follows="top|right" height="16"
|
||||
image_name="icon_lock.tga" left="333" mouse_opaque="true" name="square"
|
||||
width="16" />
|
||||
<icon bottom="-24" color="1 1 1 1" follows="left|top" height="16" left="8"
|
||||
mouse_opaque="true" name="icon" width="16" />
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-24" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="left" height="16" left="26"
|
||||
mouse_opaque="true" name="title" v_pad="0" width="355">
|
||||
[DESC]
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-24" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="left" height="16" left="26"
|
||||
mouse_opaque="true" name="title_no_modify" v_pad="0" width="355">
|
||||
[DESC]: cannot modify
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-24" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="left" height="16" left="26"
|
||||
mouse_opaque="true" name="title_loading" v_pad="0" width="355">
|
||||
[DESC]: loading...
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-24" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="left" height="16" left="26"
|
||||
mouse_opaque="true" name="title_not_worn" v_pad="0" width="355">
|
||||
[DESC]: not worn
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-38" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="14" left="8"
|
||||
mouse_opaque="true" name="path" v_pad="0" width="373">
|
||||
Located in [PATH]
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-74" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="28" left="8"
|
||||
mouse_opaque="true" name="not worn instructions" v_pad="0" width="373">
|
||||
Put on a new alpha mask by dragging one from your inventory to your avatar. Alternately, you create a new one from scratch and wear it.
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-74" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="28" left="8"
|
||||
mouse_opaque="true" name="no modify instructions" v_pad="0" width="373">
|
||||
You do not have permission to modify this wearable.
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-486" drop_shadow_visible="true" follows="left|top|right"
|
||||
font="SansSerif" h_pad="0" halign="right" height="28" right="117"
|
||||
mouse_opaque="true" name="Item Action Label" v_pad="0" width="100">
|
||||
Alpha:
|
||||
</text>
|
||||
<texture_picker name="Head Alpha" label="Head Alpha" tool_tip="Click to choose a picture"
|
||||
can_apply_immediately="true" default_image_name="Default" allow_no_texture="true"
|
||||
follows="left|top" width="64" height="80" left="120" bottom="-165"/>
|
||||
<texture_picker name="Upper Alpha" label="Upper Alpha" tool_tip="Click to choose a picture"
|
||||
can_apply_immediately="true" default_image_name="Default" allow_no_texture="true"
|
||||
follows="left|top" width="64" height="80" left_delta="90" bottom="-165"/>
|
||||
<texture_picker name="Lower Alpha" label="Lower Alpha" tool_tip="Click to choose a picture"
|
||||
can_apply_immediately="true" default_image_name="Default" allow_no_texture="true"
|
||||
follows="left|top" width="64" height="80" left_delta="90" bottom="-165"/>
|
||||
<check_box name="head alpha texture invisible"
|
||||
follows="left" width="16" height="16" left="142" bottom="-185"/>
|
||||
<check_box name="upper alpha texture invisible"
|
||||
follows="left" width="16" height="16" left_delta="90" bottom="-185"/>
|
||||
<check_box name="lower alpha texture invisible"
|
||||
follows="left" width="16" height="16" left_delta="90" bottom="-185"/>
|
||||
<texture_picker name="Hair Alpha" label="Hair Alpha" tool_tip="Click to choose a picture"
|
||||
can_apply_immediately="true" default_image_name="Default" allow_no_texture="true"
|
||||
follows="left|top" width="64" height="80" left="120" bottom="-280"/>
|
||||
<texture_picker name="Eye Alpha" label="Eye Alpha" tool_tip="Click to choose a picture"
|
||||
can_apply_immediately="true" default_image_name="Default" allow_no_texture="true"
|
||||
follows="left|top" width="64" height="80" left_delta="90" bottom="-280"/>
|
||||
<check_box name="hair alpha texture invisible"
|
||||
follows="left" width="16" height="16" left="142" bottom="-300"/>
|
||||
<check_box name="eye alpha texture invisible"
|
||||
follows="left" width="16" height="16" left_delta="90" bottom="-300"/>
|
||||
<button name="Create New" label="Create New Alpha" label_selected="Create New Alpha"
|
||||
follows="left|top" halign="center" width="170" height="24" left="8" bottom="-128"
|
||||
mouse_opaque="true" scale_image="true"/>
|
||||
<button name="Take Off" label="Take Off" label_selected="Take Off"
|
||||
follows="left|top" width="82" height="20" left="123" bottom="-340"/>
|
||||
<button name="Save" label="Save" label_selected="Save"
|
||||
follows="right|bottom" width="82" height="20" left="123" bottom="-478"/>
|
||||
<button name="Save As" label="Save As..." label_selected="Save As..."
|
||||
follows="right|bottom" width="92" height="20" left="209" bottom="-478"/>
|
||||
<button name="Revert" label="Revert" label_selected="Revert"
|
||||
follows="right|bottom" width="82" height="20" left="305" bottom="-478"/>
|
||||
</panel>
|
||||
</tab_container>
|
||||
<scroll_container bottom="-476" follows="left|top|right|bottom" height="382" left="197"
|
||||
mouse_opaque="false" name="panel_container" opaque="false" width="292" />
|
||||
|
||||
@@ -118,6 +118,14 @@
|
||||
mouse_opaque="true" name="New Underpants" width="125">
|
||||
<on_click filter="" function="Inventory.DoCreate" userdata="underpants" />
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom_delta="-18" height="18" label="New Tattoo" left="0"
|
||||
mouse_opaque="true" name="New Tattoo" width="125">
|
||||
<on_click filter="" function="Inventory.DoCreate" userdata="tattoo" />
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom_delta="-18" height="18" label="New Alpha" left="0"
|
||||
mouse_opaque="true" name="New Alpha" width="125">
|
||||
<on_click filter="" function="Inventory.DoCreate" userdata="alpha" />
|
||||
</menu_item_call>
|
||||
</menu>
|
||||
<menu bottom_delta="-599" drop_shadow="true" height="85" left="0"
|
||||
mouse_opaque="false" name="New Body Parts" opaque="true" width="118">
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
<check_box bottom="-276" enabled="true" follows="left|top" font="SansSerifSmall"
|
||||
height="16" initial_value="false" label="Eyes" left="13"
|
||||
mouse_opaque="true" name="checkbox_Eyes" radio_style="false" width="100" />
|
||||
<check_box bottom="-434" enabled="true" follows="left|top" font="SansSerifSmall"
|
||||
<check_box bottom="-456" enabled="true" follows="left|top" font="SansSerifSmall"
|
||||
height="16" initial_value="false" label="Rename Clothing To Folder Name"
|
||||
left="13" mouse_opaque="true" name="rename" radio_style="false" width="210" />
|
||||
<check_box bottom="-216" enabled="true" follows="left|top" font="SansSerifSmall"
|
||||
@@ -53,6 +53,12 @@
|
||||
<check_box bottom="-376" enabled="true" follows="left|top" font="SansSerifSmall"
|
||||
height="16" initial_value="false" label="Skirt" left="113"
|
||||
mouse_opaque="true" name="checkbox_Skirt" radio_style="false" width="100" />
|
||||
<check_box bottom="-396" enabled="true" follows="left|top" font="SansSerifSmall"
|
||||
height="16" initial_value="false" label="Tattoo" left="113"
|
||||
mouse_opaque="true" name="checkbox_Tattoo" radio_style="false" width="100" />
|
||||
<check_box bottom="-416" enabled="true" follows="left|top" font="SansSerifSmall"
|
||||
height="16" initial_value="false" label="Alpha" left="113"
|
||||
mouse_opaque="true" name="checkbox_Alpha" radio_style="false" width="100" />
|
||||
<check_box bottom="-216" enabled="false" follows="left|top" font="SansSerifSmall"
|
||||
height="16" initial_value="false" label="Chest" left="213"
|
||||
mouse_opaque="true" name="checkbox_Chest" radio_style="false" width="100" />
|
||||
@@ -244,7 +250,7 @@ now wearing into it.
|
||||
Attachments:
|
||||
</text>
|
||||
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
|
||||
bottom="-414" drop_shadow_visible="true" enabled="true" follows="left|top"
|
||||
bottom="-436" drop_shadow_visible="true" enabled="true" follows="left|top"
|
||||
font="SansSerifSmall" h_pad="0" halign="left" height="14" left="13"
|
||||
mouse_opaque="true" name="Options:" v_pad="0" width="100">
|
||||
Options:
|
||||
|
||||
@@ -88,6 +88,14 @@
|
||||
mouse_opaque="true" name="New Underpants" width="128">
|
||||
<on_click filter="" function="Inventory.DoCreate" userdata="underpants" />
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom_delta="-18" height="18" label="New Tattoo" left="0"
|
||||
mouse_opaque="true" name="New Tattoo" width="128">
|
||||
<on_click filter="" function="Inventory.DoCreate" userdata="tattoo" />
|
||||
</menu_item_call>
|
||||
<menu_item_call bottom_delta="-18" height="18" label="New Alpha" left="0"
|
||||
mouse_opaque="true" name="New Alpha" width="128">
|
||||
<on_click filter="" function="Inventory.DoCreate" userdata="alpha" />
|
||||
</menu_item_call>
|
||||
</menu>
|
||||
<menu bottom_delta="0" color="MenuDefaultBgColor" drop_shadow="true" height="175" left="0"
|
||||
mouse_opaque="false" name="New Body Parts" opaque="true" tear_off="false"
|
||||
|
||||
Reference in New Issue
Block a user