This commit is contained in:
Reonu
2021-08-17 18:42:35 +01:00
2 changed files with 45 additions and 29 deletions

View File

@@ -503,7 +503,7 @@ void puppycam_input_pitch(void)
if (gPlayer1Controller->buttonDown & D_CBUTTONS || gPuppyCam.stick2[1] != 0)
gPuppyCam.pitchAcceleration += 50*(gPuppyCam.options.sensitivityY/100.f);
else
gPuppyCam.pitchAcceleration = approach_f32_asymptotic(gPuppyCam.pitchAcceleration, 0, DECELERATION);
gPuppyCam.pitchAcceleration = 0;
gPuppyCam.pitchAcceleration = CLAMP(gPuppyCam.pitchAcceleration, -100, 100);
@@ -531,7 +531,7 @@ void puppycam_input_zoom(void)
void puppycam_input_centre(void)
{
s32 inputDefault = L_TRIG;
if (gPuppyCam.options.inputType == 3)
if (gPuppyCam.options.inputType == 2)
inputDefault = R_TRIG;
//Handles L button centering.
if (gPlayer1Controller->buttonPressed & inputDefault && gPuppyCam.flags & PUPPYCAM_BEHAVIOUR_YAW_ROTATION &&
@@ -559,17 +559,17 @@ static void puppycam_input_hold_preset1(f32 ivX)
if ((gPlayer1Controller->buttonDown & L_CBUTTONS && !gPuppyCam.options.analogue) || gPuppyCam.stick2[0] != 0)
{
gPuppyCam.yawAcceleration -= 50*(gPuppyCam.options.sensitivityX/100.f);
gPuppyCam.yawAcceleration -= 75*(gPuppyCam.options.sensitivityX/100.f);
gPuppyCam.framesSinceC[0] = 0;
}
else
if ((gPlayer1Controller->buttonDown & R_CBUTTONS && !gPuppyCam.options.analogue) || gPuppyCam.stick2[0] != 0)
{
gPuppyCam.yawAcceleration += 50*(gPuppyCam.options.sensitivityX/100.f);
gPuppyCam.yawAcceleration += 75*(gPuppyCam.options.sensitivityX/100.f);
gPuppyCam.framesSinceC[1] = 0;
}
else
gPuppyCam.yawAcceleration = approach_f32_asymptotic(gPuppyCam.yawAcceleration, 0, DECELERATION);
gPuppyCam.yawAcceleration = 0;
}
//An alternative control scheme, hold the button down to turn the camera, or press it once to turn it quickly.
@@ -604,15 +604,15 @@ static void puppycam_input_hold_preset2(f32 ivX)
//Handles continuous movement as normal, as long as the button's held.
if (gPlayer1Controller->buttonDown & L_CBUTTONS)
{
gPuppyCam.yawAcceleration -= 10*(gPuppyCam.options.sensitivityX/100.f);
gPuppyCam.yawAcceleration -= 75*(gPuppyCam.options.sensitivityX/100.f);
}
else
if (gPlayer1Controller->buttonDown & R_CBUTTONS)
{
gPuppyCam.yawAcceleration += 10*(gPuppyCam.options.sensitivityX/100.f);
gPuppyCam.yawAcceleration += 75*(gPuppyCam.options.sensitivityX/100.f);
}
else
gPuppyCam.yawAcceleration = approach_f32_asymptotic(gPuppyCam.yawAcceleration, 0, DECELERATION);
gPuppyCam.yawAcceleration = 0;
}
//Another alternative control scheme. This one aims to mimic the parallel camera scheme down to the last bit from the original game.
@@ -636,7 +636,7 @@ static void puppycam_input_hold_preset3(f32 ivX)
gPuppyCam.yawAcceleration -= (gPuppyCam.options.sensitivityX/100.f)*stickMag[0];
}
else
gPuppyCam.yawAcceleration = approach_f32_asymptotic(gPuppyCam.yawAcceleration, 0, DECELERATION);
gPuppyCam.yawAcceleration = 0;
if (ABS(gPlayer1Controller->rawStickY) > DEADZONE)
{
@@ -1029,37 +1029,44 @@ void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f
}
}
void find_surface_on_ray_cell(s16 cellX, s16 cellZ, Vec3f orig, Vec3f normalized_dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length)
void find_surface_on_ray_cell(s16 cellX, s16 cellZ, Vec3f orig, Vec3f normalized_dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length, s32 flags)
{
// Skip if OOB
if (cellX >= 0 && cellX <= (NUM_CELLS - 1) && cellZ >= 0 && cellZ <= (NUM_CELLS - 1))
{
// Iterate through each surface in this partition
if (normalized_dir[1] > -0.99999f)
if (normalized_dir[1] > -0.99999f && flags & RAYCAST_FIND_CEIL)
{
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_CEILS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
}
if (normalized_dir[1] < 0.99999f)
if (normalized_dir[1] < 0.99999f && flags & RAYCAST_FIND_FLOOR)
{
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_FLOORS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
}
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
if (flags & RAYCAST_FIND_WALL)
{
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WALLS].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
}
if (flags & RAYCAST_FIND_WATER)
{
find_surface_on_ray_list(gStaticSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
find_surface_on_ray_list(gDynamicSurfacePartition[cellZ][cellX][SPATIAL_PARTITION_WATER].next, orig, normalized_dir, dir_length, hit_surface, hit_pos, max_length);
}
}
}
void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos)
void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos, s32 flags)
{
f32 max_length;
s16 cellZ, cellX, cellPrevX, cellPrevZ;
s32 cellZ, cellX, cellPrevX, cellPrevZ;
f32 fCellZ, fCellX;
f32 dir_length;
Vec3f normalized_dir;
f32 step, dx, dz;
u32 i;
s32 i;
// Set that no surface has been hit
*hit_surface = NULL;
@@ -1074,13 +1081,15 @@ void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Ve
// Get our cell coordinate
fCellX = (orig[0] + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
fCellZ = (orig[2] + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
cellX = (s16)fCellX;
cellZ = (s16)fCellZ;
cellX = fCellX;
cellZ = fCellZ;
cellPrevX = cellX;
cellPrevZ = cellZ;
// Don't do DDA if straight down
if (normalized_dir[1] >= 0.99999f || normalized_dir[1] <= -0.99999f)
{
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length);
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags);
return;
}
@@ -1095,20 +1104,20 @@ void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Ve
for (i = 0; i < step && *hit_surface == NULL; i++)
{
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length);
find_surface_on_ray_cell(cellX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags);
// Move cell coordinate
fCellX += dx;
fCellZ += dz;
cellPrevX = cellX;
cellPrevZ = cellZ;
cellX = (s16)fCellX;
cellZ = (s16)fCellZ;
cellX = fCellX;
cellZ = fCellZ;
if ((cellPrevX != cellX) && (cellPrevZ != cellZ))
{
find_surface_on_ray_cell(cellX, cellPrevZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length);
find_surface_on_ray_cell(cellPrevX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length);
find_surface_on_ray_cell(cellX, cellPrevZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags);
find_surface_on_ray_cell(cellPrevX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags);
}
}
}
@@ -1475,8 +1484,8 @@ static void puppycam_collision(void)
camdir[1][1] = camdir[0][1];
camdir[1][2] = camdir[0][2];
find_surface_on_ray(target[0], camdir[0], &surf[0], hitpos[0]);
find_surface_on_ray(target[1], camdir[1], &surf[1], hitpos[1]);
find_surface_on_ray(target[0], camdir[0], &surf[0], hitpos[0], RAYCAST_FIND_FLOOR | RAYCAST_FIND_CEIL | RAYCAST_FIND_WALL);
find_surface_on_ray(target[1], camdir[1], &surf[1], hitpos[1], RAYCAST_FIND_FLOOR | RAYCAST_FIND_CEIL | RAYCAST_FIND_WALL);
resolve_and_return_wall_collisions(hitpos[0], 0.0f, 25.0f);
resolve_and_return_wall_collisions(hitpos[1], 0.0f, 25.0f);
dist[0] = ((target[0][0] - hitpos[0][0]) * (target[0][0] - hitpos[0][0]) + (target[0][1] - hitpos[0][1]) * (target[0][1] - hitpos[0][1]) + (target[0][2] - hitpos[0][2]) * (target[0][2] - hitpos[0][2]));

View File

@@ -25,6 +25,13 @@
#define PUPPYCAM_MODE3_ZOOMED_OUT 0x4
#define PUPPYCAM_MODE3_ENTER_FIRST_PERSON 0x8
#define RAYCAST_FIND_FLOOR (0x1)
#define RAYCAST_FIND_WALL (0x2)
#define RAYCAST_FIND_CEIL (0x4)
#define RAYCAST_FIND_WATER (0x8)
#define RAYCAST_FIND_ALL (0xFFFFFFFF)
#include "include/command_macros_base.h"
#define PUPPYVOLUME(x, y, z, length, height, width, yaw, functionptr, anglesptr, addflags, removeflags, flagpersistance, room, shape) \
@@ -166,7 +173,7 @@ extern void puppycam_boot(void);
extern void puppycam_init(void);
extern void puppycam_loop(void);
extern void puppycam_shake(s16 x, s16 y, s16 z);
extern void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos);
extern void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos, s32 flags);
extern f32 approach_f32_asymptotic(f32 current, f32 target, f32 multiplier);
extern void puppycam_default_config(void);
extern s16 LENCOS(s16 length, s16 direction);