Exemple #1
0
        public override void handleCollision(Q3BSPLevel level, GameTime gameTime)
        {
            if (!active)
            {
                return;
            }

            //Simple collision detection against level
            Q3BSPCollisionData collision = level.TraceBox(position, newPosition, minPoint, maxPoint);

            position = collision.collisionPoint;
        }
Exemple #2
0
        public override void handleCollision(Q3BSPLevel level, GameTime gameTime)
        {
            // if noclipping is enabled, do not check for collisions
            if (!m_settings.clipping)
            {
                position = newPosition;
            }
            // otherwise, check for collisions
            else
            {
                Q3BSPCollisionData collision = level.TraceBox(position, newPosition, minPoint, maxPoint);
                Vector3            point     = collision.collisionPoint;

                if (collision.collisionPoint != collision.endPosition)
                {
                    Vector3 start = collision.startPosition;
                    Vector3 col   = collision.collisionPoint;
                    Vector3 end   = collision.endPosition;

                    //Wall Detection: Not Working
                    //point = slopeCollision(level, start, col, end, m_left, 75);
                    //Ramp Detection
                    point = slopeCollision(level, start, col, end, new Vector3(0, 0.5f, 0), maxClimb);
                }
                position = point;

                //Gravity
                //Check if on floor
                collision = level.TraceBox(position, position - new Vector3(0, 1, 0), minPoint, maxPoint);
                if (collision.collisionPoint == collision.endPosition || isJumping)
                {
                    //Not on floor so check gravity
                    updateGravity(gameTime);
                    collision = level.TraceBox(position, newPosition, minPoint, maxPoint);
                    if (collision.collisionPoint != collision.endPosition)
                    {
                        resetGravity();
                    }
                    position = collision.collisionPoint;
                }
                else
                {
                    //On floor don't do gravity, but reset it
                    resetGravity();
                }
            }
        }
Exemple #3
0
        private Vector3 slopeCollision(Q3BSPLevel level, Vector3 start, Vector3 collision, Vector3 end, Vector3 offset, float angle)
        {
            start += offset;
            end   += offset;

            // check the slope of a collision face
            Q3BSPCollisionData slopetest = level.TraceBox(start, end, minPoint, maxPoint);

            // get the angle of the collision face, and check to see that it is not too steep for the player to climb, then return the appropriate collision point
            if (slopetest.collisionPoint != collision + offset)
            {
                float opp   = offset.Length();
                float adj   = (end - start).Length();
                float theta = MathHelper.ToDegrees((float)Math.Atan(opp / adj));
                if (theta < angle)
                {
                    return(slopetest.collisionPoint);
                }
            }

            return(collision);
        }
        public Q3BSPCollisionData Trace(Vector3 startPosition, Vector3 endPosition)
        {
            Q3BSPCollisionData cd = new Q3BSPCollisionData();

            cd.startOutside   = true;
            cd.inSolid        = false;
            cd.ratio          = 1.0f;
            cd.startPosition  = startPosition;
            cd.endPosition    = endPosition;
            cd.collisionPoint = startPosition;

            WalkNode(0, 0.0f, 1.0f, startPosition, endPosition, ref cd);

            if (1.0f == cd.ratio)
            {
                cd.collisionPoint = endPosition;
            }
            else
            {
                cd.collisionPoint = startPosition + cd.ratio * (endPosition - startPosition);
            }

            return(cd);
        }
