fix whitespace
parent
d6e10ba4b0
commit
5370a6d323
|
|
@ -1,25 +1,25 @@
|
|||
/**
|
||||
/**
|
||||
* @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$
|
||||
*/
|
||||
|
|
@ -51,175 +51,175 @@ bool LLPhysicsVolumeParams::hasDecomposition() const
|
|||
/* 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();
|
||||
const LLProfileParams& profile_params = volume_params.getProfileParams();
|
||||
const LLPathParams& path_params = volume_params.getPathParams();
|
||||
|
||||
specOut.mScale = scale;
|
||||
specOut.mScale = scale;
|
||||
|
||||
const F32 avgScale = ( scale[VX] + scale[VY] + scale[VZ] )/3.0f;
|
||||
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;
|
||||
}
|
||||
}
|
||||
// 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 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 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() );
|
||||
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 );
|
||||
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);
|
||||
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 );
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
// 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.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] );
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
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 );
|
||||
}
|
||||
}
|
||||
// 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() )
|
||||
{
|
||||
if ( volume_params.shouldForceConvex() )
|
||||
{
|
||||
// Server distinguishes between convex of a prim vs isSculpt, but we don't care.
|
||||
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;
|
||||
}
|
||||
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.isMeshSculpt())
|
||||
{
|
||||
// Check overall dimensions, not individual triangles.
|
||||
|
|
@ -243,12 +243,12 @@ void LLPhysicsShapeBuilderUtil::determinePhysicsShape( const LLPhysicsVolumePara
|
|||
specOut.mType = PhysicsShapeSpecification::USER_MESH;
|
||||
}
|
||||
}
|
||||
else if ( volume_params.isSculpt() )
|
||||
{
|
||||
else if ( volume_params.isSculpt() )
|
||||
{
|
||||
specOut.mType = PhysicsShapeSpecification::SCULPT;
|
||||
}
|
||||
else // Resort to mesh
|
||||
{
|
||||
specOut.mType = PhysicsShapeSpecification::PRIM_MESH;
|
||||
}
|
||||
}
|
||||
else // Resort to mesh
|
||||
{
|
||||
specOut.mType = PhysicsShapeSpecification::PRIM_MESH;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue