本文整理汇总了C++中NxVec3::isZero方法的典型用法代码示例。如果您正苦于以下问题:C++ NxVec3::isZero方法的具体用法?C++ NxVec3::isZero怎么用?C++ NxVec3::isZero使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类NxVec3
的用法示例。
在下文中一共展示了NxVec3::isZero方法的3个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: sweepTest
void PxSingleActor::sweepTest( MatrixF *mat )
{
NxVec3 nxCurrPos = getPosition();
// If the position is zero,
// the parent hasn't been updated yet
// and we don't even need to do the sweep test.
// This is a fix for a problem that was happening
// where on the add of the PxSingleActor, it would
// set the position to a very small value because it would be getting a hit
// even though the current position was 0.
if ( nxCurrPos.isZero() )
return;
// Set up the flags and the query structure.
NxU32 flags = NX_SF_STATICS | NX_SF_DYNAMICS;
NxSweepQueryHit sweepResult;
dMemset( &sweepResult, 0, sizeof( sweepResult ) );
NxVec3 nxNewPos = mat->getPosition();
// Get the velocity which will be our sweep direction and distance.
NxVec3 nxDir = nxNewPos - nxCurrPos;
if ( nxDir.isZero() )
return;
// Get the scene and do the sweep.
mActor->wakeUp();
mActor->linearSweep( nxDir, flags, NULL, 1, &sweepResult, NULL );
if ( sweepResult.hitShape && sweepResult.t < nxDir.magnitude() )
{
nxDir.normalize();
nxDir *= sweepResult.t;
nxCurrPos += nxDir;
mat->setPosition( Point3F( nxCurrPos.x, nxCurrPos.y, nxCurrPos.z ) );
}
}
示例2: MoveCharacter
// Using swept code & direct position update (no physics engine)
// This function is the generic character controller logic, valid for all swept volumes
void SweepTest::MoveCharacter(
void* user_data,
void* user_data2,
SweptVolume& volume,
const NxVec3& direction,
NxU32 nb_boxes, const NxExtendedBounds3* boxes, const void** box_user_data,
NxU32 nb_capsules, const NxExtendedCapsule* capsules, const void** capsule_user_data,
NxU32 groups, float min_dist,
NxU32& collision_flags,
const NxGroupsMask* groupsMask,
bool constrainedClimbingMode
)
{
mHitNonWalkable = false;
NxU32 CollisionFlags = 0;
const NxU32 MaxIter = mMaxIter; // 1 for "collide and stop"
const NxU32 MaxIterUp = MaxIter;
const NxU32 MaxIterSides = MaxIter;
// const NxU32 MaxIterDown = gWalkExperiment ? MaxIter : 1;
const NxU32 MaxIterDown = 1;
// ### this causes the artificial gap on top of chars
float StepOffset = mStepOffset; // Default step offset can be cancelled in some cases.
// Save initial height
Extended OriginalHeight = volume.mCenter[mUpDirection];
Extended OriginalBottomPoint = OriginalHeight - volume.mHalfHeight; // UBI
// TEST! Disable auto-step when flying. Not sure this is really useful.
if(direction[mUpDirection]>0.0f)
StepOffset = 0.0f;
// Decompose motion into 3 independent motions: up, side, down
// - if the motion is purely down (gravity only), the up part is needed to fight accuracy issues. For example if the
// character is already touching the geometry a bit, the down sweep test might have troubles. If we first move it above
// the geometry, the problems disappear.
// - if the motion is lateral (character moving forward under normal gravity) the decomposition provides the autostep feature
// - if the motion is purely up, the down part can be skipped
NxVec3 UpVector(0.0f, 0.0f, 0.0f);
NxVec3 DownVector(0.0f, 0.0f, 0.0f);
if(direction[mUpDirection]<0.0f) DownVector[mUpDirection] = direction[mUpDirection];
else UpVector[mUpDirection] = direction[mUpDirection];
NxVec3 SideVector = direction;
SideVector[mUpDirection] = 0.0f;
// If the side motion is zero, i.e. if the character is not really moving, disable auto-step.
if(!SideVector.isZero())
UpVector[mUpDirection] += StepOffset;
// ==========[ Initial volume query ]===========================
if(1)
{
NxVec3 MotionExtents = UpVector;
MotionExtents.max(SideVector);
MotionExtents.max(DownVector);
NxExtendedBounds3 TemporalBox;
volume.ComputeTemporalBox(*this, TemporalBox, volume.mCenter, MotionExtents);
// Gather touched geoms
UpdateTouchedGeoms(user_data, volume,
nb_boxes, boxes, box_user_data,
nb_capsules, capsules, capsule_user_data,
groups, TemporalBox, groupsMask);
}
// ==========[ UP PASS ]===========================
mCachedTriIndexIndex = 0;
const bool PerformUpPass = true;
NxU32 NbCollisions=0;
if(PerformUpPass)
{
// Prevent user callback for up motion. This up displacement is artificial, and only needed for auto-stepping.
// If we call the user for this, we might eventually apply upward forces to objects resting on top of us, even
// if we visually don't move. This produces weird-looking motions.
mValidateCallback = false;
// In the walk-experiment we explicitely want to ban any up motions, to avoid characters climbing slopes they shouldn't climb.
// So let's bypass the whole up pass.
if(!mWalkExperiment)
{
// ### MaxIter here seems to "solve" the V bug
if(DoSweepTest(user_data,
user_data2,
nb_boxes, boxes, box_user_data,
nb_capsules, capsules, capsule_user_data,
volume, UpVector, MaxIterUp, &NbCollisions, groups, min_dist, groupsMask))
{
if(NbCollisions)
{
CollisionFlags |= NXCC_COLLISION_UP;
// Clamp step offset to make sure we don't undo more than what we did
//.........这里部分代码省略.........
示例3: DoSweepTest
// This is the generic sweep test for all swept volumes, but not character-controller specific
bool SweepTest::DoSweepTest(void* user_data,
void* user_data2,
NxU32 nb_boxes, const NxExtendedBounds3* boxes, const void** box_user_data,
NxU32 nb_capsules, const NxExtendedCapsule* capsules, const void** capsule_user_data,
SweptVolume& swept_volume,
const NxVec3& direction, NxU32 max_iter, NxU32* nb_collisions,
NxU32 group_flags, float min_dist, const NxGroupsMask* groupsMask, bool down_pass)
{
// Early exit when motion is zero. Since the motion is decomposed into several vectors
// and this function is called for each of them, it actually happens quite often.
if(direction.isZero())
return false;
bool HasMoved = false;
mValidTri = false;
NxExtendedVec3 CurrentPosition = swept_volume.mCenter;
NxExtendedVec3 TargetPosition = swept_volume.mCenter;
TargetPosition += direction;
NxU32 NbCollisions = 0;
while(max_iter--)
{
gNbIters++;
// Compute current direction
NxVec3 CurrentDirection = TargetPosition - CurrentPosition;
// Make sure the new TBV is still valid
{
// Compute temporal bounding box. We could use a capsule or an OBB instead:
// - the volume would be smaller
// - but the query would be slower
// Overall it's unclear whether it's worth it or not.
// TODO: optimize this part ?
NxExtendedBounds3 TemporalBox;
swept_volume.ComputeTemporalBox(*this, TemporalBox, CurrentPosition, CurrentDirection);
// Gather touched geoms
UpdateTouchedGeoms(user_data, swept_volume,
nb_boxes, boxes, box_user_data,
nb_capsules, capsules, capsule_user_data,
group_flags, TemporalBox, groupsMask);
}
const float Length = CurrentDirection.magnitude();
if(Length<min_dist) break;
CurrentDirection /= Length;
// From Quake2: "if velocity is against the original velocity, stop dead to avoid tiny occilations in sloping corners"
if((CurrentDirection|direction) <= 0.0f) break;
// From this point, we're going to update the position at least once
HasMoved = true;
// Find closest collision
SweptContact C;
C.mDistance = Length + mSkinWidth;
if(!CollideGeoms(this, swept_volume, mGeomStream, CurrentPosition, CurrentDirection, C))
{
// no collision found => move to desired position
CurrentPosition = TargetPosition;
break;
}
ASSERT(C.mGeom); // If we reach this point, we must have touched a geom
if(C.mGeom->mType==TOUCHED_USER_BOX || C.mGeom->mType==TOUCHED_USER_CAPSULE)
{
// We touched a user object, typically another CCT
if(mValidateCallback) UserHitCallback(user_data2, C, CurrentDirection, Length);
// Trying to solve the following problem:
// - by default, the CCT "friction" is infinite, i.e. a CCT will not slide on a slope (this is by design)
// - this produces bad results when a capsule CCT stands on top of another capsule CCT, without sliding. Visually it looks
// like the character is standing on the other character's head, it looks bad. So, here, we would like to let the CCT
// slide away, i.e. we don't want friction.
// So here we simply increase the number of iterations (== let the CCT slide) when the first down collision is with another CCT.
if(down_pass && !NbCollisions)
max_iter += 9;
}
else
{
// We touched a normal object
#ifdef USE_CONTACT_NORMAL_FOR_SLOPE_TEST
mValidTri = true;
mCN = C.mWorldNormal;
#else
if(C.mIndex!=INVALID_ID)
{
mValidTri = true;
mTouched = mWorldTriangles[C.mIndex];
}
#endif
{
if(mValidateCallback) ShapeHitCallback(user_data2, C, CurrentDirection, Length);
}
}
//.........这里部分代码省略.........