le palle si scontrano
This commit is contained in:
57
main.c
57
main.c
@@ -4,7 +4,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "objects.h"
|
#include "objects.h"
|
||||||
|
|
||||||
|
|
||||||
struct global {
|
struct global {
|
||||||
const int scwidth, scheight;
|
const int scwidth, scheight;
|
||||||
int fps;
|
int fps;
|
||||||
@@ -15,12 +14,6 @@ struct global {
|
|||||||
|
|
||||||
struct global gl = {1600, 900, 144, {}, 0, 15};
|
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)
|
void addobj(object *obj)
|
||||||
{
|
{
|
||||||
gl.objs[gl.obj_count++] = 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()
|
void updateobjs()
|
||||||
{
|
{
|
||||||
for (int i = 0; i < gl.obj_count; i++)
|
for (int i = 0; i < gl.obj_count; i++)
|
||||||
@@ -93,6 +49,10 @@ void updateobjs()
|
|||||||
//{
|
//{
|
||||||
// Vector3SubtractValue(obj->pos, min_dist_delta);
|
// 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;
|
float ratio_speed_to_terminal = Vector3Length(obj->vel)/gl.terminal_v;
|
||||||
if (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");
|
InitWindow(gl.scwidth, gl.scheight, "raylib engine");
|
||||||
|
|
||||||
SetTargetFPS(gl.fps);
|
SetTargetFPS(gl.fps);
|
||||||
addobj(newobj((Vector3){0, 20, 0}, 3, RED, 1, 50000));
|
addobj(newobj((Vector3){0, 20, 0}, 1, RED, 1, 1000));
|
||||||
addobj(newobj((Vector3){4, 20, 0}, 1, BLUE, 1, 1000));
|
addobj(newobj((Vector3){8, 20, 0}, 2, BLUE, 1, 2000));
|
||||||
addobj(newobj((Vector3){-6, 18, 0}, 2, GREEN, 1, 2000));
|
gl.objs[1]->vel = (Vector3){0, 0, 0};
|
||||||
gl.objs[1]->vel = (Vector3){0, 0, 2};
|
|
||||||
Camera3D camera = {{0, 20, -30}, {0, 0, 0}, {0, 1, 0}, 45, CAMERA_PERSPECTIVE};
|
Camera3D camera = {{0, 20, -30}, {0, 0, 0}, {0, 1, 0}, 45, CAMERA_PERSPECTIVE};
|
||||||
DisableCursor();
|
DisableCursor();
|
||||||
|
|
||||||
@@ -133,7 +92,7 @@ int main(void) {
|
|||||||
{
|
{
|
||||||
ClearBackground(BLACK);
|
ClearBackground(BLACK);
|
||||||
BeginMode3D(camera);
|
BeginMode3D(camera);
|
||||||
DrawPlane((Vector3){0, 0, 0}, (Vector2){100, 100}, GRAY);
|
DrawPlane((Vector3){0, 0, 0}, (Vector2){500, 500}, RAYWHITE);
|
||||||
updateobjs();
|
updateobjs();
|
||||||
drawobjs();
|
drawobjs();
|
||||||
EndMode3D();
|
EndMode3D();
|
||||||
|
|||||||
101
objects.c
Normal file
101
objects.c
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
#include "objects.h"
|
||||||
|
#include <math.h>
|
||||||
|
#include <raymath.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
17
objects.h
17
objects.h
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include <raylib.h>
|
#include <raylib.h>
|
||||||
|
#include <raymath.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -11,14 +12,8 @@ typedef struct {
|
|||||||
double mass;
|
double mass;
|
||||||
} object;
|
} object;
|
||||||
|
|
||||||
object *newobj(Vector3 pos, double r, Color c, double rest, double m)
|
|
||||||
{
|
object *newobj(Vector3 pos, double r, Color c, double rest, double m);
|
||||||
object *obj = (object*)malloc(sizeof(object));
|
Vector3 gravitation_force(object *obj1, object *obj2);
|
||||||
obj->r = r;
|
void integrate_g(object *obj1, object *obj2, Vector3 force);
|
||||||
obj->pos = pos;
|
void resolve_collision(object *obj1, object *obj2);
|
||||||
obj->color = c;
|
|
||||||
obj->vel = (Vector3){0, 0, 0};
|
|
||||||
obj->restitution = rest;
|
|
||||||
obj->mass = m;
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user