You've already forked Microtransactions64
mirror of
https://github.com/Print-and-Panic/Microtransactions64.git
synced 2026-01-21 10:17:19 -08:00
Merge branch 'nightly' of https://github.com/Reonu/HackerSM64 into nightly
This commit is contained in:
2
Makefile
2
Makefile
@@ -576,9 +576,7 @@ $(BUILD_DIR)/src/usb/usb.o: OPT_FLAGS := -O0
|
||||
$(BUILD_DIR)/src/usb/usb.o: CFLAGS += -Wno-unused-variable -Wno-sign-compare -Wno-unused-function
|
||||
$(BUILD_DIR)/src/usb/debug.o: OPT_FLAGS := -O0
|
||||
$(BUILD_DIR)/src/usb/debug.o: CFLAGS += -Wno-unused-parameter -Wno-maybe-uninitialized
|
||||
$(BUILD_DIR)/src/engine/surface_collision.o: OPT_FLAGS := -Os
|
||||
$(BUILD_DIR)/src/audio/*.o: OPT_FLAGS := -Os -fno-jump-tables
|
||||
$(BUILD_DIR)/src/game/*.o: OPT_FLAGS := -Ofast
|
||||
|
||||
ALL_DIRS := $(BUILD_DIR) $(addprefix $(BUILD_DIR)/,$(SRC_DIRS) asm/debug $(GODDARD_SRC_DIRS) $(LIBZ_SRC_DIRS) $(ULTRA_BIN_DIRS) $(BIN_DIRS) $(TEXTURE_DIRS) $(TEXT_DIRS) $(SOUND_SAMPLE_DIRS) $(addprefix levels/,$(LEVEL_DIRS)) rsp include) $(YAY0_DIR) $(addprefix $(YAY0_DIR)/,$(VERSION)) $(SOUND_BIN_DIR) $(SOUND_BIN_DIR)/sequences/$(VERSION)
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#define OBJ_FLAG_SILHOUETTE (1 << 19) // 0x00080000
|
||||
#define OBJ_FLAG_OCCLUDE_SILHOUETTE (1 << 20) // 0x00100000
|
||||
#define OBJ_FLAG_OPACITY_FROM_CAMERA_DIST (1 << 21) // 0x00200000
|
||||
#define OBJ_FLAG_UCODE_SMALL (1 << 22) // 0x00400000
|
||||
#define OBJ_FLAG_HITBOX_WAS_SET (1 << 30) // 0x40000000
|
||||
|
||||
/* oHeldState */
|
||||
|
||||
@@ -68,7 +68,6 @@ struct MemoryPool *gEffectsMemoryPool;
|
||||
|
||||
|
||||
uintptr_t sSegmentTable[32];
|
||||
uintptr_t sSegmentROMTable[32];
|
||||
u32 sPoolFreeSpace;
|
||||
u8 *sPoolStart;
|
||||
u8 *sPoolEnd;
|
||||
@@ -339,13 +338,13 @@ void *load_segment(s32 segment, u8 *srcStart, u8 *srcEnd, u32 side, u8 *bssStart
|
||||
addr = dynamic_dma_read(srcStart, srcEnd, side, TLB_PAGE_SIZE, (uintptr_t)bssEnd - (uintptr_t)bssStart);
|
||||
if (addr != NULL) {
|
||||
u8 *realAddr = (u8 *)ALIGN((uintptr_t)addr, TLB_PAGE_SIZE);
|
||||
set_segment_base_addr(segment, realAddr); sSegmentROMTable[segment] = (uintptr_t) srcStart;
|
||||
set_segment_base_addr(segment, realAddr);
|
||||
mapTLBPages(segment << 24, VIRTUAL_TO_PHYSICAL(realAddr), (srcEnd - srcStart) + ((uintptr_t)bssEnd - (uintptr_t)bssStart), segment);
|
||||
}
|
||||
} else {
|
||||
addr = dynamic_dma_read(srcStart, srcEnd, side, 0, 0);
|
||||
if (addr != NULL) {
|
||||
set_segment_base_addr(segment, addr); sSegmentROMTable[segment] = (uintptr_t) srcStart;
|
||||
set_segment_base_addr(segment, addr);
|
||||
}
|
||||
}
|
||||
#if PUPPYPRINT_DEBUG
|
||||
@@ -420,7 +419,7 @@ void *load_segment_decompress(s32 segment, u8 *srcStart, u8 *srcEnd) {
|
||||
decompress(compressed, dest);
|
||||
#endif
|
||||
osSyncPrintf("end decompress\n");
|
||||
set_segment_base_addr(segment, dest); sSegmentROMTable[segment] = (uintptr_t) srcStart;
|
||||
set_segment_base_addr(segment, dest);
|
||||
main_pool_free(compressed);
|
||||
}
|
||||
}
|
||||
@@ -459,7 +458,7 @@ void *load_segment_decompress_heap(u32 segment, u8 *srcStart, u8 *srcEnd) {
|
||||
#elif MIO0
|
||||
decompress(compressed, gDecompressionHeap);
|
||||
#endif
|
||||
set_segment_base_addr(segment, gDecompressionHeap); sSegmentROMTable[segment] = (uintptr_t) srcStart;
|
||||
set_segment_base_addr(segment, gDecompressionHeap);
|
||||
main_pool_free(compressed);
|
||||
}
|
||||
return gDecompressionHeap;
|
||||
|
||||
@@ -920,6 +920,7 @@ void cur_obj_update(void) {
|
||||
f32 distanceFromMario;
|
||||
BhvCommandProc bhvCmdProc;
|
||||
s32 bhvProcResult;
|
||||
s32 objListIndex;
|
||||
|
||||
// Calculate the distance from the object to Mario.
|
||||
if (objFlags & OBJ_FLAG_COMPUTE_DIST_TO_MARIO) {
|
||||
@@ -995,6 +996,15 @@ void cur_obj_update(void) {
|
||||
COND_BIT((!(objFlags & OBJ_FLAG_UCODE_LARGE )), gCurrentObject->header.gfx.node.flags, GRAPH_RENDER_UCODE_REJ );
|
||||
COND_BIT(( objFlags & OBJ_FLAG_SILHOUETTE ), gCurrentObject->header.gfx.node.flags, GRAPH_RENDER_SILHOUETTE );
|
||||
COND_BIT(( objFlags & OBJ_FLAG_OCCLUDE_SILHOUETTE ), gCurrentObject->header.gfx.node.flags, GRAPH_RENDER_OCCLUDE_SILHOUETTE);
|
||||
BehaviorScript *bhvScript = segmented_to_virtual(gCurrentObject->behavior);
|
||||
if ((bhvScript[0] >> 24) == 0) {
|
||||
objListIndex = (bhvScript[0] >> 16) & 0xFFFF;
|
||||
}
|
||||
if (objListIndex == OBJ_LIST_SURFACE && !(objFlags & OBJ_FLAG_UCODE_SMALL))
|
||||
{
|
||||
gCurrentObject->header.gfx.node.flags &= ~GRAPH_RENDER_UCODE_REJ;
|
||||
gCurrentObject->header.gfx.node.flags |= GRAPH_RENDER_UCODE_ZEX;
|
||||
}
|
||||
|
||||
#ifdef OBJ_OPACITY_BY_CAM_DIST
|
||||
if (objFlags & OBJ_FLAG_OPACITY_FROM_CAMERA_DIST) {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#define GRAPH_RENDER_SILHOUETTE (1 << 6) // 0x0040
|
||||
#define GRAPH_RENDER_OCCLUDE_SILHOUETTE (1 << 7) // 0x0080
|
||||
#define GRAPH_RENDER_UCODE_REJ (1 << 8) // 0x0100
|
||||
#define GRAPH_RENDER_UCODE_ZEX (1 << 9) // 0x0200
|
||||
|
||||
// The amount of bits to use for the above flags out of a s16 variable.
|
||||
// The remaining bits to the left are used for the render layers.
|
||||
|
||||
@@ -1116,3 +1116,165 @@ s32 anim_spline_poll(Vec3f result) {
|
||||
|
||||
return hasEnded;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* RAYCASTING *
|
||||
**************************************************/
|
||||
|
||||
#define RAY_OFFSET 30.0f /*How many units to extrapolate surfaces when testing for a raycast*/
|
||||
#define RAY_STEPS 4 /*How many steps to do when casting rays, default to quartersteps.*/
|
||||
|
||||
s32 ray_surface_intersect(Vec3f orig, Vec3f dir, f32 dir_length, struct Surface *surface, Vec3f hit_pos, f32 *length) {
|
||||
Vec3f v0, v1, v2, e1, e2, h, s, q;
|
||||
f32 a, f, u, v;
|
||||
Vec3f add_dir;
|
||||
Vec3f norm;
|
||||
// Ignore certain surface types.
|
||||
if (surface->type == SURFACE_INTANGIBLE || surface->flags & SURFACE_FLAG_NO_CAM_COLLISION) return FALSE;
|
||||
// Get surface normal and some other stuff
|
||||
vec3_set(norm, 0, surface->normal.y, 0);
|
||||
vec3_mul_val(norm, RAY_OFFSET);
|
||||
vec3_copy(v0, surface->vertex1);
|
||||
vec3_copy(v1, surface->vertex2);
|
||||
vec3_copy(v2, surface->vertex3);
|
||||
vec3_add( v0, norm);
|
||||
vec3_add( v1, norm);
|
||||
vec3_add( v2, norm);
|
||||
vec3_diff(e1, v1, v0);
|
||||
vec3_diff(e2, v2, v0);
|
||||
vec3_cross(h, dir, e2);
|
||||
// Check if we're perpendicular from the surface
|
||||
a = vec3_dot(e1, h);
|
||||
if ((a > -NEAR_ZERO) && (a < NEAR_ZERO)) return FALSE;
|
||||
// Check if we're making contact with the surface
|
||||
f = 1.0f / a;
|
||||
vec3_diff(s, orig, v0);
|
||||
u = f * vec3_dot(s, h);
|
||||
if ((u < 0.0f) || (u > 1.0f)) return FALSE;
|
||||
vec3_cross(q, s, e1);
|
||||
v = f * vec3_dot(dir, q);
|
||||
if ((v < 0.0f) || ((u + v) > 1.0f)) return FALSE;
|
||||
// Get the length between our origin and the surface contact point
|
||||
*length = f * vec3_dot(e2, q);
|
||||
if (*length <= 0.00001 || *length > dir_length) return FALSE;
|
||||
// Successful contact
|
||||
vec3f_copy(add_dir, dir);
|
||||
vec3_mul_val(add_dir, *length);
|
||||
vec3_sum(hit_pos, orig, add_dir);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length) {
|
||||
s32 hit;
|
||||
f32 length;
|
||||
Vec3f chk_hit_pos;
|
||||
f32 top, bottom;
|
||||
#if PUPPYPRINT_DEBUG
|
||||
OSTime first = osGetTime();
|
||||
#endif
|
||||
|
||||
// Get upper and lower bounds of ray
|
||||
if (dir[1] >= 0.0f) {
|
||||
top = (orig[1] + (dir[1] * dir_length));
|
||||
bottom = orig[1];
|
||||
} else {
|
||||
top = orig[1];
|
||||
bottom = (orig[1] + (dir[1] * dir_length));
|
||||
}
|
||||
|
||||
// Iterate through every surface of the list
|
||||
for (; list != NULL; list = list->next) {
|
||||
// Reject surface if out of vertical bounds
|
||||
if (list->surface->lowerY > top || list->surface->upperY < bottom) continue;
|
||||
// Check intersection between the ray and this surface
|
||||
if ((hit = ray_surface_intersect(orig, dir, dir_length, list->surface, chk_hit_pos, &length)) && (length <= *max_length)) {
|
||||
*hit_surface = list->surface;
|
||||
vec3f_copy(hit_pos, chk_hit_pos);
|
||||
*max_length = length;
|
||||
}
|
||||
}
|
||||
#if PUPPYPRINT_DEBUG
|
||||
collisionTime[perfIteration] += (osGetTime() - first);
|
||||
#endif
|
||||
}
|
||||
|
||||
void find_surface_on_ray_cell(s32 cellX, s32 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] > -NEAR_ONE) && (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] < NEAR_ONE) && (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);
|
||||
}
|
||||
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, s32 flags) {
|
||||
s32 cellZ, cellX, cellPrevX, cellPrevZ;
|
||||
f32 fCellZ, fCellX;
|
||||
Vec3f normalized_dir;
|
||||
f32 step;
|
||||
s32 i;
|
||||
|
||||
// Set that no surface has been hit
|
||||
*hit_surface = NULL;
|
||||
vec3_sum(hit_pos, orig, dir);
|
||||
|
||||
// Get normalized direction
|
||||
f32 dir_length = vec3_mag(dir);
|
||||
f32 max_length = dir_length;
|
||||
vec3f_copy(normalized_dir, dir);
|
||||
vec3f_normalize(normalized_dir);
|
||||
|
||||
// Get our cell coordinate
|
||||
fCellX = (orig[0] + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
|
||||
fCellZ = (orig[2] + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
|
||||
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, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get cells we cross using DDA
|
||||
if (ABS(dir[0]) >= ABS(dir[2])) {
|
||||
step = RAY_STEPS * ABS(dir[0]) / CELL_SIZE;
|
||||
} else {
|
||||
step = RAY_STEPS * ABS(dir[2]) / CELL_SIZE;
|
||||
}
|
||||
f32 dx = dir[0] / step / CELL_SIZE;
|
||||
f32 dz = dir[2] / step / CELL_SIZE;
|
||||
|
||||
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, flags);
|
||||
|
||||
// Move cell coordinate
|
||||
fCellX += dx;
|
||||
fCellZ += dz;
|
||||
cellPrevX = cellX;
|
||||
cellPrevZ = cellZ;
|
||||
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, flags);
|
||||
find_surface_on_ray_cell(cellPrevX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -530,5 +530,6 @@ void spline_get_weights(Vec4f result, f32 t, UNUSED s32 c);
|
||||
void anim_spline_init(Vec4s *keyFrames);
|
||||
s32 anim_spline_poll(Vec3f result);
|
||||
void mtxf_rot_trans_mul(Vec3s rot, Vec3f trans, Mat4 dest, Mat4 src);
|
||||
void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos, s32 flags);
|
||||
|
||||
#endif // MATH_UTIL_H
|
||||
|
||||
@@ -832,166 +832,3 @@ s32 unused_resolve_floor_or_ceil_collisions(s32 checkCeil, f32 *px, f32 *py, f32
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**************************************************
|
||||
* RAYCASTING *
|
||||
**************************************************/
|
||||
|
||||
#define RAY_OFFSET 30.0f /*How many units to extrapolate surfaces when testing for a raycast*/
|
||||
#define RAY_STEPS 4 /*How many steps to do when casting rays, default to quartersteps.*/
|
||||
|
||||
s32 ray_surface_intersect(Vec3f orig, Vec3f dir, f32 dir_length, struct Surface *surface, Vec3f hit_pos, f32 *length) {
|
||||
Vec3f v0, v1, v2, e1, e2, h, s, q;
|
||||
f32 a, f, u, v;
|
||||
Vec3f add_dir;
|
||||
Vec3f norm;
|
||||
// Ignore certain surface types.
|
||||
if (surface->type == SURFACE_INTANGIBLE || surface->flags & SURFACE_FLAG_NO_CAM_COLLISION) return FALSE;
|
||||
// Get surface normal and some other stuff
|
||||
vec3_set(norm, 0, surface->normal.y, 0);
|
||||
vec3_mul_val(norm, RAY_OFFSET);
|
||||
vec3_copy(v0, surface->vertex1);
|
||||
vec3_copy(v1, surface->vertex2);
|
||||
vec3_copy(v2, surface->vertex3);
|
||||
vec3_add( v0, norm);
|
||||
vec3_add( v1, norm);
|
||||
vec3_add( v2, norm);
|
||||
vec3_diff(e1, v1, v0);
|
||||
vec3_diff(e2, v2, v0);
|
||||
vec3_cross(h, dir, e2);
|
||||
// Check if we're perpendicular from the surface
|
||||
a = vec3_dot(e1, h);
|
||||
if ((a > -NEAR_ZERO) && (a < NEAR_ZERO)) return FALSE;
|
||||
// Check if we're making contact with the surface
|
||||
f = 1.0f / a;
|
||||
vec3_diff(s, orig, v0);
|
||||
u = f * vec3_dot(s, h);
|
||||
if ((u < 0.0f) || (u > 1.0f)) return FALSE;
|
||||
vec3_cross(q, s, e1);
|
||||
v = f * vec3_dot(dir, q);
|
||||
if ((v < 0.0f) || ((u + v) > 1.0f)) return FALSE;
|
||||
// Get the length between our origin and the surface contact point
|
||||
*length = f * vec3_dot(e2, q);
|
||||
if (*length <= 0.00001 || *length > dir_length) return FALSE;
|
||||
// Successful contact
|
||||
vec3f_copy(add_dir, dir);
|
||||
vec3_mul_val(add_dir, *length);
|
||||
vec3_sum(hit_pos, orig, add_dir);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void find_surface_on_ray_list(struct SurfaceNode *list, Vec3f orig, Vec3f dir, f32 dir_length, struct Surface **hit_surface, Vec3f hit_pos, f32 *max_length) {
|
||||
s32 hit;
|
||||
f32 length;
|
||||
Vec3f chk_hit_pos;
|
||||
f32 top, bottom;
|
||||
#if PUPPYPRINT_DEBUG
|
||||
OSTime first = osGetTime();
|
||||
#endif
|
||||
|
||||
// Get upper and lower bounds of ray
|
||||
if (dir[1] >= 0.0f) {
|
||||
top = (orig[1] + (dir[1] * dir_length));
|
||||
bottom = orig[1];
|
||||
} else {
|
||||
top = orig[1];
|
||||
bottom = (orig[1] + (dir[1] * dir_length));
|
||||
}
|
||||
|
||||
// Iterate through every surface of the list
|
||||
for (; list != NULL; list = list->next) {
|
||||
// Reject surface if out of vertical bounds
|
||||
if (list->surface->lowerY > top || list->surface->upperY < bottom) continue;
|
||||
// Check intersection between the ray and this surface
|
||||
if ((hit = ray_surface_intersect(orig, dir, dir_length, list->surface, chk_hit_pos, &length)) && (length <= *max_length)) {
|
||||
*hit_surface = list->surface;
|
||||
vec3f_copy(hit_pos, chk_hit_pos);
|
||||
*max_length = length;
|
||||
}
|
||||
}
|
||||
#if PUPPYPRINT_DEBUG
|
||||
collisionTime[perfIteration] += (osGetTime() - first);
|
||||
#endif
|
||||
}
|
||||
|
||||
void find_surface_on_ray_cell(s32 cellX, s32 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] > -NEAR_ONE) && (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] < NEAR_ONE) && (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);
|
||||
}
|
||||
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, s32 flags) {
|
||||
s32 cellZ, cellX, cellPrevX, cellPrevZ;
|
||||
f32 fCellZ, fCellX;
|
||||
Vec3f normalized_dir;
|
||||
f32 step;
|
||||
s32 i;
|
||||
|
||||
// Set that no surface has been hit
|
||||
*hit_surface = NULL;
|
||||
vec3_sum(hit_pos, orig, dir);
|
||||
|
||||
// Get normalized direction
|
||||
f32 dir_length = vec3_mag(dir);
|
||||
f32 max_length = dir_length;
|
||||
vec3f_copy(normalized_dir, dir);
|
||||
vec3f_normalize(normalized_dir);
|
||||
|
||||
// Get our cell coordinate
|
||||
fCellX = (orig[0] + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
|
||||
fCellZ = (orig[2] + LEVEL_BOUNDARY_MAX) / CELL_SIZE;
|
||||
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, flags);
|
||||
return;
|
||||
}
|
||||
|
||||
// Get cells we cross using DDA
|
||||
if (ABS(dir[0]) >= ABS(dir[2])) {
|
||||
step = RAY_STEPS * ABS(dir[0]) / CELL_SIZE;
|
||||
} else {
|
||||
step = RAY_STEPS * ABS(dir[2]) / CELL_SIZE;
|
||||
}
|
||||
f32 dx = dir[0] / step / CELL_SIZE;
|
||||
f32 dz = dir[2] / step / CELL_SIZE;
|
||||
|
||||
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, flags);
|
||||
|
||||
// Move cell coordinate
|
||||
fCellX += dx;
|
||||
fCellZ += dz;
|
||||
cellPrevX = cellX;
|
||||
cellPrevZ = cellZ;
|
||||
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, flags);
|
||||
find_surface_on_ray_cell(cellPrevX, cellZ, orig, normalized_dir, dir_length, hit_surface, hit_pos, &max_length, flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -46,6 +46,5 @@ s32 find_water_level_and_floor(s32 x, s32 z, struct Surface **pfloor);
|
||||
s32 find_water_level(s32 x, s32 z);
|
||||
s32 find_poison_gas_level(s32 x, s32 z);
|
||||
void debug_surface_list_info(f32 xPos, f32 zPos);
|
||||
void find_surface_on_ray(Vec3f orig, Vec3f dir, struct Surface **hit_surface, Vec3f hit_pos, s32 flags);
|
||||
|
||||
#endif // SURFACE_COLLISION_H
|
||||
|
||||
@@ -224,7 +224,7 @@ void king_bobomb_act_5(void) { // bobomb returns home
|
||||
if (o->oPosY < o->oHomeY)
|
||||
o->oVelY = 100.0f;
|
||||
else {
|
||||
arc_to_goal_pos(&o->oPosVec, &o->oPosVec, 100.0f, -4.0f);
|
||||
arc_to_goal_pos(&o->oHomeX, &o->oPosVec, 100.0f, -4.0f);
|
||||
o->oSubAction++;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -210,7 +210,6 @@ extern s32 gSurfacesAllocated;
|
||||
void iterate_surfaces_visual(s32 x, s32 z, Vtx *verts) {
|
||||
struct SurfaceNode *node;
|
||||
struct Surface *surf;
|
||||
s32 cellX, cellZ;
|
||||
s32 i = 0;
|
||||
s32 col[3] = {0xFF, 0x00, 0x00};
|
||||
|
||||
@@ -337,7 +336,6 @@ void visual_surface_display(Vtx *verts, s32 iteration)
|
||||
s32 iterate_surface_count(s32 x, s32 z)
|
||||
{
|
||||
struct SurfaceNode *node;
|
||||
s32 cellX, cellZ;
|
||||
s32 i = 0;
|
||||
s32 j = 0;
|
||||
TerrainData *p = gEnvironmentRegions;
|
||||
@@ -350,8 +348,8 @@ s32 iterate_surface_count(s32 x, s32 z)
|
||||
return 0;
|
||||
}
|
||||
|
||||
cellX = GET_CELL_COORD(x);
|
||||
cellZ = GET_CELL_COORD(z);
|
||||
s32 cellX = GET_CELL_COORD(x);
|
||||
s32 cellZ = GET_CELL_COORD(z);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user