summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/llprimitive/llmodel.cpp76
-rw-r--r--indra/newview/llfloatermodelpreview.cpp160
-rwxr-xr-xindra/newview/llmeshrepository.cpp181
3 files changed, 304 insertions, 113 deletions
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 3439cf3310..5acf93cfc4 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -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)
@@ -1449,7 +1453,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 +1496,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 +1588,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 +1617,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 +1630,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 +1769,7 @@ bool LLModel::loadModel(std::istream& is)
"low_lod",
"medium_lod",
"high_lod",
- "physics_shape",
+ "physics_mesh",
};
const S32 MODEL_LODS = 5;
@@ -1871,8 +1868,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 +2009,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 +2019,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 +2047,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 +2062,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 +2119,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 +2170,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 +2187,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 +2220,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 +2236,8 @@ LLSD LLModel::Decomposition::asLLSD() const
{
for (U32 k = 0; k < 3; k++)
{
+ llassert(mBaseHull[j].mV[k] <= 0.50001f && mBaseHull[j].mV[k] >= -0.50001f);
+
//convert to 16-bit normalized across domain
U16 val = (U16) (((mBaseHull[j].mV[k]-min.mV[k])/range.mV[k])*65535);
@@ -2239,7 +2253,7 @@ LLSD LLModel::Decomposition::asLLSD() const
}
}
- ret["Hull"] = p;
+ ret["BoundingVerts"] = p;
}
return ret;
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 8be5c427fe..f21d60dd03 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -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;
}
@@ -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);
}
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 12e0b26fed..d8024b362e 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -62,6 +62,8 @@
#include "llinventorymodel.h"
#include "llfoldertype.h"
+#include "boost/lexical_cast.hpp"
+
#ifndef LL_WINDOWS
#include "netdb.h"
#endif
@@ -85,6 +87,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 +506,7 @@ 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));
if (isGoodStatus(status))
{
mThread->mWholeModelUploadURL = content["uploader"].asString();
@@ -530,7 +538,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 +837,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 +909,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();
@@ -1385,14 +1393,14 @@ BOOL LLMeshUploadThread::isDiscarded()
void LLMeshUploadThread::run()
{
- if (gSavedSettings.getBOOL("MeshUseWholeModelUpload"))
+ //if (gSavedSettings.getBOOL("MeshUseWholeModelUpload"))
{
doWholeModelUpload();
}
- else
+ /*else
{
doIterativeUpload();
- }
+ }*/
}
void dumpLLSDToFile(const LLSD& content, std::string filename)
@@ -1431,9 +1439,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 +1478,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++;
}
+
+ // 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;
+ LLSD instance_entry;
- for (S32 i = 0; i < 5; i++)
- {
- data.mModel[i] = instance.mLOD[i];
- }
+ 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);
+ 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());
+ 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];
+ 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];
- if (mUploadTextures)
- {
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());
- }
-
- LLPointer<LLImageJ2C> upload_file =
- LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage());
- ostr.write((const char*) upload_file->getData(), upload_file->getDataSize());
+ data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel());
}
+
+ 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 +1632,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 +1654,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
@@ -2234,7 +2255,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;
@@ -2860,7 +2881,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)
@@ -3314,8 +3335,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);
}