* Clean up the AlignedManifoldArray in KinematicCharacterController.
* Keep StaticObject collision flag for ghost object to prevent an assert from firing. * Keep GhostPairCallback alive until collision pairs are cleared. * Adjust KinematicCharacterController construction in CharacterDemo. * Fix up axis assignment in KinematicCharacterController.
This commit is contained in:
Родитель
a25ac01af1
Коммит
d723d3b850
|
@ -106,7 +106,7 @@ namespace BulletSharp
|
|||
}
|
||||
}
|
||||
|
||||
public class GhostPairCallback : OverlappingPairCallback
|
||||
public sealed class GhostPairCallback : OverlappingPairCallback
|
||||
{
|
||||
public GhostPairCallback()
|
||||
: base(ConstructionInfo.Null)
|
||||
|
|
|
@ -90,7 +90,7 @@ namespace BulletSharp
|
|||
public void SetInternalGhostPairCallback(OverlappingPairCallback ghostPairCallback)
|
||||
{
|
||||
_ghostPairCallback = ghostPairCallback;
|
||||
btOverlappingPairCache_setInternalGhostPairCallback(Native, ghostPairCallback.Native);
|
||||
btOverlappingPairCache_setInternalGhostPairCallback(Native, ghostPairCallback?.Native ?? IntPtr.Zero);
|
||||
}
|
||||
|
||||
public void SetOverlapFilterCallback(OverlapFilterCallback callback)
|
||||
|
|
|
@ -2,19 +2,21 @@ using BulletSharp.Math;
|
|||
|
||||
namespace BulletSharp
|
||||
{
|
||||
public interface ICharacterController : IAction
|
||||
{
|
||||
public interface ICharacterController : IAction
|
||||
{
|
||||
void SetWalkDirection(ref Vector3 walkDirection);
|
||||
void SetVelocityForTimeInterval(ref Vector3 velocity, float timeInterval);
|
||||
void Reset(CollisionWorld collisionWorld);
|
||||
void Warp(ref Vector3 origin);
|
||||
|
||||
void PreStep(CollisionWorld collisionWorld);
|
||||
|
||||
void PreStep(CollisionWorld collisionWorld);
|
||||
void PlayerStep(CollisionWorld collisionWorld, float deltaTime);
|
||||
bool CanJump { get; }
|
||||
void Jump(Vector3? dir = null);
|
||||
|
||||
bool OnGround { get; }
|
||||
void Jump();
|
||||
void Jump(ref Vector3 dir);
|
||||
|
||||
void SetUpInterpolate(bool value);
|
||||
}
|
||||
|
||||
bool OnGround { get; }
|
||||
bool CanJump { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
using BulletSharp.Math;
|
||||
using System;
|
||||
|
||||
namespace BulletSharp
|
||||
{
|
||||
public class KinematicCharacterController : ICharacterController
|
||||
public class KinematicCharacterController : ICharacterController, IDisposable
|
||||
{
|
||||
#region PROTECTED
|
||||
|
||||
protected float m_halfHeight;
|
||||
|
||||
protected PairCachingGhostObject m_ghostObject;
|
||||
|
@ -65,9 +64,7 @@ namespace BulletSharp
|
|||
protected bool full_drop;
|
||||
protected bool bounce_fix;
|
||||
|
||||
protected static Vector3[] upAxisDirection = { new Vector3(1, 0, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1) };
|
||||
|
||||
public static Vector3 GetNormalizedVector(ref Vector3 v)
|
||||
protected static Vector3 GetNormalizedVector(ref Vector3 v)
|
||||
{
|
||||
if (v.Length < MathUtil.SIMD_EPSILON)
|
||||
{
|
||||
|
@ -75,6 +72,7 @@ namespace BulletSharp
|
|||
}
|
||||
return Vector3.Normalize(v);
|
||||
}
|
||||
|
||||
protected Vector3 ComputeReflectionDirection(ref Vector3 direction, ref Vector3 normal)
|
||||
{
|
||||
float dot;
|
||||
|
@ -160,7 +158,7 @@ namespace BulletSharp
|
|||
}
|
||||
else
|
||||
{
|
||||
//printf("touching %f\n", dist);
|
||||
//System.Console.WriteLine("touching " + dist);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -170,7 +168,7 @@ namespace BulletSharp
|
|||
Matrix newTrans = m_ghostObject.WorldTransform;
|
||||
newTrans.Origin = m_currentPosition;
|
||||
m_ghostObject.WorldTransform = newTrans;
|
||||
// printf("m_touchingNormal = %f,%f,%f\n",m_touchingNormal[0],m_touchingNormal[1],m_touchingNormal[2]);
|
||||
//System.Console.WriteLine("m_touchingNormal = " + m_touchingNormal);
|
||||
return penetration;
|
||||
}
|
||||
|
||||
|
@ -197,7 +195,7 @@ namespace BulletSharp
|
|||
start.SetRotation(m_currentOrientation, out start);
|
||||
end.SetRotation(m_targetOrientation, out end);
|
||||
|
||||
using(KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback( m_ghostObject, -m_up, m_maxSlopeCosine ))
|
||||
using (KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, -m_up, m_maxSlopeCosine))
|
||||
{
|
||||
callback.CollisionFilterGroup = GhostObject.BroadphaseHandle.CollisionFilterGroup;
|
||||
callback.CollisionFilterMask = GhostObject.BroadphaseHandle.CollisionFilterMask;
|
||||
|
@ -237,7 +235,7 @@ namespace BulletSharp
|
|||
m_touchingContact = true;
|
||||
if (numPenetrationLoops > 4)
|
||||
{
|
||||
//printf("character could not recover from penetration = %d\n", numPenetrationLoops);
|
||||
//System.Console.WriteLine("character could not recover from penetration = " + numPenetrationLoops);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -275,42 +273,38 @@ namespace BulletSharp
|
|||
perpindicularDir = PerpindicularComponent(ref reflectDir, ref hitNormal);
|
||||
|
||||
m_targetPosition = m_currentPosition;
|
||||
/*
|
||||
if (false) //tangentMag != 0.0)
|
||||
if (false) //tangentMag != 0.0)
|
||||
{
|
||||
Vector3 parComponent = parallelDir * (tangentMag * movementLength);
|
||||
// printf("parComponent=%f,%f,%f\n",parComponent[0],parComponent[1],parComponent[2]);
|
||||
m_targetPosition += parComponent;
|
||||
//Vector3 parComponent = parallelDir * (tangentMag * movementLength);
|
||||
//System.Console.WriteLine("parComponent=" + parComponent);
|
||||
//m_targetPosition += parComponent;
|
||||
}
|
||||
*/
|
||||
|
||||
if (normalMag != 0.0f)
|
||||
{
|
||||
Vector3 perpComponent = perpindicularDir * (normalMag * movementLength);
|
||||
// printf("perpComponent=%f,%f,%f\n",perpComponent[0],perpComponent[1],perpComponent[2]);
|
||||
//System.Console.WriteLine("perpComponent=" + perpComponent);
|
||||
m_targetPosition += perpComponent;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// printf("movementLength don't normalize a zero vector\n");
|
||||
//System.Console.WriteLine("movementLength don't normalize a zero vector");
|
||||
}
|
||||
}
|
||||
|
||||
protected void StepForwardAndStrafe(CollisionWorld collisionWorld, ref Vector3 walkMove)
|
||||
{
|
||||
// printf("m_normalizedDirection=%f,%f,%f\n",
|
||||
// m_normalizedDirection[0],m_normalizedDirection[1],m_normalizedDirection[2]);
|
||||
//System.Console.WriteLine("m_normalizedDirection=" + m_normalizedDirection);
|
||||
// phase 2: forward and strafe
|
||||
Matrix start, end;
|
||||
Matrix start = Matrix.Identity;
|
||||
Matrix end = Matrix.Identity;
|
||||
|
||||
m_targetPosition = m_currentPosition + walkMove;
|
||||
|
||||
start = Matrix.Identity;
|
||||
end = Matrix.Identity;
|
||||
|
||||
float fraction = 1.0f;
|
||||
float distance2 = (m_currentPosition - m_targetPosition).LengthSquared;
|
||||
// printf("distance2=%f\n",distance2);
|
||||
//System.Console.WriteLine("distance2=" + distance2);
|
||||
|
||||
int maxIter = 10;
|
||||
|
||||
|
@ -323,7 +317,7 @@ namespace BulletSharp
|
|||
start.SetRotation(m_currentOrientation, out start);
|
||||
end.SetRotation(m_targetOrientation, out end);
|
||||
|
||||
using( KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback( m_ghostObject, sweepDirNegative, 0.0f ) )
|
||||
using (KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, sweepDirNegative, 0.0f))
|
||||
{
|
||||
callback.CollisionFilterGroup = GhostObject.BroadphaseHandle.CollisionFilterGroup;
|
||||
callback.CollisionFilterMask = GhostObject.BroadphaseHandle.CollisionFilterMask;
|
||||
|
@ -331,7 +325,7 @@ namespace BulletSharp
|
|||
float margin = m_convexShape.Margin;
|
||||
m_convexShape.Margin = margin + m_addedMargin;
|
||||
|
||||
if (!(start == end))
|
||||
if (start != end)
|
||||
{
|
||||
if (m_useGhostObjectSweepTest)
|
||||
{
|
||||
|
@ -349,12 +343,11 @@ namespace BulletSharp
|
|||
if (callback.HasHit && GhostObject.HasContactResponse && NeedsCollision(m_ghostObject, callback.HitCollisionObject))
|
||||
{
|
||||
// we moved only a fraction
|
||||
//btScalar hitDistance;
|
||||
//hitDistance = (callback.m_hitPointWorld - m_currentPosition).length();
|
||||
//float hitDistance = (callback.HitPointWorld - m_currentPosition).Length;
|
||||
|
||||
// m_currentPosition.setInterpolate3 (m_currentPosition, m_targetPosition, callback.m_closestHitFraction);
|
||||
Vector3 v = callback.HitNormalWorld;
|
||||
UpdateTargetPositionBasedOnCollision(ref v);
|
||||
//Vector3.Lerp(ref m_currentPosition, ref m_targetPosition, callback.ClosestHitFraction, out m_currentPosition);
|
||||
Vector3 hitNormalWorld = callback.HitNormalWorld;
|
||||
UpdateTargetPositionBasedOnCollision(ref hitNormalWorld);
|
||||
Vector3 currentDir = m_targetPosition - m_currentPosition;
|
||||
distance2 = currentDir.LengthSquared;
|
||||
if (distance2 > MathUtil.SIMD_EPSILON)
|
||||
|
@ -368,7 +361,7 @@ namespace BulletSharp
|
|||
}
|
||||
else
|
||||
{
|
||||
// printf("currentDir: don't normalize a zero vector\n");
|
||||
//System.Console.WriteLine("currentDir: don't normalize a zero vector");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -385,10 +378,10 @@ namespace BulletSharp
|
|||
bool runonce = false;
|
||||
|
||||
// phase 3: down
|
||||
/*btScalar additionalDownStep = (m_wasOnGround && !onGround()) ? m_stepHeight : 0.0;
|
||||
btVector3 step_drop = m_up * (m_currentStepOffset + additionalDownStep);
|
||||
btScalar downVelocity = (additionalDownStep == 0.0 && m_verticalVelocity<0.0?-m_verticalVelocity:0.0) * dt;
|
||||
btVector3 gravity_drop = m_up * downVelocity;
|
||||
/*float additionalDownStep = (m_wasOnGround && !OnGround) ? m_stepHeight : 0;
|
||||
Vector3 step_drop = m_up * (m_currentStepOffset + additionalDownStep);
|
||||
float downVelocity = (additionalDownStep == 0.0 && m_verticalVelocity < 0 ? -m_verticalVelocity : 0) * dt;
|
||||
Vector3 gravity_drop = m_up * downVelocity;
|
||||
m_targetPosition -= (step_drop + gravity_drop);*/
|
||||
|
||||
Vector3 orig_position = m_targetPosition;
|
||||
|
@ -404,8 +397,8 @@ namespace BulletSharp
|
|||
Vector3 step_drop = m_up * (m_currentStepOffset + downVelocity);
|
||||
m_targetPosition -= step_drop;
|
||||
|
||||
using( KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback( m_ghostObject, m_up, m_maxSlopeCosine ) )
|
||||
using( KinematicClosestNotMeConvexResultCallback callback2 = new KinematicClosestNotMeConvexResultCallback( m_ghostObject, m_up, m_maxSlopeCosine ) )
|
||||
using (KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, m_up, m_maxSlopeCosine))
|
||||
using (KinematicClosestNotMeConvexResultCallback callback2 = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, m_up, m_maxSlopeCosine))
|
||||
{
|
||||
callback.CollisionFilterGroup = GhostObject.BroadphaseHandle.CollisionFilterGroup;
|
||||
callback.CollisionFilterMask = GhostObject.BroadphaseHandle.CollisionFilterMask;
|
||||
|
@ -415,19 +408,14 @@ namespace BulletSharp
|
|||
|
||||
while (true)
|
||||
{
|
||||
start = Matrix.Identity;
|
||||
end = Matrix.Identity;
|
||||
|
||||
end_double = Matrix.Identity;
|
||||
|
||||
start.Origin = m_currentPosition;
|
||||
end.Origin = m_targetPosition;
|
||||
Matrix.Translation(ref m_currentPosition, out start);
|
||||
Matrix.Translation(ref m_targetPosition, out end);
|
||||
|
||||
start.SetRotation(m_currentOrientation, out start);
|
||||
end.SetRotation(m_targetOrientation, out end);
|
||||
|
||||
//set double test for 2x the step drop, to check for a large drop vs small drop
|
||||
end_double.Origin = m_targetPosition - step_drop;
|
||||
end_double = Matrix.Translation(m_targetPosition - step_drop);
|
||||
|
||||
if (m_useGhostObjectSweepTest)
|
||||
{
|
||||
|
@ -482,7 +470,7 @@ namespace BulletSharp
|
|||
// we dropped a fraction of the height -> hit floor
|
||||
float fraction = (m_currentPosition.Y - callback.HitPointWorld.Y) / 2;
|
||||
|
||||
//printf("hitpoint: %g - pos %g\n", callback.m_hitPointWorld.getY(), m_currentPosition.getY());
|
||||
//System.Console.WriteLine("hitpoint: {0} - pos {1}", callback.HitPointWorld.Y, m_currentPosition.Y);
|
||||
|
||||
if (bounce_fix == true)
|
||||
{
|
||||
|
@ -518,21 +506,21 @@ namespace BulletSharp
|
|||
m_targetPosition -= step_drop;
|
||||
}
|
||||
}
|
||||
//printf("full drop - %g, %g\n", m_currentPosition.getY(), m_targetPosition.getY());
|
||||
//System.Console.WriteLine("full drop - {0}, {1}", m_currentPosition.Y, m_targetPosition.Y);
|
||||
|
||||
m_currentPosition = m_targetPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual bool NeedsCollision( CollisionObject body0, CollisionObject body1 )
|
||||
protected virtual bool NeedsCollision(CollisionObject body0, CollisionObject body1)
|
||||
{
|
||||
bool collides = (body0.BroadphaseHandle.CollisionFilterGroup & body1.BroadphaseHandle.CollisionFilterMask) != 0;
|
||||
collides = collides && (body1.BroadphaseHandle.CollisionFilterGroup & body0.BroadphaseHandle.CollisionFilterMask) != 0;
|
||||
return collides;
|
||||
}
|
||||
|
||||
protected void SetUpVector( ref Vector3 up )
|
||||
protected void SetUpVector(ref Vector3 up)
|
||||
{
|
||||
if (m_up == up)
|
||||
return;
|
||||
|
@ -566,70 +554,51 @@ namespace BulletSharp
|
|||
return MathUtil.ShortestArcQuat(ref v0, ref v1);
|
||||
}
|
||||
|
||||
#endregion // PROTECTED
|
||||
|
||||
#region PUBLIC
|
||||
|
||||
public KinematicCharacterController(PairCachingGhostObject ghostObject, ConvexShape convexShape, float stepHeight, ref Vector3 up)
|
||||
{
|
||||
m_ghostObject = ghostObject;
|
||||
m_up = new Vector3(0.0f, 0.0f, 1.0f);
|
||||
m_jumpAxis = new Vector3(0.0f, 0.0f, 1.0f);
|
||||
m_addedMargin = 0.02f;
|
||||
m_walkDirection = new Vector3(0.0f, 0.0f, 0.0f);
|
||||
m_AngVel = new Vector3(0.0f, 0.0f, 0.0f);
|
||||
m_useGhostObjectSweepTest = true;
|
||||
m_turnAngle = 0.0f;
|
||||
m_convexShape = convexShape;
|
||||
m_useWalkDirection = true; // use walk direction by default, legacy behavior
|
||||
m_velocityTimeInterval = 0.0f;
|
||||
m_verticalVelocity = 0.0f;
|
||||
m_verticalOffset = 0.0f;
|
||||
m_gravity = 9.8f * 3.0f; // 3G acceleration.
|
||||
m_fallSpeed = 55.0f; // Terminal velocity of a sky diver in m/s.
|
||||
m_jumpSpeed = 10.0f; // ?
|
||||
m_SetjumpSpeed = m_jumpSpeed;
|
||||
m_wasOnGround = false;
|
||||
m_wasJumping = false;
|
||||
m_interpolateUp = true;
|
||||
m_currentStepOffset = 0.0f;
|
||||
m_maxPenetrationDepth = 0.2f;
|
||||
full_drop = false;
|
||||
bounce_fix = false;
|
||||
m_linearDamping = 0.0f;
|
||||
m_angularDamping = 0.0f;
|
||||
|
||||
Up = up;
|
||||
StepHeight = stepHeight;
|
||||
MaxSlope = MathUtil.DegToRadians(45.0f);
|
||||
}
|
||||
|
||||
///btActionInterface interface
|
||||
// IAction interface
|
||||
public virtual void UpdateAction(CollisionWorld collisionWorld, float deltaTime)
|
||||
{
|
||||
PreStep(collisionWorld);
|
||||
PlayerStep(collisionWorld, deltaTime);
|
||||
}
|
||||
|
||||
///btActionInterface interface
|
||||
// IAction interface
|
||||
public void DebugDraw(DebugDraw debugDrawer)
|
||||
{
|
||||
}
|
||||
|
||||
public Vector3 Up
|
||||
{
|
||||
get => m_up;
|
||||
set
|
||||
{
|
||||
Vector3 up = value;
|
||||
if (up.LengthSquared > 0 && m_gravity > 0.0f)
|
||||
if (value.LengthSquared > 0 && m_gravity > 0.0f)
|
||||
{
|
||||
Gravity = -m_gravity * Vector3.Normalize(up);
|
||||
Gravity = -m_gravity * Vector3.Normalize(value);
|
||||
return;
|
||||
}
|
||||
|
||||
SetUpVector(ref up);
|
||||
SetUpVector(ref value);
|
||||
}
|
||||
get => m_up;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -640,6 +609,7 @@ namespace BulletSharp
|
|||
/// This call will reset any velocity set by setVelocityForTimeInterval().
|
||||
/// </summary>
|
||||
public virtual void SetWalkDirection(Vector3 walkDirection) => SetWalkDirection(ref walkDirection);
|
||||
|
||||
public virtual void SetWalkDirection(ref Vector3 walkDirection)
|
||||
{
|
||||
m_useWalkDirection = true;
|
||||
|
@ -655,27 +625,28 @@ namespace BulletSharp
|
|||
/// Negative time intervals will result in no motion.
|
||||
/// </summary>
|
||||
public void SetVelocityForTimeInterval(Vector3 velocity, float timeInterval) => SetVelocityForTimeInterval(ref velocity, timeInterval);
|
||||
|
||||
public virtual void SetVelocityForTimeInterval(ref Vector3 velocity, float timeInterval)
|
||||
{
|
||||
// printf("setVelocity!\n");
|
||||
// printf(" interval: %f\n", timeInterval);
|
||||
// printf(" velocity: (%f, %f, %f)\n",
|
||||
// velocity.x(), velocity.y(), velocity.z());
|
||||
//System.Console.WriteLine("SetVelocity!");
|
||||
//System.Console.WriteLine(" interval: " + timeInterval);
|
||||
//System.Console.WriteLine(" velocity: " + velocity);
|
||||
|
||||
m_useWalkDirection = false;
|
||||
m_walkDirection = velocity;
|
||||
m_normalizedDirection = GetNormalizedVector(ref m_walkDirection);
|
||||
m_normalizedDirection = GetNormalizedVector(ref m_walkDirection);
|
||||
m_velocityTimeInterval = timeInterval;
|
||||
}
|
||||
|
||||
public virtual Vector3 AngularVelocity
|
||||
{
|
||||
set => m_AngVel = value;
|
||||
get => m_AngVel;
|
||||
set => m_AngVel = value;
|
||||
}
|
||||
|
||||
public virtual Vector3 LinearVelocity
|
||||
{
|
||||
get => m_walkDirection + (m_verticalVelocity * m_up);
|
||||
set
|
||||
{
|
||||
Vector3 velocity = value;
|
||||
|
@ -684,7 +655,7 @@ namespace BulletSharp
|
|||
// HACK: if we are moving in the direction of the up, treat it as a jump :(
|
||||
if (m_walkDirection.LengthSquared > 0)
|
||||
{
|
||||
Vector3 w = Vector3.Normalize( velocity );
|
||||
Vector3 w = Vector3.Normalize(velocity);
|
||||
float c = w.Dot(m_up);
|
||||
if (c != 0)
|
||||
{
|
||||
|
@ -703,18 +674,18 @@ namespace BulletSharp
|
|||
else
|
||||
m_verticalVelocity = 0.0f;
|
||||
}
|
||||
get => m_walkDirection + (m_verticalVelocity * m_up);
|
||||
}
|
||||
|
||||
public float LinearDamping
|
||||
{
|
||||
set => m_linearDamping = value > 1f ? 1f : value < 0f ? 0f : value;
|
||||
get => m_linearDamping;
|
||||
set => m_linearDamping = value > 1f ? 1f : value < 0f ? 0f : value;
|
||||
}
|
||||
|
||||
public float AngularDamping
|
||||
{
|
||||
set => m_angularDamping = value > 1f ? 1f : value < 0f ? 0f : value;
|
||||
get => m_angularDamping;
|
||||
set => m_angularDamping = value > 1f ? 1f : value < 0f ? 0f : value;
|
||||
}
|
||||
|
||||
public void Reset(CollisionWorld collisionWorld)
|
||||
|
@ -745,16 +716,17 @@ namespace BulletSharp
|
|||
public void PreStep(CollisionWorld collisionWorld)
|
||||
{
|
||||
m_currentPosition = m_ghostObject.WorldTransform.Origin;
|
||||
m_targetPosition = m_currentPosition;
|
||||
m_targetPosition = m_currentPosition;
|
||||
|
||||
m_ghostObject.WorldTransform.Decompose( out _, out m_currentOrientation, out _ );
|
||||
m_targetOrientation = m_currentOrientation;
|
||||
// printf("m_targetPosition=%f,%f,%f\n",m_targetPosition[0],m_targetPosition[1],m_targetPosition[2]);
|
||||
m_ghostObject.WorldTransform.Decompose(out _, out m_currentOrientation, out _);
|
||||
m_targetOrientation = m_currentOrientation;
|
||||
//System.Console.WriteLine("m_targetPosition=" + m_targetPosition);
|
||||
}
|
||||
|
||||
public void PlayerStep(CollisionWorld collisionWorld, float dt)
|
||||
{
|
||||
// printf("playerStep(): ");
|
||||
// printf(" dt = %f", dt);
|
||||
//System.Console.WriteLine("PlayerStep():");
|
||||
//System.Console.WriteLine(" dt = " + dt);
|
||||
|
||||
if (m_AngVel.LengthSquared > 0.0f)
|
||||
{
|
||||
|
@ -783,7 +755,7 @@ namespace BulletSharp
|
|||
// quick check...
|
||||
if (!m_useWalkDirection && (m_velocityTimeInterval <= 0.0))
|
||||
{
|
||||
// printf("\n");
|
||||
//System.Console.WriteLine();
|
||||
return; // no motion
|
||||
}
|
||||
|
||||
|
@ -814,8 +786,8 @@ namespace BulletSharp
|
|||
|
||||
xform = m_ghostObject.WorldTransform;
|
||||
|
||||
// printf("walkDirection(%f,%f,%f)\n",walkDirection[0],walkDirection[1],walkDirection[2]);
|
||||
// printf("walkSpeed=%f\n",walkSpeed);
|
||||
//System.Console.WriteLine("walkDirection=" + m_walkDirection);
|
||||
//System.Console.WriteLine("walkSpeed=" + walkSpeed);
|
||||
|
||||
StepUp(collisionWorld);
|
||||
//todo: Experimenting with behavior of controller when it hits a ceiling..
|
||||
|
@ -842,7 +814,7 @@ namespace BulletSharp
|
|||
}
|
||||
else
|
||||
{
|
||||
//printf(" time: %f", m_velocityTimeInterval);
|
||||
//System.Console.WriteLine(" time: " + m_velocityTimeInterval);
|
||||
// still have some time left for moving!
|
||||
float dtMoving =
|
||||
(dt < m_velocityTimeInterval) ? dt : m_velocityTimeInterval;
|
||||
|
@ -851,7 +823,7 @@ namespace BulletSharp
|
|||
// how far will we move while we are moving?
|
||||
Vector3 move = m_walkDirection * dtMoving;
|
||||
|
||||
//printf(" dtMoving: %f", dtMoving);
|
||||
//System.Console.WriteLine(" dtMoving: " + dtMoving);
|
||||
|
||||
// okay, step
|
||||
StepForwardAndStrafe(collisionWorld, ref move);
|
||||
|
@ -873,7 +845,7 @@ namespace BulletSharp
|
|||
// m_verticalVelocity = 0.0;
|
||||
// }
|
||||
//}
|
||||
// printf("\n");
|
||||
//System.Console.WriteLine();
|
||||
|
||||
xform.Origin = m_currentPosition;
|
||||
m_ghostObject.WorldTransform = xform;
|
||||
|
@ -886,7 +858,7 @@ namespace BulletSharp
|
|||
m_touchingContact = true;
|
||||
if (numPenetrationLoops > 4)
|
||||
{
|
||||
//printf("character could not recover from penetration = %d\n", numPenetrationLoops);
|
||||
//System.Console.WriteLine("character could not recover from penetration, numPenetrationLoops=" + numPenetrationLoops);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -894,48 +866,61 @@ namespace BulletSharp
|
|||
|
||||
public float StepHeight
|
||||
{
|
||||
set => m_stepHeight = value;
|
||||
get => m_stepHeight;
|
||||
set => m_stepHeight = value;
|
||||
}
|
||||
|
||||
public float FallSpeed
|
||||
{
|
||||
set => m_fallSpeed = value;
|
||||
get => m_fallSpeed;
|
||||
set => m_fallSpeed = value;
|
||||
}
|
||||
|
||||
public float JumpSpeed
|
||||
{
|
||||
set => m_SetjumpSpeed = m_jumpSpeed = value;
|
||||
get => m_jumpSpeed;
|
||||
set => m_SetjumpSpeed = m_jumpSpeed = value;
|
||||
}
|
||||
|
||||
public void SetMaxJumpHeight(float maxJumpHeight) => m_maxJumpHeight = maxJumpHeight;
|
||||
public bool CanJump => OnGround;
|
||||
|
||||
public void Jump(Vector3? _temp = null)
|
||||
public void Jump()
|
||||
{
|
||||
Vector3 v = _temp ?? Vector3.Zero;
|
||||
m_jumpSpeed = v.LengthSquared == 0 ? m_SetjumpSpeed : v.Length;
|
||||
m_jumpSpeed = m_SetjumpSpeed;
|
||||
m_verticalVelocity = m_jumpSpeed;
|
||||
m_wasJumping = true;
|
||||
|
||||
m_jumpAxis = v.LengthSquared == 0 ? m_up : Vector3.Normalize(v);
|
||||
m_jumpAxis = m_up;
|
||||
|
||||
m_jumpPosition = m_ghostObject.WorldTransform.Origin;
|
||||
}
|
||||
|
||||
public void Jump(ref Vector3 dir)
|
||||
{
|
||||
m_jumpSpeed = dir.Length;
|
||||
m_verticalVelocity = m_jumpSpeed;
|
||||
m_wasJumping = true;
|
||||
|
||||
m_jumpAxis = Vector3.Normalize(dir);
|
||||
|
||||
m_jumpPosition = m_ghostObject.WorldTransform.Origin;
|
||||
|
||||
#if false
|
||||
currently no jumping.
|
||||
btTransform xform;
|
||||
m_rigidBody->getMotionState()->getWorldTransform (xform);
|
||||
btVector3 up = xform.getBasis()[1];
|
||||
up.normalize ();
|
||||
btScalar magnitude = (btScalar(1.0)/m_rigidBody->getInvMass()) * btScalar(8.0);
|
||||
#if false
|
||||
// currently no jumping.
|
||||
Matrix xform;
|
||||
m_rigidBody.getMotionState()->getWorldTransform (xform);
|
||||
Vector3 up = xform.Basis[1];
|
||||
up.Normalize();
|
||||
float magnitude = (btScalar(1.0)/m_rigidBody->getInvMass()) * 8.0f;
|
||||
m_rigidBody->applyCentralImpulse (up * magnitude);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calls Jump()
|
||||
/// </summary>
|
||||
public void ApplyImpulse( ref Vector3 v ) => Jump( v );
|
||||
public void ApplyImpulse(ref Vector3 dir) => Jump(ref dir);
|
||||
|
||||
public Vector3 Gravity
|
||||
{
|
||||
|
@ -962,7 +947,7 @@ namespace BulletSharp
|
|||
set
|
||||
{
|
||||
m_maxSlopeRadians = value;
|
||||
m_maxSlopeCosine = (float)System.Math.Cos(value);
|
||||
m_maxSlopeCosine = (float)System.Math.Cos(value);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -973,18 +958,37 @@ namespace BulletSharp
|
|||
}
|
||||
|
||||
public PairCachingGhostObject GhostObject => m_ghostObject;
|
||||
|
||||
public void SetUseGhostSweepTest(bool useGhostObjectSweepTest)
|
||||
{
|
||||
m_useGhostObjectSweepTest = useGhostObjectSweepTest;
|
||||
}
|
||||
|
||||
public bool OnGround => ((m_verticalVelocity < 0 ? -m_verticalVelocity : m_verticalVelocity) < MathUtil.SIMD_EPSILON) && ((m_verticalOffset < 0 ? -m_verticalOffset : m_verticalOffset) < MathUtil.SIMD_EPSILON);
|
||||
public bool OnGround => System.Math.Abs(m_verticalVelocity) < MathUtil.SIMD_EPSILON && System.Math.Abs(m_verticalOffset) < MathUtil.SIMD_EPSILON;
|
||||
|
||||
public void SetUpInterpolate(bool v)
|
||||
{
|
||||
m_interpolateUp = v;
|
||||
}
|
||||
|
||||
#endregion
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
m_manifoldArray.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
~KinematicCharacterController()
|
||||
{
|
||||
Dispose(false);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
|
||||
///@todo Interact with dynamic objects,
|
||||
|
|
|
@ -1148,13 +1148,13 @@ namespace BulletSharp
|
|||
Vector3 ya = new Vector3(y.X, 0, y.Z);
|
||||
return (xa - ya).LengthSquared;
|
||||
}
|
||||
|
||||
|
||||
public static void SetRotation(this Matrix matrix, Quaternion newRotation, out Matrix result)
|
||||
{
|
||||
matrix.Decompose(out Vector3 scale, out _, out Vector3 translation);
|
||||
result = Matrix.Scaling(scale) * Matrix.RotationQuaternion(newRotation) * Matrix.Translation(translation);
|
||||
}
|
||||
|
||||
|
||||
public static Quaternion GetRotation(this Matrix matrix)
|
||||
{
|
||||
matrix.Decompose(out _, out Quaternion rot, out _);
|
||||
|
|
|
@ -144,11 +144,13 @@ namespace CharacterDemo
|
|||
|
||||
public void Dispose()
|
||||
{
|
||||
_ghostPairCallback.Dispose();
|
||||
CameraSphere.Dispose();
|
||||
ConvexResultCallback.Dispose();
|
||||
Character.Dispose();
|
||||
|
||||
this.StandardCleanup();
|
||||
|
||||
_ghostPairCallback.Dispose();
|
||||
}
|
||||
|
||||
private void CreateCharacter()
|
||||
|
@ -162,13 +164,14 @@ namespace CharacterDemo
|
|||
GhostObject = new PairCachingGhostObject()
|
||||
{
|
||||
CollisionShape = capsule,
|
||||
CollisionFlags = CollisionFlags.CharacterObject,
|
||||
WorldTransform = Matrix.Translation(10.210098f, -1.6433364f, 16.453260f)
|
||||
};
|
||||
GhostObject.CollisionFlags |= CollisionFlags.CharacterObject;
|
||||
World.AddCollisionObject(GhostObject, CollisionFilterGroups.CharacterFilter, CollisionFilterGroups.StaticFilter | CollisionFilterGroups.DefaultFilter);
|
||||
|
||||
const float stepHeight = 0.35f;
|
||||
Character = new KinematicCharacterController(GhostObject, capsule, stepHeight);
|
||||
Vector3 up = Vector3.UnitY;
|
||||
Character = new KinematicCharacterController(GhostObject, capsule, stepHeight, ref up);
|
||||
World.AddAction(Character);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -154,6 +154,14 @@ namespace DemoFramework
|
|||
_bodyPicker.RemovePickingConstraint();
|
||||
Simulation.Dispose();
|
||||
_boxShooter.Dispose();
|
||||
|
||||
if (BulletObjectTracker.Current != null)
|
||||
{
|
||||
if (BulletObjectTracker.Current.UserOwnedObjects.Count != 0)
|
||||
{
|
||||
throw new Exception("Bullet has active objects that were not disposed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void Run()
|
||||
|
|
|
@ -21,14 +21,6 @@ namespace DemoFramework
|
|||
simulation.Broadphase.Dispose();
|
||||
simulation.Dispatcher.Dispose();
|
||||
simulation.CollisionConfiguration.Dispose();
|
||||
|
||||
if (BulletObjectTracker.Current != null)
|
||||
{
|
||||
if (BulletObjectTracker.Current.UserOwnedObjects.Count != 0)
|
||||
{
|
||||
throw new Exception("Bullet has active objects that were not disposed.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void CleanupConstraints(DynamicsWorld world)
|
||||
|
|
Загрузка…
Ссылка в новой задаче