Example #1
0
        protected void StepDown(CollisionWorld collisionWorld, float dt)
        {
            IndexedMatrix start = IndexedMatrix.Identity, end = IndexedMatrix.Identity;

            // phase 3: down

            /*float additionalDownStep = (m_wasOnGround && !onGround()) ? m_stepHeight : 0.0;
             * btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + additionalDownStep);
             * float downVelocity = (additionalDownStep == 0.0 && m_verticalVelocity<0.0?-m_verticalVelocity:0.0) * dt;
             * btVector3 gravity_drop = getUpAxisDirections()[m_upAxis] * downVelocity;
             * m_targetPosition -= (step_drop + gravity_drop);*/

            float downVelocity = (m_verticalVelocity < 0.0f ? -m_verticalVelocity : 0.0f) * dt;

            if (downVelocity > 0.0 && downVelocity < m_stepHeight &&
                (m_wasOnGround || !m_wasJumping))
            {
                downVelocity = m_stepHeight;
            }

            IndexedVector3 step_drop = upAxisDirection[m_upAxis] * (m_currentStepOffset + downVelocity);

            m_targetPosition -= step_drop;

            start._origin = m_currentPosition;
            end._origin   = m_targetPosition;

            KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, upAxisDirection[m_upAxis], m_maxSlopeCosine);

            callback.m_collisionFilterGroup = GetGhostObject().GetBroadphaseHandle().m_collisionFilterGroup;
            callback.m_collisionFilterMask  = GetGhostObject().GetBroadphaseHandle().m_collisionFilterMask;

            if (m_useGhostObjectSweepTest)
            {
                // this doesn't work....
                m_ghostObject.ConvexSweepTest(m_convexShape, ref start, ref end, callback, collisionWorld.GetDispatchInfo().GetAllowedCcdPenetration());
            }
            else
            {
                // this works....
                collisionWorld.ConvexSweepTest(m_convexShape, start, end, callback, collisionWorld.GetDispatchInfo().GetAllowedCcdPenetration());
            }

            if (callback.HasHit())
            {
                // we dropped a fraction of the height -> hit floor
                m_currentPosition  = MathUtil.Interpolate3(ref m_currentPosition, ref m_targetPosition, callback.m_closestHitFraction);
                m_verticalVelocity = 0.0f;
                m_verticalOffset   = 0.0f;
                m_wasJumping       = false;
            }
            else
            {
                // we dropped the full height
                m_currentPosition = m_targetPosition;
            }
        }