Exemple #5
0
        //Custom Collision Detection
        public override void handleCollision(XNAQ3Lib.Q3BSP.Q3BSPLevel level, GameTime gameTime)
        {
            base.handleCollision(level, gameTime);
            //Gravity
            //Check if on floor
            Q3BSPCollisionData collision = level.TraceBox(position, position - new Vector3(0, 1, 0), minPoint, maxPoint);

            if (collision.collisionPoint == collision.endPosition || isJumping)
            {
                //Not on floor so check gravity
                updateGravity(gameTime);
                collision = level.TraceBox(position, newPosition, minPoint, maxPoint);
                if (collision.collisionPoint != collision.endPosition)
                {
                    resetGravity();
                }
                position = collision.collisionPoint;
            }
            else
            {
                //On floor don't do gravity, but reset it
                resetGravity();
            }
        }
        private void CheckBrush(ref Q3BSPBrush brush, ref Q3BSPCollisionData cd)
        {
            float startFraction = -1.0f;
            float endFraction   = 1.0f;
            bool  startsOut     = false;
            bool  endsOut       = false;

            for (int i = 0; i < brush.BrushSideCount; i++)
            {
                Q3BSPBrushSide brushSide = brushSides[brush.StartBrushSide + i];
                Plane          plane     = planes[brushSide.PlaneIndex];

                float startDistance = Vector3.Dot(cd.startPosition, plane.Normal) - plane.D;
                float endDistance   = Vector3.Dot(cd.endPosition, plane.Normal) - plane.D;

                if (startDistance > 0)
                {
                    startsOut = true;
                }
                if (endDistance > 0)
                {
                    endsOut = true;
                }

                if (startDistance > 0 && endDistance > 0)
                {
                    return;
                }

                if (startDistance <= 0 && endDistance <= 0)
                {
                    continue;
                }

                if (startDistance > endDistance)
                {
                    float fraction = (startDistance - Q3BSPConstants.epsilon) / (startDistance - endDistance);
                    if (fraction > startFraction)
                    {
                        startFraction = fraction;
                    }
                }
                else
                {
                    float fraction = (startDistance + Q3BSPConstants.epsilon) / (startDistance - endDistance);
                    if (fraction < endFraction)
                    {
                        endFraction = fraction;
                    }
                }
            }

            if (false == startsOut)
            {
                cd.startOutside = false;
                if (false == endsOut)
                {
                    cd.inSolid = true;
                }

                return;
            }

            if (startFraction < endFraction)
            {
                if (startFraction > -1.0f && startFraction < cd.ratio)
                {
                    if (startFraction < 0)
                    {
                        startFraction = 0;
                    }
                    cd.ratio = startFraction;
                }
            }
        }
        private void WalkNode(int nodeIndex, float startRatio, float endRatio, Vector3 startPosition, Vector3 endPosition, ref Q3BSPCollisionData cd)
        {
            // Is this a leaf?
            if (0 > nodeIndex)
            {
                Q3BSPLeaf leaf = leafs[-(nodeIndex + 1)];
                for (int i = 0; i < leaf.LeafBrushCount; i++)
                {
                    Q3BSPBrush brush = brushes[leafBrushes[leaf.StartLeafBrush + i]];
                    if (0 < brush.BrushSideCount &&
                        1 == (textureData[brush.TextureIndex].Contents & 1))
                    {
                        CheckBrush(ref brush, ref cd);
                    }
                }

                return;
            }

            // This is a node
            Q3BSPNode thisNode      = nodes[nodeIndex];
            Plane     thisPlane     = planes[thisNode.Plane];
            float     startDistance = Vector3.Dot(startPosition, thisPlane.Normal) - thisPlane.D;
            float     endDistance   = Vector3.Dot(endPosition, thisPlane.Normal) - thisPlane.D;

            if (startDistance >= 0 && endDistance >= 0)
            {
                // Both points are in front
                WalkNode(thisNode.Left, startRatio, endRatio, startPosition, endPosition, ref cd);
            }
            else if (startDistance < 0 && endDistance < 0)
            {
                WalkNode(thisNode.Right, startRatio, endRatio, startPosition, endPosition, ref cd);
            }
            else
            {
                // The line spans the splitting plane
                int     side           = 0;
                float   fraction1      = 0.0f;
                float   fraction2      = 0.0f;
                float   middleFraction = 0.0f;
                Vector3 middlePosition = new Vector3();

                if (startDistance < endDistance)
                {
                    side = 1;
                    float inverseDistance = 1.0f / (startDistance - endDistance);
                    fraction1 = (startDistance + Q3BSPConstants.epsilon) * inverseDistance;
                    fraction2 = (startDistance + Q3BSPConstants.epsilon) * inverseDistance;
                }
                else if (endDistance < startDistance)
                {
                    side = 0;
                    float inverseDistance = 1.0f / (startDistance - endDistance);
                    fraction1 = (startDistance + Q3BSPConstants.epsilon) * inverseDistance;
                    fraction2 = (startDistance - Q3BSPConstants.epsilon) * inverseDistance;
                }
                else
                {
                    side      = 0;
                    fraction1 = 1.0f;
                    fraction2 = 0.0f;
                }

                if (fraction1 < 0.0f)
                {
                    fraction1 = 0.0f;
                }
                else if (fraction1 > 1.0f)
                {
                    fraction1 = 1.0f;
                }
                if (fraction2 < 0.0f)
                {
                    fraction2 = 0.0f;
                }
                else if (fraction2 > 1.0f)
                {
                    fraction2 = 1.0f;
                }

                middleFraction = startRatio + (endRatio - startRatio) * fraction1;
                middlePosition = startPosition + fraction1 * (endPosition - startPosition);

                int side1;
                int side2;
                if (0 == side)
                {
                    side1 = thisNode.Left;
                    side2 = thisNode.Right;
                }
                else
                {
                    side1 = thisNode.Right;
                    side2 = thisNode.Left;
                }

                WalkNode(side1, startRatio, middleFraction, startPosition, middlePosition, ref cd);

                middleFraction = startRatio + (endRatio - startRatio) * fraction2;
                middlePosition = startPosition + fraction2 * (endPosition - startPosition);

                WalkNode(side2, middleFraction, endRatio, middlePosition, endPosition, ref cd);
            }
        }