diff options
Diffstat (limited to 'indra')
25 files changed, 762 insertions, 489 deletions
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index f473a708cd..618b056768 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -6023,6 +6023,11 @@ void LLVolumeFace::cacheOptimize() LLVCacheLRU cache; + if (mNumVertices < 3) + { //nothing to do + return; + } + //mapping of vertices to triangles and indices std::vector<LLVCacheVertexData> vertex_data; diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index e3b68156ca..b3d5c7b072 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -149,9 +149,10 @@ void load_face_from_dom_inputs(LLVolumeFace& face, const domInputLocalOffset_Arr } } -void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride, +bool get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S32& tc_offset, S32& norm_offset, S32 &idx_stride, domSource* &pos_source, domSource* &tc_source, domSource* &norm_source) { + idx_stride = 0; for (U32 j = 0; j < inputs.getCount(); ++j) @@ -163,7 +164,11 @@ void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S const domURIFragmentType& uri = inputs[j]->getSource(); daeElementRef elem = uri.getElement(); domVertices* vertices = (domVertices*) elem.cast(); - + if ( !vertices ) + { + return false; + } + domInputLocal_Array& v_inp = vertices->getInput_array(); @@ -207,6 +212,8 @@ void get_dom_sources(const domInputLocalOffset_Array& inputs, S32& pos_offset, S } idx_stride += 1; + + return true; } LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& face_list, std::vector<std::string>& materials, domTrianglesRef& tri) @@ -227,8 +234,12 @@ LLModel::EModelStatus load_face_from_dom_triangles(std::vector<LLVolumeFace>& fa S32 idx_stride = 0; - get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source); + if ( !get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source) || !pos_source ) + { + return LLModel::BAD_ELEMENT; + } + domPRef p = tri->getP(); domListOfUInts& idx = p->getValue(); @@ -367,7 +378,10 @@ LLModel::EModelStatus load_face_from_dom_polylist(std::vector<LLVolumeFace>& fac S32 idx_stride = 0; - get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source); + if (!get_dom_sources(inputs, pos_offset, tc_offset, norm_offset, idx_stride, pos_source, tc_source, norm_source)) + { + return LLModel::BAD_ELEMENT; + } LLVolumeFace face; @@ -564,7 +578,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac const domURIFragmentType& uri = inputs[i]->getSource(); daeElementRef elem = uri.getElement(); domVertices* vertices = (domVertices*) elem.cast(); - + if (!vertices) + { + return LLModel::BAD_ELEMENT; + } domInputLocal_Array& v_inp = vertices->getInput_array(); for (U32 k = 0; k < v_inp.getCount(); ++k) @@ -574,6 +591,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac const domURIFragmentType& uri = v_inp[k]->getSource(); daeElementRef elem = uri.getElement(); domSource* src = (domSource*) elem.cast(); + if (!src) + { + return LLModel::BAD_ELEMENT; + } v = &(src->getFloat_array()->getValue()); } } @@ -585,6 +606,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac const domURIFragmentType& uri = inputs[i]->getSource(); daeElementRef elem = uri.getElement(); domSource* src = (domSource*) elem.cast(); + if (!src) + { + return LLModel::BAD_ELEMENT; + } n = &(src->getFloat_array()->getValue()); } else if (strcmp(COMMON_PROFILE_INPUT_TEXCOORD, inputs[i]->getSemantic()) == 0 && inputs[i]->getSet() == 0) @@ -593,6 +618,10 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac const domURIFragmentType& uri = inputs[i]->getSource(); daeElementRef elem = uri.getElement(); domSource* src = (domSource*) elem.cast(); + if (!src) + { + return LLModel::BAD_ELEMENT; + } t = &(src->getFloat_array()->getValue()); } } @@ -712,7 +741,7 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac //static std::string LLModel::getStatusString(U32 status) { - const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow"}; + const static std::string status_strings[(S32)INVALID_STATUS] = {"status_no_error", "status_vertex_number_overflow","bad_element"}; if(status < INVALID_STATUS) { @@ -750,7 +779,6 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh) for (U32 i = 0; i < polys.getCount(); ++i) { domPolylistRef& poly = polys.get(i); - mStatus = load_face_from_dom_polylist(mVolumeFaces, mMaterialList, poly); if(mStatus != NO_ERRORS) @@ -760,12 +788,12 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh) return ; //abort } } - + domPolygons_Array& polygons = mesh->getPolygons_array(); + for (U32 i = 0; i < polygons.getCount(); ++i) { domPolygonsRef& poly = polygons.get(i); - mStatus = load_face_from_dom_polygons(mVolumeFaces, mMaterialList, poly); if(mStatus != NO_ERRORS) @@ -775,7 +803,7 @@ void LLModel::addVolumeFacesFromDomMesh(domMesh* mesh) return ; //abort } } - + } BOOL LLModel::createVolumeFacesFromDomMesh(domMesh* mesh) diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index ebca1f9d9d..cd9f76fcb7 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -73,6 +73,7 @@ public: { NO_ERRORS = 0, VERTEX_NUMBER_OVERFLOW, //vertex number is >= 65535. + BAD_ELEMENT, INVALID_STATUS } ; diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp index 6b4e9cf923..15a7438ec9 100644 --- a/indra/llui/llspinctrl.cpp +++ b/indra/llui/llspinctrl.cpp @@ -52,6 +52,7 @@ LLSpinCtrl::Params::Params() : label_width("label_width"), decimal_digits("decimal_digits"), allow_text_entry("allow_text_entry", true), + label_wrap("label_wrap", false), text_enabled_color("text_enabled_color"), text_disabled_color("text_disabled_color"), up_button("up_button"), @@ -80,6 +81,7 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p) { LLRect label_rect( 0, centered_top, label_width, centered_bottom ); LLTextBox::Params params; + params.wrap(p.label_wrap); params.name("SpinCtrl Label"); params.rect(label_rect); params.initial_value(p.label()); diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h index 8960971594..d197084e38 100644 --- a/indra/llui/llspinctrl.h +++ b/indra/llui/llspinctrl.h @@ -44,6 +44,7 @@ public: Optional<S32> label_width; Optional<U32> decimal_digits; Optional<bool> allow_text_entry; + Optional<bool> label_wrap; Optional<LLUIColor> text_enabled_color; Optional<LLUIColor> text_disabled_color; diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 029f282d7c..5e6c5ebec8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -9,34 +9,6 @@ #extension GL_ARB_texture_rectangle : enable -varying float vary_texture_index; - -uniform sampler2D tex0; -uniform sampler2D tex1; -uniform sampler2D tex2; -uniform sampler2D tex3; -uniform sampler2D tex4; -uniform sampler2D tex5; -uniform sampler2D tex6; -uniform sampler2D tex7; - -vec4 textureLookup(vec2 texcoord) -{ - switch (int(vary_texture_index+0.25)) - { - case 0: return texture2D(tex0, texcoord); - case 1: return texture2D(tex1, texcoord); - case 2: return texture2D(tex2, texcoord); - case 3: return texture2D(tex3, texcoord); - case 4: return texture2D(tex4, texcoord); - case 5: return texture2D(tex5, texcoord); - case 6: return texture2D(tex6, texcoord); - case 7: return texture2D(tex7, texcoord); - } - - return vec4(0,0,0,0); -} - vec3 fullbrightAtmosTransport(vec3 light); vec3 fullbrightScaleSoftClip(vec3 light); @@ -45,12 +17,13 @@ void main() { float shadow = 1.0; - vec4 color = textureLookup(gl_TexCoord[0].xy)*gl_Color; + vec4 color = diffuseLookup(gl_TexCoord[0].xy)*gl_Color; color.rgb = fullbrightAtmosTransport(color.rgb); color.rgb = fullbrightScaleSoftClip(color.rgb); - gl_FragColor = color; + //gl_FragColor = color; + gl_FragColor = vec4(1,0,1,1); } diff --git a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl index 6dbcc479e1..d53850b489 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/sunLightSSAOF.glsl @@ -234,7 +234,7 @@ void main() gl_FragColor[0] = shadow; gl_FragColor[1] = calcAmbientOcclusion(pos, norm); - spos.xyz = shadow_pos+offset*spot_shadow_offset; + spos.xyz = shadow_pos+norm*spot_shadow_offset; //spotlight shadow 1 vec4 lpos = shadow_matrix[4]*spos; diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 25dd2ffe78..1d29c5b597 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 27 +version 28 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -64,6 +64,7 @@ RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 WatchdogDisabled 1 1 RenderUseStreamVBO 1 1 +RenderFSAASamples 1 16 // // Low Graphics Settings @@ -95,6 +96,7 @@ SkyUseClassicClouds 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // Mid Graphics Settings @@ -124,6 +126,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // High Graphics Settings (purty) @@ -153,6 +156,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 4 // // Ultra graphics (REALLY PURTY!) @@ -181,6 +185,7 @@ WLSkyDetail 1 128 RenderDeferred 1 1 RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 +RenderFSAASamples 1 8 // // Class Unknown Hardware (unknown) diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt index 058bdcc730..9daa5a5b29 100644 --- a/indra/newview/featuretable_linux.txt +++ b/indra/newview/featuretable_linux.txt @@ -1,4 +1,4 @@ -version 23 +version 24 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -62,6 +62,7 @@ RenderShaderLightingMaxLevel 1 3 RenderDeferred 1 1 RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 +RenderFSAASamples 1 16 // // Low Graphics Settings @@ -93,6 +94,7 @@ SkyUseClassicClouds 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // Mid Graphics Settings @@ -122,6 +124,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // High Graphics Settings (purty) @@ -151,6 +154,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 4 // // Ultra graphics (REALLY PURTY!) @@ -180,6 +184,7 @@ WLSkyDetail 1 128 RenderDeferred 1 1 RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 +RenderFSAASamples 1 8 // // Class Unknown Hardware (unknown) diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 8b8340bd71..d7b4128ca2 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 24 +version 25 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -64,6 +64,7 @@ RenderDeferredSSAO 1 1 RenderShadowDetail 1 2 WatchdogDisabled 1 1 RenderUseStreamVBO 1 1 +RenderFSAASamples 1 16 // // Low Graphics Settings @@ -95,6 +96,7 @@ SkyUseClassicClouds 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // Mid Graphics Settings @@ -124,6 +126,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // High Graphics Settings (purty) @@ -153,6 +156,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 2 +RenderFSAASamples 1 4 // // Ultra graphics (REALLY PURTY!) @@ -182,6 +186,7 @@ WLSkyDetail 1 128 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 2 +RenderFSAASamples 1 8 // // Class Unknown Hardware (unknown) diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt index 65a6f59bbe..0a23b4d6a6 100644 --- a/indra/newview/featuretable_xp.txt +++ b/indra/newview/featuretable_xp.txt @@ -1,4 +1,4 @@ -version 27 +version 28 // NOTE: This is mostly identical to featuretable_mac.txt with a few differences // Should be combined into one table @@ -64,6 +64,7 @@ RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 WatchdogDisabled 1 1 RenderUseStreamVBO 1 1 +RenderFSAASamples 1 16 // // Low Graphics Settings @@ -95,6 +96,7 @@ SkyUseClassicClouds 1 0 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // Mid Graphics Settings @@ -124,6 +126,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 0 +RenderFSAASamples 1 0 // // High Graphics Settings (purty) @@ -153,6 +156,7 @@ WLSkyDetail 1 48 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 2 +RenderFSAASamples 1 4 // // Ultra graphics (REALLY PURTY!) @@ -182,6 +186,7 @@ WLSkyDetail 1 128 RenderDeferred 1 0 RenderDeferredSSAO 1 0 RenderShadowDetail 1 2 +RenderFSAASamples 1 8 // // Class Unknown Hardware (unknown) diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 8985d3680e..813b3820ee 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -537,6 +537,12 @@ void LLDrawPoolBump::beginFullbrightShiny() gGL.getTexUnit(cube_channel)->bind(cube_map); gGL.getTexUnit(0)->activate(); } + + if (mVertexShaderLevel > 1) + { //indexed texture rendering, channel 0 is always diffuse + diffuse_channel = 0; + } + mShiny = TRUE; } diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index d56bc9cd10..76f3e7fdf4 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -697,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")); } @@ -1349,6 +1354,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(); @@ -2277,6 +2299,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() diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index ed7cbe6d1e..a328bfb4dd 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -1,433 +1,438 @@ -/** - * @file llfloatermodelpreview.h - * @brief LLFloaterModelPreview class definition - * - * $LicenseInfo:firstyear=2004&license=viewerlgpl$ - * Second Life Viewer Source Code - * Copyright (C) 2010, Linden Research, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; - * version 2.1 of the License only. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA - * $/LicenseInfo$ - */ - -#ifndef LL_LLFLOATERMODELPREVIEW_H -#define LL_LLFLOATERMODELPREVIEW_H - -#include "llfloaternamedesc.h" - -#include "lldynamictexture.h" -#include "llfloatermodelwizard.h" -#include "llquaternion.h" -#include "llmeshrepository.h" -#include "llmodel.h" -#include "llthread.h" -#include "llviewermenufile.h" - -class LLComboBox; -class LLJoint; -class LLViewerJointMesh; -class LLVOAvatar; -class LLTextBox; -class LLVertexBuffer; -class LLModelPreview; -class LLFloaterModelPreview; -class daeElement; -class domProfile_COMMON; -class domInstance_geometry; -class domNode; -class domTranslate; -class LLMenuButton; -class LLToggleableMenu; - -typedef std::map<std::string, LLMatrix4> JointTransformMap; -typedef std::map<std::string, LLMatrix4>:: iterator JointTransformMapIt; - -const S32 NUM_LOD = 4; - -class LLModelLoader : public LLThread -{ -public: - typedef enum - { - STARTING = 0, - READING_FILE, - CREATING_FACES, - GENERATING_VERTEX_BUFFERS, - GENERATING_LOD, - DONE, - ERROR_PARSING //basically loading failed - } eLoadState; - - U32 mState; - std::string mFilename; - S32 mLod; - LLModelPreview* mPreview; - LLMatrix4 mTransform; - BOOL mFirstTransform; - LLVector3 mExtents[2]; - bool mTrySLM; - - std::map<daeElement*, LLPointer<LLModel> > mModel; - - typedef std::vector<LLPointer<LLModel> > model_list; - model_list mModelList; - - typedef std::vector<LLModelInstance> model_instance_list; - - typedef std::map<LLMatrix4, model_instance_list > scene; - - scene mScene; - - typedef std::queue<LLPointer<LLModel> > model_queue; - - //queue of models that need a physics rep - model_queue mPhysicsQ; - - LLModelLoader( std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap, - std::deque<std::string>& jointsFromNodes ); - ~LLModelLoader() ; - - virtual void run(); - bool doLoadModel(); - bool loadFromSLM(const std::string& filename); - void loadModelCallback(); - - void loadTextures() ; //called in the main thread. - void processElement(daeElement* element); - std::vector<LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo); - LLImportMaterial profileToMaterial(domProfile_COMMON* material); - std::string getElementLabel(daeElement *element); - LLColor4 getDaeColor(daeElement* element); - - daeElement* getChildFromElement( daeElement* pElement, std::string const & name ); - - bool isNodeAJoint( domNode* pNode ); - void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms ); - void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform ); - void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform ); - - void setLoadState(U32 state); - - void buildJointToNodeMappingFromScene( daeElement* pRoot ); - void processJointToNodeMapping( domNode* pNode ); - - - //map of avatar joints as named in COLLADA assets to internal joint names - std::map<std::string, std::string> mJointMap; - JointTransformMap& mJointList; - std::deque<std::string>& mJointsFromNode; - -private: - static std::list<LLModelLoader*> sActiveLoaderList; - static bool isAlive(LLModelLoader* loader) ; -}; - -class LLFloaterModelPreview : public LLFloater -{ -public: - - class DecompRequest : public LLPhysicsDecomp::Request - { - public: - S32 mContinue; - LLPointer<LLModel> mModel; - - DecompRequest(const std::string& stage, LLModel* mdl); - virtual S32 statusCallback(const char* status, S32 p1, S32 p2); - virtual void completed(); - - }; - static LLFloaterModelPreview* sInstance; - - LLFloaterModelPreview(const LLSD& key); - virtual ~LLFloaterModelPreview(); - - virtual BOOL postBuild(); - - BOOL handleMouseDown(S32 x, S32 y, MASK mask); - BOOL handleMouseUp(S32 x, S32 y, MASK mask); - BOOL handleHover(S32 x, S32 y, MASK mask); - BOOL handleScrollWheel(S32 x, S32 y, S32 clicks); - - static void onMouseCaptureLostModelPreview(LLMouseHandler*); - static void setUploadAmount(S32 amount) { sUploadAmount = amount; } - - void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost); - - static void onBrowseLOD(void* data); - - static void onReset(void* data); - - static void onUpload(void* data); - - static void onClearMaterials(void* data); - - static void refresh(LLUICtrl* ctrl, void* data); - - void updateResourceCost(); - - void loadModel(S32 lod); - - void onViewOptionChecked(const LLSD& userdata); - bool isViewOptionChecked(const LLSD& userdata); - bool isViewOptionEnabled(const LLSD& userdata); - void setViewOptionEnabled(const std::string& option, bool enabled); - void enableViewOption(const std::string& option); - void disableViewOption(const std::string& option); - -protected: - friend class LLModelPreview; - friend class LLMeshFilePicker; - friend class LLPhysicsDecomp; - - static void onImportScaleCommit(LLUICtrl*, void*); - static void onPelvisOffsetCommit(LLUICtrl*, void*); - static void onUploadJointsCommit(LLUICtrl*,void*); - static void onUploadSkinCommit(LLUICtrl*,void*); - - static void onPhysicsLoadRadioCommit(LLUICtrl*,void *data); - - static void onPreviewLODCommit(LLUICtrl*,void*); - - static void onGenerateNormalsCommit(LLUICtrl*,void*); - - static void onAutoFillCommit(LLUICtrl*,void*); - static void onLODParamCommit(LLUICtrl*,void*); - static void onLODParamCommitTriangleLimit(LLUICtrl*,void*); - - static void onExplodeCommit(LLUICtrl*, void*); - - static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata); - static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata); - static void onCancel(LLUICtrl* ctrl, void* userdata); - static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata); - - static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata); - static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata); - static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata); - static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata); - static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata); - - void draw(); - - void initDecompControls(); - - void setStatusMessage(const std::string& msg); - - LLModelPreview* mModelPreview; - - LLPhysicsDecomp::decomp_params mDecompParams; - - S32 mLastMouseX; - S32 mLastMouseY; - LLRect mPreviewRect; - U32 mGLName; - static S32 sUploadAmount; - - std::set<LLPointer<DecompRequest> > mCurRequest; - std::string mStatusMessage; - - //use "disabled" as false by default - std::map<std::string, bool> mViewOptionDisabled; - - //store which lod mode each LOD is using - // 0 - load from file - // 1 - auto generate - // 2 - None - S32 mLODMode[4]; - - LLMenuButton* mViewOptionMenuButton; - LLToggleableMenu* mViewOptionMenu; - LLMutex* mStatusLock; - -}; - -class LLMeshFilePicker : public LLFilePickerThread -{ -public: - LLMeshFilePicker(LLModelPreview* mp, S32 lod); - virtual void notify(const std::string& filename); - -private: - LLModelPreview* mMP; - S32 mLOD; -}; - - -class LLModelPreview : public LLViewerDynamicTexture, public LLMutex -{ - typedef boost::signals2::signal<void (F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)> details_signal_t; - typedef boost::signals2::signal<void (void)> model_loaded_signal_t; - -public: - LLModelPreview(S32 width, S32 height, LLFloater* fmp); - virtual ~LLModelPreview(); - - void resetPreviewTarget(); - void setPreviewTarget(F32 distance); - void setTexture(U32 name) { mTextureName = name; } - - void setPhysicsFromLOD(S32 lod); - BOOL render(); - void update(); - void genBuffers(S32 lod, bool skinned); - void clearBuffers(); - void refresh(); - void rotate(F32 yaw_radians, F32 pitch_radians); - void zoom(F32 zoom_amt); - void pan(F32 right, F32 up); - virtual BOOL needsRender() { return mNeedsUpdate; } - void setPreviewLOD(S32 lod); - void clearModel(S32 lod); - void loadModel(std::string filename, S32 lod); - void loadModelCallback(S32 lod); - void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false); - void generateNormals(); - void clearMaterials(); - U32 calcResourceCost(); - void rebuildUploadData(); - void saveUploadData(bool save_skinweights, bool save_joint_poisitions); - void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions); - void clearIncompatible(S32 lod); - void updateStatusMessages(); - void clearGLODGroup(); - void onLODParamCommit(bool enforce_tri_limit); - - const bool getModelPivot( void ) const { return mHasPivot; } - void setHasPivot( bool val ) { mHasPivot = val; } - void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; } - - //Sets the current avatars joints to new positions - //Makes in world go to shit, however - void changeAvatarsJointPositions( LLModel* pModel ); - //Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps) - void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset ); - void critiqueJointToNodeMappingFromScene( void ); - //Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions - //Accessors for joint position upload friendly rigs - const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; } - void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; } - bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset ); - //Determines if a rig is a legacy from the joint list - bool isRigLegacy( const std::vector<std::string> &jointListFromAsset ); - //Accessors for the legacy rigs - const bool isLegacyRigValid( void ) const { return mLegacyRigValid; } - void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; } - - static void textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata ); - - boost::signals2::connection setDetailsCallback( const details_signal_t::slot_type& cb ){ return mDetailsSignal.connect(cb); } - boost::signals2::connection setModelLoadedCallback( const model_loaded_signal_t::slot_type& cb ){ return mModelLoadedSignal.connect(cb); } - - void setLoadState( U32 state ) { mLoadState = state; } - U32 getLoadState() { return mLoadState; } - //setRestJointFlag: If an asset comes through that changes the joints, we want the reset to persist - void setResetJointFlag( bool state ) { if ( !mResetJoints ) mResetJoints = state; } - const bool getResetJointFlag( void ) const { return mResetJoints; } - void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; } - const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; } - - LLVector3 getTranslationForJointOffset( std::string joint ); - - void createPreviewAvatar( void ); - LLVOAvatar* getPreviewAvatar( void ) { return mPreviewAvatar; } - - protected: - friend class LLModelLoader; - friend class LLFloaterModelPreview; - friend class LLFloaterModelWizard; - friend class LLFloaterModelPreview::DecompRequest; - friend class LLFloaterModelWizard::DecompRequest; - friend class LLPhysicsDecomp; - - LLFloater* mFMP; - - BOOL mNeedsUpdate; - bool mDirty; - bool mGenLOD; - U32 mTextureName; - F32 mCameraDistance; - F32 mCameraYaw; - F32 mCameraPitch; - F32 mCameraZoom; - LLVector3 mCameraOffset; - LLVector3 mPreviewTarget; - LLVector3 mPreviewScale; - S32 mPreviewLOD; - U32 mResourceCost; - std::string mLODFile[LLModel::NUM_LODS]; - bool mLoading; - U32 mLoadState; - bool mResetJoints; - bool mRigParityWithScene; - - std::map<std::string, bool> mViewOption; - - //GLOD object parameters (must rebuild object if these change) - bool mLODFrozen; - F32 mBuildShareTolerance; - U32 mBuildQueueMode; - U32 mBuildOperator; - U32 mBuildBorderMode; - U32 mRequestedLoDMode[LLModel::NUM_LODS]; - S32 mRequestedTriangleCount[LLModel::NUM_LODS]; - F32 mRequestedErrorThreshold[LLModel::NUM_LODS]; - U32 mRequestedBuildOperator[LLModel::NUM_LODS]; - U32 mRequestedQueueMode[LLModel::NUM_LODS]; - U32 mRequestedBorderMode[LLModel::NUM_LODS]; - F32 mRequestedShareTolerance[LLModel::NUM_LODS]; - F32 mRequestedCreaseAngle[LLModel::NUM_LODS]; - - LLModelLoader* mModelLoader; - - LLModelLoader::scene mScene[LLModel::NUM_LODS]; - LLModelLoader::scene mBaseScene; - - LLModelLoader::model_list mModel[LLModel::NUM_LODS]; - LLModelLoader::model_list mBaseModel; - - U32 mGroup; - std::map<LLPointer<LLModel>, U32> mObject; - U32 mMaxTriangleLimit; - - LLMeshUploadThread::instance_list mUploadData; - std::set<LLViewerFetchedTexture* > mTextureSet; - - //map of vertex buffers to models (one vertex buffer in vector per face in model - std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1]; - - details_signal_t mDetailsSignal; - model_loaded_signal_t mModelLoadedSignal; - - LLVector3 mModelPivot; - bool mHasPivot; - - float mPelvisZOffset; - - bool mRigValidJointUpload; - bool mLegacyRigValid; - - bool mLastJointUpdate; - - std::deque<std::string> mMasterJointList; - std::deque<std::string> mMasterLegacyJointList; - std::deque<std::string> mJointsFromNode; - JointTransformMap mJointTransformMap; - LLPointer<LLVOAvatar> mPreviewAvatar; -}; - -#endif // LL_LLFLOATERMODELPREVIEW_H +/**
+ * @file llfloatermodelpreview.h
+ * @brief LLFloaterModelPreview class definition
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERMODELPREVIEW_H
+#define LL_LLFLOATERMODELPREVIEW_H
+
+#include "llfloaternamedesc.h"
+
+#include "lldynamictexture.h"
+#include "llfloatermodelwizard.h"
+#include "llquaternion.h"
+#include "llmeshrepository.h"
+#include "llmodel.h"
+#include "llthread.h"
+#include "llviewermenufile.h"
+
+class LLComboBox;
+class LLJoint;
+class LLViewerJointMesh;
+class LLVOAvatar;
+class LLTextBox;
+class LLVertexBuffer;
+class LLModelPreview;
+class LLFloaterModelPreview;
+class daeElement;
+class domProfile_COMMON;
+class domInstance_geometry;
+class domNode;
+class domTranslate;
+class domController;
+class LLMenuButton;
+class LLToggleableMenu;
+
+typedef std::map<std::string, LLMatrix4> JointTransformMap;
+typedef std::map<std::string, LLMatrix4>:: iterator JointTransformMapIt;
+
+const S32 NUM_LOD = 4;
+
+class LLModelLoader : public LLThread
+{
+public:
+ typedef enum
+ {
+ STARTING = 0,
+ READING_FILE,
+ CREATING_FACES,
+ GENERATING_VERTEX_BUFFERS,
+ GENERATING_LOD,
+ DONE,
+ ERROR_PARSING //basically loading failed
+ } eLoadState;
+
+ U32 mState;
+ std::string mFilename;
+ S32 mLod;
+ LLModelPreview* mPreview;
+ LLMatrix4 mTransform;
+ BOOL mFirstTransform;
+ LLVector3 mExtents[2];
+ bool mTrySLM;
+
+ std::map<daeElement*, LLPointer<LLModel> > mModel;
+
+ typedef std::vector<LLPointer<LLModel> > model_list;
+ model_list mModelList;
+
+ typedef std::vector<LLModelInstance> model_instance_list;
+
+ typedef std::map<LLMatrix4, model_instance_list > scene;
+
+ scene mScene;
+
+ typedef std::queue<LLPointer<LLModel> > model_queue;
+
+ //queue of models that need a physics rep
+ model_queue mPhysicsQ;
+
+ LLModelLoader( std::string filename, S32 lod, LLModelPreview* preview, JointTransformMap& jointMap,
+ std::deque<std::string>& jointsFromNodes );
+ ~LLModelLoader() ;
+
+ virtual void run();
+ bool doLoadModel();
+ bool loadFromSLM(const std::string& filename);
+ void loadModelCallback();
+
+ void loadTextures() ; //called in the main thread.
+ void processElement(daeElement* element);
+ std::vector<LLImportMaterial> getMaterials(LLModel* model, domInstance_geometry* instance_geo);
+ LLImportMaterial profileToMaterial(domProfile_COMMON* material);
+ std::string getElementLabel(daeElement *element);
+ LLColor4 getDaeColor(daeElement* element);
+
+ daeElement* getChildFromElement( daeElement* pElement, std::string const & name );
+
+ bool isNodeAJoint( domNode* pNode );
+ void processJointNode( domNode* pNode, std::map<std::string,LLMatrix4>& jointTransforms );
+ void extractTranslation( domTranslate* pTranslate, LLMatrix4& transform );
+ void extractTranslationViaElement( daeElement* pTranslateElement, LLMatrix4& transform );
+
+ void setLoadState(U32 state);
+
+ void buildJointToNodeMappingFromScene( daeElement* pRoot );
+ void processJointToNodeMapping( domNode* pNode );
+
+
+ //map of avatar joints as named in COLLADA assets to internal joint names
+ std::map<std::string, std::string> mJointMap;
+ JointTransformMap& mJointList;
+ std::deque<std::string>& mJointsFromNode;
+
+private:
+ static std::list<LLModelLoader*> sActiveLoaderList;
+ static bool isAlive(LLModelLoader* loader) ;
+};
+
+class LLFloaterModelPreview : public LLFloater
+{
+public:
+
+ class DecompRequest : public LLPhysicsDecomp::Request
+ {
+ public:
+ S32 mContinue;
+ LLPointer<LLModel> mModel;
+
+ DecompRequest(const std::string& stage, LLModel* mdl);
+ virtual S32 statusCallback(const char* status, S32 p1, S32 p2);
+ virtual void completed();
+
+ };
+ static LLFloaterModelPreview* sInstance;
+
+ LLFloaterModelPreview(const LLSD& key);
+ virtual ~LLFloaterModelPreview();
+
+ virtual BOOL postBuild();
+
+ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+ BOOL handleHover(S32 x, S32 y, MASK mask);
+ BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+
+ static void onMouseCaptureLostModelPreview(LLMouseHandler*);
+ static void setUploadAmount(S32 amount) { sUploadAmount = amount; }
+
+ void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost);
+
+ static void onBrowseLOD(void* data);
+
+ static void onReset(void* data);
+
+ static void onUpload(void* data);
+
+ static void onClearMaterials(void* data);
+
+ static void refresh(LLUICtrl* ctrl, void* data);
+
+ void updateResourceCost();
+
+ void loadModel(S32 lod);
+
+ void onViewOptionChecked(const LLSD& userdata);
+ bool isViewOptionChecked(const LLSD& userdata);
+ bool isViewOptionEnabled(const LLSD& userdata);
+ void setViewOptionEnabled(const std::string& option, bool enabled);
+ void enableViewOption(const std::string& option);
+ void disableViewOption(const std::string& option);
+
+protected:
+ friend class LLModelPreview;
+ friend class LLMeshFilePicker;
+ friend class LLPhysicsDecomp;
+
+ static void onImportScaleCommit(LLUICtrl*, void*);
+ static void onPelvisOffsetCommit(LLUICtrl*, void*);
+ static void onUploadJointsCommit(LLUICtrl*,void*);
+ static void onUploadSkinCommit(LLUICtrl*,void*);
+
+ static void onPhysicsLoadRadioCommit(LLUICtrl*,void *data);
+
+ static void onPreviewLODCommit(LLUICtrl*,void*);
+
+ static void onGenerateNormalsCommit(LLUICtrl*,void*);
+
+ static void onAutoFillCommit(LLUICtrl*,void*);
+ static void onLODParamCommit(LLUICtrl*,void*);
+ static void onLODParamCommitTriangleLimit(LLUICtrl*,void*);
+
+ static void onExplodeCommit(LLUICtrl*, void*);
+
+ static void onPhysicsParamCommit(LLUICtrl* ctrl, void* userdata);
+ static void onPhysicsStageExecute(LLUICtrl* ctrl, void* userdata);
+ static void onCancel(LLUICtrl* ctrl, void* userdata);
+ static void onPhysicsStageCancel(LLUICtrl* ctrl, void* userdata);
+
+ static void onPhysicsBrowse(LLUICtrl* ctrl, void* userdata);
+ static void onPhysicsUseLOD(LLUICtrl* ctrl, void* userdata);
+ static void onPhysicsOptimize(LLUICtrl* ctrl, void* userdata);
+ static void onPhysicsDecomposeBack(LLUICtrl* ctrl, void* userdata);
+ static void onPhysicsSimplifyBack(LLUICtrl* ctrl, void* userdata);
+
+ void draw();
+
+ void initDecompControls();
+
+ void setStatusMessage(const std::string& msg);
+
+ LLModelPreview* mModelPreview;
+
+ LLPhysicsDecomp::decomp_params mDecompParams;
+
+ S32 mLastMouseX;
+ S32 mLastMouseY;
+ LLRect mPreviewRect;
+ U32 mGLName;
+ static S32 sUploadAmount;
+
+ std::set<LLPointer<DecompRequest> > mCurRequest;
+ std::string mStatusMessage;
+
+ //use "disabled" as false by default
+ std::map<std::string, bool> mViewOptionDisabled;
+
+ //store which lod mode each LOD is using
+ // 0 - load from file
+ // 1 - auto generate
+ // 2 - None
+ S32 mLODMode[4];
+
+ LLMenuButton* mViewOptionMenuButton;
+ LLToggleableMenu* mViewOptionMenu;
+ LLMutex* mStatusLock;
+
+};
+
+class LLMeshFilePicker : public LLFilePickerThread
+{
+public:
+ LLMeshFilePicker(LLModelPreview* mp, S32 lod);
+ virtual void notify(const std::string& filename);
+
+private:
+ LLModelPreview* mMP;
+ S32 mLOD;
+};
+
+
+class LLModelPreview : public LLViewerDynamicTexture, public LLMutex
+{
+ typedef boost::signals2::signal<void (F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)> details_signal_t;
+ typedef boost::signals2::signal<void (void)> model_loaded_signal_t;
+
+public:
+ LLModelPreview(S32 width, S32 height, LLFloater* fmp);
+ virtual ~LLModelPreview();
+
+ void resetPreviewTarget();
+ void setPreviewTarget(F32 distance);
+ void setTexture(U32 name) { mTextureName = name; }
+
+ void setPhysicsFromLOD(S32 lod);
+ BOOL render();
+ void update();
+ void genBuffers(S32 lod, bool skinned);
+ void clearBuffers();
+ void refresh();
+ void rotate(F32 yaw_radians, F32 pitch_radians);
+ void zoom(F32 zoom_amt);
+ void pan(F32 right, F32 up);
+ virtual BOOL needsRender() { return mNeedsUpdate; }
+ void setPreviewLOD(S32 lod);
+ void clearModel(S32 lod);
+ void loadModel(std::string filename, S32 lod);
+ void loadModelCallback(S32 lod);
+ void genLODs(S32 which_lod = -1, U32 decimation = 3, bool enforce_tri_limit = false);
+ void generateNormals();
+ void clearMaterials();
+ U32 calcResourceCost();
+ void rebuildUploadData();
+ void saveUploadData(bool save_skinweights, bool save_joint_poisitions);
+ void saveUploadData(const std::string& filename, bool save_skinweights, bool save_joint_poisitions);
+ void clearIncompatible(S32 lod);
+ void updateStatusMessages();
+ void clearGLODGroup();
+ void onLODParamCommit(bool enforce_tri_limit);
+
+ const bool getModelPivot( void ) const { return mHasPivot; }
+ void setHasPivot( bool val ) { mHasPivot = val; }
+ void setModelPivot( const LLVector3& pivot ) { mModelPivot = pivot; }
+
+ //Determines the viability of an asset to be used as an avatar rig (w or w/o joint upload caps)
+ void critiqueRigForUploadApplicability( const std::vector<std::string> &jointListFromAsset );
+ void critiqueJointToNodeMappingFromScene( void );
+ //Is a rig valid so that it can be used as a criteria for allowing for uploading of joint positions
+ //Accessors for joint position upload friendly rigs
+ const bool isRigValidForJointPositionUpload( void ) const { return mRigValidJointUpload; }
+ void setRigValidForJointPositionUpload( bool rigValid ) { mRigValidJointUpload = rigValid; }
+ bool isRigSuitableForJointPositionUpload( const std::vector<std::string> &jointListFromAsset );
+ //Determines if a rig is a legacy from the joint list
+ bool isRigLegacy( const std::vector<std::string> &jointListFromAsset );
+ //Accessors for the legacy rigs
+ const bool isLegacyRigValid( void ) const { return mLegacyRigValid; }
+ void setLegacyRigValid( bool rigValid ) { mLegacyRigValid = rigValid; }
+ //Verify that a controller matches vertex counts
+ bool verifyController( domController* pController );
+
+ static void textureLoadedCallback( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* src_aux, S32 discard_level, BOOL final, void* userdata );
+
+ boost::signals2::connection setDetailsCallback( const details_signal_t::slot_type& cb ){ return mDetailsSignal.connect(cb); }
+ boost::signals2::connection setModelLoadedCallback( const model_loaded_signal_t::slot_type& cb ){ return mModelLoadedSignal.connect(cb); }
+
+ void setLoadState( U32 state ) { mLoadState = state; }
+ U32 getLoadState() { return mLoadState; }
+ //setRestJointFlag: If an asset comes through that changes the joints, we want the reset to persist
+ void setResetJointFlag( bool state ) { if ( !mResetJoints ) mResetJoints = state; }
+ const bool getResetJointFlag( void ) const { return mResetJoints; }
+ void setRigWithSceneParity( bool state ) { mRigParityWithScene = state; }
+ const bool getRigWithSceneParity( void ) const { return mRigParityWithScene; }
+
+ LLVector3 getTranslationForJointOffset( std::string joint );
+
+private:
+ //Utility function for controller vertex compare
+ bool verifyCount( int expected, int result );
+ //Creates the dummy avatar for the preview window
+ void createPreviewAvatar( void );
+ //Accessor for the dummy avatar
+ LLVOAvatar* getPreviewAvatar( void ) { return mPreviewAvatar; }
+
+ protected:
+ friend class LLModelLoader;
+ friend class LLFloaterModelPreview;
+ friend class LLFloaterModelWizard;
+ friend class LLFloaterModelPreview::DecompRequest;
+ friend class LLFloaterModelWizard::DecompRequest;
+ friend class LLPhysicsDecomp;
+
+ LLFloater* mFMP;
+
+ BOOL mNeedsUpdate;
+ bool mDirty;
+ bool mGenLOD;
+ U32 mTextureName;
+ F32 mCameraDistance;
+ F32 mCameraYaw;
+ F32 mCameraPitch;
+ F32 mCameraZoom;
+ LLVector3 mCameraOffset;
+ LLVector3 mPreviewTarget;
+ LLVector3 mPreviewScale;
+ S32 mPreviewLOD;
+ U32 mResourceCost;
+ std::string mLODFile[LLModel::NUM_LODS];
+ bool mLoading;
+ U32 mLoadState;
+ bool mResetJoints;
+ bool mRigParityWithScene;
+
+ std::map<std::string, bool> mViewOption;
+
+ //GLOD object parameters (must rebuild object if these change)
+ bool mLODFrozen;
+ F32 mBuildShareTolerance;
+ U32 mBuildQueueMode;
+ U32 mBuildOperator;
+ U32 mBuildBorderMode;
+ U32 mRequestedLoDMode[LLModel::NUM_LODS];
+ S32 mRequestedTriangleCount[LLModel::NUM_LODS];
+ F32 mRequestedErrorThreshold[LLModel::NUM_LODS];
+ U32 mRequestedBuildOperator[LLModel::NUM_LODS];
+ U32 mRequestedQueueMode[LLModel::NUM_LODS];
+ U32 mRequestedBorderMode[LLModel::NUM_LODS];
+ F32 mRequestedShareTolerance[LLModel::NUM_LODS];
+ F32 mRequestedCreaseAngle[LLModel::NUM_LODS];
+
+ LLModelLoader* mModelLoader;
+
+ LLModelLoader::scene mScene[LLModel::NUM_LODS];
+ LLModelLoader::scene mBaseScene;
+
+ LLModelLoader::model_list mModel[LLModel::NUM_LODS];
+ LLModelLoader::model_list mBaseModel;
+
+ U32 mGroup;
+ std::map<LLPointer<LLModel>, U32> mObject;
+ U32 mMaxTriangleLimit;
+
+ LLMeshUploadThread::instance_list mUploadData;
+ std::set<LLViewerFetchedTexture* > mTextureSet;
+
+ //map of vertex buffers to models (one vertex buffer in vector per face in model
+ std::map<LLModel*, std::vector<LLPointer<LLVertexBuffer> > > mVertexBuffer[LLModel::NUM_LODS+1];
+
+ details_signal_t mDetailsSignal;
+ model_loaded_signal_t mModelLoadedSignal;
+
+ LLVector3 mModelPivot;
+ bool mHasPivot;
+
+ float mPelvisZOffset;
+
+ bool mRigValidJointUpload;
+ bool mLegacyRigValid;
+
+ bool mLastJointUpdate;
+
+ std::deque<std::string> mMasterJointList;
+ std::deque<std::string> mMasterLegacyJointList;
+ std::deque<std::string> mJointsFromNode;
+ JointTransformMap mJointTransformMap;
+ LLPointer<LLVOAvatar> mPreviewAvatar;
+};
+
+#endif // LL_LLFLOATERMODELPREVIEW_H
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp index 0f11d05175..0d798afdcc 100644 --- a/indra/newview/llfloatertools.cpp +++ b/indra/newview/llfloatertools.cpp @@ -424,6 +424,7 @@ void LLFloaterTools::refresh() // Refresh object and prim count labels LLLocale locale(LLLocale::USER_LOCALE); +#if 0 if (gMeshRepo.meshRezEnabled()) { std::string obj_count_string; @@ -448,6 +449,7 @@ void LLFloaterTools::refresh() getChildView("RenderingCost")->setEnabled(have_selection && sShowObjectCost); } else +#endif { // Get the number of objects selected std::string root_object_count_string; diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 0b10024663..6b8b0f5a00 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2688,7 +2688,18 @@ 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_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0); + if (mesh.has("physics_mesh") && mesh["physics_mesh"].has("size") && (mesh["physics_mesh"]["size"].asInteger() > 0)) + { + return true; + } + + LLModel::Decomposition* decomp = getDecomposition(mesh_id); + if (decomp && !decomp->mHull.empty()) + { + return true; + } + + return false; } LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 7f91f9a952..d96fa087b1 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -35,6 +35,7 @@ #include "llvolumeoctree.h" #include "llviewercamera.h" #include "llface.h" +#include "llfloatertools.h" #include "llviewercontrol.h" #include "llviewerregion.h" #include "llcamera.h" @@ -4272,7 +4273,29 @@ public: if (vobj) { LLVector3 intersection; - if (vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal)) + bool skip_check = false; + if (vobj->isAvatar()) + { + LLVOAvatar* avatar = (LLVOAvatar*) vobj; + if (avatar->isSelf() && LLFloater::isVisible(gFloaterTools)) + { + LLViewerObject* hit = avatar->lineSegmentIntersectRiggedAttachments(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal); + if (hit) + { + mEnd = intersection; + if (mIntersection) + { + *mIntersection = intersection; + } + + mHit = hit->mDrawable; + skip_check = true; + } + + } + } + + if (!skip_check && vobj->lineSegmentIntersect(mStart, mEnd, -1, mPickTransparent, mFaceHit, &intersection, mTexCoord, mNormal, mBinormal)) { mEnd = intersection; // shorten ray so we only find CLOSER hits if (mIntersection) diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 5dadd2c33b..f725f0fe86 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -996,8 +996,7 @@ void render_hud_attachments() S32 use_occlusion = LLPipeline::sUseOcclusion; LLPipeline::sUseOcclusion = 0; - LLPipeline::sDisableShaders = TRUE; - + //cull, sort, and render hud objects static LLCullResult result; LLSpatialGroup::sNoDelete = TRUE; @@ -1037,7 +1036,6 @@ void render_hud_attachments() gPipeline.toggleRenderDebugFeature((void*) LLPipeline::RENDER_DEBUG_FEATURE_UI); } LLPipeline::sUseOcclusion = use_occlusion; - LLPipeline::sDisableShaders = FALSE; } glMatrixMode(GL_PROJECTION); glPopMatrix(); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index a1cb6d4ea6..e3ed2d0649 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1303,8 +1303,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true; gDeferredFullbrightProgram.mFeatures.hasGamma = true; gDeferredFullbrightProgram.mFeatures.hasTransport = true; - gDeferredFullbrightProgram.mFeatures.isFullbright = true; - gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = 0; + gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = gGLManager.mNumTextureImageUnits; gDeferredFullbrightProgram.mShaderFiles.clear(); gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER_ARB)); gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightF.glsl", GL_FRAGMENT_SHADER_ARB)); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index 77bbf994e9..1b53348b43 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -56,6 +56,7 @@ #include "lleditingmotion.h" #include "llemote.h" //#include "llfirstuse.h" +#include "llfloatertools.h" #include "llheadrotmotion.h" #include "llhudeffecttrail.h" #include "llhudmanager.h" @@ -1541,7 +1542,35 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e return TRUE; } } + + if (isSelf()) + { + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* attached_object = (*attachment_iter); + + if (attached_object && !attached_object->isDead() && attachment->getValid()) + { + LLDrawable* drawable = attached_object->mDrawable; + if (drawable->isState(LLDrawable::RIGGED)) + { //regenerate octree for rigged attachment + gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE); + } + } + } + } + } } + + LLVector3 position; if (mNameText.notNull() && mNameText->lineSegmentIntersect(start, end, position)) @@ -1557,6 +1586,56 @@ BOOL LLVOAvatar::lineSegmentIntersect(const LLVector3& start, const LLVector3& e return FALSE; } +LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, + S32 face, + BOOL pick_transparent, + S32* face_hit, + LLVector3* intersection, + LLVector2* tex_coord, + LLVector3* normal, + LLVector3* bi_normal) +{ + if (isSelf() && !gAgent.needsRenderAvatar()) + { + return NULL; + } + + LLViewerObject* hit = NULL; + + if (lineSegmentBoundingBox(start, end)) + { + LLVector3 local_end = end; + LLVector3 local_intersection; + + for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); + iter != mAttachmentPoints.end(); + ++iter) + { + LLViewerJointAttachment* attachment = iter->second; + + for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin(); + attachment_iter != attachment->mAttachedObjects.end(); + ++attachment_iter) + { + LLViewerObject* attached_object = (*attachment_iter); + + if (attached_object->lineSegmentIntersect(start, local_end, face, pick_transparent, face_hit, &local_intersection, tex_coord, normal, bi_normal)) + { + local_end = local_intersection; + if (intersection) + { + *intersection = local_intersection; + } + + hit = attached_object; + } + } + } + } + + return hit; +} + //----------------------------------------------------------------------------- // parseSkeletonFile() //----------------------------------------------------------------------------- diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h index 295799fd24..03c0498a2a 100644 --- a/indra/newview/llvoavatar.h +++ b/indra/newview/llvoavatar.h @@ -145,6 +145,14 @@ public: LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point LLVector3* normal = NULL, // return the surface normal at the intersection point LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point + LLViewerObject* lineSegmentIntersectRiggedAttachments(const LLVector3& start, const LLVector3& end, + S32 face = -1, // which face to check, -1 = ALL_SIDES + BOOL pick_transparent = FALSE, + S32* face_hit = NULL, // which face was hit + LLVector3* intersection = NULL, // return the intersection point + LLVector2* tex_coord = NULL, // return the texture coordinates of the intersection point + LLVector3* normal = NULL, // return the surface normal at the intersection point + LLVector3* bi_normal = NULL); // return the surface bi-normal at the intersection point //-------------------------------------------------------------------- // LLCharacter interface and related diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index d978167f50..c5e2c56e4b 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3365,7 +3365,8 @@ BOOL LLVOVolume::lineSegmentIntersect(const LLVector3& start, const LLVector3& e { if (LLFloater::isVisible(gFloaterTools) && getAvatar()->isSelf()) { - gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_RIGGED, TRUE); + updateRiggedVolume(); + genBBoxes(FALSE); volume = mRiggedVolume; transform = false; } diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 4677d014b8..f58595b3c5 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -4,9 +4,11 @@ name="Model Preview" title="Upload Model" width="620"> <string name="status_idle">Idle</string> + <string name="status_parse_error">Dae parsing issue - see log for details.</string> <string name="status_reading_file">Loading...</string> <string name="status_generating_meshes">Generating Meshes...</string> <string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string> + <string name="bad_element">Error: element is invalid</string> <string name="high">High</string> <string name="medium">Medium</string> <string name="low">Low</string> diff --git a/indra/newview/skins/default/xui/en/floater_model_wizard.xml b/indra/newview/skins/default/xui/en/floater_model_wizard.xml index 47b2e5fd79..8603682e3a 100644 --- a/indra/newview/skins/default/xui/en/floater_model_wizard.xml +++ b/indra/newview/skins/default/xui/en/floater_model_wizard.xml @@ -1019,9 +1019,11 @@ Advanced users familiar with 3d content creation tools may prefer to use the [se <spinner visible="false" left="10" height="20" follows="top|left" width="80" top_pad="-50" value="1.0" min_val="0.01" max_val="64.0" name="import_scale"/> <string name="status_idle">Idle</string> + <string name="status_parse_error">Dae parsing issue - see log for details.</string> <string name="status_reading_file">Loading...</string> <string name="status_generating_meshes">Generating Meshes...</string> - <string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string> + <string name="status_vertex_number_overflow">Error: Vertex number is more than 65534, aborted!</string> + <string name="bad_element">Error: element is invalid</string> <string name="high">High</string> <string name="medium">Medium</string> <string name="low">Low</string> diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index f5f6b990d1..7441b2cd9c 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2457,8 +2457,9 @@ even though the user gets a free copy. height="19" increment="0.1" initial_value="0" - label="Density" + label="Density in 100 kg/m^3" label_width="70" + label_wrap="true" layout="topleft" left_delta="0" max_val="22587" @@ -2479,7 +2480,7 @@ even though the user gets a free copy. max_val="1" min_val="0" name="Physics Restitution" - top_pad="4" + top_pad="8" width="132" /> </panel> <panel |