merge
commit
f1784209d5
10
BuildParams
10
BuildParams
|
|
@ -102,6 +102,16 @@ mesh-development.build_debug_release_separately = true
|
|||
mesh-development.build_CYGWIN_Debug = false
|
||||
mesh-development.build_viewer_update_version_manager = false
|
||||
|
||||
# ========================================
|
||||
# mesh-asset-deprecation
|
||||
# ========================================
|
||||
mesh-asset-deprecation.viewer_channel = "Project Viewer - Mesh Asset Deprecation"
|
||||
mesh-asset-deprecation.login_channel = "Project Viewer - Mesh Asset Deprecation"
|
||||
mesh-asset-deprecation.viewer_grid = aditi
|
||||
mesh-asset-deprecation.build_debug_release_separately = true
|
||||
mesh-asset-deprecation.build_CYGWIN_Debug = false
|
||||
mesh-asset-deprecation.build_viewer_update_version_manager = false
|
||||
|
||||
# ========================================
|
||||
# viewer-mesh
|
||||
# ========================================
|
||||
|
|
|
|||
|
|
@ -18,9 +18,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>930bdd987a321eda1838caba8cd6098f</string>
|
||||
<string>3ecad1f19fb884e4ce0c27f6407cb5d9</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/230348/arch/Darwin/installer/glod-1.0pre4-darwin-20110519.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232171/arch/Darwin/installer/glod-1.0pre4-darwin-20110606.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>darwin</string>
|
||||
|
|
@ -30,9 +30,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>fb33b6cac2e6b98f93c5efa2af2e5a00</string>
|
||||
<string>f1f73a9ca1d2dfa68570c7379ebabcce</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/230348/arch/Linux/installer/glod-1.0pre4-linux-20110519.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232171/arch/Linux/installer/glod-1.0pre4-linux-20110607.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>linux</string>
|
||||
|
|
@ -42,9 +42,9 @@
|
|||
<key>archive</key>
|
||||
<map>
|
||||
<key>hash</key>
|
||||
<string>388cf0e292f756b4bb37696622f0bbc5</string>
|
||||
<string>afcf9be19bebee7713ca5188b645d2b0</string>
|
||||
<key>url</key>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/230348/arch/CYGWIN/installer/glod-1.0pre4-windows-20110519.tar.bz2</string>
|
||||
<string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232171/arch/CYGWIN/installer/glod-1.0pre4-windows-20110606.tar.bz2</string>
|
||||
</map>
|
||||
<key>name</key>
|
||||
<string>windows</string>
|
||||
|
|
|
|||
|
|
@ -2419,12 +2419,25 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size)
|
|||
|
||||
for (U32 i = 0; i < face_count; ++i)
|
||||
{
|
||||
LLVolumeFace& face = mVolumeFaces[i];
|
||||
|
||||
if (mdl[i].has("NoGeometry"))
|
||||
{ //face has no geometry, continue
|
||||
face.resizeIndices(3);
|
||||
face.resizeVertices(1);
|
||||
memset(face.mPositions, 0, sizeof(LLVector4a));
|
||||
memset(face.mNormals, 0, sizeof(LLVector4a));
|
||||
memset(face.mTexCoords, 0, sizeof(LLVector2));
|
||||
memset(face.mIndices, 0, sizeof(U16)*3);
|
||||
continue;
|
||||
}
|
||||
|
||||
LLSD::Binary pos = mdl[i]["Position"];
|
||||
LLSD::Binary norm = mdl[i]["Normal"];
|
||||
LLSD::Binary tc = mdl[i]["TexCoord0"];
|
||||
LLSD::Binary idx = mdl[i]["TriangleList"];
|
||||
|
||||
LLVolumeFace& face = mVolumeFaces[i];
|
||||
|
||||
|
||||
//copy out indices
|
||||
face.resizeIndices(idx.size()/2);
|
||||
|
|
|
|||
|
|
@ -742,6 +742,7 @@ char const* const _PREHASH_MoneyData = LLMessageStringTable::getInstance()->getS
|
|||
char const* const _PREHASH_ObjectDeselect = LLMessageStringTable::getInstance()->getString("ObjectDeselect");
|
||||
char const* const _PREHASH_NewAssetID = LLMessageStringTable::getInstance()->getString("NewAssetID");
|
||||
char const* const _PREHASH_ObjectAdd = LLMessageStringTable::getInstance()->getString("ObjectAdd");
|
||||
char const* const _PREHASH_SimulatorFeatures = LLMessageStringTable::getInstance()->getString("SimulatorFeatures");
|
||||
char const* const _PREHASH_RayEndIsIntersection = LLMessageStringTable::getInstance()->getString("RayEndIsIntersection");
|
||||
char const* const _PREHASH_CompleteAuction = LLMessageStringTable::getInstance()->getString("CompleteAuction");
|
||||
char const* const _PREHASH_CircuitCode = LLMessageStringTable::getInstance()->getString("CircuitCode");
|
||||
|
|
|
|||
|
|
@ -742,6 +742,7 @@ extern char const* const _PREHASH_MoneyData;
|
|||
extern char const* const _PREHASH_ObjectDeselect;
|
||||
extern char const* const _PREHASH_NewAssetID;
|
||||
extern char const* const _PREHASH_ObjectAdd;
|
||||
extern char const* const _PREHASH_SimulatorFeatures;
|
||||
extern char const* const _PREHASH_RayEndIsIntersection;
|
||||
extern char const* const _PREHASH_CompleteAuction;
|
||||
extern char const* const _PREHASH_CircuitCode;
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ std::string model_names[] =
|
|||
"low_lod",
|
||||
"medium_lod",
|
||||
"high_lod",
|
||||
"physics_shape"
|
||||
"physics_mesh"
|
||||
};
|
||||
|
||||
const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string);
|
||||
|
|
@ -1390,7 +1390,11 @@ LLSD LLModel::writeModel(
|
|||
if (!decomp.mBaseHull.empty() ||
|
||||
!decomp.mHull.empty())
|
||||
{
|
||||
mdl["decomposition"] = decomp.asLLSD();
|
||||
mdl["physics_convex"] = decomp.asLLSD();
|
||||
if (!decomp.mHull.empty())
|
||||
{ //convex decomposition exists, physics mesh will not be used
|
||||
model[LLModel::LOD_PHYSICS] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (U32 idx = 0; idx < MODEL_NAMES_LENGTH; ++idx)
|
||||
|
|
@ -1415,8 +1419,9 @@ LLSD LLModel::writeModel(
|
|||
for (S32 i = 0; i < model[idx]->getNumVolumeFaces(); ++i)
|
||||
{ //for each face
|
||||
const LLVolumeFace& face = model[idx]->getVolumeFace(i);
|
||||
if (!face.mNumVertices)
|
||||
if (face.mNumVertices < 3)
|
||||
{ //don't export an empty face
|
||||
mdl[model_names[idx]][i]["NoGeometry"] = true;
|
||||
continue;
|
||||
}
|
||||
LLSD::Binary verts(face.mNumVertices*3*2);
|
||||
|
|
@ -1449,7 +1454,6 @@ LLSD LLModel::writeModel(
|
|||
//position + normal
|
||||
for (U32 k = 0; k < 3; ++k)
|
||||
{ //for each component
|
||||
|
||||
//convert to 16-bit normalized across domain
|
||||
U16 val = (U16) (((pos[k]-min_pos.mV[k])/pos_range.mV[k])*65535);
|
||||
|
||||
|
|
@ -1493,7 +1497,6 @@ LLSD LLModel::writeModel(
|
|||
//write out face data
|
||||
mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue();
|
||||
mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue();
|
||||
|
||||
mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue();
|
||||
mdl[model_names[idx]][i]["TexCoord0Domain"]["Max"] = max_tc.getValue();
|
||||
|
||||
|
|
@ -1586,15 +1589,15 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
|
|||
|
||||
std::string decomposition;
|
||||
|
||||
if (mdl.has("decomposition"))
|
||||
if (mdl.has("physics_convex"))
|
||||
{ //write out convex decomposition
|
||||
decomposition = zip_llsd(mdl["decomposition"]);
|
||||
decomposition = zip_llsd(mdl["physics_convex"]);
|
||||
|
||||
U32 size = decomposition.size();
|
||||
if (size > 0)
|
||||
{
|
||||
header["decomposition"]["offset"] = (LLSD::Integer) cur_offset;
|
||||
header["decomposition"]["size"] = (LLSD::Integer) size;
|
||||
header["physics_convex"]["offset"] = (LLSD::Integer) cur_offset;
|
||||
header["physics_convex"]["size"] = (LLSD::Integer) size;
|
||||
cur_offset += size;
|
||||
bytes += size;
|
||||
}
|
||||
|
|
@ -1615,11 +1618,6 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
|
|||
cur_offset += size;
|
||||
bytes += size;
|
||||
}
|
||||
else
|
||||
{
|
||||
header[model_names[i]]["offset"] = -1;
|
||||
header[model_names[i]]["size"] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!nowrite)
|
||||
|
|
@ -1633,7 +1631,7 @@ LLSD LLModel::writeModelToStream(std::ostream& ostr, LLSD& mdl, BOOL nowrite)
|
|||
|
||||
if (!decomposition.empty())
|
||||
{ //write decomposition block
|
||||
ostr.write((const char*) decomposition.data(), header["decomposition"]["size"].asInteger());
|
||||
ostr.write((const char*) decomposition.data(), header["physics_convex"]["size"].asInteger());
|
||||
}
|
||||
|
||||
for (S32 i = 0; i < MODEL_NAMES_LENGTH; i++)
|
||||
|
|
@ -1772,7 +1770,7 @@ bool LLModel::loadModel(std::istream& is)
|
|||
"low_lod",
|
||||
"medium_lod",
|
||||
"high_lod",
|
||||
"physics_shape",
|
||||
"physics_mesh",
|
||||
};
|
||||
|
||||
const S32 MODEL_LODS = 5;
|
||||
|
|
@ -1871,8 +1869,8 @@ bool LLModel::loadSkinInfo(LLSD& header, std::istream &is)
|
|||
|
||||
bool LLModel::loadDecomposition(LLSD& header, std::istream& is)
|
||||
{
|
||||
S32 offset = header["decomposition"]["offset"].asInteger();
|
||||
S32 size = header["decomposition"]["size"].asInteger();
|
||||
S32 offset = header["physics_convex"]["offset"].asInteger();
|
||||
S32 size = header["physics_convex"]["size"].asInteger();
|
||||
|
||||
if (offset >= 0 && size > 0)
|
||||
{
|
||||
|
|
@ -2012,7 +2010,7 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
|
|||
{
|
||||
// updated for const-correctness. gcc is picky about this type of thing - Nyx
|
||||
const LLSD::Binary& hulls = decomp["HullList"].asBinary();
|
||||
const LLSD::Binary& position = decomp["Position"].asBinary();
|
||||
const LLSD::Binary& position = decomp["Positions"].asBinary();
|
||||
|
||||
U16* p = (U16*) &position[0];
|
||||
|
||||
|
|
@ -2022,11 +2020,19 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
|
|||
LLVector3 max;
|
||||
LLVector3 range;
|
||||
|
||||
min.setValue(decomp["Min"]);
|
||||
max.setValue(decomp["Max"]);
|
||||
if (decomp.has("Min"))
|
||||
{
|
||||
min.setValue(decomp["Min"]);
|
||||
max.setValue(decomp["Max"]);
|
||||
}
|
||||
else
|
||||
{
|
||||
min.set(-0.5f, -0.5f, -0.5f);
|
||||
max.set(0.5f, 0.5f, 0.5f);
|
||||
}
|
||||
|
||||
range = max-min;
|
||||
|
||||
|
||||
for (U32 i = 0; i < hulls.size(); ++i)
|
||||
{
|
||||
U16 count = (hulls[i] == 0) ? 256 : hulls[i];
|
||||
|
|
@ -2042,6 +2048,7 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
|
|||
//point must be unique
|
||||
//llassert(valid.find(test) == valid.end());
|
||||
valid.insert(test);
|
||||
|
||||
mHull[i].push_back(LLVector3(
|
||||
(F32) p[0]/65535.f*range.mV[0]+min.mV[0],
|
||||
(F32) p[1]/65535.f*range.mV[1]+min.mV[1],
|
||||
|
|
@ -2056,9 +2063,9 @@ void LLModel::Decomposition::fromLLSD(LLSD& decomp)
|
|||
}
|
||||
}
|
||||
|
||||
if (decomp.has("Hull"))
|
||||
if (decomp.has("BoundingVerts"))
|
||||
{
|
||||
const LLSD::Binary& position = decomp["Hull"].asBinary();
|
||||
const LLSD::Binary& position = decomp["BundingVerts"].asBinary();
|
||||
|
||||
U16* p = (U16*) &position[0];
|
||||
|
||||
|
|
@ -2113,11 +2120,9 @@ LLSD LLModel::Decomposition::asLLSD() const
|
|||
}
|
||||
|
||||
//write decomposition block
|
||||
// ["decomposition"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points
|
||||
// ["decomposition"]["PositionDomain"]["Min"/"Max"]
|
||||
// ["decomposition"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points
|
||||
// ["decomposition"]["Hull"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape
|
||||
|
||||
// ["physics_convex"]["HullList"] -- list of 8 bit integers, each entry represents a hull with specified number of points
|
||||
// ["physics_convex"]["Position"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points
|
||||
// ["physics_convex"]["BoundingVerts"] -- list of 16-bit integers to be decoded to given domain, encoded 3D points representing a single hull approximation of given shape
|
||||
|
||||
//get minimum and maximum
|
||||
LLVector3 min;
|
||||
|
|
@ -2166,6 +2171,8 @@ LLSD LLModel::Decomposition::asLLSD() const
|
|||
{
|
||||
LLSD::Binary p(total*3*2);
|
||||
|
||||
LLVector3 min(-0.5f, -0.5f, -0.5f);
|
||||
LLVector3 max(0.5f, 0.5f, 0.5f);
|
||||
LLVector3 range = max-min;
|
||||
|
||||
U32 vert_idx = 0;
|
||||
|
|
@ -2181,8 +2188,12 @@ LLSD LLModel::Decomposition::asLLSD() const
|
|||
U64 test = 0;
|
||||
for (U32 k = 0; k < 3; k++)
|
||||
{
|
||||
F32* src = (F32*) (mHull[i][j].mV);
|
||||
|
||||
llassert(src[k] <= 0.501f && src[k] >= -0.501f);
|
||||
|
||||
//convert to 16-bit normalized across domain
|
||||
U16 val = (U16) (((mHull[i][j].mV[k]-min.mV[k])/range.mV[k])*65535);
|
||||
U16 val = (U16) (((src[k]-min.mV[k])/range.mV[k])*65535);
|
||||
|
||||
if(valid.size() < 3)
|
||||
{
|
||||
|
|
@ -2210,13 +2221,15 @@ LLSD LLModel::Decomposition::asLLSD() const
|
|||
llassert(valid.size() > 2);
|
||||
}
|
||||
|
||||
ret["Position"] = p;
|
||||
ret["Positions"] = p;
|
||||
}
|
||||
|
||||
if (!mBaseHull.empty())
|
||||
{
|
||||
LLSD::Binary p(mBaseHull.size()*3*2);
|
||||
|
||||
LLVector3 min(-0.5f, -0.5f, -0.5f);
|
||||
LLVector3 max(0.5f, 0.5f, 0.5f);
|
||||
LLVector3 range = max-min;
|
||||
|
||||
U32 vert_idx = 0;
|
||||
|
|
@ -2224,6 +2237,8 @@ LLSD LLModel::Decomposition::asLLSD() const
|
|||
{
|
||||
for (U32 k = 0; k < 3; k++)
|
||||
{
|
||||
llassert(mBaseHull[j].mV[k] <= 0.51f && mBaseHull[j].mV[k] >= -0.51f);
|
||||
|
||||
//convert to 16-bit normalized across domain
|
||||
U16 val = (U16) (((mBaseHull[j].mV[k]-min.mV[k])/range.mV[k])*65535);
|
||||
|
||||
|
|
@ -2239,7 +2254,7 @@ LLSD LLModel::Decomposition::asLLSD() const
|
|||
}
|
||||
}
|
||||
|
||||
ret["Hull"] = p;
|
||||
ret["BoundingVerts"] = p;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ LLLocale::LLLocale(const std::string& locale_string)
|
|||
char* new_locale_string = setlocale( LC_ALL, locale_string.c_str());
|
||||
if ( new_locale_string == NULL)
|
||||
{
|
||||
llwarns << "Failed to set locale " << locale_string << llendl;
|
||||
LL_WARNS_ONCE("LLLocale") << "Failed to set locale " << locale_string << LL_ENDL;
|
||||
setlocale(LC_ALL, SYSTEM_LOCALE.c_str());
|
||||
}
|
||||
//else
|
||||
|
|
|
|||
|
|
@ -459,14 +459,6 @@ S32 LLDrawPoolAvatar::getNumPasses()
|
|||
{
|
||||
return 10;
|
||||
}
|
||||
if (LLPipeline::sImpostorRender)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1419,7 +1411,7 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
|
|||
|
||||
void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
|
||||
{
|
||||
if (avatar->isSelf() && !gAgent.needsRenderAvatar())
|
||||
if (avatar->isSelf() && !gAgent.needsRenderAvatar() || !gMeshRepo.meshRezEnabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -178,6 +178,80 @@ std::string lod_label_name[NUM_LOD+1] =
|
|||
"I went off the end of the lod_label_name array. Me so smart."
|
||||
};
|
||||
|
||||
|
||||
#define LL_DEGENERACY_TOLERANCE 1e-7f
|
||||
|
||||
inline F32 dot3fpu(const LLVector4a& a, const LLVector4a& b)
|
||||
{
|
||||
volatile F32 p0 = a[0] * b[0];
|
||||
volatile F32 p1 = a[1] * b[1];
|
||||
volatile F32 p2 = a[2] * b[2];
|
||||
return p0 + p1 + p2;
|
||||
}
|
||||
|
||||
bool ll_is_degenerate(const LLVector4a& a, const LLVector4a& b, const LLVector4a& c, F32 tolerance = LL_DEGENERACY_TOLERANCE)
|
||||
{
|
||||
// small area check
|
||||
{
|
||||
LLVector4a edge1; edge1.setSub( a, b );
|
||||
LLVector4a edge2; edge2.setSub( a, c );
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/// Linden Modified
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// If no one edge is more than 10x longer than any other edge, we weaken
|
||||
// the tolerance by a factor of 1e-4f.
|
||||
|
||||
LLVector4a edge3; edge3.setSub( c, b );
|
||||
const F32 len1sq = edge1.dot3(edge1).getF32();
|
||||
const F32 len2sq = edge2.dot3(edge2).getF32();
|
||||
const F32 len3sq = edge3.dot3(edge3).getF32();
|
||||
bool abOK = (len1sq <= 100.f * len2sq) && (len1sq <= 100.f * len3sq);
|
||||
bool acOK = (len2sq <= 100.f * len1sq) && (len1sq <= 100.f * len3sq);
|
||||
bool cbOK = (len3sq <= 100.f * len1sq) && (len1sq <= 100.f * len2sq);
|
||||
if ( abOK && acOK && cbOK )
|
||||
{
|
||||
tolerance *= 1e-4f;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
/// End Modified
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLVector4a cross; cross.setCross3( edge1, edge2 );
|
||||
|
||||
LLVector4a edge1b; edge1b.setSub( b, a );
|
||||
LLVector4a edge2b; edge2b.setSub( b, c );
|
||||
LLVector4a crossb; crossb.setCross3( edge1b, edge2b );
|
||||
|
||||
if ( ( cross.dot3(cross).getF32() < tolerance ) || ( crossb.dot3(crossb).getF32() < tolerance ))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// point triangle distance check
|
||||
{
|
||||
LLVector4a Q; Q.setSub(a, b);
|
||||
LLVector4a R; R.setSub(c, b);
|
||||
|
||||
const F32 QQ = dot3fpu(Q, Q);
|
||||
const F32 RR = dot3fpu(R, R);
|
||||
const F32 QR = dot3fpu(R, Q);
|
||||
|
||||
volatile F32 QQRR = QQ * RR;
|
||||
volatile F32 QRQR = QR * QR;
|
||||
F32 Det = (QQRR - QRQR);
|
||||
|
||||
if( Det == 0.0f )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool validate_face(const LLVolumeFace& face)
|
||||
{
|
||||
for (U32 i = 0; i < face.mNumIndices; ++i)
|
||||
|
|
@ -189,6 +263,31 @@ bool validate_face(const LLVolumeFace& face)
|
|||
}
|
||||
}
|
||||
|
||||
if (face.mNumIndices % 3 != 0 || face.mNumIndices == 0)
|
||||
{
|
||||
llwarns << "Face has invalid number of indices." << llendl;
|
||||
return false;
|
||||
}
|
||||
|
||||
/*const LLVector4a scale(0.5f);
|
||||
|
||||
for (U32 i = 0; i < face.mNumIndices; i+=3)
|
||||
{
|
||||
U16 idx1 = face.mIndices[i];
|
||||
U16 idx2 = face.mIndices[i+1];
|
||||
U16 idx3 = face.mIndices[i+2];
|
||||
|
||||
LLVector4a v1; v1.setMul(face.mPositions[idx1], scale);
|
||||
LLVector4a v2; v2.setMul(face.mPositions[idx2], scale);
|
||||
LLVector4a v3; v3.setMul(face.mPositions[idx3], scale);
|
||||
|
||||
if (ll_is_degenerate(v1,v2,v3))
|
||||
{
|
||||
llwarns << "Degenerate face found!" << llendl;
|
||||
return false;
|
||||
}
|
||||
}*/
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -1300,7 +1399,7 @@ bool LLModelLoader::doLoadModel()
|
|||
if(model->getStatus() != LLModel::NO_ERRORS)
|
||||
{
|
||||
setLoadState(ERROR_PARSING + model->getStatus()) ;
|
||||
return true ; //abort
|
||||
return false; //abort
|
||||
}
|
||||
|
||||
if (model.notNull() && validate_model(model))
|
||||
|
|
@ -2688,7 +2787,7 @@ LLModelPreview::~LLModelPreview()
|
|||
{
|
||||
if (mModelLoader)
|
||||
{
|
||||
delete mModelLoader;
|
||||
mModelLoader->mPreview = NULL;
|
||||
mModelLoader = NULL;
|
||||
}
|
||||
//*HACK : *TODO : turn this back on when we understand why this crashes
|
||||
|
|
@ -3784,7 +3883,35 @@ void LLModelPreview::updateStatusMessages()
|
|||
mMaxTriangleLimit = total_tris[LLModel::LOD_HIGH];
|
||||
}
|
||||
|
||||
bool has_degenerate = false;
|
||||
|
||||
{//check for degenerate triangles in physics mesh
|
||||
U32 lod = LLModel::LOD_PHYSICS;
|
||||
const LLVector4a scale(0.5f);
|
||||
for (U32 i = 0; i < mModel[lod].size() && !has_degenerate; ++i)
|
||||
{ //for each model in the lod
|
||||
if (mModel[lod][i]->mPhysics.mHull.empty())
|
||||
{ //no decomp exists
|
||||
S32 cur_submeshes = mModel[lod][i]->getNumVolumeFaces();
|
||||
for (S32 j = 0; j < cur_submeshes && !has_degenerate; ++j)
|
||||
{ //for each submesh (face), add triangles and vertices to current total
|
||||
const LLVolumeFace& face = mModel[lod][i]->getVolumeFace(j);
|
||||
for (S32 k = 0; k < face.mNumIndices && !has_degenerate; )
|
||||
{
|
||||
LLVector4a v1; v1.setMul(face.mPositions[face.mIndices[k++]], scale);
|
||||
LLVector4a v2; v2.setMul(face.mPositions[face.mIndices[k++]], scale);
|
||||
LLVector4a v3; v3.setMul(face.mPositions[face.mIndices[k++]], scale);
|
||||
|
||||
if (ll_is_degenerate(v1,v2,v3))
|
||||
{
|
||||
has_degenerate = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mFMP->childSetTextArg("submeshes_info", "[SUBMESHES]", llformat("%d", total_submeshes[LLModel::LOD_HIGH]));
|
||||
|
||||
std::string mesh_status_na = mFMP->getString("mesh_status_na");
|
||||
|
|
@ -3885,7 +4012,10 @@ void LLModelPreview::updateStatusMessages()
|
|||
|
||||
for (U32 j = 0; upload_ok && j < mdl->mPhysics.mHull.size(); ++j)
|
||||
{
|
||||
upload_ok = upload_ok && mdl->mPhysics.mHull[i].size() <= 256;
|
||||
if (mdl->mPhysics.mHull[j].size() > 256)
|
||||
{
|
||||
upload_ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3909,7 +4039,7 @@ void LLModelPreview::updateStatusMessages()
|
|||
}
|
||||
|
||||
const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean();
|
||||
if ( upload_ok && !errorStateFromLoader && skinAndRigOk && confirmed_checkbox)
|
||||
if ( upload_ok && !errorStateFromLoader && skinAndRigOk && !has_degenerate && confirmed_checkbox)
|
||||
{
|
||||
mFMP->childEnable("ok_btn");
|
||||
}
|
||||
|
|
@ -4695,6 +4825,32 @@ BOOL LLModelPreview::render()
|
|||
glLineWidth(3.f);
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
|
||||
|
||||
{ //show degenerate triangles
|
||||
LLStrider<LLVector3> pos_strider;
|
||||
buffer->getVertexStrider(pos_strider, 0);
|
||||
LLVector4a* pos = (LLVector4a*) pos_strider.get();
|
||||
|
||||
LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS);
|
||||
LLGLDisable cull(GL_CULL_FACE);
|
||||
LLStrider<U16> idx;
|
||||
buffer->getIndexStrider(idx, 0);
|
||||
|
||||
glColor4f(1.f,0.f,0.f,1.f);
|
||||
const LLVector4a scale(0.5f);
|
||||
for (U32 i = 0; i < buffer->getNumIndices(); i += 3)
|
||||
{
|
||||
LLVector4a v1; v1.setMul(pos[*idx++], scale);
|
||||
LLVector4a v2; v2.setMul(pos[*idx++], scale);
|
||||
LLVector4a v3; v3.setMul(pos[*idx++], scale);
|
||||
|
||||
if (ll_is_degenerate(v1,v2,v3))
|
||||
{
|
||||
buffer->draw(LLRender::TRIANGLES, 3, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||
glLineWidth(1.f);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@
|
|||
#include "llvlcomposition.h"
|
||||
#include "lltrans.h"
|
||||
#include "llagentui.h"
|
||||
#include "llmeshrepository.h"
|
||||
|
||||
const S32 TERRAIN_TEXTURE_COUNT = 4;
|
||||
const S32 CORNER_COUNT = 4;
|
||||
|
|
@ -590,9 +591,7 @@ bool LLPanelRegionGeneralInfo::refreshFromRegion(LLViewerRegion* region)
|
|||
getChildView("im_btn")->setEnabled(allow_modify);
|
||||
getChildView("manage_telehub_btn")->setEnabled(allow_modify);
|
||||
|
||||
const bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") &&
|
||||
gAgent.getRegion() &&
|
||||
!gAgent.getRegion()->getCapability("GetMesh").empty();
|
||||
const bool enable_mesh = gMeshRepo.meshRezEnabled();
|
||||
getChildView("mesh_rez_enabled_check")->setVisible(enable_mesh);
|
||||
getChildView("mesh_rez_enabled_check")->setEnabled(getChildView("mesh_rez_enabled_check")->getEnabled() && enable_mesh);
|
||||
// Data gets filled in by processRegionInfo
|
||||
|
|
|
|||
|
|
@ -86,6 +86,7 @@
|
|||
#include "llvovolume.h"
|
||||
#include "lluictrlfactory.h"
|
||||
#include "llaccountingquotamanager.h"
|
||||
#include "llmeshrepository.h"
|
||||
|
||||
// Globals
|
||||
LLFloaterTools *gFloaterTools = NULL;
|
||||
|
|
@ -423,7 +424,7 @@ void LLFloaterTools::refresh()
|
|||
// Refresh object and prim count labels
|
||||
LLLocale locale(LLLocale::USER_LOCALE);
|
||||
|
||||
if ((gAgent.getRegion() && (gAgent.getRegion()->getCapability("GetMesh").empty() || gAgent.getRegion()->getCapability("ObjectAdd").empty())) || !gSavedSettings.getBOOL("MeshEnabled"))
|
||||
if (gMeshRepo.meshRezEnabled())
|
||||
{
|
||||
std::string obj_count_string;
|
||||
LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount());
|
||||
|
|
@ -788,10 +789,7 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
|
|||
getChildView("Strength:")->setVisible( land_visible);
|
||||
}
|
||||
|
||||
bool show_mesh_cost = gAgent.getRegion() &&
|
||||
!gAgent.getRegion()->getCapability("GetMesh").empty() &&
|
||||
gSavedSettings.getBOOL("MeshEnabled") &&
|
||||
!gAgent.getRegion()->getCapability("ObjectAdd").empty();
|
||||
bool show_mesh_cost = gMeshRepo.meshRezEnabled();
|
||||
|
||||
getChildView("obj_count")->setVisible( !land_visible && !show_mesh_cost);
|
||||
getChildView("prim_count")->setVisible( !land_visible && !show_mesh_cost);
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
#include "llworld.h"
|
||||
#include "v2math.h"
|
||||
#include "llvoavatar.h"
|
||||
#include "llmeshrepository.h"
|
||||
|
||||
|
||||
const F32 MAX_MANIP_SELECT_DISTANCE_SQUARED = 11.f * 11.f;
|
||||
|
|
@ -90,9 +91,7 @@ F32 get_default_max_prim_scale(bool is_flora)
|
|||
{
|
||||
// a bit of a hack, but if it's foilage, we don't want to use the
|
||||
// new larger scale which would result in giant trees and grass
|
||||
if (gSavedSettings.getBOOL("MeshEnabled") &&
|
||||
gAgent.getRegion() &&
|
||||
!gAgent.getRegion()->getCapability("GetMesh").empty() &&
|
||||
if (gMeshRepo.meshRezEnabled() &&
|
||||
!gAgent.getRegion()->getCapability("ObjectAdd").empty() &&
|
||||
!is_flora)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -61,6 +61,9 @@
|
|||
#include "pipeline.h"
|
||||
#include "llinventorymodel.h"
|
||||
#include "llfoldertype.h"
|
||||
#include "llviewerparcelmgr.h"
|
||||
|
||||
#include "boost/lexical_cast.hpp"
|
||||
|
||||
#ifndef LL_WINDOWS
|
||||
#include "netdb.h"
|
||||
|
|
@ -85,6 +88,12 @@ U32 LLMeshRepository::sPeakKbps = 0;
|
|||
|
||||
const U32 MAX_TEXTURE_UPLOAD_RETRIES = 5;
|
||||
|
||||
static S32 dump_num = 0;
|
||||
std::string make_dump_name(std::string prefix, S32 num)
|
||||
{
|
||||
return prefix + boost::lexical_cast<std::string>(num) + std::string(".xml");
|
||||
|
||||
}
|
||||
void dumpLLSDToFile(const LLSD& content, std::string filename);
|
||||
|
||||
std::string header_lod[] =
|
||||
|
|
@ -498,7 +507,8 @@ public:
|
|||
//assert_main_thread();
|
||||
llinfos << "completed" << llendl;
|
||||
mThread->mPendingUploads--;
|
||||
dumpLLSDToFile(content,"whole_model_fee_response.xml");
|
||||
dumpLLSDToFile(content,make_dump_name("whole_model_fee_response_",dump_num));
|
||||
llinfos << "LLWholeModelFeeResponder content: " << content << llendl;
|
||||
if (isGoodStatus(status))
|
||||
{
|
||||
mThread->mWholeModelUploadURL = content["uploader"].asString();
|
||||
|
|
@ -530,7 +540,7 @@ public:
|
|||
//assert_main_thread();
|
||||
llinfos << "upload completed" << llendl;
|
||||
mThread->mPendingUploads--;
|
||||
dumpLLSDToFile(content,"whole_model_upload_response.xml");
|
||||
dumpLLSDToFile(content,make_dump_name("whole_model_upload_response_",dump_num));
|
||||
// requested "mesh" asset type isn't actually the type
|
||||
// of the resultant object, fix it up here.
|
||||
mPostData["asset_type"] = "object";
|
||||
|
|
@ -829,8 +839,8 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
|
|||
|
||||
if (header_size > 0)
|
||||
{
|
||||
S32 offset = header_size + mMeshHeader[mesh_id]["decomposition"]["offset"].asInteger();
|
||||
S32 size = mMeshHeader[mesh_id]["decomposition"]["size"].asInteger();
|
||||
S32 offset = header_size + mMeshHeader[mesh_id]["physics_convex"]["offset"].asInteger();
|
||||
S32 size = mMeshHeader[mesh_id]["physics_convex"]["size"].asInteger();
|
||||
|
||||
mHeaderMutex->unlock();
|
||||
|
||||
|
|
@ -901,8 +911,8 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
|
|||
|
||||
if (header_size > 0)
|
||||
{
|
||||
S32 offset = header_size + mMeshHeader[mesh_id]["physics_shape"]["offset"].asInteger();
|
||||
S32 size = mMeshHeader[mesh_id]["physics_shape"]["size"].asInteger();
|
||||
S32 offset = header_size + mMeshHeader[mesh_id]["physics_mesh"]["offset"].asInteger();
|
||||
S32 size = mMeshHeader[mesh_id]["physics_mesh"]["size"].asInteger();
|
||||
|
||||
mHeaderMutex->unlock();
|
||||
|
||||
|
|
@ -1294,8 +1304,6 @@ LLMeshUploadThread::LLMeshUploadThread(LLMeshUploadThread::instance_list& data,
|
|||
mOrigin = gAgent.getPositionAgent();
|
||||
mHost = gAgent.getRegionHost();
|
||||
|
||||
mUploadObjectAssetCapability = gAgent.getRegion()->getCapability("UploadObjectAsset");
|
||||
mNewInventoryCapability = gAgent.getRegion()->getCapability("NewFileAgentInventoryVariablePrice");
|
||||
mWholeModelFeeCapability = gAgent.getRegion()->getCapability("NewFileAgentInventory");
|
||||
|
||||
mOrigin += gAgent.getAtAxis() * scale.magVec();
|
||||
|
|
@ -1385,14 +1393,7 @@ BOOL LLMeshUploadThread::isDiscarded()
|
|||
|
||||
void LLMeshUploadThread::run()
|
||||
{
|
||||
if (gSavedSettings.getBOOL("MeshUseWholeModelUpload"))
|
||||
{
|
||||
doWholeModelUpload();
|
||||
}
|
||||
else
|
||||
{
|
||||
doIterativeUpload();
|
||||
}
|
||||
doWholeModelUpload();
|
||||
}
|
||||
|
||||
void dumpLLSDToFile(const LLSD& content, std::string filename)
|
||||
|
|
@ -1431,9 +1432,13 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
|
|||
{
|
||||
LLMeshUploadData data;
|
||||
data.mBaseModel = iter->first;
|
||||
LLModelInstance& instance = *(iter->second.begin());
|
||||
LLModel* model = instance.mModel;
|
||||
if (mesh_index.find(model) == mesh_index.end())
|
||||
LLModelInstance& first_instance = *(iter->second.begin());
|
||||
for (S32 i = 0; i < 5; i++)
|
||||
{
|
||||
data.mModel[i] = first_instance.mLOD[i];
|
||||
}
|
||||
|
||||
if (mesh_index.find(data.mBaseModel) == mesh_index.end())
|
||||
{
|
||||
// Have not seen this model before - create a new mesh_list entry for it.
|
||||
std::string model_name = data.mBaseModel->getName();
|
||||
|
|
@ -1466,107 +1471,116 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures)
|
|||
std::string str = ostr.str();
|
||||
|
||||
res["mesh_list"][mesh_num] = LLSD::Binary(str.begin(),str.end());
|
||||
mesh_index[model] = mesh_num;
|
||||
mesh_index[data.mBaseModel] = mesh_num;
|
||||
mesh_num++;
|
||||
}
|
||||
|
||||
LLSD instance_entry;
|
||||
|
||||
for (S32 i = 0; i < 5; i++)
|
||||
{
|
||||
data.mModel[i] = instance.mLOD[i];
|
||||
}
|
||||
|
||||
LLVector3 pos, scale;
|
||||
LLQuaternion rot;
|
||||
LLMatrix4 transformation = instance.mTransform;
|
||||
decomposeMeshMatrix(transformation,pos,rot,scale);
|
||||
instance_entry["position"] = ll_sd_from_vector3(pos);
|
||||
instance_entry["rotation"] = ll_sd_from_quaternion(rot);
|
||||
instance_entry["scale"] = ll_sd_from_vector3(scale);
|
||||
|
||||
instance_entry["material"] = LL_MCODE_WOOD;
|
||||
LLPermissions perm;
|
||||
perm.setOwnerAndGroup(gAgent.getID(), gAgent.getID(), LLUUID::null, false);
|
||||
perm.setCreator(gAgent.getID());
|
||||
|
||||
perm.initMasks(PERM_ITEM_UNRESTRICTED | PERM_MOVE, //base
|
||||
PERM_ITEM_UNRESTRICTED | PERM_MOVE, //owner
|
||||
LLFloaterPerms::getEveryonePerms(),
|
||||
LLFloaterPerms::getGroupPerms(),
|
||||
LLFloaterPerms::getNextOwnerPerms());
|
||||
instance_entry["permissions"] = ll_create_sd_from_permissions(perm);
|
||||
instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
|
||||
instance_entry["mesh"] = mesh_index[model];
|
||||
|
||||
if (mUploadTextures)
|
||||
// For all instances that use this model
|
||||
for (instance_list::iterator instance_iter = iter->second.begin();
|
||||
instance_iter != iter->second.end();
|
||||
++instance_iter)
|
||||
{
|
||||
|
||||
LLModelInstance& instance = *instance_iter;
|
||||
|
||||
LLSD instance_entry;
|
||||
|
||||
for (S32 i = 0; i < 5; i++)
|
||||
{
|
||||
data.mModel[i] = instance.mLOD[i];
|
||||
}
|
||||
|
||||
LLVector3 pos, scale;
|
||||
LLQuaternion rot;
|
||||
LLMatrix4 transformation = instance.mTransform;
|
||||
decomposeMeshMatrix(transformation,pos,rot,scale);
|
||||
instance_entry["position"] = ll_sd_from_vector3(pos);
|
||||
instance_entry["rotation"] = ll_sd_from_quaternion(rot);
|
||||
instance_entry["scale"] = ll_sd_from_vector3(scale);
|
||||
|
||||
instance_entry["material"] = LL_MCODE_WOOD;
|
||||
LLPermissions perm;
|
||||
perm.setOwnerAndGroup(gAgent.getID(), gAgent.getID(), LLUUID::null, false);
|
||||
perm.setCreator(gAgent.getID());
|
||||
|
||||
perm.initMasks(PERM_ITEM_UNRESTRICTED | PERM_MOVE, //base
|
||||
PERM_ITEM_UNRESTRICTED | PERM_MOVE, //owner
|
||||
LLFloaterPerms::getEveryonePerms(),
|
||||
LLFloaterPerms::getGroupPerms(),
|
||||
LLFloaterPerms::getNextOwnerPerms());
|
||||
instance_entry["permissions"] = ll_create_sd_from_permissions(perm);
|
||||
instance_entry["physics_shape_type"] = (U8)(LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL);
|
||||
instance_entry["mesh"] = mesh_index[data.mBaseModel];
|
||||
|
||||
instance_entry["face_list"] = LLSD::emptyArray();
|
||||
|
||||
for (S32 face_num = 0; face_num < model->getNumVolumeFaces(); face_num++)
|
||||
for (S32 face_num = 0; face_num < data.mBaseModel->getNumVolumeFaces(); face_num++)
|
||||
{
|
||||
LLImportMaterial& material = instance.mMaterial[face_num];
|
||||
LLSD face_entry = LLSD::emptyMap();
|
||||
LLViewerFetchedTexture *texture = material.mDiffuseMap.get();
|
||||
|
||||
if (texture != NULL)
|
||||
if ((texture != NULL) &&
|
||||
(textures.find(texture) == textures.end()))
|
||||
{
|
||||
if (textures.find(texture) == textures.end())
|
||||
{
|
||||
textures.insert(texture);
|
||||
}
|
||||
textures.insert(texture);
|
||||
}
|
||||
|
||||
std::stringstream ostr;
|
||||
if (include_textures) // otherwise data is blank.
|
||||
std::stringstream texture_str;
|
||||
if (texture != NULL && include_textures && mUploadTextures)
|
||||
{
|
||||
// Get binary rep of texture, if needed.
|
||||
LLTextureUploadData data(texture, material.mDiffuseMapLabel);
|
||||
if (!data.mTexture->isRawImageValid())
|
||||
{
|
||||
LLTextureUploadData data(texture, material.mDiffuseMapLabel);
|
||||
if (!data.mTexture->isRawImageValid())
|
||||
{
|
||||
data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel());
|
||||
}
|
||||
data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel());
|
||||
}
|
||||
|
||||
LLPointer<LLImageJ2C> upload_file =
|
||||
LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage());
|
||||
ostr.write((const char*) upload_file->getData(), upload_file->getDataSize());
|
||||
}
|
||||
LLPointer<LLImageJ2C> upload_file =
|
||||
LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage());
|
||||
texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize());
|
||||
}
|
||||
|
||||
if (texture_index.find(texture) == texture_index.end())
|
||||
{
|
||||
texture_index[texture] = texture_num;
|
||||
std::string str = ostr.str();
|
||||
res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end());
|
||||
texture_num++;
|
||||
}
|
||||
if (texture != NULL &&
|
||||
mUploadTextures &&
|
||||
texture_index.find(texture) == texture_index.end())
|
||||
{
|
||||
texture_index[texture] = texture_num;
|
||||
std::string str = texture_str.str();
|
||||
res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end());
|
||||
texture_num++;
|
||||
}
|
||||
|
||||
// Subset of TextureEntry fields.
|
||||
if (texture)
|
||||
if (texture != NULL && mUploadTextures)
|
||||
{
|
||||
face_entry["image"] = texture_index[texture];
|
||||
face_entry["scales"] = 1.0;
|
||||
face_entry["scalet"] = 1.0;
|
||||
face_entry["offsets"] = 0.0;
|
||||
face_entry["offsett"] = 0.0;
|
||||
face_entry["imagerot"] = 0.0;
|
||||
}
|
||||
face_entry["scales"] = 1.0;
|
||||
face_entry["scalet"] = 1.0;
|
||||
face_entry["offsets"] = 0.0;
|
||||
face_entry["offsett"] = 0.0;
|
||||
face_entry["imagerot"] = 0.0;
|
||||
face_entry["colors"] = ll_sd_from_color4(material.mDiffuseColor);
|
||||
face_entry["fullbright"] = material.mFullbright;
|
||||
instance_entry["face_list"][face_num] = face_entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res["instance_list"][instance_num] = instance_entry;
|
||||
instance_num++;
|
||||
res["instance_list"][instance_num] = instance_entry;
|
||||
instance_num++;
|
||||
}
|
||||
}
|
||||
|
||||
result["asset_resources"] = res;
|
||||
dumpLLSDToFile(result,"whole_model.xml");
|
||||
dumpLLSDToFile(result,make_dump_name("whole_model_",dump_num));
|
||||
|
||||
dest = result;
|
||||
}
|
||||
|
||||
void LLMeshUploadThread::doWholeModelUpload()
|
||||
{
|
||||
dump_num++;
|
||||
|
||||
mCurlRequest = new LLCurlRequest();
|
||||
|
||||
// Queue up models for hull generation (viewer-side)
|
||||
|
|
@ -1611,7 +1625,7 @@ void LLMeshUploadThread::doWholeModelUpload()
|
|||
|
||||
LLSD model_data;
|
||||
wholeModelToLLSD(model_data,false);
|
||||
dumpLLSDToFile(model_data,"whole_model_fee_request.xml");
|
||||
dumpLLSDToFile(model_data,make_dump_name("whole_model_fee_request_",dump_num));
|
||||
|
||||
mPendingUploads++;
|
||||
LLCurlRequest::headers_t headers;
|
||||
|
|
@ -1633,7 +1647,7 @@ void LLMeshUploadThread::doWholeModelUpload()
|
|||
LLSD full_model_data;
|
||||
wholeModelToLLSD(full_model_data, true);
|
||||
LLSD body = full_model_data["asset_resources"];
|
||||
dumpLLSDToFile(body,"whole_model_body.xml");
|
||||
dumpLLSDToFile(body,make_dump_name("whole_model_body_",dump_num));
|
||||
mCurlRequest->post(mWholeModelUploadURL, headers, body,
|
||||
new LLWholeModelUploadResponder(this, model_data));
|
||||
do
|
||||
|
|
@ -1649,163 +1663,6 @@ void LLMeshUploadThread::doWholeModelUpload()
|
|||
mFinished = true;
|
||||
}
|
||||
|
||||
void LLMeshUploadThread::doIterativeUpload()
|
||||
{
|
||||
if(isDiscarded())
|
||||
{
|
||||
mFinished = true;
|
||||
return ;
|
||||
}
|
||||
|
||||
mCurlRequest = new LLCurlRequest();
|
||||
|
||||
std::set<LLViewerTexture* > textures;
|
||||
|
||||
//populate upload queue with relevant models
|
||||
for (instance_map::iterator iter = mInstance.begin(); iter != mInstance.end(); ++iter)
|
||||
{
|
||||
LLMeshUploadData data;
|
||||
data.mBaseModel = iter->first;
|
||||
|
||||
LLModelInstance& instance = *(iter->second.begin());
|
||||
|
||||
for (S32 i = 0; i < 5; i++)
|
||||
{
|
||||
data.mModel[i] = instance.mLOD[i];
|
||||
}
|
||||
|
||||
uploadModel(data);
|
||||
|
||||
if (mUploadTextures)
|
||||
{
|
||||
for (std::vector<LLImportMaterial>::iterator material_iter = instance.mMaterial.begin();
|
||||
material_iter != instance.mMaterial.end(); ++material_iter)
|
||||
{
|
||||
|
||||
if (textures.find(material_iter->mDiffuseMap.get()) == textures.end())
|
||||
{
|
||||
textures.insert(material_iter->mDiffuseMap.get());
|
||||
|
||||
LLTextureUploadData data(material_iter->mDiffuseMap.get(), material_iter->mDiffuseMapLabel);
|
||||
uploadTexture(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//queue up models for hull generation
|
||||
LLModel* physics = data.mModel[LLModel::LOD_PHYSICS];
|
||||
if (physics == NULL)
|
||||
{ //no physics model available, use high lod
|
||||
physics = data.mModel[LLModel::LOD_HIGH];
|
||||
}
|
||||
|
||||
DecompRequest* request = new DecompRequest(physics, data.mBaseModel, this);
|
||||
gMeshRepo.mDecompThread->submitRequest(request);
|
||||
}
|
||||
|
||||
while (!mPhysicsComplete)
|
||||
{
|
||||
apr_sleep(100);
|
||||
}
|
||||
|
||||
//upload textures
|
||||
bool done = false;
|
||||
do
|
||||
{
|
||||
if (!mTextureQ.empty())
|
||||
{
|
||||
sendCostRequest(mTextureQ.front());
|
||||
mTextureQ.pop();
|
||||
}
|
||||
|
||||
if (!mConfirmedTextureQ.empty())
|
||||
{
|
||||
doUploadTexture(mConfirmedTextureQ.front());
|
||||
mConfirmedTextureQ.pop();
|
||||
}
|
||||
|
||||
mCurlRequest->process();
|
||||
|
||||
done = mTextureQ.empty() && mConfirmedTextureQ.empty();
|
||||
}
|
||||
while (!done || mCurlRequest->getQueued() > 0);
|
||||
|
||||
LLSD object_asset;
|
||||
object_asset["objects"] = LLSD::emptyArray();
|
||||
|
||||
done = false;
|
||||
do
|
||||
{
|
||||
static S32 count = 0;
|
||||
static F32 last_hundred = gFrameTimeSeconds;
|
||||
if (gFrameTimeSeconds - last_hundred > 1.f)
|
||||
{
|
||||
last_hundred = gFrameTimeSeconds;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
//how many requests to push before calling process
|
||||
const S32 PUSH_PER_PROCESS = 32;
|
||||
|
||||
S32 tcount = llmin(count+PUSH_PER_PROCESS, 100);
|
||||
|
||||
while (!mUploadQ.empty() && count < tcount)
|
||||
{ //send any pending upload requests
|
||||
mMutex->lock();
|
||||
LLMeshUploadData data = mUploadQ.front();
|
||||
mUploadQ.pop();
|
||||
mMutex->unlock();
|
||||
sendCostRequest(data);
|
||||
count++;
|
||||
}
|
||||
|
||||
tcount = llmin(count+PUSH_PER_PROCESS, 100);
|
||||
|
||||
while (!mConfirmedQ.empty() && count < tcount)
|
||||
{ //process any meshes that have been confirmed for upload
|
||||
LLMeshUploadData& data = mConfirmedQ.front();
|
||||
doUploadModel(data);
|
||||
mConfirmedQ.pop();
|
||||
count++;
|
||||
}
|
||||
|
||||
tcount = llmin(count+PUSH_PER_PROCESS, 100);
|
||||
|
||||
while (!mInstanceQ.empty() && count < tcount && !isDiscarded())
|
||||
{ //create any objects waiting for upload
|
||||
count++;
|
||||
object_asset["objects"].append(createObject(mInstanceQ.front()));
|
||||
mInstanceQ.pop();
|
||||
}
|
||||
|
||||
mCurlRequest->process();
|
||||
|
||||
done = isDiscarded() || (mInstanceQ.empty() && mConfirmedQ.empty() && mUploadQ.empty());
|
||||
}
|
||||
while (!done || mCurlRequest->getQueued() > 0);
|
||||
|
||||
delete mCurlRequest;
|
||||
mCurlRequest = NULL;
|
||||
|
||||
// now upload the object asset
|
||||
std::string url = mUploadObjectAssetCapability;
|
||||
|
||||
if (object_asset["objects"][0].has("permissions"))
|
||||
{ //copy permissions from first available object to be used for coalesced object
|
||||
object_asset["permissions"] = object_asset["objects"][0]["permissions"];
|
||||
}
|
||||
|
||||
if(!isDiscarded())
|
||||
{
|
||||
mPendingUploads++;
|
||||
LLHTTPClient::post(url, object_asset, new LLModelObjectUploadResponder(this,object_asset));
|
||||
}
|
||||
else
|
||||
{
|
||||
mFinished = true;
|
||||
}
|
||||
}
|
||||
|
||||
void LLMeshUploadThread::uploadModel(LLMeshUploadData& data)
|
||||
{ //called from arbitrary thread
|
||||
{
|
||||
|
|
@ -2234,7 +2091,7 @@ void LLMeshHeaderResponder::completedRaw(U32 status, const std::string& reason,
|
|||
|
||||
//just in case skin info or decomposition is at the end of the file (which it shouldn't be)
|
||||
lod_bytes = llmax(lod_bytes, header["skin"]["offset"].asInteger() + header["skin"]["size"].asInteger());
|
||||
lod_bytes = llmax(lod_bytes, header["decomposition"]["offset"].asInteger() + header["decomposition"]["size"].asInteger());
|
||||
lod_bytes = llmax(lod_bytes, header["physics_convex"]["offset"].asInteger() + header["physics_convex"]["size"].asInteger());
|
||||
|
||||
S32 header_bytes = (S32) gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
|
||||
S32 bytes = lod_bytes + header_bytes;
|
||||
|
|
@ -2522,7 +2379,6 @@ void LLMeshRepository::notifyLoadedMeshes()
|
|||
if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived())
|
||||
{
|
||||
region_name = gAgent.getRegion()->getName();
|
||||
|
||||
mGetMeshCapability = gAgent.getRegion()->getCapability("GetMesh");
|
||||
}
|
||||
}
|
||||
|
|
@ -2860,7 +2716,7 @@ void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail)
|
|||
bool LLMeshRepository::hasPhysicsShape(const LLUUID& mesh_id)
|
||||
{
|
||||
LLSD mesh = mThread->getMeshHeader(mesh_id);
|
||||
return mesh.has("physics_shape") && mesh["physics_shape"].has("size") && (mesh["physics_shape"]["size"].asInteger() > 0);
|
||||
return mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0);
|
||||
}
|
||||
|
||||
LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id)
|
||||
|
|
@ -2916,102 +2772,6 @@ S32 LLMeshRepository::getMeshSize(const LLUUID& mesh_id, S32 lod)
|
|||
|
||||
}
|
||||
|
||||
void LLMeshUploadThread::sendCostRequest(LLMeshUploadData& data)
|
||||
{
|
||||
if(isDiscarded())
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
//write model file to memory buffer
|
||||
std::stringstream ostr;
|
||||
|
||||
LLModel::Decomposition& decomp =
|
||||
data.mModel[LLModel::LOD_PHYSICS].notNull() ?
|
||||
data.mModel[LLModel::LOD_PHYSICS]->mPhysics :
|
||||
data.mBaseModel->mPhysics;
|
||||
|
||||
LLSD header = LLModel::writeModel(
|
||||
ostr,
|
||||
data.mModel[LLModel::LOD_PHYSICS],
|
||||
data.mModel[LLModel::LOD_HIGH],
|
||||
data.mModel[LLModel::LOD_MEDIUM],
|
||||
data.mModel[LLModel::LOD_LOW],
|
||||
data.mModel[LLModel::LOD_IMPOSTOR],
|
||||
decomp,
|
||||
mUploadSkin,
|
||||
mUploadJoints,
|
||||
true);
|
||||
|
||||
std::string desc = data.mBaseModel->mLabel;
|
||||
|
||||
// Grab the total vertex count of the model
|
||||
// along with other information for the "asset_resources" map
|
||||
// to send to the server.
|
||||
LLSD asset_resources = LLSD::emptyMap();
|
||||
|
||||
|
||||
std::string url = mNewInventoryCapability;
|
||||
|
||||
if (!url.empty())
|
||||
{
|
||||
LLSD body = generate_new_resource_upload_capability_body(
|
||||
LLAssetType::AT_MESH,
|
||||
desc,
|
||||
desc,
|
||||
LLFolderType::FT_MESH,
|
||||
LLInventoryType::IT_MESH,
|
||||
LLFloaterPerms::getNextOwnerPerms(),
|
||||
LLFloaterPerms::getGroupPerms(),
|
||||
LLFloaterPerms::getEveryonePerms());
|
||||
|
||||
body["asset_resources"] = asset_resources;
|
||||
|
||||
mPendingConfirmations++;
|
||||
LLCurlRequest::headers_t headers;
|
||||
|
||||
data.mPostData = body;
|
||||
|
||||
mCurlRequest->post(url, headers, body, new LLMeshCostResponder(data, this));
|
||||
}
|
||||
}
|
||||
|
||||
void LLMeshUploadThread::sendCostRequest(LLTextureUploadData& data)
|
||||
{
|
||||
if(isDiscarded())
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
if (data.mTexture && data.mTexture->getDiscardLevel() >= 0)
|
||||
{
|
||||
LLSD asset_resources = LLSD::emptyMap();
|
||||
|
||||
std::string url = mNewInventoryCapability;
|
||||
|
||||
if (!url.empty())
|
||||
{
|
||||
LLSD body = generate_new_resource_upload_capability_body(
|
||||
LLAssetType::AT_TEXTURE,
|
||||
data.mLabel,
|
||||
data.mLabel,
|
||||
LLFolderType::FT_TEXTURE,
|
||||
LLInventoryType::IT_TEXTURE,
|
||||
LLFloaterPerms::getNextOwnerPerms(),
|
||||
LLFloaterPerms::getGroupPerms(),
|
||||
LLFloaterPerms::getEveryonePerms());
|
||||
|
||||
body["asset_resources"] = asset_resources;
|
||||
|
||||
mPendingConfirmations++;
|
||||
LLCurlRequest::headers_t headers;
|
||||
|
||||
data.mPostData = body;
|
||||
mCurlRequest->post(url, headers, body, new LLTextureCostResponder(data, this));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void LLMeshUploadThread::doUploadModel(LLMeshUploadData& data)
|
||||
{
|
||||
|
|
@ -3314,8 +3074,8 @@ bool LLImportMaterial::operator<(const LLImportMaterial &rhs) const
|
|||
void LLMeshRepository::updateInventory(inventory_data data)
|
||||
{
|
||||
LLMutexLock lock(mMeshMutex);
|
||||
dumpLLSDToFile(data.mPostData,"update_inventory_post_data.xml");
|
||||
dumpLLSDToFile(data.mResponse,"update_inventory_response.xml");
|
||||
dumpLLSDToFile(data.mPostData,make_dump_name("update_inventory_post_data_",dump_num));
|
||||
dumpLLSDToFile(data.mResponse,make_dump_name("update_inventory_response_",dump_num));
|
||||
mInventoryQ.push(data);
|
||||
}
|
||||
|
||||
|
|
@ -3955,3 +3715,27 @@ void LLMeshRepository::buildPhysicsMesh(LLModel::Decomposition& decomp)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool LLMeshRepository::meshUploadEnabled()
|
||||
{
|
||||
LLViewerRegion *region = gAgent.getRegion();
|
||||
if(gSavedSettings.getBOOL("MeshEnabled") &&
|
||||
LLViewerParcelMgr::getInstance()->allowAgentBuild() &&
|
||||
region)
|
||||
{
|
||||
return region->meshUploadEnabled();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LLMeshRepository::meshRezEnabled()
|
||||
{
|
||||
LLViewerRegion *region = gAgent.getRegion();
|
||||
if(gSavedSettings.getBOOL("MeshEnabled") &&
|
||||
region)
|
||||
{
|
||||
return region->meshRezEnabled();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -393,8 +393,6 @@ public:
|
|||
BOOL mDiscarded ;
|
||||
|
||||
LLHost mHost;
|
||||
std::string mUploadObjectAssetCapability;
|
||||
std::string mNewInventoryCapability;
|
||||
std::string mWholeModelFeeCapability;
|
||||
std::string mWholeModelUploadURL;
|
||||
|
||||
|
|
@ -413,12 +411,10 @@ public:
|
|||
|
||||
void uploadTexture(LLTextureUploadData& data);
|
||||
void doUploadTexture(LLTextureUploadData& data);
|
||||
void sendCostRequest(LLTextureUploadData& data);
|
||||
void priceResult(LLTextureUploadData& data, const LLSD& content);
|
||||
void onTextureUploaded(LLTextureUploadData& data);
|
||||
|
||||
void uploadModel(LLMeshUploadData& data);
|
||||
void sendCostRequest(LLMeshUploadData& data);
|
||||
void doUploadModel(LLMeshUploadData& data);
|
||||
void onModelUploaded(LLMeshUploadData& data);
|
||||
void createObjects(LLMeshUploadData& data);
|
||||
|
|
@ -432,7 +428,6 @@ public:
|
|||
BOOL isDiscarded();
|
||||
|
||||
void doWholeModelUpload();
|
||||
void doIterativeUpload();
|
||||
|
||||
void wholeModelToLLSD(LLSD& dest, bool include_textures);
|
||||
|
||||
|
|
@ -482,6 +477,10 @@ public:
|
|||
|
||||
void buildHull(const LLVolumeParams& params, S32 detail);
|
||||
void buildPhysicsMesh(LLModel::Decomposition& decomp);
|
||||
|
||||
bool meshUploadEnabled();
|
||||
bool meshRezEnabled();
|
||||
|
||||
|
||||
LLSD& getMeshHeader(const LLUUID& mesh_id);
|
||||
|
||||
|
|
|
|||
|
|
@ -530,17 +530,24 @@ void LLPanelVolume::refresh()
|
|||
getChildView("Light Ambiance")->setVisible( visible);
|
||||
getChildView("light texture control")->setVisible( visible);
|
||||
|
||||
bool enable_mesh = gSavedSettings.getBOOL("MeshEnabled") &&
|
||||
gAgent.getRegion() &&
|
||||
!gAgent.getRegion()->getCapability("GetMesh").empty() &&
|
||||
!gAgent.getRegion()->getCapability("ObjectAdd").empty();
|
||||
bool enable_mesh = false;
|
||||
|
||||
LLSD sim_features;
|
||||
LLViewerRegion *region = gAgent.getRegion();
|
||||
if(region)
|
||||
{
|
||||
LLSD sim_features;
|
||||
region->getSimulatorFeatures(sim_features);
|
||||
enable_mesh = sim_features.has("PhysicsShapeTypes");
|
||||
}
|
||||
getChildView("label physicsshapetype")->setVisible(enable_mesh);
|
||||
getChildView("Physics Shape Type Combo Ctrl")->setVisible(enable_mesh);
|
||||
getChildView("Physics Gravity")->setVisible(enable_mesh);
|
||||
getChildView("Physics Friction")->setVisible(enable_mesh);
|
||||
getChildView("Physics Density")->setVisible(enable_mesh);
|
||||
getChildView("Physics Restitution")->setVisible(enable_mesh);
|
||||
|
||||
/* TODO: add/remove individual physics shape types as per the PhysicsShapeTypes simulator features */
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -107,9 +107,7 @@ class LLMeshUploadVisible : public view_listener_t
|
|||
{
|
||||
bool handleEvent(const LLSD& userdata)
|
||||
{
|
||||
return gSavedSettings.getBOOL("MeshEnabled") &&
|
||||
LLViewerParcelMgr::getInstance()->allowAgentBuild() &&
|
||||
!gAgent.getRegion()->getCapability("ObjectAdd").empty();
|
||||
return gMeshRepo.meshUploadEnabled();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -1203,78 +1201,6 @@ void upload_new_resource(
|
|||
}
|
||||
}
|
||||
|
||||
BOOL upload_new_variable_price_resource(
|
||||
const LLTransactionID &tid,
|
||||
LLAssetType::EType asset_type,
|
||||
std::string name,
|
||||
std::string desc,
|
||||
LLFolderType::EType destination_folder_type,
|
||||
LLInventoryType::EType inv_type,
|
||||
U32 next_owner_perms,
|
||||
U32 group_perms,
|
||||
U32 everyone_perms,
|
||||
const std::string& display_name,
|
||||
const LLSD& asset_resources)
|
||||
{
|
||||
LLAssetID uuid =
|
||||
upload_new_resource_prep(
|
||||
tid,
|
||||
asset_type,
|
||||
inv_type,
|
||||
name,
|
||||
display_name,
|
||||
desc);
|
||||
|
||||
llinfos << "*** Uploading: " << llendl;
|
||||
llinfos << "Type: " << LLAssetType::lookup(asset_type) << llendl;
|
||||
llinfos << "UUID: " << uuid << llendl;
|
||||
llinfos << "Name: " << name << llendl;
|
||||
llinfos << "Desc: " << desc << llendl;
|
||||
lldebugs << "Folder: "
|
||||
<< gInventory.findCategoryUUIDForType((destination_folder_type == LLFolderType::FT_NONE) ? (LLFolderType::EType)asset_type : destination_folder_type) << llendl;
|
||||
lldebugs << "Asset Type: " << LLAssetType::lookup(asset_type) << llendl;
|
||||
|
||||
std::string url = gAgent.getRegion()->getCapability(
|
||||
"NewFileAgentInventoryVariablePrice");
|
||||
|
||||
if ( !url.empty() )
|
||||
{
|
||||
lldebugs
|
||||
<< "New Agent Inventory variable price upload" << llendl;
|
||||
|
||||
// Each of the two capabilities has similar data, so
|
||||
// let's reuse that code
|
||||
|
||||
LLSD body;
|
||||
|
||||
body = generate_new_resource_upload_capability_body(
|
||||
asset_type,
|
||||
name,
|
||||
desc,
|
||||
destination_folder_type,
|
||||
inv_type,
|
||||
next_owner_perms,
|
||||
group_perms,
|
||||
everyone_perms);
|
||||
|
||||
body["asset_resources"] = asset_resources;
|
||||
|
||||
LLHTTPClient::post(
|
||||
url,
|
||||
body,
|
||||
new LLNewAgentInventoryVariablePriceResponder(
|
||||
uuid,
|
||||
asset_type,
|
||||
body));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid)
|
||||
{
|
||||
if ( gDisconnected )
|
||||
|
|
|
|||
|
|
@ -68,23 +68,6 @@ void upload_new_resource(
|
|||
S32 expected_upload_cost,
|
||||
void *userdata);
|
||||
|
||||
// TODO* : Move all uploads to use this new function
|
||||
// since at some point, that upload path will be deprecated and no longer
|
||||
// used
|
||||
|
||||
// We make a new function here to ensure that previous code is not broken
|
||||
BOOL upload_new_variable_price_resource(
|
||||
const LLTransactionID& tid,
|
||||
LLAssetType::EType type,
|
||||
std::string name,
|
||||
std::string desc,
|
||||
LLFolderType::EType destination_folder_type,
|
||||
LLInventoryType::EType inv_type,
|
||||
U32 next_owner_perms,
|
||||
U32 group_perms,
|
||||
U32 everyone_perms,
|
||||
const std::string& display_name,
|
||||
const LLSD& asset_resources);
|
||||
|
||||
LLAssetID generate_asset_id_for_new_upload(const LLTransactionID& tid);
|
||||
void increase_new_upload_stats(LLAssetType::EType asset_type);
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@
|
|||
#include "llspatialpartition.h"
|
||||
#include "stringize.h"
|
||||
#include "llviewercontrol.h"
|
||||
#include "llsdserialize.h"
|
||||
|
||||
#ifdef LL_WINDOWS
|
||||
#pragma warning(disable:4355)
|
||||
|
|
@ -1140,6 +1141,20 @@ void LLViewerRegion::getInfo(LLSD& info)
|
|||
info["Region"]["Handle"]["y"] = (LLSD::Integer)y;
|
||||
}
|
||||
|
||||
void LLViewerRegion::getSimulatorFeatures(LLSD& sim_features)
|
||||
{
|
||||
sim_features = mSimulatorFeatures;
|
||||
}
|
||||
|
||||
void LLViewerRegion::setSimulatorFeatures(const LLSD& sim_features)
|
||||
{
|
||||
std::stringstream str;
|
||||
|
||||
LLSDSerialize::toPrettyXML(sim_features, str);
|
||||
llinfos << str.str() << llendl;
|
||||
mSimulatorFeatures = sim_features;
|
||||
}
|
||||
|
||||
LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObject* objectp, LLDataPackerBinaryBuffer &dp)
|
||||
{
|
||||
U32 local_id = objectp->getLocalID();
|
||||
|
|
@ -1510,9 +1525,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
|
|||
capabilityNames.append("LandResources");
|
||||
capabilityNames.append("MapLayer");
|
||||
capabilityNames.append("MapLayerGod");
|
||||
capabilityNames.append("NewAccountingEnabled");
|
||||
capabilityNames.append("NewFileAgentInventory");
|
||||
capabilityNames.append("NewFileAgentInventoryVariablePrice");
|
||||
capabilityNames.append("ObjectAdd");
|
||||
capabilityNames.append("ParcelPropertiesUpdate");
|
||||
capabilityNames.append("ParcelMediaURLFilterList");
|
||||
|
|
@ -1544,7 +1557,6 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
|
|||
capabilityNames.append("UpdateNotecardTaskInventory");
|
||||
capabilityNames.append("UpdateScriptTask");
|
||||
capabilityNames.append("UploadBakedTexture");
|
||||
capabilityNames.append("UploadObjectAsset");
|
||||
capabilityNames.append("ViewerMetrics");
|
||||
capabilityNames.append("ViewerStartAuction");
|
||||
capabilityNames.append("ViewerStats");
|
||||
|
|
@ -1562,6 +1574,42 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
|
|||
LLHTTPClient::post(url, capabilityNames, mImpl->mHttpResponderPtr);
|
||||
}
|
||||
|
||||
class SimulatorFeaturesReceived : public LLHTTPClient::Responder
|
||||
{
|
||||
LOG_CLASS(SimulatorFeaturesReceived);
|
||||
public:
|
||||
SimulatorFeaturesReceived(LLViewerRegion* region)
|
||||
: mRegion(region)
|
||||
{ }
|
||||
|
||||
|
||||
void error(U32 statusNum, const std::string& reason)
|
||||
{
|
||||
LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL;
|
||||
}
|
||||
|
||||
void result(const LLSD& content)
|
||||
{
|
||||
if(!mRegion) //region is removed or responder is not created.
|
||||
{
|
||||
return ;
|
||||
}
|
||||
|
||||
mRegion->setSimulatorFeatures(content);
|
||||
}
|
||||
|
||||
static boost::intrusive_ptr<SimulatorFeaturesReceived> build(
|
||||
LLViewerRegion* region)
|
||||
{
|
||||
return boost::intrusive_ptr<SimulatorFeaturesReceived>(
|
||||
new SimulatorFeaturesReceived(region));
|
||||
}
|
||||
|
||||
private:
|
||||
LLViewerRegion* mRegion;
|
||||
};
|
||||
|
||||
|
||||
void LLViewerRegion::setCapability(const std::string& name, const std::string& url)
|
||||
{
|
||||
if(name == "EventQueueGet")
|
||||
|
|
@ -1574,6 +1622,11 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u
|
|||
{
|
||||
LLHTTPSender::setSender(mImpl->mHost, new LLCapHTTPSender(url));
|
||||
}
|
||||
else if (name == "SimulatorFeatures")
|
||||
{
|
||||
// kick off a request for simulator features
|
||||
LLHTTPClient::get(url, new SimulatorFeaturesReceived(this));
|
||||
}
|
||||
else
|
||||
{
|
||||
mImpl->mCapabilities[name] = url;
|
||||
|
|
@ -1667,3 +1720,16 @@ std::string LLViewerRegion::getDescription() const
|
|||
return stringize(*this);
|
||||
}
|
||||
|
||||
bool LLViewerRegion::meshUploadEnabled() const
|
||||
{
|
||||
return (mSimulatorFeatures.has("MeshUploadEnabled") &&
|
||||
mSimulatorFeatures["MeshUploadEnabled"].asBoolean());
|
||||
}
|
||||
|
||||
bool LLViewerRegion::meshRezEnabled() const
|
||||
{
|
||||
return (mSimulatorFeatures.has("MeshRezEnabled") &&
|
||||
mSimulatorFeatures["MeshRezEnabled"].asBoolean());
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -276,6 +276,11 @@ public:
|
|||
|
||||
void getInfo(LLSD& info);
|
||||
|
||||
bool meshRezEnabled() const;
|
||||
bool meshUploadEnabled() const;
|
||||
|
||||
void getSimulatorFeatures(LLSD& info);
|
||||
void setSimulatorFeatures(const LLSD& info);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
@ -401,6 +406,8 @@ private:
|
|||
bool mCapabilitiesReceived;
|
||||
|
||||
BOOL mReleaseNotesRequested;
|
||||
|
||||
LLSD mSimulatorFeatures;
|
||||
};
|
||||
|
||||
inline BOOL LLViewerRegion::getAllowDamage() const
|
||||
|
|
|
|||
|
|
@ -601,7 +601,7 @@ public:
|
|||
|
||||
ypos += y_inc;
|
||||
|
||||
if (gSavedSettings.getBOOL("MeshEnabled"))
|
||||
if (gMeshRepo.meshRezEnabled())
|
||||
{
|
||||
addText(xpos, ypos, llformat("%.3f MB Mesh Data Received", LLMeshRepository::sBytesReceived/(1024.f*1024.f)));
|
||||
|
||||
|
|
|
|||
|
|
@ -3983,7 +3983,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
|
|||
|
||||
LLVOVolume* vobj = drawablep->getVOVolume();
|
||||
|
||||
if (vobj->getVolume() && vobj->getVolume()->isTetrahedron())
|
||||
if (vobj->getVolume() && vobj->getVolume()->isTetrahedron() || (vobj->isMesh() && !gMeshRepo.meshRezEnabled()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue