summaryrefslogtreecommitdiff
path: root/indra/newview/llfloatermodelpreview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llfloatermodelpreview.cpp')
-rw-r--r--indra/newview/llfloatermodelpreview.cpp511
1 files changed, 427 insertions, 84 deletions
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index 9dd5269a6b..ab6753b4be 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;
}
@@ -314,15 +413,17 @@ BOOL LLFloaterModelPreview::postBuild()
childSetCommitCallback("pelvis_offset", onPelvisOffsetCommit, this);
childSetCommitCallback("lod_file_or_limit", refresh, this);
- childSetCommitCallback("physics_load_radio", refresh, this);
+ childSetCommitCallback("physics_load_radio", onPhysicsLoadRadioCommit, this);
//childSetCommitCallback("physics_optimize", refresh, this);
//childSetCommitCallback("physics_use_hull", refresh, this);
childDisable("upload_skin");
childDisable("upload_joints");
-
+
childDisable("ok_btn");
+ childSetCommitCallback("confirm_checkbox", refresh, this);
+
mViewOptionMenuButton = getChild<LLMenuButton>("options_gear_btn");
mCommitCallbackRegistrar.add("ModelImport.ViewOption.Action", boost::bind(&LLFloaterModelPreview::onViewOptionChecked, this, _2));
@@ -470,6 +571,29 @@ void LLFloaterModelPreview::onPelvisOffsetCommit( LLUICtrl*, void* userdata )
}
//static
+void LLFloaterModelPreview::onPhysicsLoadRadioCommit( LLUICtrl*, void *userdata)
+{
+ LLFloaterModelPreview* fmp = LLFloaterModelPreview::sInstance;
+ if (fmp)
+ {
+ if (fmp->childGetValue("physics_use_lod").asBoolean())
+ {
+ onPhysicsUseLOD(NULL,NULL);
+ }
+ if (fmp->childGetValue("physics_load_from_file").asBoolean())
+ {
+
+ }
+ LLModelPreview *model_preview = fmp->mModelPreview;
+ if (model_preview)
+ {
+ model_preview->refresh();
+ model_preview->updateStatusMessages();
+ }
+ }
+}
+
+//static
void LLFloaterModelPreview::onUploadJointsCommit(LLUICtrl*,void* userdata)
{
LLFloaterModelPreview *fp =(LLFloaterModelPreview *)userdata;
@@ -573,6 +697,11 @@ void LLFloaterModelPreview::draw()
childSetTextArg("status", "[STATUS]", getString(LLModel::getStatusString(mModelPreview->getLoadState() - LLModelLoader::ERROR_PARSING)));
}
else
+ if ( mModelPreview->getLoadState() == LLModelLoader::ERROR_PARSING )
+ {
+ childSetTextArg("status", "[STATUS]", getString("status_parse_error"));
+ }
+ else
{
childSetTextArg("status", "[STATUS]", getString("status_idle"));
}
@@ -992,7 +1121,7 @@ LLModelLoader::LLModelLoader( std::string filename, S32 lod, LLModelPreview* pre
std::deque<std::string>& jointsFromNodes )
: mJointList( jointMap )
, mJointsFromNode( jointsFromNodes )
-, LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mFirstTransform(TRUE)
+, LLThread("Model Loader"), mFilename(filename), mLod(lod), mPreview(preview), mFirstTransform(TRUE), mNumOfFetchingTextures(0)
{
mJointMap["mPelvis"] = "mPelvis";
mJointMap["mTorso"] = "mTorso";
@@ -1157,11 +1286,7 @@ void stretch_extents(LLModel* model, LLMatrix4& mat, LLVector3& min, LLVector3&
void LLModelLoader::run()
{
- if (!doLoadModel())
- {
- mPreview = NULL;
- }
-
+ doLoadModel();
doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this));
}
@@ -1225,6 +1350,23 @@ bool LLModelLoader::doLoadModel()
return false;
}
+ //Verify some basic properties of the dae
+ //1. Basic validity check on controller
+ U32 controllerCount = (int) db->getElementCount( NULL, "controller" );
+ bool result = false;
+ for ( int i=0; i<controllerCount; ++i )
+ {
+ domController* pController = NULL;
+ db->getElement( (daeElement**) &pController, i , NULL, "controller" );
+ result = mPreview->verifyController( pController );
+ if (!result)
+ {
+ setLoadState( ERROR_PARSING );
+ return true;
+ }
+ }
+
+
//get unit scale
mTransform.setIdentity();
@@ -1275,7 +1417,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))
@@ -1634,7 +1776,7 @@ bool LLModelLoader::doLoadModel()
{
if (pos.getCount() <= j+2)
{
- llerrs << "WTF?" << llendl;
+ llerrs << "Invalid position array size." << llendl;
}
LLVector3 v(pos[j], pos[j+1], pos[j+2]);
@@ -1759,11 +1901,19 @@ bool LLModelLoader::doLoadModel()
{
llwarns << "document has no visual_scene" << llendl;
setLoadState( ERROR_PARSING );
- return false;
+ return true;
}
+
setLoadState( DONE );
- processElement(scene);
+ bool badElement = false;
+
+ processElement( scene, badElement );
+
+ if ( badElement )
+ {
+ setLoadState( ERROR_PARSING );
+ }
return true;
}
@@ -2124,7 +2274,8 @@ void LLModelLoader::loadTextures()
iter->second[i].mMaterial[j].mDiffuseMap =
LLViewerTextureManager::getFetchedTextureFromUrl("file://" + iter->second[i].mMaterial[j].mDiffuseMapFilename, TRUE, LLViewerTexture::BOOST_PREVIEW);
iter->second[i].mMaterial[j].mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE);
- iter->second[i].mMaterial[j].mDiffuseMap->forceToSaveRawImage();
+ iter->second[i].mMaterial[j].mDiffuseMap->forceToSaveRawImage(0, F32_MAX);
+ mNumOfFetchingTextures++ ;
}
}
}
@@ -2153,6 +2304,90 @@ bool LLModelLoader::isNodeAJoint( domNode* pNode )
return false;
}
+//-----------------------------------------------------------------------------
+// verifyCount
+//-----------------------------------------------------------------------------
+bool LLModelPreview::verifyCount( int expected, int result )
+{
+ if ( expected != result )
+ {
+ llinfos<< "Error: (expected/got)"<<expected<<"/"<<result<<"verts"<<llendl;
+ return false;
+ }
+ return true;
+}
+//-----------------------------------------------------------------------------
+// verifyController
+//-----------------------------------------------------------------------------
+bool LLModelPreview::verifyController( domController* pController )
+{
+
+ bool result = true;
+
+ domSkin* pSkin = pController->getSkin();
+
+ if ( pSkin )
+ {
+ xsAnyURI & uri = pSkin->getSource();
+ domElement* pElement = uri.getElement();
+
+ if ( !pElement )
+ {
+ llinfos<<"Can't resolve skin source"<<llendl;
+ return false;
+ }
+
+ daeString type_str = pElement->getTypeName();
+ if ( stricmp(type_str, "geometry") == 0 )
+ {
+ //Skin is reference directly by geometry and get the vertex count from skin
+ domSkin::domVertex_weights* pVertexWeights = pSkin->getVertex_weights();
+ U32 vertexWeightsCount = pVertexWeights->getCount();
+ domGeometry* pGeometry = (domGeometry*) (domElement*) uri.getElement();
+ domMesh* pMesh = pGeometry->getMesh();
+
+ if ( pMesh )
+ {
+ //Get vertex count from geometry
+ domVertices* pVertices = pMesh->getVertices();
+ if ( !pVertices )
+ {
+ llinfos<<"No vertices!"<<llendl;
+ return false;
+ }
+
+ if ( pVertices )
+ {
+ xsAnyURI src = pVertices->getInput_array()[0]->getSource();
+ domSource* pSource = (domSource*) (domElement*) src.getElement();
+ U32 verticesCount = pSource->getTechnique_common()->getAccessor()->getCount();
+ result = verifyCount( verticesCount, vertexWeightsCount );
+ if ( !result )
+ {
+ return result;
+ }
+ }
+ }
+
+ U32 vcountCount = (U32) pVertexWeights->getVcount()->getValue().getCount();
+ result = verifyCount( vcountCount, vertexWeightsCount );
+ if ( !result )
+ {
+ return result;
+ }
+
+ domInputLocalOffset_Array& inputs = pVertexWeights->getInput_array();
+ U32 sum = 0;
+ for (size_t i=0; i<vcountCount; i++)
+ {
+ sum += pVertexWeights->getVcount()->getValue()[i];
+ }
+ result = verifyCount( sum * inputs.getCount(), (domInt) pVertexWeights->getV()->getValue().getCount() );
+ }
+ }
+
+ return result;
+}
//-----------------------------------------------------------------------------
// extractTranslation()
@@ -2263,7 +2498,7 @@ daeElement* LLModelLoader::getChildFromElement( daeElement* pElement, std::strin
return NULL;
}
-void LLModelLoader::processElement(daeElement* element)
+void LLModelLoader::processElement( daeElement* element, bool& badElement )
{
LLMatrix4 saved_transform = mTransform;
@@ -2296,8 +2531,11 @@ void LLModelLoader::processElement(daeElement* element)
{
domFloat3 dom_value = scale->getValue();
+
+ LLVector3 scale_vector = LLVector3(dom_value[0], dom_value[1], dom_value[2]);
+ scale_vector.abs(); // Set all values positive, since we don't currently support mirrored meshes
LLMatrix4 scaling;
- scaling.initScale(LLVector3(dom_value[0], dom_value[1], dom_value[2]));
+ scaling.initScale(scale_vector);
scaling *= mTransform;
mTransform = scaling;
@@ -2360,6 +2598,12 @@ void LLModelLoader::processElement(daeElement* element)
}
}
}
+ else
+ {
+ llinfos<<"Unable to resolve geometry URL."<<llendl;
+ badElement = true;
+ }
+
}
domInstance_node* instance_node = daeSafeCast<domInstance_node>(element);
@@ -2368,7 +2612,7 @@ void LLModelLoader::processElement(daeElement* element)
daeElement* instance = instance_node->getUrl().getElement();
if (instance)
{
- processElement(instance);
+ processElement(instance,badElement);
}
}
@@ -2376,7 +2620,7 @@ void LLModelLoader::processElement(daeElement* element)
daeTArray< daeSmartRef<daeElement> > children = element->getChildren();
for (S32 i = 0; i < children.getCount(); i++)
{
- processElement(children[i]);
+ processElement(children[i],badElement);
}
domNode* node = daeSafeCast<domNode>(element);
@@ -2660,7 +2904,7 @@ LLModelPreview::~LLModelPreview()
{
if (mModelLoader)
{
- delete mModelLoader;
+ mModelLoader->mPreview = NULL;
mModelLoader = NULL;
}
//*HACK : *TODO : turn this back on when we understand why this crashes
@@ -2675,7 +2919,8 @@ U32 LLModelPreview::calcResourceCost()
if (mFMP && mModelLoader)
{
- if ( getLoadState() < LLModelLoader::ERROR_PARSING )
+ const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean();
+ if ( getLoadState() < LLModelLoader::ERROR_PARSING && confirmed_checkbox )
{
mFMP->childEnable("ok_btn");
}
@@ -2817,7 +3062,8 @@ void LLModelPreview::rebuildUploadData()
F32 max_scale = 0.f;
- if ( mBaseScene.size() > 0 )
+ const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean();
+ if ( mBaseScene.size() > 0 && confirmed_checkbox )
{
mFMP->childEnable("ok_btn");
}
@@ -3221,6 +3467,8 @@ void LLModelPreview::loadModelCallback(S32 lod)
}
mLoading = false;
+ if (mFMP)
+ mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->set(FALSE);
refresh();
mModelLoadedSignal();
@@ -3234,7 +3482,7 @@ void LLModelPreview::resetPreviewTarget()
mPreviewScale = (mModelLoader->mExtents[1] - mModelLoader->mExtents[0]) * 0.5f;
}
- setPreviewTarget(mPreviewScale.magVec()*2.f);
+ setPreviewTarget(mPreviewScale.magVec()*10.f);
}
void LLModelPreview::generateNormals()
@@ -3752,7 +4000,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 +4129,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 +4155,16 @@ void LLModelPreview::updateStatusMessages()
}
}
- if ( upload_ok && !errorStateFromLoader && skinAndRigOk )
+ if(upload_ok && mModelLoader)
+ {
+ if(!mModelLoader->areTexturesReady() && mFMP->childGetValue("upload_textures").asBoolean())
+ {
+ upload_ok = false ;
+ }
+ }
+
+ const BOOL confirmed_checkbox = mFMP->getChild<LLCheckBoxCtrl>("confirm_checkbox")->getValue().asBoolean();
+ if ( upload_ok && !errorStateFromLoader && skinAndRigOk && !has_degenerate && confirmed_checkbox)
{
mFMP->childEnable("ok_btn");
}
@@ -4238,11 +4526,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights)
const LLModel::weight_list& weight_list = base_mdl->getJointInfluences(pos);
LLVector4 w(0,0,0,0);
- if (weight_list.size() > 4)
- {
- llerrs << "WTF?" << llendl;
- }
-
+
for (U32 i = 0; i < weight_list.size(); ++i)
{
F32 wght = llmin(weight_list[i].mWeight, 0.999999f);
@@ -4455,7 +4739,7 @@ BOOL LLModelPreview::render()
LLVector3 target_pos = mPreviewTarget+offset;
F32 z_near = 0.001f;
- F32 z_far = mCameraDistance+mPreviewScale.magVec()+mCameraOffset.magVec();
+ F32 z_far = mCameraDistance*10.0f+mPreviewScale.magVec()+mCameraOffset.magVec();
if (skin_weight)
{
@@ -4605,39 +4889,43 @@ BOOL LLModelPreview::render()
LLModel::Decomposition& physics = model->mPhysics;
- if (physics.mMesh.empty())
- { //build vertex buffer for physics mesh
- gMeshRepo.buildPhysicsMesh(physics);
- }
-
- if (!physics.mMesh.empty())
- { //render hull instead of mesh
+ if (!physics.mHull.empty())
+ {
render_mesh = false;
- for (U32 i = 0; i < physics.mMesh.size(); ++i)
- {
- if (explode > 0.f)
+
+ if (physics.mMesh.empty())
+ { //build vertex buffer for physics mesh
+ gMeshRepo.buildPhysicsMesh(physics);
+ }
+
+ if (!physics.mMesh.empty())
+ { //render hull instead of mesh
+ for (U32 i = 0; i < physics.mMesh.size(); ++i)
{
- gGL.pushMatrix();
+ if (explode > 0.f)
+ {
+ gGL.pushMatrix();
- LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters;
- offset *= explode;
+ LLVector3 offset = model->mHullCenter[i]-model->mCenterOfHullCenters;
+ offset *= explode;
- gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
- }
+ gGL.translatef(offset.mV[0], offset.mV[1], offset.mV[2]);
+ }
- static std::vector<LLColor4U> hull_colors;
+ static std::vector<LLColor4U> hull_colors;
- if (i+1 >= hull_colors.size())
- {
- hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 255));
- }
+ if (i+1 >= hull_colors.size())
+ {
+ hull_colors.push_back(LLColor4U(rand()%128+127, rand()%128+127, rand()%128+127, 255));
+ }
- glColor4ubv(hull_colors[i].mV);
- LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
+ glColor4ubv(hull_colors[i].mV);
+ LLVertexBuffer::drawArrays(LLRender::TRIANGLES, physics.mMesh[i].mPositions, physics.mMesh[i].mNormals);
- if (explode > 0.f)
- {
- gGL.popMatrix();
+ if (explode > 0.f)
+ {
+ gGL.popMatrix();
+ }
}
}
}
@@ -4663,9 +4951,10 @@ BOOL LLModelPreview::render()
glColor3f(1.f, 1.f, 0.f);
- glLineWidth(3.f);
+ glLineWidth(2.f);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0);
+
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glLineWidth(1.f);
}
@@ -4674,6 +4963,80 @@ BOOL LLModelPreview::render()
gGL.popMatrix();
}
+ glLineWidth(3.f);
+ glPointSize(8.f);
+ gPipeline.enableLightsFullbright(LLColor4::white);
+ //show degenerate triangles
+ LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS);
+ LLGLDisable cull(GL_CULL_FACE);
+ glColor4f(1.f,0.f,0.f,1.f);
+ const LLVector4a scale(0.5f);
+
+ for (LLMeshUploadThread::instance_list::iterator iter = mUploadData.begin(); iter != mUploadData.end(); ++iter)
+ {
+ LLModelInstance& instance = *iter;
+
+ LLModel* model = instance.mLOD[LLModel::LOD_PHYSICS];
+
+ if (!model)
+ {
+ continue;
+ }
+
+ gGL.pushMatrix();
+ LLMatrix4 mat = instance.mTransform;
+
+ glMultMatrixf((GLfloat*) mat.mMatrix);
+
+
+ LLPhysicsDecomp* decomp = gMeshRepo.mDecompThread;
+ if (decomp)
+ {
+ LLMutexLock(decomp->mMutex);
+
+ LLModel::Decomposition& physics = model->mPhysics;
+
+ if (physics.mHull.empty())
+ {
+ if (mVertexBuffer[LLModel::LOD_PHYSICS].empty())
+ {
+ genBuffers(LLModel::LOD_PHYSICS, false);
+ }
+
+ for (U32 i = 0; i < mVertexBuffer[LLModel::LOD_PHYSICS][model].size(); ++i)
+ {
+ LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][i];
+
+ buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0);
+
+ LLStrider<LLVector3> pos_strider;
+ buffer->getVertexStrider(pos_strider, 0);
+ LLVector4a* pos = (LLVector4a*) pos_strider.get();
+
+ LLStrider<U16> idx;
+ buffer->getIndexStrider(idx, 0);
+
+ 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::LINE_LOOP, 3, i);
+ buffer->draw(LLRender::POINTS, 3, i);
+ }
+ }
+ }
+ }
+ }
+
+ gGL.popMatrix();
+ }
+ glLineWidth(1.f);
+ glPointSize(1.f);
+ gPipeline.enableLightsPreview();
gGL.setSceneBlendType(LLRender::BT_ALPHA);
}
}
@@ -4938,6 +5301,14 @@ void LLModelPreview::textureLoadedCallback( BOOL success, LLViewerFetchedTexture
{
LLModelPreview* preview = (LLModelPreview*) userdata;
preview->refresh();
+
+ if(final && preview->mModelLoader)
+ {
+ if(preview->mModelLoader->mNumOfFetchingTextures > 0)
+ {
+ preview->mModelLoader->mNumOfFetchingTextures-- ;
+ }
+ }
}
void LLModelPreview::onLODParamCommit(bool enforce_tri_limit)
@@ -4959,35 +5330,7 @@ LLFloaterModelPreview::DecompRequest::DecompRequest(const std::string& stage, LL
mParams = sInstance->mDecompParams;
//copy out positions and indices
- if (mdl)
- {
- U16 index_offset = 0;
-
- mPositions.clear();
- mIndices.clear();
-
- //queue up vertex positions and indices
- for (S32 i = 0; i < mdl->getNumVolumeFaces(); ++i)
- {
- const LLVolumeFace& face = mdl->getVolumeFace(i);
- if (mPositions.size() + face.mNumVertices > 65535)
- {
- continue;
- }
-
- for (U32 j = 0; j < face.mNumVertices; ++j)
- {
- mPositions.push_back(LLVector3(face.mPositions[j].getF32ptr()));
- }
-
- for (U32 j = 0; j < face.mNumIndices; ++j)
- {
- mIndices.push_back(face.mIndices[j]+index_offset);
- }
-
- index_offset += face.mNumVertices;
- }
- }
+ assignData(mdl) ;
}
void LLFloaterModelPreview::setStatusMessage(const std::string& msg)