summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llcommon/llbase32.cpp12
-rw-r--r--indra/llcommon/llchat.h3
-rw-r--r--indra/llcommon/lllslconstants.h6
-rw-r--r--indra/llmath/llvolume.cpp278
-rw-r--r--indra/llmath/llvolume.h44
-rw-r--r--indra/llmessage/message_prehash.cpp14
-rw-r--r--indra/llmessage/message_prehash.h7
-rw-r--r--indra/llprimitive/llprimitive.cpp97
-rw-r--r--indra/llprimitive/llprimitive.h28
-rw-r--r--indra/llprimitive/lltextureentry.cpp15
-rw-r--r--indra/llprimitive/lltextureentry.h8
-rw-r--r--indra/lscript/lscript_compile/indra.l8
-rw-r--r--indra/lscript/lscript_library/lscript_library.cpp1
-rw-r--r--indra/newview/English.lproj/InfoPlist.strings4
-rw-r--r--indra/newview/Info-SecondLife.plist2
-rw-r--r--indra/newview/app_settings/keywords.ini6
-rw-r--r--indra/newview/llagent.cpp4
-rw-r--r--indra/newview/llface.cpp21
-rw-r--r--indra/newview/llfloaterimagepreview.cpp215
-rw-r--r--indra/newview/llfloaterimagepreview.h29
-rw-r--r--indra/newview/llmanipscale.cpp4
-rw-r--r--indra/newview/llpanelobject.cpp199
-rw-r--r--indra/newview/llpanelobject.h15
-rw-r--r--indra/newview/llviewercamera.cpp2
-rw-r--r--indra/newview/llviewerinventory.cpp1
-rw-r--r--indra/newview/llviewerobject.cpp15
-rw-r--r--indra/newview/llviewerregion.cpp2
-rw-r--r--indra/newview/llvovolume.cpp126
-rw-r--r--indra/newview/llvovolume.h4
-rw-r--r--scripts/messages/message_template.msg16
30 files changed, 1082 insertions, 104 deletions
diff --git a/indra/llcommon/llbase32.cpp b/indra/llcommon/llbase32.cpp
index 711ba63ea2..96e4d76f3b 100644
--- a/indra/llcommon/llbase32.cpp
+++ b/indra/llcommon/llbase32.cpp
@@ -6,6 +6,12 @@
* Based on code from bitter
* http://ghostwhitecrab.com/bitter/
*
+ * Some parts of this file are:
+ * Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
+ * $License$
+ */
+
+/**
* Copyright (c) 2006 Christian Biere <christianbiere@gmx.de>
* All rights reserved.
*
@@ -192,6 +198,8 @@ base32_decode(char *dst, size_t size, const void *data, size_t len)
*/
+// The following is
+// Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
// static
std::string LLBase32::encode(const U8* input, size_t input_size)
{
@@ -207,8 +215,8 @@ std::string LLBase32::encode(const U8* input, size_t input_size)
size_t encoded = base32_encode(&output[0], output_size, input, input_size);
- llinfos << "encoded " << encoded << " into buffer of size " << output_size
- << llendl;
+ llinfos << "encoded " << encoded << " into buffer of size "
+ << output_size << llendl;
}
return output;
}
diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h
index 88867b2081..61bdc81907 100644
--- a/indra/llcommon/llchat.h
+++ b/indra/llcommon/llchat.h
@@ -29,7 +29,8 @@ typedef enum e_chat_type
CHAT_TYPE_SHOUT = 2,
CHAT_TYPE_START = 4,
CHAT_TYPE_STOP = 5,
- CHAT_TYPE_DEBUG_MSG = 6
+ CHAT_TYPE_DEBUG_MSG = 6,
+ CHAT_TYPE_REGION = 7
} EChatType;
typedef enum e_chat_audible_level
diff --git a/indra/llcommon/lllslconstants.h b/indra/llcommon/lllslconstants.h
index bd14e8ce04..87234a463c 100644
--- a/indra/llcommon/lllslconstants.h
+++ b/indra/llcommon/lllslconstants.h
@@ -55,6 +55,7 @@ const S32 LSL_PRIM_TYPE_SPHERE = 3;
const S32 LSL_PRIM_TYPE_TORUS = 4;
const S32 LSL_PRIM_TYPE_TUBE = 5;
const S32 LSL_PRIM_TYPE_RING = 6;
+const S32 LSL_PRIM_TYPE_SCULPT = 7;
const S32 LSL_PRIM_HOLE_DEFAULT = 0x00;
const S32 LSL_PRIM_HOLE_CIRCLE = 0x10;
@@ -97,6 +98,11 @@ const S32 LSL_PRIM_BUMP_STUCCO = 15;
const S32 LSL_PRIM_BUMP_SUCTION = 16;
const S32 LSL_PRIM_BUMP_WEAVE = 17;
+const S32 LSL_PRIM_SCULPT_TYPE_SPHERE = 1;
+const S32 LSL_PRIM_SCULPT_TYPE_TORUS = 2;
+const S32 LSL_PRIM_SCULPT_TYPE_PLANE = 3;
+const S32 LSL_PRIM_SCULPT_TYPE_CYLINDER = 4;
+
const S32 LSL_ALL_SIDES = -1;
const S32 LSL_LINK_ROOT = 1;
const S32 LSL_LINK_FIRST_CHILD = 2;
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 20d07064e3..c779a8b714 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -434,9 +434,18 @@ LLProfile::Face* LLProfile::addHole(BOOL flat, F32 sides, F32 offset, F32 box_ho
return face;
}
-BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split)
+
+F32 next_power_of_two(F32 value)
{
- if (!mDirty)
+ S32 power = (S32)llceil((F32)log((double)value)/(F32)log(2.0));
+ return pow(2.0f, power);
+}
+
+
+
+BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split, BOOL is_sculpted)
+{
+ if ((!mDirty) && (!is_sculpted))
{
return FALSE;
}
@@ -572,10 +581,14 @@ BOOL LLProfile::generate(BOOL path_open,F32 detail, S32 split)
circle_detail = llceil(circle_detail / 4.0f) * 4.0f;
}
}
+
+ S32 sides = (S32)circle_detail;
+
+ if (is_sculpted)
+ sides = (S32)next_power_of_two((F32)sides);
+
+ genNGon(sides);
- //llinfos << "(CIRCLE) detail: " << detail << "; genNGon("
- // << llfloor(circle_detail) << ")" << llendl;
- genNGon(llfloor(circle_detail));
if (path_open)
{
addCap (LL_FACE_PATH_BEGIN);
@@ -824,7 +837,7 @@ BOOL LLProfileParams::importLegacyStream(std::istream& input_stream)
}
else
{
- llwarns << "unknown keyword " << keyword << " in profile import" << llendl;
+ llwarns << "unknown keyword " << keyword << " in profile import" << llendl;
}
}
@@ -1054,9 +1067,9 @@ const LLVector2 LLPathParams::getEndScale() const
return end_scale;
}
-BOOL LLPath::generate(F32 detail, S32 split)
+BOOL LLPath::generate(F32 detail, S32 split, BOOL is_sculpted)
{
- if (!mDirty)
+ if ((!mDirty) && (!is_sculpted))
{
return FALSE;
}
@@ -1111,7 +1124,13 @@ BOOL LLPath::generate(F32 detail, S32 split)
{
// Increase the detail as the revolutions and twist increase.
F32 twist_mag = fabs(mParams.getTwistBegin() - mParams.getTwist());
- genNGon(llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * mParams.getRevolutions()));
+
+ S32 sides = (S32)llfloor(llfloor((MIN_DETAIL_FACES * detail + twist_mag * 3.5f * (detail-0.5f))) * mParams.getRevolutions());
+
+ if (is_sculpted)
+ sides = (S32)next_power_of_two((F32)sides);
+
+ genNGon(sides);
}
break;
@@ -1174,7 +1193,7 @@ BOOL LLPath::generate(F32 detail, S32 split)
return TRUE;
}
-BOOL LLDynamicPath::generate(F32 detail, S32 split)
+BOOL LLDynamicPath::generate(F32 detail, S32 split, BOOL is_sculpted)
{
mOpen = TRUE; // Draw end caps
if (getPathLength() == 0)
@@ -1535,13 +1554,15 @@ LLProfile::~LLProfile()
}
-S32 LLVolume::mNumMeshPoints = 0;
+S32 LLVolume::sNumMeshPoints = 0;
LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL generate_single_face, const BOOL is_unique) : mParams(params)
{
mUnique = is_unique;
mFaceMask = 0x0;
mDetail = detail;
+ mSculptLevel = -2;
+
// set defaults
if (mParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE)
{
@@ -1558,7 +1579,10 @@ LLVolume::LLVolume(const LLVolumeParams &params, const F32 detail, const BOOL ge
mGenerateSingleFace = generate_single_face;
generate();
- createVolumeFaces();
+ if (mParams.getSculptID().isNull())
+ {
+ createVolumeFaces();
+ }
}
void LLVolume::regen()
@@ -1569,7 +1593,7 @@ void LLVolume::regen()
LLVolume::~LLVolume()
{
- mNumMeshPoints -= mMesh.size();
+ sNumMeshPoints -= mMesh.size();
delete mPathp;
delete mProfilep;
delete[] mVolumeFaces;
@@ -1620,9 +1644,9 @@ BOOL LLVolume::generate()
if (regenPath || regenProf )
{
- mNumMeshPoints -= mMesh.size();
+ sNumMeshPoints -= mMesh.size();
mMesh.resize(mProfilep->mProfile.size() * mPathp->mPath.size());
- mNumMeshPoints += mMesh.size();
+ sNumMeshPoints += mMesh.size();
S32 s = 0, t=0;
S32 sizeS = mPathp->mPath.size();
@@ -1752,6 +1776,128 @@ void LLVolume::createVolumeFaces()
}
+// sculpt replaces generate() for sculpted surfaces
+void LLVolume::sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level)
+{
+ BOOL data_is_empty = FALSE;
+
+ if (sculpt_width == 0 || sculpt_height == 0 || sculpt_data == NULL)
+ {
+ sculpt_level = -1;
+ data_is_empty = TRUE;
+ }
+
+ mPathp->generate(mDetail, 0, TRUE);
+ mProfilep->generate(mPathp->isOpen(), mDetail, 0, TRUE);
+
+
+ S32 sizeS = mPathp->mPath.size();
+ S32 sizeT = mProfilep->mProfile.size();
+
+ sNumMeshPoints -= mMesh.size();
+ mMesh.resize(sizeS * sizeT);
+ sNumMeshPoints += mMesh.size();
+
+ S32 vertex_change = 0;
+ // first test to see if image has enough variation to create geometry
+ if (!data_is_empty)
+ {
+ S32 last_index = 0;
+ for (S32 s = 0; s < sizeS; s++)
+ for (S32 t = 0; t < sizeT; t++)
+ {
+ U32 x = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_width);
+ U32 y = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_height);
+
+ if (y == sculpt_height) // clamp to bottom row
+ y = sculpt_height - 1;
+
+ if (x == sculpt_width) // stitch sides
+ x = 0;
+
+ if ((y == 0) || (y == sculpt_height-1)) // stitch top and bottom
+ x = sculpt_width / 2;
+
+ U32 index = (x + y * sculpt_width) * sculpt_components;
+
+ if (fabs((F32)(sculpt_data[index] - sculpt_data[last_index])) +
+ fabs((F32)(sculpt_data[index+1] - sculpt_data[last_index+1])) +
+ fabs((F32)(sculpt_data[index+2] - sculpt_data[last_index+2])) > 256 * 0.02)
+ vertex_change++;
+
+ last_index = index;
+ }
+ }
+
+
+ if ((F32)vertex_change / sizeS / sizeT < 0.05) // less than 5%
+ data_is_empty = TRUE;
+
+
+ //generate vertex positions
+ // Run along the path.
+ S32 s = 0, t = 0;
+ S32 line = 0;
+ while (s < sizeS)
+ {
+ t = 0;
+ // Run along the profile.
+ while (t < sizeT)
+ {
+ S32 i = t + line;
+ Point& pt = mMesh[i];
+
+ U32 x = (U32) ((F32)t/(sizeT-1) * (F32) sculpt_width);
+ U32 y = (U32) ((F32)s/(sizeS-1) * (F32) sculpt_height);
+
+ if (y == sculpt_height) // clamp to bottom row
+ y = sculpt_height - 1;
+
+ if (x == sculpt_width) // stitch sides
+ x = 0;
+
+ if ((y == 0) || (y == sculpt_height-1)) // stitch top and bottom
+ x = sculpt_width / 2;
+
+
+ if (data_is_empty) // if empty, make a sphere
+ {
+ F32 u = (F32)s/(sizeS-1);
+ F32 v = (F32)t/(sizeT-1);
+
+ const F32 RADIUS = (F32) 0.3;
+
+ pt.mPos.mV[0] = (F32)(sin(F_PI * v) * cos(2.0 * F_PI * u) * RADIUS);
+ pt.mPos.mV[1] = (F32)(sin(F_PI * v) * sin(2.0 * F_PI * u) * RADIUS);
+ pt.mPos.mV[2] = (F32)(cos(F_PI * v) * RADIUS);
+ }
+
+ else
+ {
+ U32 index = (x + y * sculpt_width) * sculpt_components;
+ pt.mPos.mV[0] = sculpt_data[index ] / 256.f - 0.5f;
+ pt.mPos.mV[1] = sculpt_data[index+1] / 256.f - 0.5f;
+ pt.mPos.mV[2] = sculpt_data[index+2] / 256.f - 0.5f;
+ }
+
+ t++;
+ }
+ line += sizeT;
+ s++;
+ }
+
+ for (S32 i = 0; i < (S32)mProfilep->mFaces.size(); i++)
+ {
+ mFaceMask |= mProfilep->mFaces[i].mFaceID;
+ }
+
+ mSculptLevel = sculpt_level;
+ createVolumeFaces();
+}
+
+
+
+
BOOL LLVolume::isCap(S32 face)
{
return mProfilep->mFaces[face].mCap;
@@ -1765,14 +1911,18 @@ BOOL LLVolume::isFlat(S32 face)
bool LLVolumeParams::operator==(const LLVolumeParams &params) const
{
- return (getPathParams() == params.getPathParams()) &&
- (getProfileParams() == params.getProfileParams());
+ return ( (getPathParams() == params.getPathParams()) &&
+ (getProfileParams() == params.getProfileParams()) &&
+ (mSculptID == params.mSculptID) &&
+ (mSculptType == params.mSculptType) );
}
bool LLVolumeParams::operator!=(const LLVolumeParams &params) const
{
- return (getPathParams() != params.getPathParams()) ||
- (getProfileParams() != params.getProfileParams());
+ return ( (getPathParams() != params.getPathParams()) ||
+ (getProfileParams() != params.getProfileParams()) ||
+ (mSculptID != params.mSculptID) ||
+ (mSculptType != params.mSculptType) );
}
bool LLVolumeParams::operator<(const LLVolumeParams &params) const
@@ -1781,16 +1931,29 @@ bool LLVolumeParams::operator<(const LLVolumeParams &params) const
{
return getPathParams() < params.getPathParams();
}
- else
+
+ if (getProfileParams() != params.getProfileParams())
{
return getProfileParams() < params.getProfileParams();
}
+
+ if (mSculptID != params.mSculptID)
+ {
+ return mSculptID < params.mSculptID;
+ }
+
+
+ return mSculptType < params.mSculptType;
+
+
}
void LLVolumeParams::copyParams(const LLVolumeParams &params)
{
mProfileParams.copyParams(params.mProfileParams);
mPathParams.copyParams(params.mPathParams);
+ mSculptID = params.getSculptID();
+ mSculptType = params.getSculptType();
}
// Less restricitve approx 0 for volumes
@@ -2050,6 +2213,13 @@ bool LLVolumeParams::setSkew(const F32 skew_value)
return valid;
}
+bool LLVolumeParams::setSculptID(const LLUUID sculpt_id, U8 sculpt_type)
+{
+ mSculptID = sculpt_id;
+ mSculptType = sculpt_type;
+ return true;
+}
+
bool LLVolumeParams::setType(U8 profile, U8 path)
{
bool result = true;
@@ -2809,7 +2979,7 @@ void LLVolume::generateSilhouetteVertices(std::vector<LLVector3> &vertices,
segments.clear();
//for each face
- for (S32 i = 0; i < getNumFaces(); i++) {
+ for (S32 i = 0; i < getNumVolumeFaces(); i++) {
LLVolumeFace face = this->getVolumeFace(i);
if (face.mTypeMask & (LLVolumeFace::CAP_MASK)) {
@@ -4416,6 +4586,9 @@ BOOL LLVolumeFace::createSide()
}
}
+ BOOL s_bottom_converges = ((mVertices[0].mPosition - mVertices[mNumS*(mNumT-2)].mPosition).magVecSquared() < 0.000001f);
+ BOOL s_top_converges = ((mVertices[mNumS-1].mPosition - mVertices[mNumS*(mNumT-2)+mNumS-1].mPosition).magVecSquared() < 0.000001f);
+
if (mVolumep->getPath().isOpen() == FALSE) { //wrap normals on T
for (S32 i = 0; i < mNumS; i++) {
LLVector3 norm = mVertices[i].mNormal + mVertices[mNumS*(mNumT-1)+i].mNormal;
@@ -4424,30 +4597,73 @@ BOOL LLVolumeFace::createSide()
}
}
- if (mVolumep->getProfile().isOpen() == FALSE) { //wrap normals on S
- for (S32 i = 0; i < mNumT; i++) {
- LLVector3 norm = mVertices[mNumS*i].mNormal + mVertices[mNumS*i+mNumS-1].mNormal;
- mVertices[mNumS * i].mNormal = norm;
- mVertices[mNumS * i+mNumS-1].mNormal = norm;
+ if ((mVolumep->getProfile().isOpen() == FALSE) &&
+ !(s_bottom_converges))
+ { //wrap normals on S
+ for (S32 i = 0; i < mNumT; i++) {
+ LLVector3 norm = mVertices[mNumS*i].mNormal + mVertices[mNumS*i+mNumS-1].mNormal;
+ mVertices[mNumS * i].mNormal = norm;
+ mVertices[mNumS * i+mNumS-1].mNormal = norm;
+ }
}
- }
- if (mVolumep->getPathType() == LL_PCODE_PATH_CIRCLE && ((mVolumep->getProfileType() & LL_PCODE_PROFILE_MASK) == LL_PCODE_PROFILE_CIRCLE_HALF)) {
- if ((mVertices[0].mPosition - mVertices[mNumS*(mNumT-2)].mPosition).magVecSquared() < 0.000001f)
+ if (mVolumep->getPathType() == LL_PCODE_PATH_CIRCLE &&
+ ((mVolumep->getProfileType() & LL_PCODE_PROFILE_MASK) == LL_PCODE_PROFILE_CIRCLE_HALF))
+ {
+ if (s_bottom_converges)
{ //all lower S have same normal
for (S32 i = 0; i < mNumT; i++) {
mVertices[mNumS*i].mNormal = LLVector3(1,0,0);
}
}
- if ((mVertices[mNumS-1].mPosition - mVertices[mNumS*(mNumT-2)+mNumS-1].mPosition).magVecSquared() < 0.000001f)
- { //all upper T have same normal
+ if (s_top_converges)
+ { //all upper S have same normal
for (S32 i = 0; i < mNumT; i++) {
mVertices[mNumS*i+mNumS-1].mNormal = LLVector3(-1,0,0);
}
}
}
+ U8 sculpt_type = mVolumep->getParams().getSculptType();
+
+ if (sculpt_type == LL_SCULPT_TYPE_SPHERE)
+ {
+ // average normals for north pole
+
+ LLVector3 average(0.0, 0.0, 0.0);
+ for (S32 i = 0; i < mNumS; i++)
+ {
+ average += mVertices[i].mNormal;
+ }
+
+ // set average
+ for (S32 i = 0; i < mNumS; i++)
+ {
+ mVertices[i].mNormal = average;
+ }
+ }
+
+
+ if (sculpt_type == LL_SCULPT_TYPE_SPHERE)
+ {
+ // average normals for south pole
+
+ LLVector3 average(0.0, 0.0, 0.0);
+ for (S32 i = 0; i < mNumS; i++)
+ {
+ average += mVertices[i + mNumS * (mNumT - 1)].mNormal;
+ }
+
+ // set average
+ for (S32 i = 0; i < mNumS; i++)
+ {
+ mVertices[i + mNumS * (mNumT - 1)].mNormal = average;
+ }
+ }
+
+
+
//normalize normals and binormals here so the meshes that reference
//this volume data don't have to
for (U32 i = 0; i < mVertices.size(); i++)
diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h
index 22742e09da..3ce3058887 100644
--- a/indra/llmath/llvolume.h
+++ b/indra/llmath/llvolume.h
@@ -149,6 +149,16 @@ const LLFaceID LL_FACE_OUTER_SIDE_3 = 0x1 << 8;
//============================================================================
+// sculpt types
+
+const U8 LL_SCULPT_TYPE_NONE = 0;
+const U8 LL_SCULPT_TYPE_SPHERE = 1;
+const U8 LL_SCULPT_TYPE_TORUS = 2;
+const U8 LL_SCULPT_TYPE_PLAIN = 3;
+const U8 LL_SCULPT_TYPE_CYLINDER = 4;
+
+
+
class LLProfileParams
{
public:
@@ -492,8 +502,9 @@ public:
{
}
- LLVolumeParams(LLProfileParams &profile, LLPathParams &path)
- : mProfileParams(profile), mPathParams(path)
+ LLVolumeParams(LLProfileParams &profile, LLPathParams &path,
+ LLUUID sculpt_id = LLUUID::null, U8 sculpt_type = LL_SCULPT_TYPE_NONE)
+ : mProfileParams(profile), mPathParams(path), mSculptID(sculpt_id), mSculptType(sculpt_type)
{
}
@@ -544,6 +555,7 @@ public:
bool setRevolutions(const F32 revolutions); // 1 to 4
bool setRadiusOffset(const F32 radius_offset);
bool setSkew(const F32 skew);
+ bool setSculptID(const LLUUID sculpt_id, U8 sculpt_type);
static bool validate(U8 prof_curve, F32 prof_begin, F32 prof_end, F32 hollow,
U8 path_curve, F32 path_begin, F32 path_end,
@@ -571,6 +583,8 @@ public:
const F32& getTaperY() const { return mPathParams.getTaperY(); }
const F32& getRevolutions() const { return mPathParams.getRevolutions(); }
const F32& getSkew() const { return mPathParams.getSkew(); }
+ const LLUUID& getSculptID() const { return mSculptID; }
+ const U8& getSculptType() const { return mSculptType; }
BOOL isConvex() const;
@@ -593,6 +607,8 @@ public:
protected:
LLProfileParams mProfileParams;
LLPathParams mPathParams;
+ LLUUID mSculptID;
+ U8 mSculptType;
};
@@ -615,7 +631,7 @@ public:
BOOL isFlat(S32 face) const { return (mFaces[face].mCount == 2); }
BOOL isOpen() const { return mOpen; }
void setDirty() { mDirty = TRUE; }
- BOOL generate(BOOL path_open, F32 detail = 1.0f, S32 split = 0);
+ BOOL generate(BOOL path_open, F32 detail = 1.0f, S32 split = 0, BOOL is_sculpted = FALSE);
BOOL isConcave() const { return mConcave; }
public:
const LLProfileParams &mParams;
@@ -684,7 +700,7 @@ public:
virtual ~LLPath();
void genNGon(S32 sides, F32 offset=0.0f, F32 end_scale = 1.f, F32 twist_scale = 1.f);
- virtual BOOL generate(F32 detail=1.0f, S32 split = 0);
+ virtual BOOL generate(F32 detail=1.0f, S32 split = 0, BOOL is_sculpted = FALSE);
BOOL isOpen() const { return mOpen; }
F32 getStep() const { return mStep; }
@@ -711,7 +727,7 @@ class LLDynamicPath : public LLPath
{
public:
LLDynamicPath(const LLPathParams &params) : LLPath(params) { }
- BOOL generate(F32 detail=1.0f, S32 split = 0);
+ BOOL generate(F32 detail=1.0f, S32 split = 0, BOOL is_sculpted = FALSE);
};
// Yet another "face" class - caches volume-specific, but not instance-specific data for faces)
@@ -801,7 +817,7 @@ public:
U8 getProfileType() const { return mProfilep->mParams.getCurveType(); }
U8 getPathType() const { return mPathp->mParams.getCurveType(); }
S32 getNumFaces() const { return (S32)mProfilep->mFaces.size(); }
-
+ S32 getNumVolumeFaces() const { return mNumVolumeFaces; }
const F32 getDetail() const { return mDetail; }
const LLVolumeParams & getParams() const { return mParams; }
LLVolumeParams getCopyOfParams() const { return mParams; }
@@ -819,6 +835,11 @@ public:
BOOL isFlat(S32 face);
BOOL isUnique() const { return mUnique; }
+ S32 getSculptLevel() const { return mSculptLevel; }
+ void setSculptLevel(S32 level) { mSculptLevel = level; }
+
+ U8 getSculptType() const { return mSculptType; }
+
S32 *getTriangleIndices(U32 &num_indices) const;
void generateSilhouetteVertices(std::vector<LLVector3> &vertices, std::vector<LLVector3> &normals, std::vector<S32> &segments, const LLVector3& view_vec,
const LLMatrix4& mat,
@@ -843,7 +864,7 @@ public:
LLFaceID generateFaceMask();
BOOL isFaceMaskValid(LLFaceID face_mask);
- static S32 mNumMeshPoints;
+ static S32 sNumMeshPoints;
friend std::ostream& operator<<(std::ostream &s, const LLVolume &volume);
friend std::ostream& operator<<(std::ostream &s, const LLVolume *volumep); // HACK to bypass Windoze confusion over
@@ -852,14 +873,19 @@ public:
U32 mFaceMask; // bit array of which faces exist in this volume
LLVector3 mLODScaleBias; // vector for biasing LOD based on scale
-
+
+ void sculpt(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, S32 sculpt_level);
+
protected:
BOOL generate();
void createVolumeFaces();
-protected:
+ protected:
BOOL mUnique;
F32 mDetail;
+ S32 mSculptLevel;
+ U8 mSculptType;
+
LLVolumeParams mParams;
LLPath *mPathp;
LLProfile *mProfilep;
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 9d7e603690..e153114d1d 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -534,8 +534,8 @@ char * _PREHASH_ReturnIDs;
char * _PREHASH_Date;
char * _PREHASH_AgentWearablesUpdate;
char * _PREHASH_AgentDataUpdate;
-char * _PREHASH_Hash;
char * _PREHASH_GroupDataUpdate;
+char * _PREHASH_Hash;
char * _PREHASH_AgentGroupDataUpdate;
char * _PREHASH_Left;
char * _PREHASH_Mask;
@@ -663,7 +663,6 @@ char * _PREHASH_CreateNewOutfitAttachments;
char * _PREHASH_RegionHandle;
char * _PREHASH_TeleportProgress;
char * _PREHASH_AgentQuitCopy;
-char * _PREHASH_ToViewer;
char * _PREHASH_AvatarInterestsUpdate;
char * _PREHASH_GroupNoticeID;
char * _PREHASH_ParcelName;
@@ -722,6 +721,7 @@ char * _PREHASH_LogoutReply;
char * _PREHASH_FeatureDisabled;
char * _PREHASH_ObjectLocalID;
char * _PREHASH_Dropped;
+char * _PREHASH_PhysicalAvatarEventList;
char * _PREHASH_WebProfilesDisabled;
char * _PREHASH_Destination;
char * _PREHASH_MasterID;
@@ -995,7 +995,6 @@ char * _PREHASH_TrackAgentSession;
char * _PREHASH_CacheMissType;
char * _PREHASH_VFileID;
char * _PREHASH_GroupInsigniaID;
-char * _PREHASH_FromID;
char * _PREHASH_Online;
char * _PREHASH_KickFlags;
char * _PREHASH_CovenantID;
@@ -1179,7 +1178,6 @@ char * _PREHASH_EventData;
char * _PREHASH_Final;
char * _PREHASH_TelehubPos;
char * _PREHASH_ReportAutosaveCrash;
-char * _PREHASH_Reset;
char * _PREHASH_CreateTrustedCircuit;
char * _PREHASH_DenyTrustedCircuit;
char * _PREHASH_RequestTrustedCircuit;
@@ -1362,7 +1360,6 @@ char * _PREHASH_SimulatorPublicHostBlock;
char * _PREHASH_HeaderData;
char * _PREHASH_RequestMultipleObjects;
char * _PREHASH_RetrieveInstantMessages;
-char * _PREHASH_DequeueInstantMessages;
char * _PREHASH_OpenCircuit;
char * _PREHASH_SecureSessionID;
char * _PREHASH_CrossedRegion;
@@ -2000,8 +1997,8 @@ void init_prehash_data()
_PREHASH_Date = gMessageStringTable.getString("Date");
_PREHASH_AgentWearablesUpdate = gMessageStringTable.getString("AgentWearablesUpdate");
_PREHASH_AgentDataUpdate = gMessageStringTable.getString("AgentDataUpdate");
- _PREHASH_Hash = gMessageStringTable.getString("Hash");
_PREHASH_GroupDataUpdate = gMessageStringTable.getString("GroupDataUpdate");
+ _PREHASH_Hash = gMessageStringTable.getString("Hash");
_PREHASH_AgentGroupDataUpdate = gMessageStringTable.getString("AgentGroupDataUpdate");
_PREHASH_Left = gMessageStringTable.getString("Left");
_PREHASH_Mask = gMessageStringTable.getString("Mask");
@@ -2129,7 +2126,6 @@ void init_prehash_data()
_PREHASH_RegionHandle = gMessageStringTable.getString("RegionHandle");
_PREHASH_TeleportProgress = gMessageStringTable.getString("TeleportProgress");
_PREHASH_AgentQuitCopy = gMessageStringTable.getString("AgentQuitCopy");
- _PREHASH_ToViewer = gMessageStringTable.getString("ToViewer");
_PREHASH_AvatarInterestsUpdate = gMessageStringTable.getString("AvatarInterestsUpdate");
_PREHASH_GroupNoticeID = gMessageStringTable.getString("GroupNoticeID");
_PREHASH_ParcelName = gMessageStringTable.getString("ParcelName");
@@ -2188,6 +2184,7 @@ void init_prehash_data()
_PREHASH_FeatureDisabled = gMessageStringTable.getString("FeatureDisabled");
_PREHASH_ObjectLocalID = gMessageStringTable.getString("ObjectLocalID");
_PREHASH_Dropped = gMessageStringTable.getString("Dropped");
+ _PREHASH_PhysicalAvatarEventList = gMessageStringTable.getString("PhysicalAvatarEventList");
_PREHASH_WebProfilesDisabled = gMessageStringTable.getString("WebProfilesDisabled");
_PREHASH_Destination = gMessageStringTable.getString("Destination");
_PREHASH_MasterID = gMessageStringTable.getString("MasterID");
@@ -2461,7 +2458,6 @@ void init_prehash_data()
_PREHASH_CacheMissType = gMessageStringTable.getString("CacheMissType");
_PREHASH_VFileID = gMessageStringTable.getString("VFileID");
_PREHASH_GroupInsigniaID = gMessageStringTable.getString("GroupInsigniaID");
- _PREHASH_FromID = gMessageStringTable.getString("FromID");
_PREHASH_Online = gMessageStringTable.getString("Online");
_PREHASH_KickFlags = gMessageStringTable.getString("KickFlags");
_PREHASH_CovenantID = gMessageStringTable.getString("CovenantID");
@@ -2645,7 +2641,6 @@ void init_prehash_data()
_PREHASH_Final = gMessageStringTable.getString("Final");
_PREHASH_TelehubPos = gMessageStringTable.getString("TelehubPos");
_PREHASH_ReportAutosaveCrash = gMessageStringTable.getString("ReportAutosaveCrash");
- _PREHASH_Reset = gMessageStringTable.getString("Reset");
_PREHASH_CreateTrustedCircuit = gMessageStringTable.getString("CreateTrustedCircuit");
_PREHASH_DenyTrustedCircuit = gMessageStringTable.getString("DenyTrustedCircuit");
_PREHASH_RequestTrustedCircuit = gMessageStringTable.getString("RequestTrustedCircuit");
@@ -2828,7 +2823,6 @@ void init_prehash_data()
_PREHASH_HeaderData = gMessageStringTable.getString("HeaderData");
_PREHASH_RequestMultipleObjects = gMessageStringTable.getString("RequestMultipleObjects");
_PREHASH_RetrieveInstantMessages = gMessageStringTable.getString("RetrieveInstantMessages");
- _PREHASH_DequeueInstantMessages = gMessageStringTable.getString("DequeueInstantMessages");
_PREHASH_OpenCircuit = gMessageStringTable.getString("OpenCircuit");
_PREHASH_SecureSessionID = gMessageStringTable.getString("SecureSessionID");
_PREHASH_CrossedRegion = gMessageStringTable.getString("CrossedRegion");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index 19b9881dde..209b399ce8 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -534,8 +534,8 @@ extern char * _PREHASH_ReturnIDs;
extern char * _PREHASH_Date;
extern char * _PREHASH_AgentWearablesUpdate;
extern char * _PREHASH_AgentDataUpdate;
-extern char * _PREHASH_Hash;
extern char * _PREHASH_GroupDataUpdate;
+extern char * _PREHASH_Hash;
extern char * _PREHASH_AgentGroupDataUpdate;
extern char * _PREHASH_Left;
extern char * _PREHASH_Mask;
@@ -663,7 +663,6 @@ extern char * _PREHASH_CreateNewOutfitAttachments;
extern char * _PREHASH_RegionHandle;
extern char * _PREHASH_TeleportProgress;
extern char * _PREHASH_AgentQuitCopy;
-extern char * _PREHASH_ToViewer;
extern char * _PREHASH_AvatarInterestsUpdate;
extern char * _PREHASH_GroupNoticeID;
extern char * _PREHASH_ParcelName;
@@ -722,6 +721,7 @@ extern char * _PREHASH_LogoutReply;
extern char * _PREHASH_FeatureDisabled;
extern char * _PREHASH_ObjectLocalID;
extern char * _PREHASH_Dropped;
+extern char * _PREHASH_PhysicalAvatarEventList;
extern char * _PREHASH_WebProfilesDisabled;
extern char * _PREHASH_Destination;
extern char * _PREHASH_MasterID;
@@ -995,7 +995,6 @@ extern char * _PREHASH_TrackAgentSession;
extern char * _PREHASH_CacheMissType;
extern char * _PREHASH_VFileID;
extern char * _PREHASH_GroupInsigniaID;
-extern char * _PREHASH_FromID;
extern char * _PREHASH_Online;
extern char * _PREHASH_KickFlags;
extern char * _PREHASH_CovenantID;
@@ -1179,7 +1178,6 @@ extern char * _PREHASH_EventData;
extern char * _PREHASH_Final;
extern char * _PREHASH_TelehubPos;
extern char * _PREHASH_ReportAutosaveCrash;
-extern char * _PREHASH_Reset;
extern char * _PREHASH_CreateTrustedCircuit;
extern char * _PREHASH_DenyTrustedCircuit;
extern char * _PREHASH_RequestTrustedCircuit;
@@ -1362,7 +1360,6 @@ extern char * _PREHASH_SimulatorPublicHostBlock;
extern char * _PREHASH_HeaderData;
extern char * _PREHASH_RequestMultipleObjects;
extern char * _PREHASH_RetrieveInstantMessages;
-extern char * _PREHASH_DequeueInstantMessages;
extern char * _PREHASH_OpenCircuit;
extern char * _PREHASH_SecureSessionID;
extern char * _PREHASH_CrossedRegion;
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 13719d0a62..7e44d15db2 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -87,6 +87,9 @@ const BOOL FLEXIBLE_OBJECT_DEFAULT_USING_COLLISION_SPHERE = FALSE;
const BOOL FLEXIBLE_OBJECT_DEFAULT_RENDERING_COLLISION_SPHERE = FALSE;
+const char *SCULPT_DEFAULT_TEXTURE = "be293869-d0d9-0a69-5989-ad27f1946fd4"; // old inverted texture: "7595d345-a24c-e7ef-f0bd-78793792133e";
+
+
//===============================================================
LLPrimitive::LLPrimitive()
{
@@ -491,6 +494,18 @@ S32 LLPrimitive::setTEMediaFlags(const U8 te, const U8 media_flags)
return mTextureList[te].setMediaFlags( media_flags );
}
+S32 LLPrimitive::setTEGlow(const U8 te, const F32 glow)
+{
+ // if we're asking for a non-existent face, return null
+ if (te >= mNumTEs)
+ {
+ llwarns << "setting non-existent te " << te << llendl
+ return 0;
+ }
+
+ return mTextureList[te].setGlow( glow );
+}
+
LLPCode LLPrimitive::legacyToPCode(const U8 legacy)
{
@@ -1272,7 +1287,8 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
S16 image_rot[MAX_TES];
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
-
+ U8 glow[MAX_TES];
+
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
U8 *cur_ptr = packed_buffer;
@@ -1308,7 +1324,7 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * (F32)0x7FFF));
bump[face_index] = te->getBumpShinyFullbright();
media_flags[face_index] = te->getMediaTexGen();
-// llinfos << "BUMP pack [" << (S32)face_index << "]=" << (S32) bump[face_index] << llendl;
+ glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
}
cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
@@ -1328,6 +1344,8 @@ BOOL LLPrimitive::packTEMessage(LLMessageSystem *mesgsys) const
cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8);
*cur_ptr++ = 0;
cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
}
mesgsys->addBinaryDataFast(_PREHASH_TextureEntry, packed_buffer, (S32)(cur_ptr - packed_buffer));
@@ -1348,7 +1366,8 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
S16 image_rot[MAX_TES];
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
-
+ U8 glow[MAX_TES];
+
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
U8 *cur_ptr = packed_buffer;
@@ -1384,8 +1403,7 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
image_rot[face_index] = (S16) llround(((fmod(te->mRotation, F_TWO_PI)/F_TWO_PI) * (F32)0x7FFF));
bump[face_index] = te->getBumpShinyFullbright();
media_flags[face_index] = te->getMediaTexGen();
-
-// llinfos << "BUMP pack (Datapacker) [" << (S32)face_index << "]=" << (S32) bump[face_index] << llendl;
+ glow[face_index] = (U8) llround((llclamp(te->getGlow(), 0.0f, 1.0f) * (F32)0xFF));
}
cur_ptr += packTEField(cur_ptr, (U8 *)image_ids, sizeof(LLUUID),last_face_index, MVT_LLUUID);
@@ -1405,6 +1423,8 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
cur_ptr += packTEField(cur_ptr, (U8 *)bump, 1 ,last_face_index, MVT_U8);
*cur_ptr++ = 0;
cur_ptr += packTEField(cur_ptr, (U8 *)media_flags, 1 ,last_face_index, MVT_U8);
+ *cur_ptr++ = 0;
+ cur_ptr += packTEField(cur_ptr, (U8 *)glow, 1 ,last_face_index, MVT_U8);
}
dp.packBinaryData(packed_buffer, (S32)(cur_ptr - packed_buffer), "TextureEntry");
@@ -1433,7 +1453,8 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con
S16 image_rot[MAX_TES];
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
-
+ U8 glow[MAX_TES];
+
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
U8 *cur_ptr = packed_buffer;
@@ -1483,7 +1504,9 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8);
cur_ptr++;
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
-
+ cur_ptr++;
+ cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
+
LLColor4 color;
LLColor4U coloru;
for (U32 i = 0; i < face_count; i++)
@@ -1494,6 +1517,7 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem *mesgsys, char *block_name, con
retval |= setTERotation(i, ((F32)image_rot[i]/ (F32)0x7FFF) * F_TWO_PI);
retval |= setTEBumpShinyFullbright(i, bump[i]);
retval |= setTEMediaTexGen(i, media_flags[i]);
+ retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
coloru = LLColor4U(colors + 4*i);
// Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
@@ -1528,6 +1552,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
S16 image_rot[MAX_TES];
U8 bump[MAX_TES];
U8 media_flags[MAX_TES];
+ U8 glow[MAX_TES];
const U32 MAX_TE_BUFFER = 4096;
U8 packed_buffer[MAX_TE_BUFFER];
@@ -1568,10 +1593,11 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8);
cur_ptr++;
cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
+ cur_ptr++;
+ cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
for (i = 0; i < face_count; i++)
{
-// llinfos << "BUMP unpack (Datapacker) [" << i << "]=" << S32(bump[i]) <<llendl;
memcpy(image_ids[i].mData,&image_data[i*16],16); /* Flawfinder: ignore */
}
@@ -1585,6 +1611,7 @@ S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
retval |= setTERotation(i, ((F32)image_rot[i]/ (F32)0x7FFF) * F_TWO_PI);
retval |= setTEBumpShinyFullbright(i, bump[i]);
retval |= setTEMediaTexGen(i, media_flags[i]);
+ retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
coloru = LLColor4U(colors + 4*i);
// Note: This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
@@ -1621,6 +1648,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size)
return (size == 16);
case PARAMS_LIGHT:
return (size == 16);
+ case PARAMS_SCULPT:
+ return (size == 17);
}
return FALSE;
@@ -1776,3 +1805,55 @@ void LLFlexibleObjectData::copy(const LLNetworkData& data)
//mUsingCollisionSphere = flex_data->mUsingCollisionSphere;
//mRenderingCollisionSphere = flex_data->mRenderingCollisionSphere;
}
+
+
+//============================================================================
+
+LLSculptParams::LLSculptParams()
+{
+ mType = PARAMS_SCULPT;
+ mSculptTexture.set(SCULPT_DEFAULT_TEXTURE);
+ mSculptType = LL_SCULPT_TYPE_SPHERE;
+}
+
+BOOL LLSculptParams::pack(LLDataPacker &dp) const
+{
+ dp.packUUID(mSculptTexture, "texture");
+ dp.packU8(mSculptType, "type");
+
+ return TRUE;
+}
+
+BOOL LLSculptParams::unpack(LLDataPacker &dp)
+{
+ dp.unpackUUID(mSculptTexture, "texture");
+ dp.unpackU8(mSculptType, "type");
+
+ return TRUE;
+}
+
+bool LLSculptParams::operator==(const LLNetworkData& data) const
+{
+ if (data.mType != PARAMS_SCULPT)
+ {
+ return false;
+ }
+
+ const LLSculptParams *param = (const LLSculptParams*)&data;
+ if ( (param->mSculptTexture != mSculptTexture) ||
+ (param->mSculptType != mSculptType) )
+
+ {
+ return false;
+ }
+
+ return true;
+}
+
+void LLSculptParams::copy(const LLNetworkData& data)
+{
+ const LLSculptParams *param = (LLSculptParams*)&data;
+ mSculptTexture = param->mSculptTexture;
+ mSculptType = param->mSculptType;
+}
+
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 90871fd319..ab1fc4f719 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -68,6 +68,7 @@ extern const F32 OBJECT_REV_MIN;
extern const F32 OBJECT_REV_MAX;
extern const F32 OBJECT_REV_INC;
+extern const char *SCULPT_DEFAULT_TEXTURE;
//============================================================================
@@ -79,7 +80,8 @@ public:
enum
{
PARAMS_FLEXIBLE = 0x10,
- PARAMS_LIGHT = 0x20
+ PARAMS_LIGHT = 0x20,
+ PARAMS_SCULPT = 0x30
};
public:
@@ -206,6 +208,29 @@ public:
void copy(const LLNetworkData& data);
};// end of attributes structure
+
+
+class LLSculptParams : public LLNetworkData
+{
+protected:
+ LLUUID mSculptTexture;
+ U8 mSculptType;
+
+public:
+ LLSculptParams();
+ /*virtual*/ BOOL pack(LLDataPacker &dp) const;
+ /*virtual*/ BOOL unpack(LLDataPacker &dp);
+ /*virtual*/ bool operator==(const LLNetworkData& data) const;
+ /*virtual*/ void copy(const LLNetworkData& data);
+
+ void setSculptTexture(const LLUUID& id) { mSculptTexture = id; }
+ LLUUID getSculptTexture() { return mSculptTexture; }
+ void setSculptType(U8 type) { mSculptType = type; }
+ U8 getSculptType() { return mSculptType; }
+};
+
+
+
class LLPrimitive : public LLXform
{
public:
@@ -246,6 +271,7 @@ public:
virtual S32 setTEShiny(const U8 te, const U8 shiny);
virtual S32 setTEFullbright(const U8 te, const U8 fullbright);
virtual S32 setTEMediaFlags(const U8 te, const U8 flags);
+ virtual S32 setTEGlow(const U8 te, const F32 glow);
virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed
void setTEArrays(const U8 size,
diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp
index 86952dfdb5..85ff779ba2 100644
--- a/indra/llprimitive/lltextureentry.cpp
+++ b/indra/llprimitive/lltextureentry.cpp
@@ -37,6 +37,7 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs)
mColor = rhs.mColor;
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
+ mGlow = rhs.mGlow;
}
LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
@@ -52,6 +53,7 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs)
mColor = rhs.mColor;
mBump = rhs.mBump;
mMediaFlags = rhs.mMediaFlags;
+ mGlow = rhs.mGlow;
}
return *this;
@@ -68,7 +70,8 @@ void LLTextureEntry::init(const LLUUID& tex_id, F32 scale_s, F32 scale_t, F32 of
mRotation = rotation;
mBump = bump;
mMediaFlags = 0x0;
-
+ mGlow = 0;
+
setColor(LLColor4(1.f, 1.f, 1.f, 1.f));
}
@@ -346,3 +349,13 @@ S32 LLTextureEntry::setTexGen(U8 tex_gen)
return 0;
}
+S32 LLTextureEntry::setGlow(F32 glow)
+{
+ if (mGlow != glow)
+ {
+ mGlow = glow;
+ return TEM_CHANGE_TEXTURE;
+ }
+ return 0;
+}
+
diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h
index b9558a159a..f8cdd3bee1 100644
--- a/indra/llprimitive/lltextureentry.h
+++ b/indra/llprimitive/lltextureentry.h
@@ -87,7 +87,8 @@ public:
S32 setMediaFlags(U8 media_flags);
S32 setTexGen(U8 texGen);
S32 setMediaTexGen(U8 media);
-
+ S32 setGlow(F32 glow);
+
const LLUUID &getID() const { return mID; }
const LLColor4 &getColor() const { return mColor; }
void getScale(F32 *s, F32 *t) const { *s = mScaleS; *t = mScaleT; }
@@ -104,7 +105,8 @@ public:
U8 getMediaFlags() const { return mMediaFlags & TEM_MEDIA_MASK; }
U8 getTexGen() const { return mMediaFlags & TEM_TEX_GEN_MASK; }
U8 getMediaTexGen() const { return mMediaFlags; }
-
+ F32 getGlow() const { return mGlow; }
+
// Media flags
enum { MF_NONE = 0x0, MF_WEB_PAGE = 0x1 };
@@ -121,6 +123,8 @@ protected:
LLColor4 mColor;
U8 mBump; // Bump map, shiny, and fullbright
U8 mMediaFlags; // replace with web page, movie, etc.
+ F32 mGlow;
+
};
#endif
diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l
index e93cc6082d..08c2683665 100644
--- a/indra/lscript/lscript_compile/indra.l
+++ b/indra/lscript/lscript_compile/indra.l
@@ -4,7 +4,7 @@ L [a-zA-Z_]
H [a-fA-F0-9]
E [Ee][+-]?{D}+
FS (f|F)
-%e 9000
+%e 10000
%n 4000
%p 5000
@@ -434,6 +434,7 @@ extern "C" { int yyerror(const char *fmt, ...); }
"PRIM_TYPE_TORUS" { count(); yylval.ival = LSL_PRIM_TYPE_TORUS; return(INTEGER_CONSTANT); }
"PRIM_TYPE_TUBE" { count(); yylval.ival = LSL_PRIM_TYPE_TUBE; return(INTEGER_CONSTANT); }
"PRIM_TYPE_RING" { count(); yylval.ival = LSL_PRIM_TYPE_RING; return(INTEGER_CONSTANT); }
+"PRIM_TYPE_SCULPT" { count(); yylval.ival = LSL_PRIM_TYPE_SCULPT; return(INTEGER_CONSTANT); }
"PRIM_HOLE_DEFAULT" { count(); yylval.ival = LSL_PRIM_HOLE_DEFAULT; return(INTEGER_CONSTANT); }
"PRIM_HOLE_CIRCLE" { count(); yylval.ival = LSL_PRIM_HOLE_CIRCLE; return(INTEGER_CONSTANT); }
@@ -476,6 +477,11 @@ extern "C" { int yyerror(const char *fmt, ...); }
"PRIM_TEXGEN_DEFAULT" { count(); yylval.ival = LSL_PRIM_TEXGEN_DEFAULT; return(INTEGER_CONSTANT); }
"PRIM_TEXGEN_PLANAR" { count(); yylval.ival = LSL_PRIM_TEXGEN_PLANAR; return(INTEGER_CONSTANT); }
+"PRIM_SCULPT_TYPE_SPHERE" { count(); yylval.ival = LSL_PRIM_SCULPT_TYPE_SPHERE; return(INTEGER_CONSTANT); }
+"PRIM_SCULPT_TYPE_TORUS" { count(); yylval.ival = LSL_PRIM_SCULPT_TYPE_TORUS; return(INTEGER_CONSTANT); }
+"PRIM_SCULPT_TYPE_PLANE" { count(); yylval.ival = LSL_PRIM_SCULPT_TYPE_PLANE; return(INTEGER_CONSTANT); }
+"PRIM_SCULPT_TYPE_CYLINDER" { count(); yylval.ival = LSL_PRIM_SCULPT_TYPE_CYLINDER; return(INTEGER_CONSTANT); }
+
"MASK_BASE" { count(); yylval.ival = 0; return(INTEGER_CONSTANT); }
"MASK_OWNER" { count(); yylval.ival = 1; return(INTEGER_CONSTANT); }
"MASK_GROUP" { count(); yylval.ival = 2; return(INTEGER_CONSTANT); }
diff --git a/indra/lscript/lscript_library/lscript_library.cpp b/indra/lscript/lscript_library/lscript_library.cpp
index fda6d0e3f3..46717594de 100644
--- a/indra/lscript/lscript_library/lscript_library.cpp
+++ b/indra/lscript/lscript_library/lscript_library.cpp
@@ -404,6 +404,7 @@ void LLScriptLibrary::init()
addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llStringTrim", "s", "si", "string llStringTrim(string src, integer trim_type)\nTrim leading and/or trailing spaces from a string.\nUses trim_type of STRING_TRIM, STRING_TRIM_HEAD or STRING_TRIM_TAIL."));
+ addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llRegionSay", NULL, "is", "llRegionSay(integer channel, string msg)\nbroadcasts msg to entire region on channel (not 0.)"));
// energy, sleep, dummy_func, name, return type, parameters, help text, gods-only
diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings
index 9142437ac5..8fae01fbdc 100644
--- a/indra/newview/English.lproj/InfoPlist.strings
+++ b/indra/newview/English.lproj/InfoPlist.strings
@@ -1,5 +1,5 @@
/* Localized versions of Info.plist keys */
CFBundleName = "Second Life";
-CFBundleShortVersionString = "Second Life version 1.15.2.0";
-CFBundleGetInfoString = "Second Life version 1.15.2.0, Copyright 2004-2007 Linden Research, Inc.";
+CFBundleShortVersionString = "Second Life version 1.16.0.5";
+CFBundleGetInfoString = "Second Life version 1.16.0.5, Copyright 2004-2007 Linden Research, Inc.";
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index a0ee123a6a..764b1520f0 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -32,7 +32,7 @@
</dict>
</array>
<key>CFBundleVersion</key>
- <string>1.15.2.0</string>
+ <string>1.16.0.5</string>
<key>CSResourcesFileMapped</key>
<true/>
</dict>
diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini
index c2a2ce2755..c7f8426804 100644
--- a/indra/newview/app_settings/keywords.ini
+++ b/indra/newview/app_settings/keywords.ini
@@ -346,6 +346,7 @@ PRIM_TYPE_SPHERE Followed by integer hole shape, vector cut, float hollow, vecto
PRIM_TYPE_TORUS Followed by integer hole shape, vector cut, float hollow, vector twist,:vector hole size, vector top shear, vector advanced cut, vector taper,:float revolutions, float radius offset, and float skew
PRIM_TYPE_TUBE Followed by integer hole shape, vector cut, float hollow, vector twist,:vector hole size, vector top shear, vector advanced cut, vector taper,:float revolutions, float radius offset, and float skew
PRIM_TYPE_RING Followed by integer hole shape, vector cut, float hollow, vector twist,:vector hole size, vector top shear, vector advanced cut, vector taper,:float revolutions, float radius offset, and float skew
+PRIM_TYPE_SCULPT Followed by a key or string texture uuid.
PRIM_HOLE_DEFAULT Sets hole type to match the prim type.
PRIM_HOLE_SQUARE Sets hole type to square.
@@ -388,6 +389,11 @@ PRIM_BUMP_WEAVE Weave bump map
PRIM_TEXGEN_DEFAULT Default texture mapping
PRIM_TEXGEN_PLANAR Planar texture mapping
+PRIM_SCULPT_TYPE_SPHERE Stitch edges in a sphere-like way
+PRIM_SCULPT_TYPE_TORUS Stitch edges in a torus-like way
+PRIM_SCULPT_TYPE_PLANE Do not stitch edges
+PRIM_SCULPT_TYPE_CYLINDER Stitch edges in a cylinder-like way
+
MASK_BASE Base permissions
MASK_OWNER Owner permissions
MASK_GROUP Group permissions
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 9fa5244c39..c6155197f6 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -4917,6 +4917,8 @@ void LLAgent::sendAnimationRequests(LLDynamicArray<LLUUID> &anim_ids, EAnimReque
num_valid_anims++;
}
+ msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList);
+ msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0);
if (num_valid_anims)
{
sendReliableMessage();
@@ -4940,6 +4942,8 @@ void LLAgent::sendAnimationRequest(const LLUUID &anim_id, EAnimRequest request)
msg->addUUIDFast(_PREHASH_AnimID, (anim_id) );
msg->addBOOLFast(_PREHASH_StartAnim, (request == ANIM_REQUEST_START) ? TRUE : FALSE);
+ msg->nextBlockFast(_PREHASH_PhysicalAvatarEventList);
+ msg->addBinaryDataFast(_PREHASH_TypeData, NULL, 0);
sendReliableMessage();
}
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index b96ffa46fe..044ae33ccc 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -706,8 +706,6 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
{
LLMemType mt1(LLMemType::MTYPE_DRAWABLE);
- const LLVolumeFace &face = volume.getVolumeFace(f);
-
//get bounding box
if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION))
{
@@ -718,9 +716,18 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
}
LLVector3 min,max;
-
- min = face.mExtents[0];
- max = face.mExtents[1];
+
+ if (f >= volume.getNumVolumeFaces())
+ {
+ min = LLVector3(-1,-1,-1);
+ max = LLVector3(1,1,1);
+ }
+ else
+ {
+ const LLVolumeFace &face = volume.getVolumeFace(f);
+ min = face.mExtents[0];
+ max = face.mExtents[1];
+ }
//min, max are in volume space, convert to drawable render space
LLVector3 center = ((min + max) * 0.5f)*mat_vert;
@@ -884,6 +891,10 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume,
full_rebuild = TRUE;
}
}
+ else
+ {
+ full_rebuild = TRUE;
+ }
}
else
{
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index f10abc4466..4f7ef34fe1 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -82,10 +82,14 @@ BOOL LLFloaterImagePreview::postBuild()
{
mAvatarPreview = new LLImagePreviewAvatar(256, 256);
mAvatarPreview->setPreviewTarget("mPelvis", "mUpperBodyMesh0", mRawImagep, 2.f, FALSE);
+
+ mSculptedPreview = new LLImagePreviewSculpted(256, 256);
+ mSculptedPreview->setPreviewTarget(mRawImagep, 2.0f);
}
else
{
mAvatarPreview = NULL;
+ mSculptedPreview = NULL;
childShow("bad_image_text");
childDisable("clothing_type_combo");
childDisable("ok_btn");
@@ -101,6 +105,8 @@ LLFloaterImagePreview::~LLFloaterImagePreview()
{
mRawImagep = NULL;
delete mAvatarPreview;
+ delete mSculptedPreview;
+
if (mGLName)
{
glDeleteTextures(1, &mGLName );
@@ -115,7 +121,7 @@ void LLFloaterImagePreview::onPreviewTypeCommit(LLUICtrl* ctrl, void* userdata)
{
LLFloaterImagePreview *fp =(LLFloaterImagePreview *)userdata;
- if (!fp->mAvatarPreview)
+ if (!fp->mAvatarPreview || !fp->mSculptedPreview)
{
return;
}
@@ -156,10 +162,15 @@ void LLFloaterImagePreview::onPreviewTypeCommit(LLUICtrl* ctrl, void* userdata)
case 8:
fp->mAvatarPreview->setPreviewTarget("mKneeLeft", "mSkirtMesh0", fp->mRawImagep, 1.3f, FALSE);
break;
+ case 9:
+ fp->mSculptedPreview->setPreviewTarget(fp->mRawImagep, 2.0f);
+ break;
default:
break;
}
+
fp->mAvatarPreview->refresh();
+ fp->mSculptedPreview->refresh();
}
//-----------------------------------------------------------------------------
@@ -173,7 +184,11 @@ void LLFloaterImagePreview::draw()
if (mRawImagep.notNull())
{
LLCtrlSelectionInterface* iface = childGetSelectionInterface("clothing_type_combo");
- if (iface && iface->getFirstSelectedIndex() <= 0)
+ U32 selected = 0;
+ if (iface)
+ selected = iface->getFirstSelectedIndex();
+
+ if (selected <= 0)
{
gl_rect_2d_checkerboard(mPreviewRect);
LLGLDisable gls_alpha(GL_ALPHA_TEST);
@@ -210,6 +225,7 @@ void LLFloaterImagePreview::draw()
if (mAvatarPreview)
{
mAvatarPreview->setTexture(mGLName);
+ mSculptedPreview->setTexture(mGLName);
}
}
@@ -233,10 +249,14 @@ void LLFloaterImagePreview::draw()
}
else
{
- if (mAvatarPreview)
+ if ((mAvatarPreview) && (mSculptedPreview))
{
glColor3f(1.f, 1.f, 1.f);
- mAvatarPreview->bindTexture();
+
+ if (selected == 9)
+ mSculptedPreview->bindTexture();
+ else
+ mAvatarPreview->bindTexture();
glBegin( GL_QUADS );
{
@@ -251,12 +271,16 @@ void LLFloaterImagePreview::draw()
}
glEnd();
- mAvatarPreview->unbindTexture();
+ if (selected == 9)
+ mSculptedPreview->unbindTexture();
+ else
+ mAvatarPreview->unbindTexture();
}
}
}
}
+
//-----------------------------------------------------------------------------
// loadImage()
//-----------------------------------------------------------------------------
@@ -397,6 +421,7 @@ BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask)
else
{
mAvatarPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
+ mSculptedPreview->pan((F32)(x - mLastMouseX) * -0.005f, (F32)(y - mLastMouseY) * -0.005f);
}
}
else if (local_mask == MASK_ORBIT)
@@ -405,6 +430,7 @@ BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask)
F32 pitch_radians = (F32)(y - mLastMouseY) * 0.02f;
mAvatarPreview->rotate(yaw_radians, pitch_radians);
+ mSculptedPreview->rotate(yaw_radians, pitch_radians);
}
else
{
@@ -421,6 +447,8 @@ BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask)
mAvatarPreview->rotate(yaw_radians, 0.f);
mAvatarPreview->zoom(zoom_amt);
+ mSculptedPreview->rotate(yaw_radians, 0.f);
+ mSculptedPreview->zoom(zoom_amt);
}
}
@@ -466,12 +494,13 @@ BOOL LLFloaterImagePreview::handleHover(S32 x, S32 y, MASK mask)
else
{
mAvatarPreview->refresh();
+ mSculptedPreview->refresh();
}
LLUI::setCursorPositionLocal(this, mLastMouseX, mLastMouseY);
}
- if (!mPreviewRect.pointInRect(x, y) || !mAvatarPreview)
+ if (!mPreviewRect.pointInRect(x, y) || !mAvatarPreview || !mSculptedPreview)
{
return LLFloater::handleHover(x, y, mask);
}
@@ -500,6 +529,9 @@ BOOL LLFloaterImagePreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
{
mAvatarPreview->zoom((F32)clicks * -0.2f);
mAvatarPreview->refresh();
+
+ mSculptedPreview->zoom((F32)clicks * -0.2f);
+ mSculptedPreview->refresh();
}
return TRUE;
@@ -540,6 +572,7 @@ LLImagePreviewAvatar::LLImagePreviewAvatar(S32 width, S32 height) : LLDynamicTex
mTextureName = 0;
}
+
LLImagePreviewAvatar::~LLImagePreviewAvatar()
{
mDummyAvatar->markDead();
@@ -582,7 +615,7 @@ void LLImagePreviewAvatar::setPreviewTarget(const char* joint_name, const char*
//-----------------------------------------------------------------------------
// update()
//-----------------------------------------------------------------------------
-BOOL LLImagePreviewAvatar::render()
+BOOL LLImagePreviewAvatar::render()
{
mNeedsUpdate = FALSE;
LLVOAvatar* avatarp = mDummyAvatar;
@@ -620,6 +653,7 @@ BOOL LLImagePreviewAvatar::render()
stop_glerror();
+ gCamera->setAspect((F32)mWidth / mHeight);
gCamera->setView(gCamera->getDefaultFOV() / mCameraZoom);
gCamera->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE);
@@ -672,3 +706,170 @@ void LLImagePreviewAvatar::pan(F32 right, F32 up)
mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f);
mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f);
}
+
+
+//-----------------------------------------------------------------------------
+// LLImagePreviewSculpted
+//-----------------------------------------------------------------------------
+
+LLImagePreviewSculpted::LLImagePreviewSculpted(S32 width, S32 height) : LLDynamicTexture(width, height, 3, ORDER_MIDDLE, FALSE)
+{
+ mNeedsUpdate = TRUE;
+ mCameraDistance = 0.f;
+ mCameraYaw = 0.f;
+ mCameraPitch = 0.f;
+ mCameraZoom = 1.f;
+ mTextureName = 0;
+
+ LLVolumeParams volume_params;
+ volume_params.setType(LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_CIRCLE);
+ mVolume = new LLVolume(volume_params, (F32) MAX_LOD);
+
+ /*
+ mDummyAvatar = new LLVOAvatar(LLUUID::null, LL_PCODE_LEGACY_AVATAR, gAgent.getRegion());
+ mDummyAvatar->createDrawable(&gPipeline);
+ mDummyAvatar->mIsDummy = TRUE;
+ mDummyAvatar->mSpecialRenderMode = 2;
+ mDummyAvatar->setPositionAgent(LLVector3::zero);
+ mDummyAvatar->slamPosition();
+ mDummyAvatar->updateJointLODs();
+ mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
+ gPipeline.markVisible(mDummyAvatar->mDrawable, *gCamera);
+ mTextureName = 0;
+ */
+}
+
+
+LLImagePreviewSculpted::~LLImagePreviewSculpted()
+{
+ /*
+ mDummyAvatar->markDead();
+ */
+}
+
+
+void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance)
+{
+ mCameraDistance = distance;
+ mCameraZoom = 1.f;
+ mCameraPitch = 0.f;
+ mCameraYaw = 0.f;
+ mCameraOffset.clearVec();
+
+ if (imagep)
+ {
+ mVolume->sculpt(imagep->getWidth(), imagep->getHeight(), imagep->getComponents(), imagep->getData(), 0);
+ }
+
+}
+
+
+//-----------------------------------------------------------------------------
+// render()
+//-----------------------------------------------------------------------------
+BOOL LLImagePreviewSculpted::render()
+{
+ mNeedsUpdate = FALSE;
+
+ LLGLSUIDefault def;
+ LLGLDisable no_blend(GL_BLEND);
+ LLGLEnable cull(GL_CULL_FACE);
+ LLGLDepthTest depth(GL_TRUE);
+
+ glMatrixMode(GL_PROJECTION);
+ glPushMatrix();
+ glLoadIdentity();
+ glOrtho(0.0f, mWidth, 0.0f, mHeight, -1.0f, 1.0f);
+
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+
+ glColor4f(0.15f, 0.2f, 0.3f, 1.f);
+
+ gl_rect_2d_simple( mWidth, mHeight );
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+
+ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+ LLVector3 target_pos(0, 0, 0);
+
+ LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) *
+ LLQuaternion(mCameraYaw, LLVector3::z_axis);
+
+ LLQuaternion av_rot = camera_rot;
+ gCamera->setOriginAndLookAt(
+ target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot), // camera
+ LLVector3::z_axis, // up
+ target_pos + (mCameraOffset * av_rot) ); // point of interest
+
+ stop_glerror();
+
+ gCamera->setAspect((F32) mWidth / mHeight);
+ gCamera->setView(gCamera->getDefaultFOV() / mCameraZoom);
+ gCamera->setPerspective(FALSE, mOrigin.mX, mOrigin.mY, mWidth, mHeight, FALSE);
+
+ gPipeline.enableLightsAvatar(0.0);
+
+
+ glPushMatrix();
+ glScalef(0.5, 0.5, 0.5);
+
+ glBegin(GL_TRIANGLES);
+ glColor3f(0.8f, 0.8f, 0.8f);
+
+ const LLVolumeFace &vf = mVolume->getVolumeFace(0);
+ S32 num_indices = (S32)vf.mIndices.size();
+ for (U32 i = 0; (S32)i < num_indices; i++)
+ {
+ LLVector3 normal = vf.mVertices[vf.mIndices[i]].mNormal;
+ normal.normVec();
+ glNormal3f(normal.mV[VX], normal.mV[VY], normal.mV[VZ]);
+
+ LLVector3 position = vf.mVertices[vf.mIndices[i]].mPosition;
+ glVertex3f(position.mV[VX], position.mV[VY], position.mV[VZ]);
+ }
+
+ glEnd();
+
+ glPopMatrix();
+
+ return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// refresh()
+//-----------------------------------------------------------------------------
+void LLImagePreviewSculpted::refresh()
+{
+ mNeedsUpdate = TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// rotate()
+//-----------------------------------------------------------------------------
+void LLImagePreviewSculpted::rotate(F32 yaw_radians, F32 pitch_radians)
+{
+ mCameraYaw = mCameraYaw + yaw_radians;
+
+ mCameraPitch = llclamp(mCameraPitch + pitch_radians, F_PI_BY_TWO * -0.8f, F_PI_BY_TWO * 0.8f);
+}
+
+//-----------------------------------------------------------------------------
+// zoom()
+//-----------------------------------------------------------------------------
+void LLImagePreviewSculpted::zoom(F32 zoom_amt)
+{
+ mCameraZoom = llclamp(mCameraZoom + zoom_amt, 1.f, 10.f);
+}
+
+void LLImagePreviewSculpted::pan(F32 right, F32 up)
+{
+ mCameraOffset.mV[VY] = llclamp(mCameraOffset.mV[VY] + right * mCameraDistance / mCameraZoom, -1.f, 1.f);
+ mCameraOffset.mV[VZ] = llclamp(mCameraOffset.mV[VZ] + up * mCameraDistance / mCameraZoom, -1.f, 1.f);
+}
diff --git a/indra/newview/llfloaterimagepreview.h b/indra/newview/llfloaterimagepreview.h
index 4978a6ea0b..af98466cf8 100644
--- a/indra/newview/llfloaterimagepreview.h
+++ b/indra/newview/llfloaterimagepreview.h
@@ -19,6 +19,34 @@ class LLViewerJointMesh;
class LLVOAvatar;
class LLTextBox;
+class LLImagePreviewSculpted : public LLDynamicTexture
+{
+ public:
+ LLImagePreviewSculpted(S32 width, S32 height);
+ virtual ~LLImagePreviewSculpted();
+
+ void setPreviewTarget(LLImageRaw *imagep, F32 distance);
+ void setTexture(U32 name) { mTextureName = name; }
+
+ BOOL render();
+ void refresh();
+ void rotate(F32 yaw_radians, F32 pitch_radians);
+ void zoom(F32 zoom_amt);
+ void pan(F32 right, F32 up);
+ virtual BOOL needsRender() { return mNeedsUpdate; }
+
+ protected:
+ BOOL mNeedsUpdate;
+ U32 mTextureName;
+ F32 mCameraDistance;
+ F32 mCameraYaw;
+ F32 mCameraPitch;
+ F32 mCameraZoom;
+ LLVector3 mCameraOffset;
+ LLPointer<LLVolume> mVolume;
+};
+
+
class LLImagePreviewAvatar : public LLDynamicTexture
{
public:
@@ -71,6 +99,7 @@ protected:
LLPointer<LLImageRaw> mRawImagep;
LLImagePreviewAvatar* mAvatarPreview;
+ LLImagePreviewSculpted* mSculptedPreview;
S32 mLastMouseX;
S32 mLastMouseY;
LLRect mPreviewRect;
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index 56a4352e22..14da426d9a 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -584,6 +584,7 @@ void LLManipScale::renderFaces( const LLBBox& bbox )
if (mManipPart == LL_NO_PART)
{
glColor4fv( default_normal_color.mV );
+ LLGLDepthTest gls_depth(GL_FALSE);
glBegin(GL_QUADS);
{
// Face 0
@@ -746,7 +747,8 @@ void LLManipScale::renderCorners( const LLBBox& bbox )
void LLManipScale::renderBoxHandle( F32 x, F32 y, F32 z )
{
LLGLDisable gls_tex(GL_TEXTURE_2D);
-
+ LLGLDepthTest gls_depth(GL_FALSE);
+
glPushMatrix();
{
glTranslatef( x, y, z );
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index 314b7bed8f..dcfede70aa 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -33,6 +33,7 @@
#include "llresmgr.h"
#include "llselectmgr.h"
#include "llspinctrl.h"
+#include "lltexturectrl.h"
#include "lltextbox.h"
#include "lltool.h"
#include "lltoolcomp.h"
@@ -60,6 +61,7 @@ enum {
MI_TORUS,
MI_TUBE,
MI_RING,
+ MI_SCULPT,
MI_NONE,
MI_VOLUME_COUNT
};
@@ -232,6 +234,34 @@ BOOL LLPanelObject::postBuild()
childSetCommitCallback("Revolutions",onCommitParametric,this);
mSpinRevolutions->setValidateBeforeCommit( &precommitValidate );
+ // Sculpt
+ mCtrlSculptTexture = LLUICtrlFactory::getTexturePickerByName(this,"sculpt texture control");
+ mCtrlSculptTexture->setDefaultImageAssetID(LLUUID(SCULPT_DEFAULT_TEXTURE));
+ mCtrlSculptTexture->setCommitCallback( LLPanelObject::onCommitSculpt );
+ mCtrlSculptTexture->setOnCancelCallback( LLPanelObject::onCancelSculpt );
+ mCtrlSculptTexture->setOnSelectCallback( LLPanelObject::onSelectSculpt );
+ mCtrlSculptTexture->setDropCallback(LLPanelObject::onDropSculpt);
+ mCtrlSculptTexture->setCallbackUserData( this );
+ // Don't allow (no copy) or (no transfer) textures to be selected during immediate mode
+ mCtrlSculptTexture->setImmediateFilterPermMask(PERM_COPY | PERM_TRANSFER);
+ // Allow any texture to be used during non-immediate mode.
+ mCtrlSculptTexture->setNonImmediateFilterPermMask(PERM_NONE);
+ LLAggregatePermissions texture_perms;
+ if (gSelectMgr->selectGetAggregateTexturePermissions(texture_perms))
+ {
+ BOOL can_copy =
+ texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_EMPTY ||
+ texture_perms.getValue(PERM_COPY) == LLAggregatePermissions::AP_ALL;
+ BOOL can_transfer =
+ texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_EMPTY ||
+ texture_perms.getValue(PERM_TRANSFER) == LLAggregatePermissions::AP_ALL;
+ mCtrlSculptTexture->setCanApplyImmediately(can_copy && can_transfer);
+ }
+ else
+ {
+ mCtrlSculptTexture->setCanApplyImmediately(FALSE);
+ }
+
// Start with everyone disabled
clearCtrls();
@@ -583,6 +613,14 @@ void LLPanelObject::getState( )
llinfos << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << llendl;
selected_item = MI_BOX;
}
+
+
+ if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+ {
+ selected_item = MI_SCULPT;
+ }
+
+
mComboBaseType ->setCurrentByIndex( selected_item );
mSelectedType = selected_item;
@@ -740,6 +778,8 @@ void LLPanelObject::getState( )
// Compute control visibility, label names, and twist range.
// Start with defaults.
+ BOOL cut_visible = TRUE;
+ BOOL hollow_visible = TRUE;
BOOL top_size_x_visible = TRUE;
BOOL top_size_y_visible = TRUE;
BOOL top_shear_x_visible = TRUE;
@@ -750,6 +790,7 @@ void LLPanelObject::getState( )
BOOL skew_visible = FALSE;
BOOL radius_offset_visible = FALSE;
BOOL revolutions_visible = FALSE;
+ BOOL sculpt_texture_visible = FALSE;
F32 twist_min = OBJECT_TWIST_LINEAR_MIN;
F32 twist_max = OBJECT_TWIST_LINEAR_MAX;
F32 twist_inc = OBJECT_TWIST_LINEAR_INC;
@@ -789,6 +830,23 @@ void LLPanelObject::getState( )
twist_inc = OBJECT_TWIST_INC;
break;
+
+ case MI_SCULPT:
+ cut_visible = FALSE;
+ hollow_visible = FALSE;
+ twist_visible = FALSE;
+ top_size_x_visible = FALSE;
+ top_size_y_visible = FALSE;
+ top_shear_x_visible = FALSE;
+ top_shear_y_visible = FALSE;
+ skew_visible = FALSE;
+ advanced_cut_visible = FALSE;
+ taper_visible = FALSE;
+ radius_offset_visible = FALSE;
+ revolutions_visible = FALSE;
+ sculpt_texture_visible = TRUE;
+
+ break;
case MI_BOX:
case MI_CYLINDER:
@@ -909,6 +967,15 @@ void LLPanelObject::getState( )
mSpinRevolutions ->setEnabled( enabled );
// Update field visibility
+ mLabelCut ->setVisible( cut_visible );
+ mSpinCutBegin ->setVisible( cut_visible );
+ mSpinCutEnd ->setVisible( cut_visible );
+
+ mLabelHollow ->setVisible( hollow_visible );
+ mSpinHollow ->setVisible( hollow_visible );
+ mLabelHoleType ->setVisible( hollow_visible );
+ mComboHoleType ->setVisible( hollow_visible );
+
mLabelTwist ->setVisible( twist_visible );
mSpinTwist ->setVisible( twist_visible );
mSpinTwistBegin ->setVisible( twist_visible );
@@ -942,6 +1009,30 @@ void LLPanelObject::getState( )
mLabelRevolutions->setVisible( revolutions_visible );
mSpinRevolutions ->setVisible( revolutions_visible );
+ mCtrlSculptTexture->setVisible( sculpt_texture_visible );
+
+
+ // sculpt texture
+
+ if (selected_item == MI_SCULPT)
+ {
+ LLUUID id;
+ LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+
+ LLTextureCtrl* mTextureCtrl = LLViewerUICtrlFactory::getTexturePickerByName(this,"sculpt texture control");
+ if((mTextureCtrl) && (sculpt_params))
+ {
+ mTextureCtrl->setTentative(FALSE);
+ mTextureCtrl->setEnabled(editable);
+ mTextureCtrl->setImageAssetID(sculpt_params->getSculptTexture());
+
+ if (mObject != objectp) // we've just selected a new object, so save for undo
+ mSculptTextureRevert = sculpt_params->getSculptTexture();
+ }
+
+ }
+
+
//----------------------------------------------------------------------------
mObject = objectp;
@@ -1063,9 +1154,26 @@ void LLPanelObject::onCommitParametric( LLUICtrl* ctrl, void* userdata )
LLVolumeParams volume_params;
self->getVolumeParams(volume_params);
+
+
+ // set sculpting
+ S32 selected_type = self->mComboBaseType->getCurrentIndex();
+
+ if (selected_type == MI_SCULPT)
+ {
+ self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, TRUE, TRUE);
+ }
+ else
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)self->mObject->getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ if (sculpt_params)
+ self->mObject->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE);
+ }
+
// Update the volume, if necessary.
self->mObject->updateVolume(volume_params);
+
// This was added to make sure thate when changes are made, the UI
// adjusts to present valid options.
// *FIX: only some changes, ie, hollow or primitive type changes,
@@ -1118,6 +1226,11 @@ void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params)
path = LL_PCODE_PATH_CIRCLE;
break;
+ case MI_SCULPT:
+ profile = LL_PCODE_PROFILE_CIRCLE;
+ path = LL_PCODE_PATH_CIRCLE;
+ break;
+
default:
llwarns << "Unknown base type " << selected_type
<< " in getVolumeParams()" << llendl;
@@ -1128,6 +1241,7 @@ void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params)
break;
}
+
if (path == LL_PCODE_PATH_LINE)
{
LLVOVolume *volobjp = (LLVOVolume *)(LLViewerObject*)(mObject);
@@ -1338,6 +1452,23 @@ void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params)
F32 shear_x = mSpinShearX->get();
F32 shear_y = mSpinShearY->get();
volume_params.setShear( shear_x, shear_y );
+
+ if (selected_type == MI_SCULPT)
+ {
+ volume_params.setSculptID(LLUUID::null, 0);
+ volume_params.setBeginAndEndT (0, 1);
+ volume_params.setBeginAndEndS (0, 1);
+ volume_params.setHollow (0);
+ volume_params.setTwistBegin (0);
+ volume_params.setTwistEnd (0);
+ volume_params.setRatio (1, 0.5);
+ volume_params.setShear (0, 0);
+ volume_params.setTaper (0, 0);
+ volume_params.setRevolutions (1);
+ volume_params.setRadiusOffset (0);
+ volume_params.setSkew (0);
+ }
+
}
// BUG: Make work with multiple objects
@@ -1482,6 +1613,18 @@ void LLPanelObject::sendPosition()
}
}
+void LLPanelObject::sendSculpt()
+{
+ LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(this,"sculpt texture control");
+ if(!mTextureCtrl)
+ return;
+
+ LLSculptParams sculpt_params;
+ sculpt_params.setSculptTexture(mTextureCtrl->getImageAssetID());
+ sculpt_params.setSculptType(LL_SCULPT_TYPE_SPHERE);
+
+ mObject->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE);
+}
void LLPanelObject::refresh()
{
@@ -1677,3 +1820,59 @@ void LLPanelObject::onCommitCastShadows( LLUICtrl* ctrl, void* userdata )
LLPanelObject* self = (LLPanelObject*) userdata;
self->sendCastShadows();
}
+
+
+// static
+void LLPanelObject::onSelectSculpt(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelObject* self = (LLPanelObject*) userdata;
+
+ LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(self, "sculpt texture control");
+
+ if (mTextureCtrl)
+ self->mSculptTextureRevert = mTextureCtrl->getImageAssetID();
+
+ self->sendSculpt();
+}
+
+
+void LLPanelObject::onCommitSculpt( LLUICtrl* ctrl, void* userdata )
+{
+ LLPanelObject* self = (LLPanelObject*) userdata;
+
+ self->sendSculpt();
+}
+
+// static
+BOOL LLPanelObject::onDropSculpt(LLUICtrl*, LLInventoryItem* item, void* userdata)
+{
+ LLPanelObject* self = (LLPanelObject*) userdata;
+
+ LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(self, "sculpt texture control");
+
+ if (mTextureCtrl)
+ {
+ LLUUID asset = item->getAssetUUID();
+
+ mTextureCtrl->setImageAssetID(asset);
+ self->mSculptTextureRevert = asset;
+ }
+
+
+ return TRUE;
+}
+
+
+// static
+void LLPanelObject::onCancelSculpt(LLUICtrl* ctrl, void* userdata)
+{
+ LLPanelObject* self = (LLPanelObject*) userdata;
+
+ LLTextureCtrl* mTextureCtrl = gUICtrlFactory->getTexturePickerByName(self,"sculpt texture control");
+ if(!mTextureCtrl)
+ return;
+
+ mTextureCtrl->setImageAssetID(self->mSculptTextureRevert);
+
+ self->sendSculpt();
+}
diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h
index 07b65b6372..8c1bea0108 100644
--- a/indra/newview/llpanelobject.h
+++ b/indra/newview/llpanelobject.h
@@ -23,6 +23,9 @@ class LLViewerObject;
class LLComboBox;
class LLPanelInventory;
class LLColorSwatchCtrl;
+class LLTextureCtrl;
+class LLInventoryItem;
+class LLUUID;
class LLPanelObject : public LLPanel
{
@@ -50,6 +53,11 @@ public:
static void onCommitParametric(LLUICtrl* ctrl, void* userdata);
static void onCommitMaterial( LLUICtrl* ctrl, void* userdata);
+
+ static void onCommitSculpt( LLUICtrl* ctrl, void* userdata);
+ static void onCancelSculpt( LLUICtrl* ctrl, void* userdata);
+ static void onSelectSculpt( LLUICtrl* ctrl, void* userdata);
+ static BOOL onDropSculpt(LLUICtrl* ctrl, LLInventoryItem* item, void* ud);
protected:
void getState();
@@ -61,7 +69,8 @@ protected:
void sendIsTemporary();
void sendIsPhantom();
void sendCastShadows();
-
+ void sendSculpt();
+
void getVolumeParams(LLVolumeParams& volume_params);
protected:
@@ -133,12 +142,16 @@ protected:
LLCheckBoxCtrl *mCheckPhantom;
LLCheckBoxCtrl *mCheckCastShadows;
+ LLTextureCtrl *mCtrlSculptTexture;
+
LLVector3 mCurEulerDegrees; // to avoid sending rotation when not changed
BOOL mIsPhysical; // to avoid sending "physical" when not changed
BOOL mIsTemporary; // to avoid sending "temporary" when not changed
BOOL mIsPhantom; // to avoid sending "phantom" when not changed
BOOL mCastShadows; // to avoid sending "cast shadows" when not changed
S32 mSelectedType; // So we know what selected type we last were
+
+ LLUUID mSculptTextureRevert; // so we can revert the sculpt texture on cancel
LLPointer<LLViewerObject> mObject;
LLPointer<LLViewerObject> mRootObject;
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index a155a7aeec..da93aced1f 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -602,7 +602,7 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts)
LLMatrix4 render_mat(vo_volume->getRenderRotation(), LLVector4(vo_volume->getRenderPosition()));
- num_faces = volume->getNumFaces();
+ num_faces = volume->getNumVolumeFaces();
for (i = 0; i < num_faces; i++)
{
const LLVolumeFace& face = volume->getVolumeFace(i);
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index d1a0b3724d..cc31aaef67 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -164,6 +164,7 @@ void LLViewerInventoryItem::updateServer(BOOL is_new) const
msg->nextBlockFast(_PREHASH_AgentData);
msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+ msg->addUUIDFast(_PREHASH_TransactionID, mTransactionID);
msg->nextBlockFast(_PREHASH_InventoryData);
msg->addU32Fast(_PREHASH_CallbackID, 0);
packMessage(msg);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index bf4ad172e6..279dfe2923 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -1308,9 +1308,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
U32 value;
dp->unpackU32(value, "SpecialCode");
-
dp->setPassFlags(value);
-
+ dp->unpackUUID(owner_id, "Owner");
if (value & 0x80)
{
@@ -1449,7 +1448,6 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
if (value & 0x10)
{
dp->unpackUUID(sound_uuid, "SoundUUID");
- dp->unpackUUID(owner_id, "OwnerID");
dp->unpackF32(gain, "SoundGain");
dp->unpackU8(sound_flags, "SoundFlags");
dp->unpackF32(cutoff, "SoundRadius");
@@ -3996,9 +3994,9 @@ void LLViewerObject::unpackParticleSource(const S32 block_num, const LLUUID& own
}
else
{
+ LLViewerPartSourceScript *pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num);
//If the owner is muted, don't create the system
if(gMuteListp->isMuted(owner_id)) return;
- LLViewerPartSourceScript *pss = LLViewerPartSourceScript::unpackPSS(this, NULL, block_num);
// We need to be able to deal with a particle source that hasn't changed, but still got an update!
if (pss)
@@ -4045,10 +4043,9 @@ void LLViewerObject::unpackParticleSource(LLDataPacker &dp, const LLUUID& owner_
}
else
{
+ LLViewerPartSourceScript *pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp);
//If the owner is muted, don't create the system
if(gMuteListp->isMuted(owner_id)) return;
- LLViewerPartSourceScript *pss = LLViewerPartSourceScript::unpackPSS(this, NULL, dp);
-
// We need to be able to deal with a particle source that hasn't changed, but still got an update!
if (pss)
{
@@ -4240,6 +4237,12 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para
new_block = new LLLightParams();
break;
}
+ case LLNetworkData::PARAMS_SCULPT:
+ {
+ new_block = new LLSculptParams();
+ break;
+ }
+
default:
{
llinfos << "Unknown param type." << llendl;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index b53480ec13..6f68f04d67 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -42,7 +42,7 @@
// Viewer object cache version, change if object update
// format changes. JC
-const U32 INDRA_OBJECT_CACHE_VERSION = 12;
+const U32 INDRA_OBJECT_CACHE_VERSION = 14;
extern BOOL gNoRender;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 1090bf4210..ec64cc23b3 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -69,6 +69,8 @@ LLVOVolume::LLVOVolume(const LLUUID &id, const LLPCode pcode, LLViewerRegion *re
mGlobalVolume = FALSE;
mVObjRadius = LLVector3(1,1,0.5f).magVec();
mNumFaces = 0;
+ mLODChanged = FALSE;
+ mSculptChanged = FALSE;
}
LLVOVolume::~LLVOVolume()
@@ -96,6 +98,15 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
// Do base class updates...
U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
+ LLUUID sculpt_id;
+ U8 sculpt_type = 0;
+ if (isSculpted())
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ sculpt_id = sculpt_params->getSculptTexture();
+ sculpt_type = sculpt_params->getSculptType();
+ }
+
if (!dp)
{
if (update_type == OUT_FULL)
@@ -137,6 +148,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
// Unpack volume data
LLVolumeParams volume_params;
LLVolumeMessage::unpackVolumeParams(&volume_params, mesgsys, _PREHASH_ObjectData, block_num);
+ volume_params.setSculptID(sculpt_id, sculpt_type);
if (setVolume(volume_params, 0))
{
@@ -166,7 +178,9 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
llwarns << "Bogus volume parameters in object " << getID() << llendl;
llwarns << getRegion()->getOriginGlobal() << llendl;
}
-
+
+ volume_params.setSculptID(sculpt_id, sculpt_type);
+
if (setVolume(volume_params, 0))
{
markForUpdate(TRUE);
@@ -442,6 +456,28 @@ void LLVOVolume::updateTextures()
if (pri > max_vsize) max_vsize = pri;
}
}
+
+ if (isSculpted())
+ {
+ LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
+ LLUUID id = sculpt_params->getSculptTexture();
+ mSculptTexture = gImageList.getImage(id);
+ if (mSculptTexture.notNull())
+ {
+ mSculptTexture->addTextureStats(mPixelArea);
+ }
+
+ S32 desired_discard = MAX_LOD - mLOD;
+ S32 current_discard = getVolume()->getSculptLevel();
+
+ if (desired_discard != current_discard)
+ {
+ gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
+ mSculptChanged = TRUE;
+ }
+
+ }
+
if (gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_TEXTURE_AREA))
{
@@ -604,22 +640,79 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &volume_params, const S32 detail
}
}
}
+
mGlobalVolume = (mVolumeImpl && mVolumeImpl->isVolumeGlobal());
- if (LLPrimitive::setVolume(volume_params, mLOD, (mVolumeImpl && mVolumeImpl->isVolumeUnique())))
+ if ((LLPrimitive::setVolume(volume_params, mLOD, (mVolumeImpl && mVolumeImpl->isVolumeUnique()))) || mSculptChanged)
{
mFaceMappingChanged = TRUE;
-
+
if (mVolumeImpl)
{
mVolumeImpl->onSetVolume(volume_params, detail);
}
+
+ if (isSculpted())
+ {
+ mSculptTexture = gImageList.getImage(volume_params.getSculptID());
+ if (mSculptTexture.notNull())
+ {
+ sculpt();
+ }
+ }
+ else
+ {
+ mSculptTexture = NULL;
+ }
return TRUE;
}
return FALSE;
}
+// sculpt replaces generate() for sculpted surfaces
+void LLVOVolume::sculpt()
+{
+ U16 sculpt_height = 0;
+ U16 sculpt_width = 0;
+ S8 sculpt_components = 0;
+ const U8* sculpt_data = NULL;
+
+ if (mSculptTexture.notNull())
+ {
+ S32 discard_level;
+ S32 desired_discard = MAX_LOD - mLOD; // desired
+
+ discard_level = desired_discard;
+
+ S32 max_discard = mSculptTexture->getMaxDiscardLevel();
+ if (discard_level > max_discard)
+ discard_level = max_discard; // clamp to the best we can do
+
+ S32 best_discard = mSculptTexture->getDiscardLevel();
+ if (discard_level < best_discard)
+ discard_level = best_discard; // clamp to what we have
+
+ if (best_discard == -1)
+ discard_level = -1; // and if we have nothing, set to nothing
+
+
+ S32 current_discard = getVolume()->getSculptLevel();
+ if (current_discard == discard_level) // no work to do here
+ return;
+
+ LLPointer<LLImageRaw> raw_image = new LLImageRaw();
+ mSculptTexture->readBackRaw(discard_level, raw_image, TRUE);
+
+ sculpt_height = raw_image->getHeight();
+ sculpt_width = raw_image->getWidth();
+
+ sculpt_components = raw_image->getComponents();
+ sculpt_data = raw_image->getData();
+ getVolume()->sculpt(sculpt_width, sculpt_height, sculpt_components, sculpt_data, discard_level);
+ }
+}
+
S32 LLVOVolume::computeLODDetail(F32 distance, F32 radius)
{
S32 cur_detail;
@@ -958,7 +1051,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
genBBoxes(FALSE);
}
}
- else if (mLODChanged)
+ else if ((mLODChanged) || (mSculptChanged))
{
LLPointer<LLVolume> old_volumep, new_volumep;
F32 old_lod, new_lod;
@@ -974,7 +1067,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
new_volumep = getVolume();
new_lod = new_volumep->getDetail();
- if (new_lod != old_lod)
+ if ((new_lod != old_lod) || mSculptChanged)
{
compiled = TRUE;
sNumLODChanges += getVolume()->getNumFaces();
@@ -1010,6 +1103,7 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
mVolumeChanged = FALSE;
mLODChanged = FALSE;
+ mSculptChanged = FALSE;
mFaceMappingChanged = FALSE;
return TRUE;
@@ -1017,9 +1111,16 @@ BOOL LLVOVolume::updateGeometry(LLDrawable *drawable)
void LLVOVolume::updateFaceSize(S32 idx)
{
- const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
LLFace* facep = mDrawable->getFace(idx);
- facep->setSize(vol_face.mVertices.size(), vol_face.mIndices.size());
+ if (idx >= getVolume()->getNumVolumeFaces())
+ {
+ facep->setSize(0,0);
+ }
+ else
+ {
+ const LLVolumeFace& vol_face = getVolume()->getVolumeFace(idx);
+ facep->setSize(vol_face.mVertices.size(), vol_face.mIndices.size());
+ }
}
BOOL LLVOVolume::isRootEdit() const
@@ -1449,7 +1550,6 @@ BOOL LLVOVolume::isFlexible() const
{
if (getVolume()->getParams().getPathParams().getCurveType() != LL_PCODE_PATH_FLEXIBLE)
{
- llwarns << "wtf" << llendl;
LLVolumeParams volume_params = getVolume()->getParams();
U8 profile_and_hole = volume_params.getProfileParams().getCurveType();
volume_params.setType(profile_and_hole, LL_PCODE_PATH_FLEXIBLE);
@@ -1462,6 +1562,16 @@ BOOL LLVOVolume::isFlexible() const
}
}
+BOOL LLVOVolume::isSculpted() const
+{
+ if (getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT))
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
BOOL LLVOVolume::isVolumeGlobal() const
{
if (mVolumeImpl)
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index 16a91bce8e..bde9058f4c 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -132,6 +132,7 @@ public:
void setTexture(const S32 face);
/*virtual*/ BOOL setVolume(const LLVolumeParams &volume_params, const S32 detail, bool unique_volume = false);
+ void sculpt();
void updateRelativeXform();
/*virtual*/ BOOL updateGeometry(LLDrawable *drawable);
/*virtual*/ void updateFaceSize(S32 idx);
@@ -177,6 +178,7 @@ public:
// Flexible Objects
U32 getVolumeInterfaceID() const;
virtual BOOL isFlexible() const;
+ virtual BOOL isSculpted() const;
BOOL isVolumeGlobal() const;
BOOL canBeFlexible() const;
BOOL setIsFlexible(BOOL is_flexible);
@@ -203,12 +205,14 @@ protected:
LLFrameTimer mTextureUpdateTimer;
S32 mLOD;
BOOL mLODChanged;
+ BOOL mSculptChanged;
F32 mRadius;
LLMatrix4 mRelativeXform;
LLMatrix3 mRelativeXformInvTrans;
BOOL mVolumeChanged;
F32 mVObjRadius;
LLVolumeInterface *mVolumeImpl;
+ LLPointer<LLViewerImage> mSculptTexture;
// statics
public:
diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg
index 8213ed0bc9..71bbb0ee14 100644
--- a/scripts/messages/message_template.msg
+++ b/scripts/messages/message_template.msg
@@ -2122,6 +2122,10 @@ sim -> dataserver
{ AnimID LLUUID }
{ StartAnim BOOL }
}
+ {
+ PhysicalAvatarEventList Variable
+ { TypeData Variable 1 }
+ }
}
// AgentRequestSit - Try to sit on an object
@@ -3957,6 +3961,11 @@ sim -> dataserver
AnimationSourceList Variable
{ ObjectID LLUUID }
}
+ {
+ PhysicalAvatarEventList Variable
+ { TypeData Variable 1 }
+ }
+
}
// AvatarAppearance - Update visual params
@@ -6360,6 +6369,7 @@ sim -> dataserver
AgentData Single
{ AgentID LLUUID }
{ SessionID LLUUID }
+ { TransactionID LLUUID }
}
{
InventoryData Variable
@@ -6400,6 +6410,7 @@ sim -> dataserver
AgentData Single
{ AgentID LLUUID }
{ SimApproved BOOL }
+ { TransactionID LLUUID }
}
{
InventoryData Variable
@@ -6928,6 +6939,11 @@ sim -> dataserver
// saving into task inventory.
{
DeRezAck Low Trusted Unencoded
+ {
+ TransactionData Single
+ { TransactionID LLUUID }
+ { Success BOOL }
+ }
}
// This message is sent from viewer -> simulator when the viewer wants