diff --git a/main b/main index 3f4f04e..9ad7af8 100755 Binary files a/main and b/main differ diff --git a/main.c b/main.c index 9dae9bf..3c6d3c5 100644 --- a/main.c +++ b/main.c @@ -4,7 +4,6 @@ #include #include "objects.h" - struct global { const int scwidth, scheight; int fps; @@ -15,12 +14,6 @@ struct global { struct global gl = {1600, 900, 144, {}, 0, 15}; -float min(float a, float b) -{return a>b?b:a;} - -float max(float a, float b) -{return a>b?a:b;} - void addobj(object *obj) { gl.objs[gl.obj_count++] = obj; @@ -35,43 +28,6 @@ void drawobjs() } } -Vector3 gravitation_force(object *obj1, object *obj2) -{ - const double GRAVITY_FACTOR = 1; - Vector3 force; - double dist, mass, total_g; - mass = obj1->mass * obj2->mass; - force = Vector3Subtract(obj2->pos, obj1->pos); - - dist = Vector3Length(force); - force = Vector3Normalize(force); - - dist = max(dist, obj1->r+obj2->r); - - total_g = GRAVITY_FACTOR * mass / (dist * dist); - force = Vector3Scale(force, total_g); - - return force; -} - -void integrate_g(object *obj1, object *obj2, Vector3 force) -{ - Vector3 acc; - double f, a; - - f = Vector3Length(force); - //acc = Vector3Scale(Vector3Subtract(obj1->pos, obj2->pos), f); - acc = force; - - a = f / obj1->mass; - acc = Vector3Scale(Vector3Normalize(acc), a*GetFrameTime()); - obj1->vel = Vector3Add(obj1->vel, acc); - - a = f / obj2->mass; - acc = Vector3Scale(Vector3Normalize(acc), a*GetFrameTime()); - obj2->vel = Vector3Add(obj2->vel, acc); -} - void updateobjs() { for (int i = 0; i < gl.obj_count; i++) @@ -93,6 +49,10 @@ void updateobjs() //{ // Vector3SubtractValue(obj->pos, min_dist_delta); //} + if (Vector3Distance(obj->pos, obj2->pos) < obj->r+obj2->r+0.01f) + { + resolve_collision(obj, obj2); + } } float ratio_speed_to_terminal = Vector3Length(obj->vel)/gl.terminal_v; if (Vector3Length(obj->vel) > gl.terminal_v) @@ -118,10 +78,9 @@ int main(void) { InitWindow(gl.scwidth, gl.scheight, "raylib engine"); SetTargetFPS(gl.fps); - addobj(newobj((Vector3){0, 20, 0}, 3, RED, 1, 50000)); - addobj(newobj((Vector3){4, 20, 0}, 1, BLUE, 1, 1000)); - addobj(newobj((Vector3){-6, 18, 0}, 2, GREEN, 1, 2000)); - gl.objs[1]->vel = (Vector3){0, 0, 2}; + addobj(newobj((Vector3){0, 20, 0}, 1, RED, 1, 1000)); + addobj(newobj((Vector3){8, 20, 0}, 2, BLUE, 1, 2000)); + gl.objs[1]->vel = (Vector3){0, 0, 0}; Camera3D camera = {{0, 20, -30}, {0, 0, 0}, {0, 1, 0}, 45, CAMERA_PERSPECTIVE}; DisableCursor(); @@ -133,7 +92,7 @@ int main(void) { { ClearBackground(BLACK); BeginMode3D(camera); - DrawPlane((Vector3){0, 0, 0}, (Vector2){100, 100}, GRAY); + DrawPlane((Vector3){0, 0, 0}, (Vector2){500, 500}, RAYWHITE); updateobjs(); drawobjs(); EndMode3D(); diff --git a/objects.c b/objects.c new file mode 100644 index 0000000..87c874f --- /dev/null +++ b/objects.c @@ -0,0 +1,101 @@ +#include "objects.h" +#include +#include + +#define min(a, b) (a>b?b:a); +#define max(a, b) (a>b?a:b); + +object *newobj(Vector3 pos, double r, Color c, double rest, double m) +{ + object *obj = (object*)malloc(sizeof(object)); + obj->r = r; + obj->pos = pos; + obj->color = c; + obj->vel = (Vector3){0, 0, 0}; + obj->restitution = rest; + obj->mass = m; + return obj; +} + +Vector3 gravitation_force(object *obj1, object *obj2) +{ + const double GRAVITY_FACTOR = 1; + Vector3 force; + double dist, mass, total_g; + mass = obj1->mass * obj2->mass; + force = Vector3Subtract(obj2->pos, obj1->pos); + + dist = Vector3Length(force); + force = Vector3Normalize(force); + + dist = max(dist, obj1->r+obj2->r); + + total_g = GRAVITY_FACTOR * mass / (dist * dist); + force = Vector3Scale(force, total_g); + + return force; +} + +void integrate_g(object *obj1, object *obj2, Vector3 force) +{ + Vector3 acc; + double f, a; + + f = Vector3Length(force); + //acc = Vector3Scale(Vector3Subtract(obj1->pos, obj2->pos), f); + acc = force; + + a = f / obj1->mass; + acc = Vector3Scale(Vector3Normalize(acc), a*GetFrameTime()); + obj1->vel = Vector3Add(obj1->vel, acc); + + a = f / obj2->mass; + acc = Vector3Scale(Vector3Normalize(acc), a*GetFrameTime()); + obj2->vel = Vector3Add(obj2->vel, acc); +} + +void resolve_collision(object *obj1, object *obj2) +{ + Vector3 normal = Vector3Subtract(obj1->pos, obj2->pos); + float distsq = Vector3LengthSqr(normal); + float sumrad = obj1->r+obj2->r; + float mindistsq = sumrad*sumrad; + + if (distsq < mindistsq) { + float dist = sqrtf(distsq); + + if (dist == 0) { + normal = Vector3RotateByAxisAngle(Vector3One(), (Vector3){0, 1, 1}, rand()*360); + dist = sumrad; + } else { + normal = Vector3Scale(normal, 1.0f / dist); + } + + float overlap = sumrad - dist; + Vector3 separation = Vector3Scale(normal, overlap / 2.0f); + + obj1->pos = Vector3Subtract(obj1->pos, separation); + obj2->pos = Vector3Add(obj2->pos, separation); + + } else { + normal = Vector3Normalize(normal); + } + + float vel1_normal = Vector3DotProduct(obj1->vel, normal); + float vel2_normal = Vector3DotProduct(obj2->vel, normal); + + if (vel1_normal - vel2_normal > 0) return; + + float totalmass = obj1->mass + obj2->mass; + float vel1_normal_final = (obj1->mass * vel1_normal + obj2->mass * vel2_normal - obj2->mass * obj2->restitution * (vel1_normal - vel2_normal)) / totalmass; + float vel2_normal_final = (obj1->mass * vel1_normal + obj2->mass * vel2_normal - obj2->mass * obj1->restitution * (vel2_normal - vel1_normal)) / totalmass; + + Vector3 vel1_tang = Vector3Subtract(obj1->vel, Vector3Scale(normal, vel1_normal)); + Vector3 vel2_tang = Vector3Subtract(obj2->vel, Vector3Scale(normal, vel2_normal)); + + obj1->vel = Vector3Add(Vector3Scale(normal, vel1_normal_final), vel1_tang); + obj2->vel = Vector3Add(Vector3Scale(normal, vel2_normal_final), vel2_tang); + +} + + diff --git a/objects.h b/objects.h index 6b0743b..229e1a2 100644 --- a/objects.h +++ b/objects.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include typedef struct { @@ -11,14 +12,8 @@ typedef struct { double mass; } object; -object *newobj(Vector3 pos, double r, Color c, double rest, double m) -{ - object *obj = (object*)malloc(sizeof(object)); - obj->r = r; - obj->pos = pos; - obj->color = c; - obj->vel = (Vector3){0, 0, 0}; - obj->restitution = rest; - obj->mass = m; - return obj; -} + +object *newobj(Vector3 pos, double r, Color c, double rest, double m); +Vector3 gravitation_force(object *obj1, object *obj2); +void integrate_g(object *obj1, object *obj2, Vector3 force); +void resolve_collision(object *obj1, object *obj2);