Bulk of mesh. Excluded via #if MESH_ENABLED. LLModel still needs updated for strided vbos, Collada SDK needs to be wrangled, and misc pieces need to be found and brought over. Skipping inventory stuff until meshes are at least displayable.
This commit is contained in:
210
indra/newview/llphysicsshapebuilderutil.cpp
Normal file
210
indra/newview/llphysicsshapebuilderutil.cpp
Normal file
@@ -0,0 +1,210 @@
|
||||
/**
|
||||
* @file llphysicsshapebuilder.cpp
|
||||
* @brief Generic system to convert LL(Physics)VolumeParams to physics shapes
|
||||
*
|
||||
* $LicenseInfo:firstyear=2001&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$
|
||||
*/
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user