Example #2
0
        protected void StepUp(CollisionWorld collisionWorld)
        {
            // phase 1: up
            IndexedMatrix start = IndexedMatrix.Identity, end = IndexedMatrix.Identity;

            m_targetPosition = m_currentPosition + upAxisDirection[m_upAxis] * (m_stepHeight + (m_verticalOffset > 0.0f ? m_verticalOffset : 0.0f));


            /* FIXME: Handle penetration properly */
            start._origin = (m_currentPosition + upAxisDirection[m_upAxis] * (m_convexShape.GetMargin() + m_addedMargin));
            end._origin   = (m_targetPosition);

            KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, -upAxisDirection[m_upAxis], 0.7071f);

            callback.m_collisionFilterGroup = GetGhostObject().GetBroadphaseHandle().m_collisionFilterGroup;
            callback.m_collisionFilterMask  = GetGhostObject().GetBroadphaseHandle().m_collisionFilterMask;

            if (m_useGhostObjectSweepTest)
            {
                m_ghostObject.ConvexSweepTest(m_convexShape, ref start, ref end, callback, collisionWorld.GetDispatchInfo().GetAllowedCcdPenetration());
            }
            else
            {
                collisionWorld.ConvexSweepTest(m_convexShape, ref start, ref end, callback, 0f);
            }

            if (callback.HasHit())
            {
                // Only modify the position if the hit was a slope and not a wall or ceiling.
                if (IndexedVector3.Dot(callback.m_hitNormalWorld, upAxisDirection[m_upAxis]) > 0.0)
                {
                    // we moved up only a fraction of the step height
                    m_currentStepOffset = m_stepHeight * callback.m_closestHitFraction;
                    m_currentPosition   = MathUtil.Interpolate3(ref m_currentPosition, ref m_targetPosition, callback.m_closestHitFraction);
                }
                m_verticalVelocity = 0.0f;
                m_verticalOffset   = 0.0f;
            }
            else
            {
                m_currentStepOffset = m_stepHeight;
                m_currentPosition   = m_targetPosition;
            }
        }
		protected void StepDown(CollisionWorld collisionWorld, float dt)
		{
			IndexedMatrix start = IndexedMatrix.Identity, end = IndexedMatrix.Identity;

			// phase 3: down
			/*float additionalDownStep = (m_wasOnGround && !onGround()) ? m_stepHeight : 0.0;
			btVector3 step_drop = getUpAxisDirections()[m_upAxis] * (m_currentStepOffset + additionalDownStep);
			float downVelocity = (additionalDownStep == 0.0 && m_verticalVelocity<0.0?-m_verticalVelocity:0.0) * dt;
			btVector3 gravity_drop = getUpAxisDirections()[m_upAxis] * downVelocity; 
			m_targetPosition -= (step_drop + gravity_drop);*/

			float downVelocity = (m_verticalVelocity < 0.0f ? -m_verticalVelocity : 0.0f) * dt;
			if (downVelocity > 0.0 && downVelocity < m_stepHeight
				&& (m_wasOnGround || !m_wasJumping))
			{
				downVelocity = m_stepHeight;
			}

			IndexedVector3 step_drop = upAxisDirection[m_upAxis] * (m_currentStepOffset + downVelocity);
			m_targetPosition -= step_drop;

			start._origin = m_currentPosition;
			end._origin = m_targetPosition;

			KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, upAxisDirection[m_upAxis], m_maxSlopeCosine);
			callback.m_collisionFilterGroup = GetGhostObject().GetBroadphaseHandle().m_collisionFilterGroup;
			callback.m_collisionFilterMask = GetGhostObject().GetBroadphaseHandle().m_collisionFilterMask;

			if (m_useGhostObjectSweepTest)
			{
                // this doesn't work....
				m_ghostObject.ConvexSweepTest(m_convexShape, ref start, ref end, callback, collisionWorld.GetDispatchInfo().GetAllowedCcdPenetration());
			}
			else
			{
                // this works....
				collisionWorld.ConvexSweepTest(m_convexShape, start, end, callback, collisionWorld.GetDispatchInfo().GetAllowedCcdPenetration());
			}

			if (callback.HasHit())
			{
				// we dropped a fraction of the height -> hit floor
				m_currentPosition = MathUtil.Interpolate3(ref m_currentPosition, ref m_targetPosition, callback.m_closestHitFraction);
                m_verticalVelocity = 0.0f;
                m_verticalOffset = 0.0f;
                m_wasJumping = false;

			}
			else
			{
				// we dropped the full height
				m_currentPosition = m_targetPosition;
			}
		}
		protected void StepForwardAndStrafe(CollisionWorld collisionWorld, ref IndexedVector3 walkMove)
		{
			//	printf("originalDir=%f,%f,%f\n",originalDir[0],originalDir[1],originalDir[2]);
			// phase 2: forward and strafe
			IndexedMatrix start = IndexedMatrix.Identity, end = IndexedMatrix.Identity;
			m_targetPosition = m_currentPosition + walkMove;

			float fraction = 1.0f;
			float distance2 = (m_currentPosition - m_targetPosition).LengthSquared();
			//	printf("distance2=%f\n",distance2);

			if (m_touchingContact)
			{
				if (IndexedVector3.Dot(m_normalizedDirection, m_touchingNormal) > 0.0f)
				{
					UpdateTargetPositionBasedOnCollision(ref m_touchingNormal, 0.0f, 1.0f);
				}
			}

			int maxIter = 10;

			while (fraction > 0.01f && maxIter-- > 0)
			{
				start._origin = (m_currentPosition);
				end._origin = (m_targetPosition);

				IndexedVector3 sweepDirNegative = m_currentPosition - m_targetPosition;

				KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, sweepDirNegative, 0f);
				callback.m_collisionFilterGroup = GetGhostObject().GetBroadphaseHandle().m_collisionFilterGroup;
				callback.m_collisionFilterMask = GetGhostObject().GetBroadphaseHandle().m_collisionFilterMask;


				float margin = m_convexShape.GetMargin();
				m_convexShape.SetMargin(margin + m_addedMargin);


				if (m_useGhostObjectSweepTest)
				{
					m_ghostObject.ConvexSweepTest(m_convexShape, ref start, ref end, callback, collisionWorld.GetDispatchInfo().GetAllowedCcdPenetration());
				}
				else
				{
					collisionWorld.ConvexSweepTest(m_convexShape, ref start, ref end, callback, collisionWorld.GetDispatchInfo().GetAllowedCcdPenetration());
				}

				m_convexShape.SetMargin(margin);


				fraction -= callback.m_closestHitFraction;

				if (callback.HasHit())
				{
					// we moved only a fraction
					float hitDistance = (callback.m_hitPointWorld - m_currentPosition).Length();

					UpdateTargetPositionBasedOnCollision(ref callback.m_hitNormalWorld, 0f, 1f);
					IndexedVector3 currentDir = m_targetPosition - m_currentPosition;
					distance2 = currentDir.LengthSquared();
					if (distance2 > MathUtil.SIMD_EPSILON)
					{
						currentDir.Normalize();
						/* See Quake2: "If velocity is against original velocity, stop ead to avoid tiny oscilations in sloping corners." */
						if (IndexedVector3.Dot(currentDir, m_normalizedDirection) <= 0.0f)
						{
							break;
						}
					}
					else
					{
						//				printf("currentDir: don't normalize a zero vector\n");
						break;
					}
				}
				else
				{
					// we moved whole way
					m_currentPosition = m_targetPosition;
				}

				//	if (callback.m_closestHitFraction == 0.f)
				//		break;

			}

		}
		protected void StepUp(CollisionWorld collisionWorld)
		{
			// phase 1: up
			IndexedMatrix start = IndexedMatrix.Identity, end = IndexedMatrix.Identity;
			m_targetPosition = m_currentPosition + upAxisDirection[m_upAxis] * (m_stepHeight + (m_verticalOffset > 0.0f ? m_verticalOffset : 0.0f));


			/* FIXME: Handle penetration properly */
            start._origin = (m_currentPosition + upAxisDirection[m_upAxis] * (m_convexShape.GetMargin() + m_addedMargin));
            end._origin = (m_targetPosition);

			KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, -upAxisDirection[m_upAxis], 0.7071f);
			callback.m_collisionFilterGroup = GetGhostObject().GetBroadphaseHandle().m_collisionFilterGroup;
			callback.m_collisionFilterMask = GetGhostObject().GetBroadphaseHandle().m_collisionFilterMask;

			if (m_useGhostObjectSweepTest)
			{
				m_ghostObject.ConvexSweepTest(m_convexShape, ref start, ref end, callback, collisionWorld.GetDispatchInfo().GetAllowedCcdPenetration());
			}
			else
			{
				collisionWorld.ConvexSweepTest(m_convexShape, ref start, ref end, callback, 0f);
			}

			if (callback.HasHit())
			{
				// Only modify the position if the hit was a slope and not a wall or ceiling.
				if (IndexedVector3.Dot(callback.m_hitNormalWorld, upAxisDirection[m_upAxis]) > 0.0)
				{
					// we moved up only a fraction of the step height
					m_currentStepOffset = m_stepHeight * callback.m_closestHitFraction;
					m_currentPosition = MathUtil.Interpolate3(ref m_currentPosition, ref m_targetPosition, callback.m_closestHitFraction);
				}
				m_verticalVelocity = 0.0f;
				m_verticalOffset = 0.0f;
			}
			else
			{
				m_currentStepOffset = m_stepHeight;
				m_currentPosition = m_targetPosition;
			}

		}
