private void ProcessNoCollisionAtState_Move(MovableEntity character)
        {
            Vector3 boundMin = character.GetCharacterCollisionBound().GetMin();
            Vector3 origin   = character.GetCharacterCollisionBound().GetOrigin();

            // Ray cast from middle height position to avoid miss ray casting
            Vector3 rayCastStartPosition = new Vector3(origin);

            FRay  rayDown = new FRay(rayCastStartPosition, -GameWorld.GetWorldInstance().GetLevel().Camera.GetLocalSpaceUpVector());
            float intersectionDistance = LandscapeRayIntersection.Intersection_TerrainRay(GameWorld.GetWorldInstance().GetLevel().Terrain.GetData(), rayDown);

            // Subtract length of bound extent from middle height position
            float boundExtent = origin.Y - boundMin.Y;
            float actualIntersectionDistance = intersectionDistance - boundExtent;

            // Character is in free fall, next position will be calculated in next tick
            if (intersectionDistance < 0.0f || RAYCAST_INTERSECTION_FAR(BodyMechanics.GetFreeFallDistanceInVelocity(character.Velocity), actualIntersectionDistance))
            {
                character.ActorState = BehaviorState.FREE_FALLING;
            }

            // Check if character can reach that height
            else
            {  // Character could be elevated on terrain
                Vector3 CharacterNewPosition = rayDown.GetPositionInTime(intersectionDistance);
                CharacterNewPosition.Y += character.GetCharacterCollisionBound().GetExtent().Y;
                character.SetPosition(CharacterNewPosition);
                character.ActorState = BehaviorState.IDLE;
            }


            // Push current position to stack
            character.pushPosition();
        }
        private void ProcessNoCollisionAtState_FreeFalling(MovableEntity character)
        {
            if (character.Velocity.LengthSquared > 0)
            {
                Vector3 boundMin = character.GetCharacterCollisionBound().GetMin();
                // Raycast from bottom height point
                Vector3 rayCastStartPosition = new Vector3(character.GetCharacterCollisionBound().GetOrigin());
                rayCastStartPosition.Y = boundMin.Y;

                FRay  ray = new FRay(rayCastStartPosition, character.Velocity);
                float intersectionDistance = LandscapeRayIntersection.Intersection_TerrainRay(GameWorld.GetWorldInstance().GetLevel().Terrain.GetData(), ray);

                // Character is still in free fall, just update position
                if (intersectionDistance < 0.0f || RAYCAST_INTERSECTION_FAR(BodyMechanics.GetFreeFallDistanceInVelocity(character.Velocity), intersectionDistance))
                {
                    character.SetPosition(BodyMechanics.UpdateFreeFallPosition(character.ComponentTranslation, character.Velocity));
                }

                // Character could be elevated on terrain
                else
                {
                    Vector3 CharacterNewPosition = ray.GetPositionInTime(intersectionDistance);
                    CharacterNewPosition.Y += character.GetCharacterCollisionBound().GetExtent().Y;
                    character.SetPosition(CharacterNewPosition);
                    character.ActorState = BehaviorState.IDLE;
                }
            }

            character.pushPosition();
        }
        private void ProcessCollisionAtState_FreeFalling(MovableEntity character, Entity collidedEntity, List <BoundBase> collidedBounds)
        {
            switch (GetEntityType(collidedEntity))
            {
            // If character collided another character during free fall because of forward velocity
            case EntityType.MOVABLE_ENTITY:
            {
                // Restore previous position and set velocity to fall
                character.popPosition();
                character.Velocity = -GameWorld.GetWorldInstance().GetLevel().Camera.GetLocalSpaceUpVector();
                break;
            }

            // If character is in free falling but has encountered some collisions with bounds
            case EntityType.STATIC_ENTITY:
            {
                List <Vector3> previousRayCastPositions = GetPreviousFreeFallBottomPositionsForRayCast(character.GetCharacterCollisionBound(), character);
                List <FRay>    listOfRays = new List <FRay>();
                for (Int32 i = 0; i < previousRayCastPositions.Count; i++)
                {
                    listOfRays.Add(new FRay(previousRayCastPositions[i], character.Velocity));
                }

                FRay rayFromMiddleBottom = listOfRays.First();

                // Necessary data for subsequent calculations
                RayCastOutputData rayCastOutputData           = null;
                float             terrainIntersectionDistance = LandscapeRayIntersection.Intersection_TerrainRay(GameWorld.GetWorldInstance().GetLevel().Terrain.GetData(), rayFromMiddleBottom);

                bool bTerrainIntersection = !(terrainIntersectionDistance < 0.0f ||
                                              RAYCAST_INTERSECTION_FAR(BodyMechanics.GetFreeFallDistanceInVelocity(character.Velocity), terrainIntersectionDistance));

                // No terrain intersection - check intersection with bounds
                if (!bTerrainIntersection)
                {
                    rayCastOutputData = GetClosestRayCastResultFromMultipleRayCast(listOfRays, collidedBounds, character);

                    // Ray collided with one of the bounds, check angle of that plane, if can elevate on it - do it
                    if (RAYCAST_COLLIDED(rayCastOutputData.shortestDistance))
                    {
                        Vector3 normalToCollidedPlane = rayCastOutputData.collidedBound.GetNormalToIntersectedPosition(rayCastOutputData.intersectionPosition);
                        // Character can step on this surface
                        if (REACHABLE_INCLINE(normalToCollidedPlane))
                        {
                            Vector3 BoundOrigin          = character.GetCharacterCollisionBound().GetOrigin();
                            Vector3 NewCharacterPosition = new Vector3(BoundOrigin.X, rayCastOutputData.intersectionPosition.Y + character.GetCharacterCollisionBound().GetExtent().Y,
                                                                       BoundOrigin.Z);
                            character.SetPosition(NewCharacterPosition);
                            character.pushPosition();
                            character.ActorState = BehaviorState.IDLE;
                        }
                        // If normal is down directed or too up directed - character can't step on this surface - return to previous position and set velocity to down
                        else
                        {
                            // This is quick fix
                            character.ActorState = BehaviorState.MOVE;
                            character.popPosition();
                            character.Velocity = -GameWorld.GetWorldInstance().GetLevel().Camera.GetLocalSpaceUpVector();
                        }
                    }
                    // No ray collision, but bound collision exists, bound position is unknown - return to previous position and set velocity to down
                    else
                    {
                        character.popPosition();
                        character.Velocity = -GameWorld.GetWorldInstance().GetLevel().Camera.GetLocalSpaceUpVector();
                    }
                }
                // Character could be elevated on terrain
                else
                {
                    Vector3 CharacterNewPosition = rayFromMiddleBottom.GetPositionInTime(terrainIntersectionDistance);
                    CharacterNewPosition.Y += character.GetCharacterCollisionBound().GetExtent().Y;
                    character.SetPosition(CharacterNewPosition);
                    character.ActorState = BehaviorState.IDLE;
                    character.pushPosition();
                }

                break;
            }
            }
        }