diff options
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/CMakeLists.txt | 24 | ||||
-rw-r--r-- | indra/newview/app_settings/settings_crash_behavior.xml | 2 | ||||
-rw-r--r-- | indra/newview/llfloatermodelpreview.cpp | 37 | ||||
-rw-r--r-- | indra/newview/llmeshrepository.cpp | 5 | ||||
-rw-r--r-- | indra/newview/llmeshrepository.h | 1 | ||||
-rw-r--r-- | indra/newview/llphysicsshapebuilderutil.cpp | 206 | ||||
-rw-r--r-- | indra/newview/llphysicsshapebuilderutil.h | 134 | ||||
-rw-r--r-- | indra/newview/llspatialpartition.cpp | 172 | ||||
-rw-r--r-- | indra/newview/skins/default/xui/en/floater_model_preview.xml | 2 |
9 files changed, 531 insertions, 52 deletions
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 1194e558f1..55a2fb7630 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -383,6 +383,7 @@ set(viewer_SOURCE_FILES llparcelselection.cpp llparticipantlist.cpp llpatchvertexarray.cpp + llphysicsshapebuilderutil.cpp llplacesinventorybridge.cpp llplacesinventorypanel.cpp llpopupview.cpp @@ -912,6 +913,7 @@ set(viewer_HEADER_FILES llparcelselection.h llparticipantlist.h llpatchvertexarray.h + llphysicsshapebuilderutil.h llplacesinventorybridge.h llplacesinventorypanel.h llpolymesh.h @@ -1436,12 +1438,22 @@ if (WINDOWS) set(release_flags "/MAP:Release/${VIEWER_BINARY_NAME}.map") endif(MSVC71) - set_target_properties(${VIEWER_BINARY_NAME} - PROPERTIES - LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCLUDE:__tcmalloc" - LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO" - LINK_FLAGS_RELEASE ${release_flags} - ) + if (INCREMENTAL_LINK) + set_target_properties(${VIEWER_BINARY_NAME} + PROPERTIES + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCREMENTAL /INCLUDE:__tcmalloc" + LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\"" + LINK_FLAGS_RELEASE ${release_flags} + ) + else(INCREMENTAL_LINK) + set_target_properties(${VIEWER_BINARY_NAME} + PROPERTIES + LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:WINDOWS /INCREMENTAL:NO /INCLUDE:__tcmalloc" + LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\"" + LINK_FLAGS_RELEASE ${release_flags} + ) + endif(INCREMENTAL_LINK) + if(USE_PRECOMPILED_HEADERS) set_target_properties( ${VIEWER_BINARY_NAME} diff --git a/indra/newview/app_settings/settings_crash_behavior.xml b/indra/newview/app_settings/settings_crash_behavior.xml index cc7f5ac88b..97651ff4ca 100644 --- a/indra/newview/app_settings/settings_crash_behavior.xml +++ b/indra/newview/app_settings/settings_crash_behavior.xml @@ -9,7 +9,7 @@ <key>Type</key> <string>S32</string> <key>Value</key> - <integer>0</integer> + <integer>1</integer> </map> </map> </llsd> diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 6e051c66a9..d89d3e5c0a 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -2961,50 +2961,21 @@ void LLModelPreview::updateStatusMessages() if (lod != lod_high) { - if (total_submeshes[lod] == 0) - { //no model loaded for this lod, see if one is required - for (U32 i = 0; i < verts[lod_high].size(); ++i) - { - const F32 ratio = 0.5f; - const S32 required_verts = 128; - - F32 scaler = powf(ratio, lod_high-lod); - S32 max_verts = (S32)(verts[lod_high][i]*scaler); - - if (max_verts > required_verts) - { //some model in this slot might have more than 128 vertices - - //if any model higher up the chain has more than 128 vertices, - // lod is required here - for (S32 j = lod+1; j <= LLModel::LOD_HIGH; ++j) - { - if (verts[j].size() > i && verts[j][i] > 128) - { - message = "required"; - upload_message = "missing_lod"; - } - } - } - } - } - else if (total_submeshes[lod] != total_submeshes[lod_high]) + if (total_submeshes[lod] && total_submeshes[lod] != total_submeshes[lod_high]) { message = "mesh_mismatch"; upload_message = "bad_lod"; } - else if (tris[lod].size() != tris[lod_high].size()) + else if (!tris[lod].empty() && tris[lod].size() != tris[lod_high].size()) { message = "model_mismatch"; upload_message = "bad_lod"; } - else + else if (!verts[lod].empty()) { for (U32 i = 0; i < verts[lod].size(); ++i) { - const F32 ratio = 0.5f; - - F32 scaler = powf(ratio, lod_high-lod); - S32 max_verts = (S32)(verts[lod_high][i]*scaler); + S32 max_verts = verts[lod+1][i]; if (verts[lod][i] > max_verts) { diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp index 757497060a..9aba84acb4 100644 --- a/indra/newview/llmeshrepository.cpp +++ b/indra/newview/llmeshrepository.cpp @@ -2130,6 +2130,11 @@ const LLMeshDecomposition* LLMeshRepository::getDecomposition(const LLUUID& mesh return NULL; } +void LLMeshRepository::buildHull(const LLVolumeParams& params, S32 detail) +{ + +} + const LLSD& LLMeshRepository::getMeshHeader(const LLUUID& mesh_id) { return mThread->getMeshHeader(mesh_id); diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h index 736d236e2e..0bc63a8469 100644 --- a/indra/newview/llmeshrepository.h +++ b/indra/newview/llmeshrepository.h @@ -407,6 +407,7 @@ public: U32 getResourceCost(const LLUUID& mesh_params); const LLMeshSkinInfo* getSkinInfo(const LLUUID& mesh_id); const LLMeshDecomposition* getDecomposition(const LLUUID& mesh_id); + void buildHull(const LLVolumeParams& params, S32 detail); const LLSD& getMeshHeader(const LLUUID& mesh_id); void uploadModel(std::vector<LLModelInstance>& data, LLVector3& scale, bool upload_textures, diff --git a/indra/newview/llphysicsshapebuilderutil.cpp b/indra/newview/llphysicsshapebuilderutil.cpp new file mode 100644 index 0000000000..54d54bfcb9 --- /dev/null +++ b/indra/newview/llphysicsshapebuilderutil.cpp @@ -0,0 +1,206 @@ +/** +* @file llphysicsshapebuilder.cpp +* @brief Generic system to convert LL(Physics)VolumeParams to physics shapes +* @author falcon@lindenlab.com +* +* $LicenseInfo:firstyear=2010&license=internal$ +* +* Copyright (c) 2010, Linden Research, Inc. +* +* The following source code is PROPRIETARY AND CONFIDENTIAL. Use of +* this source code is governed by the Linden Lab Source Code Disclosure +* Agreement ("Agreement") previously entered between you and Linden +* Lab. By accessing, using, copying, modifying or distributing this +* software, you acknowledge that you have been informed of your +* obligations under the Agreement and agree to abide by those obligations. +* +* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO +* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, +* COMPLETENESS OR PERFORMANCE. +* $/LicenseInfo$ +*/ + +#include "llviewerprecompiledheaders.h" + +#include "llphysicsshapebuilderutil.h" + +/* static */ +void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut ) +{ + const LLProfileParams& profile_params = volume_params.getProfileParams(); + const LLPathParams& path_params = volume_params.getPathParams(); + + specOut.mScale = scale; + + const F32 avgScale = ( scale[VX] + scale[VY] + scale[VZ] )/3.0f; + + // count the scale elements that are small + S32 min_size_counts = 0; + for (S32 i = 0; i < 3; ++i) + { + if (scale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) + { + ++min_size_counts; + } + } + + const bool profile_complete = ( profile_params.getBegin() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) && + ( profile_params.getEnd() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ); + + const bool path_complete = ( path_params.getBegin() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) && + ( path_params.getEnd() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ); + + const bool simple_params = ( volume_params.getHollow() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_HOLLOW/avgScale ) + && ( fabs(path_params.getShearX()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR/avgScale ) + && ( fabs(path_params.getShearY()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR/avgScale ) + && ( !volume_params.isMeshSculpt() && !volume_params.isSculpt() ); + + if (simple_params && profile_complete) + { + // Try to create an implicit shape or convexified + bool no_taper = ( fabs(path_params.getScaleX() - 1.0f) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ) + && ( fabs(path_params.getScaleY() - 1.0f) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ); + + bool no_twist = ( fabs(path_params.getTwistBegin()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST/avgScale ) + && ( fabs(path_params.getTwistEnd()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST/avgScale); + + // Box + if( + ( profile_params.getCurveType() == LL_PCODE_PROFILE_SQUARE ) + && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) + && no_taper + && no_twist + ) + { + specOut.mType = PhysicsShapeSpecification::BOX; + if ( path_complete ) + { + return; + } + else + { + // Side lengths + specOut.mScale[VX] = llmax( scale[VX], SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); + specOut.mScale[VY] = llmax( scale[VY], SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); + specOut.mScale[VZ] = llmax( scale[VZ] * (path_params.getEnd() - path_params.getBegin()), SHAPE_BUILDER_MIN_GEOMETRY_SIZE ); + + specOut.mCenter.set( 0.f, 0.f, 0.5f * scale[VZ] * ( path_params.getEnd() + path_params.getBegin() - 1.0f ) ); + return; + } + } + + // Sphere + if( path_complete + && ( profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE_HALF ) + && ( path_params.getCurveType() == LL_PCODE_PATH_CIRCLE ) + && ( fabs(volume_params.getTaper()) <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER/avgScale ) + && no_twist + ) + { + if ( ( scale[VX] == scale[VZ] ) + && ( scale[VY] == scale[VZ] ) ) + { + // perfect sphere + specOut.mType = PhysicsShapeSpecification::SPHERE; + specOut.mScale = scale; + return; + } + else if (min_size_counts > 1) + { + // small or narrow sphere -- we can boxify + for (S32 i=0; i<3; ++i) + { + if (specOut.mScale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) + { + // reduce each small dimension size to split the approximation errors + specOut.mScale[i] *= 0.75f; + } + } + specOut.mType = PhysicsShapeSpecification::BOX; + return; + } + } + + // Cylinder + if( (scale[VX] == scale[VY]) + && ( profile_params.getCurveType() == LL_PCODE_PROFILE_CIRCLE ) + && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) + && ( volume_params.getBeginS() <= SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale ) + && ( volume_params.getEndS() >= (1.0f - SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT/avgScale) ) + && no_taper + ) + { + if (min_size_counts > 1) + { + // small or narrow sphere -- we can boxify + for (S32 i=0; i<3; ++i) + { + if (specOut.mScale[i] < SHAPE_BUILDER_CONVEXIFICATION_SIZE) + { + // reduce each small dimension size to split the approximation errors + specOut.mScale[i] *= 0.75f; + } + } + + specOut.mType = PhysicsShapeSpecification::BOX; + } + else + { + specOut.mType = PhysicsShapeSpecification::CYLINDER; + F32 length = (volume_params.getPathParams().getEnd() - volume_params.getPathParams().getBegin()) * scale[VZ]; + + specOut.mScale[VY] = specOut.mScale[VX]; + specOut.mScale[VZ] = length; + // The minus one below fixes the fact that begin and end range from 0 to 1 not -1 to 1. + specOut.mCenter.set( 0.f, 0.f, 0.5f * (volume_params.getPathParams().getBegin() + volume_params.getPathParams().getEnd() - 1.f) * scale[VZ] ); + } + + return; + } + } + + if ( (min_size_counts == 3 ) + // Possible dead code here--who wants to take it out? + || (path_complete + && profile_complete + && ( path_params.getCurveType() == LL_PCODE_PATH_LINE ) + && (min_size_counts > 1 ) ) + ) + { + // it isn't simple but + // we might be able to convexify this shape if the path and profile are complete + // or the path is linear and both path and profile are complete --> we can boxify it + specOut.mType = PhysicsShapeSpecification::BOX; + specOut.mScale = scale; + return; + } + + // Special case for big, very thin objects - bump the small dimensions up to the COLLISION_TOLERANCE + if (min_size_counts == 1 // One dimension is small + && avgScale > 3.f) // ... but others are fairly large + { + for (S32 i = 0; i < 3; ++i) + { + specOut.mScale[i] = llmax( specOut.mScale[i], COLLISION_TOLERANCE ); + } + } + + if ( volume_params.shouldForceConvex() ) + { + specOut.mType = PhysicsShapeSpecification::USER_CONVEX; + } + // Make a simpler convex shape if we can. + else if (volume_params.isConvex() // is convex + || min_size_counts > 1 ) // two or more small dimensions + { + specOut.mType = PhysicsShapeSpecification::PRIM_CONVEX; + } + else if ( volume_params.isSculpt() ) // Is a sculpt of any kind (mesh or legacy) + { + specOut.mType = volume_params.isMeshSculpt() ? PhysicsShapeSpecification::USER_MESH : PhysicsShapeSpecification::SCULPT; + } + else // Resort to mesh + { + specOut.mType = PhysicsShapeSpecification::PRIM_MESH; + } +} diff --git a/indra/newview/llphysicsshapebuilderutil.h b/indra/newview/llphysicsshapebuilderutil.h new file mode 100644 index 0000000000..3de9afcb25 --- /dev/null +++ b/indra/newview/llphysicsshapebuilderutil.h @@ -0,0 +1,134 @@ +/** + * @file llphysicsshapebuilder.h + * @author falcon@lindenlab.com + * @brief Generic system to convert LL(Physics)VolumeParams to physics shapes + * + * $LicenseInfo:firstyear=2010&license=internal$ + * + * Copyright (c) 2010, Linden Research, Inc. + * + * The following source code is PROPRIETARY AND CONFIDENTIAL. Use of + * this source code is governed by the Linden Lab Source Code Disclosure + * Agreement ("Agreement") previously entered between you and Linden + * Lab. By accessing, using, copying, modifying or distributing this + * software, you acknowledge that you have been informed of your + * obligations under the Agreement and agree to abide by those obligations. + * + * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO + * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY, + * COMPLETENESS OR PERFORMANCE. + * $/LicenseInfo$ + */ + +#ifndef LL_PHYSICS_SHAPE_BUILDER_H +#define LL_PHYSICS_SHAPE_BUILDER_H + +#include "indra_constants.h" +#include "llvolume.h" + +#define USE_SHAPE_QUANTIZATION 0 + +#define SHAPE_BUILDER_DEFAULT_VOLUME_DETAIL 1 + +#define SHAPE_BUILDER_IMPLICIT_THRESHOLD_HOLLOW 0.10f +#define SHAPE_BUILDER_IMPLICIT_THRESHOLD_HOLLOW_SPHERES 0.90f +#define SHAPE_BUILDER_IMPLICIT_THRESHOLD_PATH_CUT 0.05f +#define SHAPE_BUILDER_IMPLICIT_THRESHOLD_TAPER 0.05f +#define SHAPE_BUILDER_IMPLICIT_THRESHOLD_TWIST 0.09f +#define SHAPE_BUILDER_IMPLICIT_THRESHOLD_SHEAR 0.05f + +const F32 SHAPE_BUILDER_ENTRY_SNAP_SCALE_BIN_SIZE = 0.15f; +const F32 SHAPE_BUILDER_ENTRY_SNAP_PARAMETER_BIN_SIZE = 0.010f; +const F32 SHAPE_BUILDER_CONVEXIFICATION_SIZE = 2.f * COLLISION_TOLERANCE; +const F32 SHAPE_BUILDER_MIN_GEOMETRY_SIZE = 0.5f * COLLISION_TOLERANCE; + +class LLPhysicsVolumeParams : public LLVolumeParams
+{
+public:
+
+ LLPhysicsVolumeParams( const LLVolumeParams& params, bool forceConvex ) :
+ LLVolumeParams( params ),
+ mForceConvex(forceConvex) {}
+
+ bool operator==(const LLPhysicsVolumeParams ¶ms) const
+ {
+ return ( LLVolumeParams::operator==(params) && (mForceConvex == params.mForceConvex) );
+ }
+
+ bool operator!=(const LLPhysicsVolumeParams ¶ms) const
+ {
+ return !operator==(params);
+ }
+
+ bool operator<(const LLPhysicsVolumeParams ¶ms) const
+ {
+ if ( LLVolumeParams::operator!=(params) )
+ {
+ return LLVolumeParams::operator<(params);
+ }
+ return (params.mForceConvex == false) && (mForceConvex == true);
+ }
+
+ bool shouldForceConvex() const { return mForceConvex; }
+
+private:
+ bool mForceConvex;
+};
+
+ +class LLPhysicsShapeBuilderUtil +{ +public: + + class PhysicsShapeSpecification + { + public: + enum ShapeType + { + // Primitive types + BOX, + SPHERE, + CYLINDER, + + USER_CONVEX, // User specified they wanted the convex hull of the volume + + PRIM_CONVEX, // Either a volume that is inherently convex but not a primitive type, or a shape + // with dimensions such that will convexify it anyway. + + SCULPT, // Special case for traditional sculpts--they are the convex hull of a single particular set of volume params + + USER_MESH, // A user mesh. May or may not contain a convex decomposition. + + PRIM_MESH, // A non-convex volume which we have to represent accurately + + INVALID + }; + + PhysicsShapeSpecification() : + mType( INVALID ), + mScale( 0.f, 0.f, 0.f ), + mCenter( 0.f, 0.f, 0.f ) {} + + bool isConvex() { return (mType != USER_MESH && mType != PRIM_MESH && mType != INVALID); } + bool isMesh() { return (mType == USER_MESH) || (mType == PRIM_MESH); } + + ShapeType getType() { return mType; } + const LLVector3& getScale() { return mScale; } + const LLVector3& getCenter() { return mCenter; } + + private: + friend class LLPhysicsShapeBuilderUtil; + + ShapeType mType; + + // Dimensions of an AABB around the shape + LLVector3 mScale; + + // Offset of shape from origin of primitive's reference frame + LLVector3 mCenter; + }; + + static void determinePhysicsShape( const LLPhysicsVolumeParams& volume_params, const LLVector3& scale, PhysicsShapeSpecification& specOut ); +}; + +#endif //LL_PHYSICS_SHAPE_BUILDER_H diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 56be8af599..148c222014 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -48,7 +48,9 @@ #include "llmeshrepository.h" #include "llrender.h" #include "lloctree.h" +#include "llphysicsshapebuilderutil.h" #include "llvoavatar.h" +#include "llvolumemgr.h" #include "lltextureatlas.h" static LLFastTimer::DeclareTimer FTM_FRUSTUM_CULL("Frustum Culling"); @@ -2341,6 +2343,17 @@ void pushVerts(LLDrawable* drawable, U32 mask) } } +void pushVerts(LLVolume* volume) +{ + LLVertexBuffer::unbind(); + for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i) + { + const LLVolumeFace& face = volume->getVolumeFace(i); + glVertexPointer(3, GL_FLOAT, 16, face.mPositions); + glDrawElements(GL_TRIANGLES, face.mNumIndices, GL_UNSIGNED_SHORT, face.mIndices); + } +} + void pushBufferVerts(LLVertexBuffer* buffer, U32 mask) { if (buffer) @@ -2766,8 +2779,36 @@ void renderNormals(LLDrawable* drawablep) } } +S32 get_physics_detail(const LLVolumeParams& volume_params, const LLVector3& scale) +{ + const S32 DEFAULT_DETAIL = 1; + const F32 LARGE_THRESHOLD = 5.f; + const F32 MEGA_THRESHOLD = 25.f; + + S32 detail = DEFAULT_DETAIL; + F32 avg_scale = (scale[0]+scale[1]+scale[2])/3.f; + + if (avg_scale > LARGE_THRESHOLD) + { + detail += 1; + if (avg_scale > MEGA_THRESHOLD) + { + detail += 1; + } + } + + return detail; +} + void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) { + U8 physics_type = volume->getPhysicsShapeType(); + + if (physics_type == LLViewerObject::PHYSICS_SHAPE_NONE) + { + return; + } + F32 threshold = gSavedSettings.getF32("ObjectCostHighThreshold"); F32 cost = volume->getObjectCost(); @@ -2789,10 +2830,21 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) U32 data_mask = LLVertexBuffer::MAP_VERTEX; - if (volume->isMesh()) - { + LLVolumeParams volume_params = volume->getVolume()->getParams(); + + LLPhysicsVolumeParams physics_params(volume->getVolume()->getParams(), + physics_type == LLViewerObject::PHYSICS_SHAPE_CONVEX_HULL); + + LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification physics_spec; + LLPhysicsShapeBuilderUtil::determinePhysicsShape(physics_params, volume->getScale(), physics_spec); + + U32 type = physics_spec.getType(); + + if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::USER_MESH) + { LLUUID mesh_id = volume->getVolume()->getParams().getSculptID(); const LLMeshDecomposition* decomp = gMeshRepo.getDecomposition(mesh_id); + if (decomp) { gGL.pushMatrix(); @@ -2821,18 +2873,112 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume) } gGL.popMatrix(); + } + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::BOX) + { + gGL.pushMatrix(); + glMultMatrixf((GLfloat*) volume->getRelativeXform().mMatrix); + LLVector3 center = physics_spec.getCenter(); + LLVector3 scale = physics_spec.getScale(); + LLVector3 vscale = volume->getScale()*2.f; + scale.set(scale[0]/vscale[0], scale[1]/vscale[1], scale[2]/vscale[2]); + + gGL.color4fv(color.mV); + drawBox(center, scale); + gGL.popMatrix(); + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SPHERE) + { + LLVolumeParams volume_params; + volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE ); + volume_params.setBeginAndEndS( 0.f, 1.f ); + volume_params.setBeginAndEndT( 0.f, 1.f ); + volume_params.setRatio ( 1, 1 ); + volume_params.setShear ( 0, 0 ); + LLVolume* sphere = LLPrimitive::sVolumeManager->refVolume(volume_params, 3); + + gGL.pushMatrix(); + glMultMatrixf((GLfloat*) volume->getRelativeXform().mMatrix); + glColor4fv(color.mV); + pushVerts(sphere); + gGL.popMatrix(); + LLPrimitive::sVolumeManager->unrefVolume(sphere); + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::CYLINDER) + { + LLVolumeParams volume_params; + volume_params.setType( LL_PCODE_PROFILE_CIRCLE, LL_PCODE_PATH_LINE ); + volume_params.setBeginAndEndS( 0.f, 1.f ); + volume_params.setBeginAndEndT( 0.f, 1.f ); + volume_params.setRatio ( 1, 1 ); + volume_params.setShear ( 0, 0 ); + LLVolume* cylinder = LLPrimitive::sVolumeManager->refVolume(volume_params, 3); + + gGL.pushMatrix(); + glMultMatrixf((GLfloat*) volume->getRelativeXform().mMatrix); + glColor4fv(color.mV); + pushVerts(cylinder); + gGL.popMatrix(); + LLPrimitive::sVolumeManager->unrefVolume(cylinder); + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_MESH) + { + LLVolumeParams volume_params = volume->getVolume()->getParams(); + S32 detail = get_physics_detail(volume_params, volume->getScale()); - return; + LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail); + gGL.pushMatrix(); + glMultMatrixf((GLfloat*) volume->getRelativeXform().mMatrix); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + glColor3fv(color.mV); + pushVerts(phys_volume); + + glColor4fv(color.mV); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + pushVerts(phys_volume); + gGL.popMatrix(); + LLPrimitive::sVolumeManager->unrefVolume(phys_volume); + } + else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::PRIM_CONVEX) + { + LLVolumeParams volume_params = volume->getVolume()->getParams(); + S32 detail = get_physics_detail(volume_params, volume->getScale()); + + LLVolume* phys_volume = LLPrimitive::sVolumeManager->refVolume(volume_params, detail); + + if (phys_volume->mHullPoints && phys_volume->mHullIndices) + { + gGL.pushMatrix(); + glMultMatrixf((GLfloat*) volume->getRelativeXform().mMatrix); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + + LLVertexBuffer::unbind(); + glVertexPointer(3, GL_FLOAT, 16, phys_volume->mHullPoints); + glColor3fv(color.mV); + glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); + + glColor4fv(color.mV); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDrawElements(GL_TRIANGLES, phys_volume->mNumHullIndices, GL_UNSIGNED_SHORT, phys_volume->mHullIndices); + gGL.popMatrix(); } + else + { + gMeshRepo.buildHull(volume_params, detail); + } + LLPrimitive::sVolumeManager->unrefVolume(phys_volume); } - - //push faces - glColor3fv(color.mV); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - pushVerts(drawable, data_mask); - glColor4fv(color.mV); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - pushVerts(drawable, data_mask); + + /*{ //analytical shape, just push visual rep. + glColor3fv(color.mV); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + pushVerts(drawable, data_mask); + glColor4fv(color.mV); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + pushVerts(drawable, data_mask); + }*/ } void renderPhysicsShapes(LLSpatialGroup* group) @@ -2840,6 +2986,10 @@ void renderPhysicsShapes(LLSpatialGroup* group) LLGLEnable blend(GL_BLEND); LLGLDepthTest test(GL_TRUE, GL_FALSE); + LLGLEnable offset_fill(GL_POLYGON_OFFSET_FILL); + LLGLEnable offset_line(GL_POLYGON_OFFSET_LINE); + glPolygonOffset(-1.f, -1.f); + for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getData().begin(); i != group->getData().end(); ++i) { LLDrawable* drawable = *i; 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 e7c2a8bc6f..6512548441 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -175,7 +175,7 @@ <text bottom_delta="20" left="15" follows="top|left" height="15" name="description_label" text_color="1 0.82 0.46 1"> (No charge for upload during First Look) </text> - <text bottom_delta="20" left="15" follows="top|left" height="15" name="upload_message"> + <text bottom_delta="20" left="15" width="280" follows="top|left" height="15" name="upload_message"> [MESSAGE] </text> <text bottom_delta="45" left="15" follows="top|left" height="15" name="debug section"> |