Example #6
0
        protected void StepForwardAndStrafe(CollisionWorld collisionWorld, ref IndexedVector3 walkMove)
        {
            //	printf("originalDir=%f,%f,%f\n",originalDir[0],originalDir[1],originalDir[2]);
            // phase 2: forward and strafe
            IndexedMatrix start = IndexedMatrix.Identity, end = IndexedMatrix.Identity;

            m_targetPosition = m_currentPosition + walkMove;

            float fraction  = 1.0f;
            float distance2 = (m_currentPosition - m_targetPosition).LengthSquared();

            //	printf("distance2=%f\n",distance2);

            if (m_touchingContact)
            {
                if (IndexedVector3.Dot(m_normalizedDirection, m_touchingNormal) > 0.0f)
                {
                    UpdateTargetPositionBasedOnCollision(ref m_touchingNormal, 0.0f, 1.0f);
                }
            }

            int maxIter = 10;

            while (fraction > 0.01f && maxIter-- > 0)
            {
                start._origin = (m_currentPosition);
                end._origin   = (m_targetPosition);

                IndexedVector3 sweepDirNegative = m_currentPosition - m_targetPosition;

                KinematicClosestNotMeConvexResultCallback callback = new KinematicClosestNotMeConvexResultCallback(m_ghostObject, sweepDirNegative, 0f);
                callback.m_collisionFilterGroup = GetGhostObject().GetBroadphaseHandle().m_collisionFilterGroup;
                callback.m_collisionFilterMask  = GetGhostObject().GetBroadphaseHandle().m_collisionFilterMask;


                float margin = m_convexShape.GetMargin();
                m_convexShape.SetMargin(margin + m_addedMargin);


                if (m_useGhostObjectSweepTest)
                {
                    m_ghostObject.ConvexSweepTest(m_convexShape, ref start, ref end, callback, collisionWorld.GetDispatchInfo().GetAllowedCcdPenetration());
                }
                else
                {
                    collisionWorld.ConvexSweepTest(m_convexShape, ref start, ref end, callback, collisionWorld.GetDispatchInfo().GetAllowedCcdPenetration());
                }

                m_convexShape.SetMargin(margin);


                fraction -= callback.m_closestHitFraction;

                if (callback.HasHit())
                {
                    // we moved only a fraction
                    float hitDistance = (callback.m_hitPointWorld - m_currentPosition).Length();

                    UpdateTargetPositionBasedOnCollision(ref callback.m_hitNormalWorld, 0f, 1f);
                    IndexedVector3 currentDir = m_targetPosition - m_currentPosition;
                    distance2 = currentDir.LengthSquared();
                    if (distance2 > MathUtil.SIMD_EPSILON)
                    {
                        currentDir.Normalize();
                        /* See Quake2: "If velocity is against original velocity, stop ead to avoid tiny oscilations in sloping corners." */
                        if (IndexedVector3.Dot(currentDir, m_normalizedDirection) <= 0.0f)
                        {
                            break;
                        }
                    }
                    else
                    {
                        //				printf("currentDir: don't normalize a zero vector\n");
                        break;
                    }
                }
                else
                {
                    // we moved whole way
                    m_currentPosition = m_targetPosition;
                }

                //	if (callback.m_closestHitFraction == 0.f)
                //		break;
            }
        }