Add second of several ray cast/rendering files
This commit is contained in:
parent
b23678b965
commit
2af008571e
@ -47,7 +47,7 @@ STACKSIZE = 2048
|
||||
|
||||
ASRCS =
|
||||
CSRCS = trv_color.c trv_doors.c trv_graphics.c trv_input.c trv_mem.c trv_pov.c
|
||||
CSRCS += trv_rayrend.c trv_trigtbl.c
|
||||
CSRCS += trv_rayavoid.c trv_rayrend.c trv_trigtbl.c
|
||||
MAINSRC = trv_main.c
|
||||
|
||||
ifeq ($(CONFIG_NX),y)
|
||||
|
@ -118,6 +118,22 @@ struct trv_planefile_header_s
|
||||
};
|
||||
#define SIZEOF_TRVPLANEFILEHEADER_T 6
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The is the world!!! The world is described by lists of rectangles, one
|
||||
* for each of the X, Y, and Z planes.
|
||||
*/
|
||||
|
||||
extern struct trv_rect_head_s g_xplane; /* list of X=plane rectangles */
|
||||
extern struct trv_rect_head_s g_yplane; /* list of Y=plane rectangles */
|
||||
extern struct trv_rect_head_s g_zplane; /* list of Z=plane rectangles */
|
||||
|
||||
/* "Deallocated" planes are retained in a free list */
|
||||
|
||||
extern struct trv_rect_list_s *g_rect_freelist;
|
||||
|
||||
/****************************************************************************
|
||||
* Public Function Prototypes
|
||||
****************************************************************************/
|
||||
|
@ -63,11 +63,11 @@ trv_coord_t trv_rayclip_player_ymotion(FAR struct trv_camera_s *pov,
|
||||
trv_coord_t height);
|
||||
trv_coord_t trv_ray_adjust_zpos(FAR struct trv_camera_s *pov,
|
||||
trv_coord_t height);
|
||||
FAR struct trv_rect_data_s *trv_test_xplane(FAR struct trv_camera_s *pov,
|
||||
trv_coord_t dist, int16_t yaw,
|
||||
trv_coord_t height);
|
||||
FAR struct trv_rect_data_s *trv_test_yplane(FAR struct trv_camera_s *pov,
|
||||
trv_coord_t dist, int16_t yaw,
|
||||
trv_coord_t height);
|
||||
FAR struct trv_rect_data_s *trv_ray_test_xplane(FAR struct trv_camera_s *pov,
|
||||
trv_coord_t dist, int16_t yaw,
|
||||
trv_coord_t height);
|
||||
FAR struct trv_rect_data_s *trv_ray_test_yplane(FAR struct trv_camera_s *pov,
|
||||
trv_coord_t dist, int16_t yaw,
|
||||
trv_coord_t height);
|
||||
|
||||
#endif /* __APPS_GRAPHICS_TRAVELER_INCLUDE_TRV_RAYAVOID_H */
|
||||
|
@ -124,8 +124,8 @@ static void trv_door_startopen (void)
|
||||
/* Test if there is a door within three steps in front of the player */
|
||||
/* Try the X planes first */
|
||||
|
||||
rect = trv_test_xplane(&g_trv_player, 3*STEP_DISTANCE,
|
||||
g_trv_player.yaw, g_player_height);
|
||||
rect = trv_ray_test_xplane(&g_trv_player, 3*STEP_DISTANCE,
|
||||
g_trv_player.yaw, g_player_height);
|
||||
|
||||
/* If there is no X door in front of the player, then try the Y Planes
|
||||
* (it is assumed that there would not be doors this close in both
|
||||
@ -134,8 +134,8 @@ static void trv_door_startopen (void)
|
||||
|
||||
if (!rect || !IS_DOOR(rect))
|
||||
{
|
||||
rect = trv_test_yplane(&g_trv_player, 3*STEP_DISTANCE,
|
||||
g_trv_player.yaw, g_player_height);
|
||||
rect = trv_ray_test_yplane(&g_trv_player, 3*STEP_DISTANCE,
|
||||
g_trv_player.yaw, g_player_height);
|
||||
}
|
||||
|
||||
/* Check if we found a door in either the X or Y plane. */
|
||||
|
624
graphics/traveler/src/trv_rayavoid.c
Executable file
624
graphics/traveler/src/trv_rayavoid.c
Executable file
@ -0,0 +1,624 @@
|
||||
/*******************************************************************************
|
||||
* apps/graphics/traveler/src/trv_rayavoid.c
|
||||
* This file contains the logic which determines if the desired player motion
|
||||
* would cause a collision with various walls or if the motion would cause
|
||||
* the player to change his vertical position in the world. This collision
|
||||
* avoidance logic is also used to determine if there is a door in front of
|
||||
* the player.
|
||||
*
|
||||
* Copyright (C) 2014 Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* 3. Neither the name NuttX nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Included files
|
||||
****************************************************************************/
|
||||
|
||||
#include "trv_types.h"
|
||||
#include "trv_trigtbl.h"
|
||||
#include "trv_plane.h"
|
||||
#include "trv_world.h"
|
||||
#include "trv_rayavoid.h"
|
||||
|
||||
/*****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
/* This is the closest that we will allow the player to approach a wall */
|
||||
|
||||
#define MIN_APPROACH_DISTANCE (64/4) /* One quarter cell */
|
||||
|
||||
/*****************************************************************************
|
||||
* Private Data
|
||||
****************************************************************************/
|
||||
|
||||
/* The rayClipPlayX/YMotion functions have the side effect of saving the
|
||||
* pointer to the wall with which the player collided in the following
|
||||
* private variable. This gives a "back door" mechanism which is used
|
||||
* to handle door processing.
|
||||
*/
|
||||
|
||||
static struct trv_rect_data_s *g_clip_rect;
|
||||
|
||||
/*****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: trv_ray_test_xplane
|
||||
*
|
||||
* Description:
|
||||
*
|
||||
* This function tests if there is an X plane within the supplied distance
|
||||
* from the player at the supplied angle. This function is used to
|
||||
* determine in there is a door in front of the player. NOTE: This
|
||||
* function exploits the normal collision detection logic in
|
||||
* trv_rayclip_player_xmotion and depends on the side-effect setting of
|
||||
* g_clip_rect.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
FAR struct trv_rect_data_s *trv_ray_test_xplane(FAR struct trv_camera_s *pov,
|
||||
trv_coord_t dist, int16_t yaw,
|
||||
trv_coord_t height)
|
||||
{
|
||||
(void) trv_rayclip_player_xmotion(pov, dist, yaw, height);
|
||||
return g_clip_rect;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: trv_rayclip_player_xmotion
|
||||
*
|
||||
* Description:
|
||||
* This function calculates the acceptable change in the player's position
|
||||
* along the X component of the specified yaw angle which would not cause
|
||||
* a collision with an X plane. This logic is essentially a modified X
|
||||
* ray cast.
|
||||
*
|
||||
*****************************************************************************/
|
||||
|
||||
trv_coord_t trv_rayclip_player_xmotion(FAR struct trv_camera_s *pov,
|
||||
trv_coord_t dist, int16_t yaw,
|
||||
trv_coord_t height)
|
||||
{
|
||||
FAR struct trv_rect_list_s *list; /* Points to the current X plane rectangle */
|
||||
FAR struct trv_rect_data_s *rect; /* Points to the rectangle data */
|
||||
trv_coord_t reqdeltax;
|
||||
trv_coord_t standoff;
|
||||
trv_coord_t footlevel;
|
||||
trv_coord_t relx; /* Relative position of the X plane */
|
||||
trv_coord_t absy; /* Absolute Y position at relx given yaw */
|
||||
trv_coord_t lastrelx = -1; /* Last relative X position processed */
|
||||
|
||||
/* Decompose the desired move distance into its X component */
|
||||
|
||||
reqdeltax = tTOs(g_cos_table[ yaw ] * dist);
|
||||
|
||||
/* Assume that no clipping will be performed */
|
||||
|
||||
g_clip_rect = NULL;
|
||||
|
||||
/* Perform X raycasting based on the quadrant of the yaw angle */
|
||||
/* The first and fourth quadrants correspond to the positive X
|
||||
* direction (excluding angles 90 and 270).
|
||||
*/
|
||||
|
||||
if (yaw < ANGLE_90 || yaw > ANGLE_270)
|
||||
{
|
||||
/* Calculate the requested distance along the (positive) X axis (adding
|
||||
* a little to how close the play can come to a wall
|
||||
*/
|
||||
|
||||
standoff = reqdeltax + MIN_APPROACH_DISTANCE;
|
||||
|
||||
/* This is the position of the player's feet */
|
||||
|
||||
footlevel = pov->z - height;
|
||||
|
||||
/* Look at every rectangle lying in the X plane */
|
||||
|
||||
for (list = g_xplane.head; list; list = list->flink)
|
||||
{
|
||||
rect = &list->d;
|
||||
|
||||
/* Search for a rectangle which lies "beyond" the current camera
|
||||
* position
|
||||
*/
|
||||
|
||||
if (rect->plane > pov->x)
|
||||
{
|
||||
/* Get the X distance to the plane. This is an order list: if
|
||||
* the distance to the plane is larger then the requested step
|
||||
* then the requested step is acceptable.
|
||||
*/
|
||||
|
||||
relx = rect->plane - pov->x;
|
||||
if (relx >= standoff)
|
||||
{
|
||||
return reqdeltax;
|
||||
}
|
||||
|
||||
/* The distance to the plane is smaller that the requested step.
|
||||
* It may be possible to collide with the plane. Check if a
|
||||
* collision due to the height of the player is possible first
|
||||
* (its easier to compute)
|
||||
*/
|
||||
|
||||
if (footlevel >= rect->vstart && pov->z <= rect->vend)
|
||||
{
|
||||
/* A collision is possible based on the players height.
|
||||
* Now, we'll have to check if a collision is possible
|
||||
* due to the player's Y position. We can skip this
|
||||
* step if we are processing another rectangle at the
|
||||
* same relx distance.
|
||||
*/
|
||||
|
||||
if (relx != lastrelx)
|
||||
{
|
||||
int32_t deltay; /* Scale == "triple" */
|
||||
|
||||
/* The tangent is equal to the rate of change of Y with
|
||||
* respect to the X-axis. The tangent is stored at
|
||||
* double the the "normal" scaling -- so deltay is
|
||||
* "triple" precision
|
||||
*/
|
||||
|
||||
deltay = TAN(yaw) * ((int32_t)relx);
|
||||
absy = tTOs(deltay) + pov->y; /* back to "single" */
|
||||
lastrelx = relx;
|
||||
}
|
||||
|
||||
/* Check if this Y position intersects the rectangle */
|
||||
|
||||
if (absy >= rect->hstart && absy <= rect->hend)
|
||||
{
|
||||
/* It collides -- Check, maybe we can walk through
|
||||
* this wall
|
||||
*/
|
||||
|
||||
if (!IS_PASSABLE(rect))
|
||||
{
|
||||
/* Nope... return a clipped value for the new
|
||||
* player position (which includes the a stand-off
|
||||
* constant)
|
||||
* NOTE: This returned value could be negative!
|
||||
*/
|
||||
|
||||
g_clip_rect = rect;
|
||||
return relx - MIN_APPROACH_DISTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The second and third quadrants correspond to the negative X
|
||||
* direction (excluding angles 90 and 270).
|
||||
*/
|
||||
|
||||
else if (yaw > ANGLE_90 && yaw < ANGLE_270)
|
||||
{
|
||||
/* Calculate the requested distance along the (negative) X axis
|
||||
* (adding a little to how close the play can come to a wall)
|
||||
*/
|
||||
|
||||
standoff = MIN_APPROACH_DISTANCE - reqdeltax;
|
||||
|
||||
/* This is the position of the player's feet */
|
||||
|
||||
footlevel = pov->z - height;
|
||||
|
||||
/* Look at every rectangle lying in the X plane */
|
||||
|
||||
for (list = g_xplane.tail; list; list = list->blink)
|
||||
{
|
||||
rect = &list->d;
|
||||
|
||||
/* Search for a rectangle which lies "before" the current camera
|
||||
* position
|
||||
*/
|
||||
|
||||
if (rect->plane < pov->x)
|
||||
{
|
||||
/* Get the X distance to the plane. This is an order list:
|
||||
* if the distance to the plane is larger then the requested
|
||||
* step then the requested step is acceptable.
|
||||
*/
|
||||
|
||||
relx = pov->x - rect->plane;
|
||||
if (relx >= standoff)
|
||||
{
|
||||
return reqdeltax;
|
||||
}
|
||||
|
||||
/* The distance to the plane is smaller that the requested
|
||||
* step. It may be possible to collide with the plane. Check
|
||||
* if a collision due to the height of the player is possible
|
||||
* first (its easier to compute)
|
||||
*/
|
||||
|
||||
if (footlevel >= rect->vstart && pov->z <= rect->vend)
|
||||
{
|
||||
/* A collision is possible based on the players height.
|
||||
* Now, we'll have to check if a collision is possible due
|
||||
* to the player's Y position. We can skip this step if
|
||||
* we are processing another rectangle at the same relx
|
||||
* distance.
|
||||
*/
|
||||
|
||||
if (relx != lastrelx)
|
||||
{
|
||||
int32_t deltay; /* Scale == "triple" */
|
||||
|
||||
/* The negative tangent is equal to the rate of change
|
||||
* of Y with respect to the X-axis.The tangent is
|
||||
* stored at double the the "normal" scaling -- so
|
||||
* deltay is "triple" precision
|
||||
*/
|
||||
|
||||
deltay = -TAN(yaw) * ((int32_t)relx);
|
||||
absy = tTOs(deltay) + pov->y; /* back to "single" */
|
||||
lastrelx = relx;
|
||||
}
|
||||
|
||||
/* Check if this Y position intersects the rectangle */
|
||||
|
||||
if (absy >= rect->hstart && absy <= rect->hend)
|
||||
{
|
||||
/* It collides -- Check, maybe we can walk through
|
||||
* this wall?
|
||||
*/
|
||||
|
||||
if (!IS_PASSABLE(rect))
|
||||
{
|
||||
/* Nope -- return a clipped value for the new
|
||||
* player position (which includes the a stand-off
|
||||
* constant)
|
||||
* NOTE: This returned value could be positive!
|
||||
*/
|
||||
|
||||
g_clip_rect = rect;
|
||||
return MIN_APPROACH_DISTANCE - relx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If we got there, then no collisions were found. Just return the
|
||||
* requested step value
|
||||
*/
|
||||
|
||||
return reqdeltax;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: trv_ray_test_yplane
|
||||
*
|
||||
* Description:
|
||||
* This function tests if there is an Y plane within the supplied distance
|
||||
* from the player at the supplied angle. This function is used to
|
||||
* determine in there is a door in front of the player. NOTE: This
|
||||
* function exploits the normal collision detection logic in
|
||||
* trv_rayclip_player_ymotion and depends on the side-effect setting of
|
||||
* g_clip_rect.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
FAR struct trv_rect_data_s *trv_ray_test_yplane(FAR struct trv_camera_s *pov,
|
||||
trv_coord_t dist, int16_t yaw,
|
||||
trv_coord_t height)
|
||||
{
|
||||
(void)trv_rayclip_player_ymotion(pov, dist, yaw, height);
|
||||
return g_clip_rect;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: trv_rayclip_player_ymotion
|
||||
*
|
||||
* Description:
|
||||
* This function calculates the acceptable change in the player's position
|
||||
* along the Y component of the specified yaw angle which would not cause
|
||||
* a collision with a Y plane. This logic is essentially a modified X
|
||||
* ray cast.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
trv_coord_t trv_rayclip_player_ymotion(FAR struct trv_camera_s *pov,
|
||||
trv_coord_t dist, int16_t yaw,
|
||||
trv_coord_t height)
|
||||
{
|
||||
FAR struct trv_rect_list_s *list; /* Points to the current Y plane rectangle */
|
||||
FAR struct trv_rect_data_s *rect; /* Points to the rectangle data */
|
||||
trv_coord_t reqdeltay;
|
||||
trv_coord_t standoff;
|
||||
trv_coord_t footlevel;
|
||||
trv_coord_t rely; /* Relative position of the Y plane */
|
||||
trv_coord_t absx; /* Absolute X position at rely given yaw */
|
||||
trv_coord_t lastrely = -1; /* Last relative Y position processed */
|
||||
|
||||
/* Decompose the desired move distance into its Y component */
|
||||
|
||||
reqdeltay = tTOs(g_sin_table[ yaw ] * dist);
|
||||
|
||||
/* Assume that no clipping will be performed */
|
||||
|
||||
g_clip_rect = NULL;
|
||||
|
||||
/* Perform Y raycasting based on the quadrant of the yaw angle */
|
||||
/* The first and second quadrants correspond to the positive Y
|
||||
* direction (excluding angles 0 and 180).
|
||||
*/
|
||||
|
||||
if (yaw > ANGLE_0 && yaw < ANGLE_180)
|
||||
{
|
||||
/* Calculate the requested distance along the (positive) X axis
|
||||
* (adding a little to how close the play can come to a wall)
|
||||
*/
|
||||
|
||||
standoff = reqdeltay + MIN_APPROACH_DISTANCE;
|
||||
|
||||
/* This is the position of the player's feet */
|
||||
|
||||
footlevel = pov->z - height;
|
||||
|
||||
/* Look at every rectangle lying in a Y plane */
|
||||
|
||||
for (list = g_yplane.head; list; list = list->flink)
|
||||
{
|
||||
rect = &list->d;
|
||||
|
||||
/* Search for a rectangle which lies "beyond" the current camera
|
||||
* position
|
||||
*/
|
||||
|
||||
if (rect->plane > pov->y)
|
||||
{
|
||||
/* Get the Y distance to the plane. This is an order list:
|
||||
* If the distance to the plane is larger then the requested
|
||||
* step then the requested step is acceptable.
|
||||
*/
|
||||
|
||||
rely = rect->plane - pov->y;
|
||||
if (rely >= standoff)
|
||||
{
|
||||
return reqdeltay;
|
||||
}
|
||||
|
||||
/* The distance to the plane is smaller that the requested
|
||||
* step. It may be possible to collide with the plane.
|
||||
* Check if a collision due to the height of the player is
|
||||
* possible first (its easier to compute)
|
||||
*/
|
||||
|
||||
if (footlevel >= rect->vstart && pov->z <= rect->vend)
|
||||
{
|
||||
/* A collision is possible based on the players height.
|
||||
* Now, we'll have to check if a collision is possible
|
||||
* due to the player's X position. We can skip this
|
||||
* step if we are processing another rectangle at the
|
||||
* same relx distance.
|
||||
*/
|
||||
|
||||
if (rely != lastrely)
|
||||
{
|
||||
int32_t deltax; /* Scale == "triple" */
|
||||
|
||||
/* The inverted tangent is equal to the rate of change
|
||||
* of X with respect to the Y-axis. The cotangent is
|
||||
* stored at double the the "normal" scaling -- so
|
||||
* deltax is "triple" precision
|
||||
*/
|
||||
|
||||
deltax = g_cot_table(yaw) * ((int32_t)rely);
|
||||
absx = tTOs(deltax) + pov->x; /* back to "single" */
|
||||
lastrely = rely;
|
||||
}
|
||||
|
||||
/* Check if this X position intersects the rectangle */
|
||||
|
||||
if (absx >= rect->hstart && absx <= rect->hend)
|
||||
{
|
||||
/* It collides -- Check, maybe we can walk through
|
||||
* this wall?
|
||||
*/
|
||||
|
||||
if (!IS_PASSABLE(rect))
|
||||
{
|
||||
/* Nope -- return a clipped value for the new
|
||||
* player position (which includes the a stand-off
|
||||
* constant)
|
||||
* NOTE: This returned value could be negative!
|
||||
*/
|
||||
|
||||
g_clip_rect = rect;
|
||||
return rely - MIN_APPROACH_DISTANCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* The third and fourth quadrants correspond to the negative Y
|
||||
* direction (excluding angles 0 and 180).
|
||||
*/
|
||||
|
||||
else if (yaw > ANGLE_180)
|
||||
{
|
||||
/* Calculate the requested distance along the (negative) X axis
|
||||
* (adding a little to how close the play can come to a wall)
|
||||
*/
|
||||
|
||||
standoff = MIN_APPROACH_DISTANCE - reqdeltay;
|
||||
|
||||
/* This is the position of the player's feet */
|
||||
|
||||
footlevel = pov->z - height;
|
||||
|
||||
/* Look at every rectangle lying in the X plane */
|
||||
|
||||
for (list = g_yplane.tail; list; list = list->blink)
|
||||
{
|
||||
rect = &list->d;
|
||||
|
||||
/* Search for a rectangle which lies "before" the current camera
|
||||
* position
|
||||
*/
|
||||
|
||||
if (rect->plane < pov->y)
|
||||
{
|
||||
/* Get the X distance to the plane. This is an order list: if
|
||||
* the distance to the plane is larger then the requested step
|
||||
* then the requested step is acceptable.
|
||||
*/
|
||||
|
||||
rely = pov->y - rect->plane;
|
||||
if (rely >= standoff)
|
||||
{
|
||||
return reqdeltay;
|
||||
}
|
||||
|
||||
/* The distance to the plane is smaller that the requested
|
||||
* step. It may be possible to collide with the plane. Check
|
||||
* if a collision due to the height of the player is possible
|
||||
* first (its easier to compute)
|
||||
*/
|
||||
|
||||
if (footlevel >= rect->vstart && pov->z <= rect->vend)
|
||||
{
|
||||
/* A collision is possible based on the players height.
|
||||
* Now, we'll have to check if a collision is possible due
|
||||
* to the player's X position. We can skip this step if
|
||||
* we are processing another rectangle at the same relx
|
||||
* distance.
|
||||
*/
|
||||
|
||||
if (rely != lastrely)
|
||||
{
|
||||
int32_t deltax; /* Scale == "triple" */
|
||||
|
||||
/* The negative inverted tangent is equal to the rate
|
||||
* of change of X with respect to the Y-axis. The
|
||||
* cotangent is stored at double the the "normal"
|
||||
* scaling -- so deltax is "triple" precision
|
||||
*/
|
||||
|
||||
deltax = -g_cot_table(yaw - ANGLE_180) * ((int32_t)rely);
|
||||
absx = tTOs(deltax) + pov->x; /* back to "single" */
|
||||
lastrely = rely;
|
||||
}
|
||||
|
||||
/* Check if this X position intersects the rectangle */
|
||||
|
||||
if (absx >= rect->hstart && absx <= rect->hend)
|
||||
{
|
||||
/* It collides -- Check, maybe we can walk through
|
||||
* this wall
|
||||
*/
|
||||
|
||||
if (!IS_PASSABLE(rect))
|
||||
{
|
||||
/* It collides -- return a clipped value for the
|
||||
* new player position (which includes the a
|
||||
* stand-off constant)
|
||||
* NOTE: This returned value could be positive!
|
||||
*/
|
||||
|
||||
g_clip_rect = rect;
|
||||
return MIN_APPROACH_DISTANCE - rely;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Return the clipped value */
|
||||
|
||||
return reqdeltay;
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* Name: trv_ray_adjust_zpos
|
||||
*
|
||||
* Description:
|
||||
* Make sure that the player is standing on something!
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
trv_coord_t trv_ray_adjust_zpos(FAR struct trv_camera_s *pov,
|
||||
trv_coord_t height)
|
||||
{
|
||||
struct trv_rect_list_s *list; /* Points to the current Z plane rectangle */
|
||||
struct trv_rect_data_s *rect; /* Points to the rectangle data */
|
||||
|
||||
/* We will place the player's feet at the largest Z plane
|
||||
* which is lower the the player's eye level. We traverse
|
||||
* the the g_zplane list in order of increase Z values
|
||||
*/
|
||||
|
||||
for (list = g_zplane.head; list; list = list->flink)
|
||||
{
|
||||
rect = &list->d;
|
||||
|
||||
/* The Z plane list is an ordered list. If the next
|
||||
* plane is over the player's head, then the player
|
||||
* must be standing at "ground zero."
|
||||
*/
|
||||
|
||||
if (rect->plane >= pov->z)
|
||||
{
|
||||
return height - pov->z;
|
||||
}
|
||||
|
||||
/* Check if this plane if under the player */
|
||||
|
||||
if (pov->x >= rect->hstart && pov->x <= rect->hend &&
|
||||
pov->y >= rect->vstart && pov->y <= rect->vend)
|
||||
{
|
||||
/* We have the the smallest Z plane under the player
|
||||
* which is below the player's eye level (pov->z).
|
||||
* Determine the approach delta Z value to return
|
||||
*/
|
||||
|
||||
return height + rect->plane - pov->z;
|
||||
}
|
||||
}
|
||||
|
||||
/* No plane was found under the player. Set him at his
|
||||
* height above the "bottom" of the world
|
||||
*/
|
||||
|
||||
return height - pov->z;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user