Ejemplo n.º 1
0
 public string RayIntersectsHitbox(Ray ray, out float?distance)
 {
     GenerateHitBoxesTriangles();
     foreach (Display3D.Triangle tri in GetRealTriangles())
     {
         Display3D.Triangle triangle = tri;
         float?dist = Display3D.TriangleTest.Intersects(ref ray, ref triangle);
         if (dist.HasValue)
         {
             distance = dist;
             return(tri.TriName);
         }
     }
     distance = null;
     return("");
 }
Ejemplo n.º 2
0
        public List <Display3D.Triangle> GetRealTriangles(bool drawHitbox = false)
        {
            Matrix world = GetModelMatrix();
            List <Display3D.Triangle> triangles = new List <Display3D.Triangle>();

            foreach (KeyValuePair <string, Display3D.Triangle> tri in hitBoxesTriangles)
            {
                //world = tri.Value.transformMatrix;
                Display3D.Triangle newTri = tri.Value.NewByMatrix(world);
                triangles.Add(newTri);
                if (drawHitbox)
                {
                    Display3D.CSimpleShapes.AddTriangle(newTri.V0, newTri.V1, newTri.V2, Color.Black);
                }
            }
            return(triangles);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Gets the new position of the entity by applying it all the physics
        /// </summary>
        public Vector3 GetNewPosition(GameTime gameTime, Vector3 entityPos, Vector3 translation, bool isUnderwater)
        {
            _isUnderwater = isUnderwater;
            bool isVerticalIntersecting = false;

            Vector3 translationOriginal = translation;

            translation *= (float)gameTime.ElapsedGameTime.TotalSeconds;

            Vector3 assumedNewPosition = entityPos + translation;
            Ray     translationRay     = new Ray(new Vector3(entityPos.X, entityPos.Y - _entityHeight / 2 + heightCorrection, entityPos.Z), translation);

            Vector3 horizontalNormalReaction = Vector3.Zero;

            // Water surface check
            float waterHeight = -1;

            foreach (float waterH in _waterHeight)
            {
                if (entityPos.Y + translation.Y > waterHeight)
                {
                    waterHeight = waterH;
                }
            }

            if (_isGameUsing[1] && (_isUnderwater || _isOnWaterSurface) && waterHeight != -1)
            {
                _isOnWaterSurface    = true;
                _velocity.Y          = 0;
                assumedNewPosition.Y = waterHeight + translation.Y;
            }
            else if (_isOnWaterSurface)
            {
                _isOnWaterSurface = false;
            }

            /* Horizontal check - models */
            for (int i = 0; i < _triangleList.Count; i++)
            {
                Display3D.Triangle triangleToTest = _triangleList[i];
                float?distance = Display3D.TriangleTest.Intersects(ref translationRay, ref triangleToTest);
                if (distance != null && distance <= _intersectionDistanceH)
                {
                    horizontalNormalReaction = -_triangleNormalsList[i] * translation.Length() * (_intersectionDistanceH - (float)distance);
                    //horizontalNormalReaction = -translation;
                    break;
                }
            }
            assumedNewPosition += horizontalNormalReaction;


            /* Vertical check - terrain */
            // Terrain informations
            float Steepness;
            float terrainHeight = (_isGameUsing[0]) ? _terrain.GetHeightAtPosition(assumedNewPosition.X, assumedNewPosition.Z, out Steepness) : 0;

            float jumpVelocity = 0f;

            if (_velocity.Y > 0)
            {
                jumpVelocity = _velocity.Y;
            }

            if (_isGameUsing[0] && assumedNewPosition.Y + jumpVelocity <= terrainHeight + _entityHeight + 0.001f)
            {
                isVerticalIntersecting = true;
                assumedNewPosition.Y   = terrainHeight + _entityHeight;

                _velocity = Vector3.Zero;
                Vector3 normal = _terrain.getNormalAtPoint(assumedNewPosition.X, assumedNewPosition.Z);
                if (normal.Y > _slippingResistance)
                {
                    _velocity   = -0.1f * normal;
                    _velocity.Y = -0.1f;
                }
            }
            else
            {
                isVerticalIntersecting = false;
                //float dt = (float)(gameTime.TotalGameTime.TotalMilliseconds - _lastFreeFall) * (float)gameTime.ElapsedGameTime.TotalMilliseconds;
                float dt = (float)gameTime.ElapsedGameTime.TotalSeconds;
                if (_isUnderwater && translation == Vector3.Zero)
                {
                    _velocity.Y += _gravityConstantWater * dt;
                }
                else
                {
                    _velocity.Y += _gravityConstant * dt;
                }

                if (_isUnderwater && _velocity.Y < _maxFallingVelocityWater)
                {
                    _velocity.Y = _maxFallingVelocityWater;
                }
                else if (_velocity.Y < _maxFallingVelocity)
                {
                    _velocity.Y = _maxFallingVelocity;
                }
            }

            Ray newPosTranslationRay = new Ray(assumedNewPosition + _velocity, (_velocity.Y > 0) ? Vector3.Up : Vector3.Down);

            /* Vertical check - models */
            float closestTriangleBelowDistance = 999f;
            int   closestTriangle = -1;

            for (int i = 0; i < _triangleList.Count; i++)
            {
                Display3D.Triangle triangleToTest = _triangleList[i];
                float?distance = Display3D.TriangleTest.Intersects(ref newPosTranslationRay, ref triangleToTest);
                if (distance != null)
                {
                    if (distance < closestTriangleBelowDistance)
                    {
                        closestTriangle = i;
                        closestTriangleBelowDistance = (float)distance;
                    }
                }
            }

            if (closestTriangle != -1 && closestTriangleBelowDistance <= (_velocity.Y <= 0 ? _entityHeight : _entityHeight / 3))
            {
                // If the player is falling, and not jumping
                if (_velocity.Y <= 0)
                {
                    isVerticalIntersecting = true;
                    assumedNewPosition    += _velocity;
                    Display3D.Triangle closestTriangleT = _triangleList[closestTriangle];
                    assumedNewPosition.Y = assumedNewPosition.Y - closestTriangleBelowDistance + _entityHeight;

                    Vector3 normal = _triangleNormalsList[closestTriangle];

                    if (normal.Y > _slippingResistance)
                    {
                        _velocity   = -0.1f * normal;
                        _velocity.Y = -0.1f;
                    }
                }
                _velocity.Y = 0;
            }

            if (_isOnWaterSurface)
            {
                _velocity.Y = 0;
            }

            if (isVerticalIntersecting)
            {
                _lastFreeFall     = gameTime.TotalGameTime.TotalSeconds;
                _isOnWaterSurface = false;
            }
            return(assumedNewPosition + _velocity);
        }