From 9cb31845bafe9188d9f90dc1330355c73fb96851 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 4 May 2011 20:45:14 -0500 Subject: SH-1497 Update mesh asset parser to use new format restrictions. --- indra/newview/llmeshrepository.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index dd2ffdf7f1..013fc43f99 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -772,8 +772,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(); @@ -844,8 +844,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(); @@ -1927,7 +1927,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; @@ -2543,7 +2543,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) -- cgit v1.2.3 From d79468057c954a05acdb9dd69d398dd004425ec0 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 25 May 2011 16:08:21 -0400 Subject: SH-1492 WIP --- indra/newview/llmeshrepository.cpp | 155 +++++++++++++++++++------------------ 1 file changed, 81 insertions(+), 74 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index b79f120eda..79541e49d3 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1437,9 +1437,7 @@ 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()) + 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(); @@ -1472,97 +1470,106 @@ 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]; - - if (mUploadTextures) - { - instance_entry["face_list"] = LLSD::emptyArray(); - - for (S32 face_num = 0; face_num < model->getNumVolumeFaces(); face_num++) + 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) { - LLImportMaterial& material = instance.mMaterial[face_num]; - LLSD face_entry = LLSD::emptyMap(); - LLViewerFetchedTexture *texture = material.mDiffuseMap.get(); - - if (texture != NULL) - { - if (textures.find(texture) == textures.end()) - { - textures.insert(texture); - } + instance_entry["face_list"] = LLSD::emptyArray(); - std::stringstream ostr; - if (include_textures) // otherwise data is blank. + 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) { - LLTextureUploadData data(texture, material.mDiffuseMapLabel); - if (!data.mTexture->isRawImageValid()) + if (textures.find(texture) == textures.end()) { - data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel()); + textures.insert(texture); } + + std::stringstream ostr; + if (include_textures) // otherwise data is blank. + { + LLTextureUploadData data(texture, material.mDiffuseMapLabel); + if (!data.mTexture->isRawImageValid()) + { + data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel()); + } - LLPointer upload_file = - LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage()); - ostr.write((const char*) upload_file->getData(), upload_file->getDataSize()); + LLPointer upload_file = + LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage()); + ostr.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_index.find(texture) == texture_index.end()) + // Subset of TextureEntry fields. + if (texture) { - texture_index[texture] = texture_num; - std::string str = ostr.str(); - res["texture_list"][texture_num] = LLSD::Binary(str.begin(),str.end()); - texture_num++; + 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["colors"] = ll_sd_from_color4(material.mDiffuseColor); + face_entry["fullbright"] = material.mFullbright; + instance_entry["face_list"][face_num] = face_entry; } + } - // Subset of TextureEntry fields. - if (texture) - { - 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["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; -- cgit v1.2.3 From 081ba71f9632153efa86df07b33c28471b31e2cb Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Wed, 25 May 2011 18:36:01 -0400 Subject: SH-1492 WIP --- indra/newview/llmeshrepository.cpp | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 79541e49d3..d4be311be8 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(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"; @@ -1437,6 +1445,12 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) { LLMeshUploadData data; data.mBaseModel = iter->first; + 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. @@ -1573,13 +1587,15 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) } 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) @@ -1627,7 +1643,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; @@ -1649,7 +1665,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 @@ -3317,8 +3333,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); } -- cgit v1.2.3 From 8b552a25c4fb1e9babdd52c5a5acee3540f353ac Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 26 May 2011 13:56:12 -0400 Subject: SH-1492 WIP - include face info even if textures not being uploaded --- indra/newview/llmeshrepository.cpp | 88 ++++++++++++++++++-------------------- 1 file changed, 42 insertions(+), 46 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index d4be311be8..7c75599a15 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1525,60 +1525,56 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) 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 < data.mBaseModel->getNumVolumeFaces(); face_num++) { - instance_entry["face_list"] = LLSD::emptyArray(); + LLImportMaterial& material = instance.mMaterial[face_num]; + LLSD face_entry = LLSD::emptyMap(); + LLViewerFetchedTexture *texture = material.mDiffuseMap.get(); + + if ((texture != NULL) && + (textures.find(texture) == textures.end())) + { + textures.insert(texture); + } - for (S32 face_num = 0; face_num < data.mBaseModel->getNumVolumeFaces(); face_num++) + std::stringstream texture_str; + if (texture != NULL && include_textures && mUploadTextures) { - LLImportMaterial& material = instance.mMaterial[face_num]; - LLSD face_entry = LLSD::emptyMap(); - LLViewerFetchedTexture *texture = material.mDiffuseMap.get(); - - if (texture != NULL) + // Get binary rep of texture, if needed. + LLTextureUploadData data(texture, material.mDiffuseMapLabel); + if (!data.mTexture->isRawImageValid()) { - if (textures.find(texture) == textures.end()) - { - textures.insert(texture); - } - - std::stringstream ostr; - if (include_textures) // otherwise data is blank. - { - LLTextureUploadData data(texture, material.mDiffuseMapLabel); - if (!data.mTexture->isRawImageValid()) - { - data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel()); - } + data.mTexture->reloadRawImage(data.mTexture->getDiscardLevel()); + } - LLPointer upload_file = - LLViewerTextureList::convertToUploadFile(data.mTexture->getRawImage()); - ostr.write((const char*) upload_file->getData(), upload_file->getDataSize()); - } + LLPointer 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_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) - { - 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["colors"] = ll_sd_from_color4(material.mDiffuseColor); - face_entry["fullbright"] = material.mFullbright; - instance_entry["face_list"][face_num] = face_entry; + // Subset of TextureEntry fields. + if (texture) + { + 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["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; -- cgit v1.2.3 From 01c5e12853b60d6f9ddc4f32b1450548beb09736 Mon Sep 17 00:00:00 2001 From: "Brad Payne (Vir Linden)" Date: Thu, 26 May 2011 18:22:14 -0400 Subject: SH-1492 WIP --- indra/newview/llmeshrepository.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 7c75599a15..5074caccb6 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1554,7 +1554,9 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) texture_str.write((const char*) upload_file->getData(), upload_file->getDataSize()); } - if (texture_index.find(texture) == texture_index.end()) + if (texture != NULL && + mUploadTextures && + texture_index.find(texture) == texture_index.end()) { texture_index[texture] = texture_num; std::string str = texture_str.str(); @@ -1563,15 +1565,15 @@ void LLMeshUploadThread::wholeModelToLLSD(LLSD& dest, bool include_textures) } // 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; -- cgit v1.2.3 From b0a04b08f7b3cf4040b9708125a548e646b990f7 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 3 Jun 2011 00:13:50 -0500 Subject: SH-1744 Add havok's degenerate triangle check to importer. Highlight degenerate triangles in physics mesh and block upload when degenerate triangles are present. --- indra/newview/llfloatermodelpreview.cpp | 160 +++++++++++++++++++++++++++++++- indra/newview/llmeshrepository.cpp | 6 +- 2 files changed, 161 insertions(+), 5 deletions(-) (limited to 'indra/newview') diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 2a3bd37129..b715f326a0 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; } @@ -3752,7 +3851,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"); @@ -3853,7 +3980,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; + } } } @@ -3876,7 +4006,7 @@ void LLModelPreview::updateStatusMessages() } } - if ( upload_ok && !errorStateFromLoader && skinAndRigOk ) + if ( upload_ok && !errorStateFromLoader && skinAndRigOk && !has_degenerate) { mFMP->childEnable("ok_btn"); } @@ -4666,6 +4796,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 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 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 4464d299ed..4a8c644dbc 100755 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -1399,14 +1399,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) -- cgit v1.2.3