Implement AABB SAT
parent
eaef3aa213
commit
a60713a723
|
@ -1,4 +1,5 @@
|
||||||
#include "header.h"
|
#include "header.h"
|
||||||
|
#include <math.h>
|
||||||
extern struct kinematic_obj_node *kinematic_HEAD;
|
extern struct kinematic_obj_node *kinematic_HEAD;
|
||||||
|
|
||||||
struct kinematic_obj init_kinematic_obj(int width, int height){
|
struct kinematic_obj init_kinematic_obj(int width, int height){
|
||||||
|
@ -27,47 +28,15 @@ void move(struct kinematic_obj *obj, Vector2 acceleration){
|
||||||
|
|
||||||
Rectangle collide_rect;
|
Rectangle collide_rect;
|
||||||
struct kinematic_obj_node *current;
|
struct kinematic_obj_node *current;
|
||||||
// Simplistic Collision Handling for AABB, Could add coeff of restitution?
|
// Self implement AABB SAT from Metanet
|
||||||
// TODO: Implement the slightly better method of collision from:
|
|
||||||
// https://hopefultoad.blogspot.com/2017/09/2d-aabb-collision-detection-and-response.html
|
|
||||||
|
|
||||||
// Also think about what happens if the square is completely inside the shape
|
// TODO: extend to multiple object collision, Might need to check distance
|
||||||
// Then extend to multiple object
|
|
||||||
// Might need to check distance
|
// Move the object and apply hitbox reduction
|
||||||
obj->velocity.x += acceleration.x * delta;
|
obj->velocity.x += acceleration.x * delta;
|
||||||
obj->pos.x += obj->velocity.x * delta;
|
obj->pos.x += obj->velocity.x * delta;
|
||||||
obj->rect.x = obj->pos.x + obj->dim_reduction[0];
|
obj->rect.x = obj->pos.x + obj->dim_reduction[0];
|
||||||
obj->rect.width = obj->ori_width - obj->dim_reduction[0] - obj->dim_reduction[2];
|
obj->rect.width = obj->ori_width - obj->dim_reduction[0] - obj->dim_reduction[2];
|
||||||
current = kinematic_HEAD;
|
|
||||||
while(current != NULL){
|
|
||||||
if(current->obj != obj){
|
|
||||||
if (CheckCollisionRecs(obj->rect, current->obj->rect)){
|
|
||||||
collide_rect = GetCollisionRec(obj->rect, current->obj->rect);
|
|
||||||
if(collide_rect.width < collide_rect.height){
|
|
||||||
if (!place_meeting(obj, (Vector2){-collide_rect.width,0})){
|
|
||||||
obj->rect.x -= collide_rect.width;
|
|
||||||
obj->pos.x -= collide_rect.width;
|
|
||||||
}else{
|
|
||||||
obj->rect.x += collide_rect.width;
|
|
||||||
obj->pos.x += collide_rect.width;
|
|
||||||
}
|
|
||||||
obj->velocity.x = 0;
|
|
||||||
}else{
|
|
||||||
if (!place_meeting(obj, (Vector2){0,-collide_rect.height})){
|
|
||||||
obj->rect.y -= collide_rect.height;
|
|
||||||
obj->pos.y -= collide_rect.height;
|
|
||||||
}else{
|
|
||||||
obj->rect.y += collide_rect.height;
|
|
||||||
obj->pos.y += collide_rect.height;
|
|
||||||
}
|
|
||||||
obj->velocity.y = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
current = current->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Repeat for y
|
|
||||||
obj->velocity.y += acceleration.y * delta;
|
obj->velocity.y += acceleration.y * delta;
|
||||||
obj->pos.y += obj->velocity.y * delta;
|
obj->pos.y += obj->velocity.y * delta;
|
||||||
obj->rect.y = obj->pos.y + obj->dim_reduction[1];
|
obj->rect.y = obj->pos.y + obj->dim_reduction[1];
|
||||||
|
@ -76,20 +45,39 @@ void move(struct kinematic_obj *obj, Vector2 acceleration){
|
||||||
current = kinematic_HEAD;
|
current = kinematic_HEAD;
|
||||||
while(current != NULL){
|
while(current != NULL){
|
||||||
if(current->obj != obj){
|
if(current->obj != obj){
|
||||||
if (CheckCollisionRecs(obj->rect, current->obj->rect)){
|
// SAT: If any projected axis is non overlapping, exit
|
||||||
collide_rect = GetCollisionRec(obj->rect, current->obj->rect);
|
if (obj->rect.x + obj->rect.width < current->obj->rect.x) goto iter;
|
||||||
if(collide_rect.width < collide_rect.height){
|
if (current->obj->rect.x + current->obj->rect.width < obj->rect.x) goto iter;
|
||||||
obj->rect.x -= sign(obj->velocity.x) * collide_rect.width;
|
if (obj->rect.y + obj->rect.height < current->obj->rect.y) goto iter;
|
||||||
obj->pos.x -= sign(obj->velocity.x) * collide_rect.width;
|
if (current->obj->rect.y + current->obj->rect.height < obj->rect.y) goto iter;
|
||||||
obj->velocity.x = 0;
|
|
||||||
}else{
|
// Move in the direction of the shorter movement
|
||||||
obj->rect.y -= sign(obj->velocity.y) * collide_rect.height;
|
double hmove, vmove;
|
||||||
obj->pos.y -= sign(obj->velocity.y) * collide_rect.height;
|
hmove = (current->obj->rect.width + obj->rect.width) / 2 - fabs(current->obj->rect.x - obj->rect.x + (current->obj->rect.width - obj->rect.width) / 2);
|
||||||
obj->velocity.y = 0;
|
vmove = (current->obj->rect.height + obj->rect.height) / 2 - fabs(current->obj->rect.y - obj->rect.y + (current->obj->rect.height - obj->rect.height) / 2);
|
||||||
|
if (hmove < vmove){
|
||||||
|
if (obj->rect.x + obj->rect.width / 2 < current->obj->rect.x + current->obj->rect.width / 2){
|
||||||
|
obj->rect.x -= hmove;
|
||||||
|
obj->pos.x -= hmove;
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
obj->rect.x += hmove;
|
||||||
|
obj->pos.x += hmove;
|
||||||
|
}
|
||||||
|
obj->velocity.x = 0;
|
||||||
|
}else{
|
||||||
|
if (obj->rect.y + obj->rect.height / 2 < current->obj->rect.y + current->obj->rect.height / 2){
|
||||||
|
obj->rect.y -= vmove;
|
||||||
|
obj->pos.y -= vmove;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
obj->rect.y += vmove;
|
||||||
|
obj->pos.y += vmove;
|
||||||
|
}
|
||||||
|
obj->velocity.y = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
current = current->next;
|
iter: current = current->next;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue