System info & network
This commit is contained in:
17
code/physics/base.h
Normal file
17
code/physics/base.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _PIUMA_PHYSICS_BASE_H_
|
||||
#define _PIUMA_PHYSICS_BASE_H_
|
||||
|
||||
#include "../lib/memory.h"
|
||||
|
||||
/* Reassing phy_alloc and phy_free with your own alloc/free functions if you don't
|
||||
* want to use malloc and free.
|
||||
*/
|
||||
extern alloc_t phy_alloc;
|
||||
extern realloc_t phy_realloc;
|
||||
extern free_t phy_free;
|
||||
|
||||
#define PHY_ALLOC(type, size) (type *)phy_alloc(sizeof(type) * size)
|
||||
#define PHY_REALLOC(type, ptr, size) (type *)phy_realloc(ptr, sizeof(type) * size)
|
||||
#define PHY_FREE(ptr) phy_free(ptr)
|
||||
|
||||
#endif
|
||||
28
code/physics/body.cpp
Normal file
28
code/physics/body.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include "body.h"
|
||||
#include "../lib/geometry.h"
|
||||
#include <assert.h>
|
||||
|
||||
Box phy_aabb_from_body(phy_body *body)
|
||||
{
|
||||
Box aabb;
|
||||
switch(body->shape)
|
||||
{
|
||||
case PHY_SHAPE_SPHERE: {
|
||||
aabb.min = body->position - body->sphere.radius * v3{1,1,1};
|
||||
aabb.max = body->position + body->sphere.radius * v3{1,1,1};
|
||||
} break;
|
||||
case PHY_SHAPE_BOX: {
|
||||
v3 box[8]; build_cube_vertices(box);
|
||||
m3 rotoscale = M3(rotation_v3(body->rotation) * scale_v3(body->box.dimensions));
|
||||
for(u32 i = 0; i < 8; i++)
|
||||
box[i] = body->position + rotoscale * box[i];
|
||||
|
||||
aabb = box_from_point_cloud(box, 8);
|
||||
} break;
|
||||
case PHY_SHAPE_MESH: {
|
||||
assert(false && "Yet to be implemented");
|
||||
} break;
|
||||
default: { assert(false && "Unknown shape"); }
|
||||
}
|
||||
return aabb;
|
||||
}
|
||||
61
code/physics/body.h
Normal file
61
code/physics/body.h
Normal file
@@ -0,0 +1,61 @@
|
||||
#ifndef _PIUMA_PHYSICS_OBJECT_H_
|
||||
#define _PIUMA_PHYSICS_OBJECT_H_
|
||||
|
||||
#include "../lib/math.h"
|
||||
#include "../lib/geometry.h"
|
||||
|
||||
enum phy_shape_type
|
||||
{
|
||||
PHY_SHAPE_SPHERE,
|
||||
PHY_SHAPE_BOX,
|
||||
PHY_SHAPE_MESH,
|
||||
|
||||
PHY_SHAPE_COUNT
|
||||
};
|
||||
|
||||
struct phy_sphere
|
||||
{
|
||||
f32 radius;
|
||||
};
|
||||
|
||||
struct phy_box
|
||||
{
|
||||
v3 dimensions;
|
||||
};
|
||||
|
||||
struct phy_mesh
|
||||
{
|
||||
// TODO
|
||||
};
|
||||
|
||||
|
||||
struct phy_body
|
||||
{
|
||||
v3 position;
|
||||
v3 rotation;
|
||||
|
||||
f32 mass;
|
||||
v3 center_of_mass;
|
||||
f32 gravity_multiplier;
|
||||
f32 friction;
|
||||
f32 bounciness;
|
||||
|
||||
// Dynamics
|
||||
v3 velocity;
|
||||
v3 angular_velocity;
|
||||
|
||||
// Collision
|
||||
phy_shape_type shape;
|
||||
union
|
||||
{
|
||||
phy_sphere sphere;
|
||||
phy_box box;
|
||||
phy_mesh mesh;
|
||||
};
|
||||
Box aabb;
|
||||
};
|
||||
|
||||
|
||||
Box phy_aabb_from_body(phy_body *body);
|
||||
|
||||
#endif
|
||||
336
code/physics/collision.cpp
Normal file
336
code/physics/collision.cpp
Normal file
@@ -0,0 +1,336 @@
|
||||
#include "collision.h"
|
||||
#include "../lib/ds.h"
|
||||
#include "../lib/geometry.h"
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
void phy_collisions_broadphase(phy_world *world, phy_body_pair *pair_list, u32 max_pairs, u32 *num_pairs)
|
||||
{
|
||||
// Update AABBs
|
||||
for(u32 i = 0; i < world->bodies_count; i++)
|
||||
{
|
||||
phy_body *body = world->bodies + i;
|
||||
body->aabb = phy_aabb_from_body(body);
|
||||
}
|
||||
|
||||
|
||||
u32 pairs_count = 0;
|
||||
|
||||
for(u32 a = 0; a < world->bodies_count; a++)
|
||||
{
|
||||
phy_body *body_a = world->bodies + a;
|
||||
for(u32 b = a + 1; b < world->bodies_count; b++)
|
||||
{
|
||||
phy_body *body_b = world->bodies + b;
|
||||
|
||||
if(overlaps(body_a->aabb, body_b->aabb))
|
||||
{
|
||||
// Add to list of possible collisions.
|
||||
if(pairs_count < max_pairs)
|
||||
{
|
||||
pair_list[pairs_count] = phy_body_pair{
|
||||
.body_a = body_a,
|
||||
.body_b = body_b
|
||||
};
|
||||
}
|
||||
pairs_count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(num_pairs)
|
||||
*num_pairs = pairs_count;
|
||||
}
|
||||
|
||||
|
||||
// @Cleanup: put this in the right place
|
||||
// @Performance: this is probably not a good way of doing this
|
||||
void project_box_on_axis(phy_body *body, v3 axis, f32 *min, f32 *max)
|
||||
{
|
||||
v3 points[8];
|
||||
build_cube_vertices(points);
|
||||
|
||||
m4 transform = translation_v3(body->position) * rotation_v3(body->rotation) * scale_v3(body->box.dimensions);
|
||||
|
||||
*min = *max = project_point_on_vector(axis, body->position);
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
f32 projected = project_point_on_vector(axis, (transform * V4(points[i], 1)).xyz);
|
||||
*min = minimum(*min, projected);
|
||||
*max = maximum(*max, projected);
|
||||
}
|
||||
}
|
||||
|
||||
f32 axis_range_distance(f32 a_min, f32 a_max, f32 b_min, f32 b_max)
|
||||
{
|
||||
f32 a_range = a_max - a_min;
|
||||
f32 a_center = a_min + a_range / 2;
|
||||
f32 b_range = b_max - b_min;
|
||||
f32 b_center = b_min + b_range / 2;
|
||||
return fabs(a_center - b_center) - (a_range + b_range) / 2;
|
||||
}
|
||||
|
||||
bool sat_box_face_point_collision_test(phy_body *body_a, phy_body *body_b, v3 axis, f32 a_size_on_current_axis, f32 *depth, v3 *furthest_a, v3 *furthest_b)
|
||||
{
|
||||
f32 a_middle = project_point_on_vector(axis, body_a->position);
|
||||
f32 b_middle = project_point_on_vector(axis, body_b->position);
|
||||
f32 direction = (b_middle - a_middle < 0) ? -1 : 1;
|
||||
|
||||
f32 boundary = a_middle + direction * a_size_on_current_axis / 2;
|
||||
f32 dist = +INFINITY;
|
||||
v3 point;
|
||||
|
||||
v3 points[8]; build_cube_vertices(points);
|
||||
m4 transform = translation_v3(body_b->position) * rotation_v3(body_b->rotation) * scale_v3(body_b->box.dimensions);
|
||||
|
||||
for(int i = 0; i < 8; i++)
|
||||
{
|
||||
v3 p = (transform * V4(points[i], 1)).xyz;
|
||||
f32 projected = project_point_on_vector(axis, p);
|
||||
f32 curr_dist = direction * (projected - boundary);
|
||||
if(curr_dist < dist)
|
||||
{
|
||||
dist = curr_dist;
|
||||
point = p;
|
||||
}
|
||||
}
|
||||
|
||||
if(dist < 0) // Possible collision
|
||||
{
|
||||
v3 furthest_point_b = point;
|
||||
v3 furthest_point_a = point + -dist * -direction * axis;
|
||||
|
||||
*depth = -dist * direction;
|
||||
*furthest_a = furthest_point_a;
|
||||
*furthest_b = furthest_point_b;
|
||||
return true;
|
||||
}
|
||||
// else Separated on this axis. No collision
|
||||
return false;
|
||||
}
|
||||
|
||||
bool sat_box_collision_test(phy_body *body_a, phy_body *body_b, phy_collision *res_collision)
|
||||
{
|
||||
// Separating axis test
|
||||
// 3 + 3 = 6 face normals
|
||||
// 3 * 3 = 9 right angle to pair of edges
|
||||
v3 axes[15];
|
||||
m4 a_rotation = rotation_v3(body_a->rotation);
|
||||
axes[0] = extract_column(a_rotation, 0).xyz;
|
||||
axes[1] = extract_column(a_rotation, 1).xyz;
|
||||
axes[2] = extract_column(a_rotation, 2).xyz;
|
||||
m4 b_rotation = rotation_v3(body_b->rotation);
|
||||
axes[3] = -extract_column(b_rotation, 0).xyz;
|
||||
axes[4] = -extract_column(b_rotation, 1).xyz;
|
||||
axes[5] = -extract_column(b_rotation, 2).xyz;
|
||||
|
||||
for(int a = 0; a < 3; a++)
|
||||
for(int b = 0; b < 3; b++)
|
||||
{
|
||||
(axes+6)[3*a + b] = cross(axes[a], axes[b + 3]);
|
||||
}
|
||||
|
||||
phy_collision collision;
|
||||
collision.body_a = body_a;
|
||||
collision.body_b = body_b;
|
||||
collision.depth = +INFINITY;
|
||||
|
||||
// Face axes: body a
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
v3 axis = axes[i];
|
||||
f32 depth; v3 furthest_point_a, furthest_point_b;
|
||||
bool collides = sat_box_face_point_collision_test(body_a, body_b, axis, body_a->box.dimensions.E[i], &depth, &furthest_point_a, &furthest_point_b);
|
||||
|
||||
if(!collides)
|
||||
return false;
|
||||
|
||||
if(abs(depth) < abs(collision.depth))
|
||||
{
|
||||
collision.depth = depth;
|
||||
collision.furthest_point_a = furthest_point_a;
|
||||
collision.furthest_point_b = furthest_point_b;
|
||||
collision.best_separation_direction = axis;
|
||||
}
|
||||
}
|
||||
// Face axes: body b
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
v3 axis = axes[3 + i];
|
||||
f32 depth; v3 furthest_point_a, furthest_point_b;
|
||||
bool collides = sat_box_face_point_collision_test(body_b, body_a, axis, body_b->box.dimensions.E[i], &depth, &furthest_point_b, &furthest_point_a);
|
||||
|
||||
if(!collides)
|
||||
return false;
|
||||
|
||||
if(abs(depth) < abs(collision.depth))
|
||||
{
|
||||
collision.depth = depth;
|
||||
collision.furthest_point_a = furthest_point_a;
|
||||
collision.furthest_point_b = furthest_point_b;
|
||||
collision.best_separation_direction = -axis;
|
||||
}
|
||||
}
|
||||
|
||||
// @TODO: edge-edge
|
||||
|
||||
*res_collision = collision;
|
||||
return true;
|
||||
}
|
||||
|
||||
void phy_collisions_detection(phy_world *world, phy_body_pair *pair_list, u32 num_pairs, phy_collision *collision_list, u32 max_collisions, u32 *num_collisions)
|
||||
{
|
||||
u32 n_collisions = 0;
|
||||
for(u32 i = 0; i < num_pairs; i++)
|
||||
{
|
||||
phy_body *body_a = pair_list[i].body_a;
|
||||
phy_body *body_b = pair_list[i].body_b;
|
||||
|
||||
if(body_b->shape < body_a->shape)
|
||||
swap(body_b, body_a);
|
||||
|
||||
|
||||
switch(body_a->shape)
|
||||
{
|
||||
case PHY_SHAPE_SPHERE:
|
||||
{
|
||||
switch(body_b->shape)
|
||||
{
|
||||
case PHY_SHAPE_SPHERE:
|
||||
{
|
||||
f32 dist = distance(body_a->position, body_b->position);
|
||||
f32 radius_sum = body_a->sphere.radius + body_b->sphere.radius;
|
||||
if(dist <= radius_sum)
|
||||
{
|
||||
phy_collision collision;
|
||||
|
||||
collision.body_a = body_a;
|
||||
collision.body_b = body_b;
|
||||
collision.depth = radius_sum - dist;
|
||||
v3 direction = normalize(body_b->position - body_a->position);
|
||||
collision.furthest_point_a = body_a->position + (body_a->sphere.radius - collision.depth) * direction;
|
||||
collision.furthest_point_b = body_b->position + (body_b->sphere.radius - collision.depth) * -direction;
|
||||
collision.best_separation_direction = direction;
|
||||
|
||||
if(n_collisions < max_collisions)
|
||||
collision_list[n_collisions] = collision;
|
||||
n_collisions++;
|
||||
}
|
||||
} break;
|
||||
case PHY_SHAPE_BOX:
|
||||
{
|
||||
// Use box's cordinate space
|
||||
m4 box_b_coord_space_transform = rotation_v3(-body_b->rotation) * translation_v3(-body_b->position);
|
||||
|
||||
v4 sphere_center4 = box_b_coord_space_transform * V4(body_a->position, 1.0);
|
||||
v3 sphere_center = sphere_center4.xyz / sphere_center4.w;
|
||||
|
||||
Box box = {
|
||||
.min = -0.5*body_b->box.dimensions,
|
||||
.max = 0.5*body_b->box.dimensions
|
||||
};
|
||||
|
||||
v3 closest_point;
|
||||
f32 dist = box_SDF(box, sphere_center, &closest_point);
|
||||
|
||||
if(dist - body_a->sphere.radius <= 0)
|
||||
{
|
||||
phy_collision collision;
|
||||
|
||||
collision.body_a = body_a;
|
||||
collision.body_b = body_b;
|
||||
collision.depth = dist - body_a->sphere.radius;
|
||||
v3 direction = normalize(closest_point - body_a ->position);
|
||||
collision.furthest_point_a = body_a->position + (body_a->sphere.radius - collision.depth) * direction;
|
||||
collision.furthest_point_b = body_a->position + body_a->sphere.radius * direction;
|
||||
collision.best_separation_direction = direction;
|
||||
|
||||
if(n_collisions < max_collisions)
|
||||
collision_list[n_collisions] = collision;
|
||||
n_collisions++;
|
||||
}
|
||||
|
||||
} break;
|
||||
case PHY_SHAPE_MESH:
|
||||
{
|
||||
assert(false && "Unmanaged PHY_SHAPE pair");
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
assert(false && "Unmanaged PHY_SHAPE pair");
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
case PHY_SHAPE_BOX:
|
||||
{
|
||||
switch(body_b->shape)
|
||||
{
|
||||
// case PHY_SHAPE_SPHERE: // Already managed
|
||||
case PHY_SHAPE_BOX:
|
||||
{
|
||||
phy_collision collision;
|
||||
bool collides = sat_box_collision_test(body_a, body_b, &collision);
|
||||
if(collides)
|
||||
{
|
||||
if(n_collisions < max_collisions)
|
||||
collision_list[n_collisions] = collision;
|
||||
n_collisions++;
|
||||
}
|
||||
} break;
|
||||
case PHY_SHAPE_MESH:
|
||||
{
|
||||
assert(false && "Unmanaged PHY_SHAPE pair");
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
assert(false && "Unmanaged PHY_SHAPE pair");
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
case PHY_SHAPE_MESH:
|
||||
{
|
||||
switch(body_b->shape)
|
||||
{
|
||||
// case PHY_SHAPE_SPHERE: // Already managed
|
||||
// case PHY_SHAPE_BOX: // Already managed
|
||||
case PHY_SHAPE_MESH:
|
||||
{
|
||||
assert(false && "Unmanaged PHY_SHAPE pair");
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
assert(false && "Unmanaged PHY_SHAPE pair");
|
||||
} break;
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
{
|
||||
assert(false && "Unmanaged PHY_SHAPE");
|
||||
} break;
|
||||
}
|
||||
}
|
||||
*num_collisions = n_collisions;
|
||||
}
|
||||
|
||||
void phy_collisions_resolution(phy_world *world, phy_collision *collision_list, u32 num_collisions)
|
||||
{
|
||||
|
||||
for(u32 i = 0; i < num_collisions; i++)
|
||||
{
|
||||
phy_body *body_a = collision_list[i].body_a;
|
||||
phy_body *body_b = collision_list[i].body_b;
|
||||
v3 separation_direction = collision_list[i].best_separation_direction;
|
||||
f32 depth = collision_list[i].depth;
|
||||
|
||||
if(body_a->mass != 0) // Not a static body
|
||||
{
|
||||
body_a->position += -separation_direction * depth;//-normalize(body_a->velocity) * dot(normalize(body_a->velocity), separation_direction * depth);
|
||||
body_a->velocity = {0,0,0};//length(body_a->velocity) * separation_direction * body_a->bounciness;
|
||||
}
|
||||
if(body_b->mass != 0) // Not a static body
|
||||
{
|
||||
body_b->position += separation_direction * depth;//-normalize(body_b->velocity) * dot(normalize(body_b->velocity), separation_direction * depth);
|
||||
body_b->velocity = {0,0,0};//length(body_a->velocity) * -separation_direction * body_b->bounciness;
|
||||
}
|
||||
}
|
||||
}
|
||||
35
code/physics/collision.h
Normal file
35
code/physics/collision.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#ifndef _PIUMA_PHYSICS_COLLISION_H_
|
||||
#define _PIUMA_PHYSICS_COLLISION_H_
|
||||
|
||||
#include "world.h"
|
||||
|
||||
struct phy_body_pair
|
||||
{
|
||||
phy_body *body_a;
|
||||
phy_body *body_b;
|
||||
};
|
||||
|
||||
struct phy_collision
|
||||
{
|
||||
phy_body *body_a;
|
||||
phy_body *body_b;
|
||||
|
||||
f32 depth;
|
||||
v3 furthest_point_a;
|
||||
v3 furthest_point_b;
|
||||
v3 best_separation_direction;
|
||||
};
|
||||
|
||||
|
||||
// Generates possibile collision pairs and saves it in the memory pointed by pair_list, up to a maximum of max_pairs. The number of possible collisions is returned in num_pairs (might be >= max_pairs).
|
||||
void phy_collisions_broadphase(phy_world *world, phy_body_pair *pair_list, u32 max_pairs, u32 *num_pairs);
|
||||
|
||||
// Generates list of collisions and saves it in the memory pointed by collision_list, up to a maximum of max_pairs. The number of collisions is returned in num_collisions (might be >= max_collisions).
|
||||
// Uses pair_list (with size num_pairs) as a list of possible collisions (computed with a faster algorithm).
|
||||
void phy_collisions_detection(phy_world *world, phy_body_pair *pair_list, u32 num_pairs, phy_collision *collision_list, u32 max_collisions, u32 *num_collisions);
|
||||
|
||||
// Modifies world state based on collision_list
|
||||
void phy_collisions_resolution(phy_world *world, phy_collision *collision_list, u32 num_collisions);
|
||||
|
||||
|
||||
#endif
|
||||
25
code/physics/physics.cpp
Normal file
25
code/physics/physics.cpp
Normal file
@@ -0,0 +1,25 @@
|
||||
#include "physics.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
alloc_t phy_alloc = malloc;
|
||||
realloc_t phy_realloc = realloc;
|
||||
free_t phy_free = free;
|
||||
|
||||
|
||||
void phy_init()
|
||||
{
|
||||
phy_init(malloc, realloc, free);
|
||||
}
|
||||
|
||||
void phy_init(alloc_t alloc, realloc_t realloc, free_t free)
|
||||
{
|
||||
phy_alloc = alloc;
|
||||
phy_realloc = realloc;
|
||||
phy_free = free;
|
||||
}
|
||||
|
||||
void phy_deinit()
|
||||
{
|
||||
|
||||
}
|
||||
16
code/physics/physics.h
Normal file
16
code/physics/physics.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef _PIUMA_PHYSICS_PHYSICS_H_
|
||||
#define _PIUMA_PHYSICS_PHYSICS_H_
|
||||
|
||||
#include "base.h"
|
||||
#include "body.h"
|
||||
#include "world.h"
|
||||
#include "simulation.h"
|
||||
#include "collision.h"
|
||||
|
||||
// Initialization
|
||||
void phy_init();
|
||||
void phy_init(alloc_t alloc, realloc_t realloc, free_t free);
|
||||
void phy_deinit();
|
||||
|
||||
|
||||
#endif
|
||||
40
code/physics/simulation.cpp
Normal file
40
code/physics/simulation.cpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#include "base.h"
|
||||
#include "simulation.h"
|
||||
#include "../lib/geometry.h"
|
||||
#include "collision.h"
|
||||
|
||||
void phy_integrate(phy_world *world, f64 delta_t)
|
||||
{
|
||||
for(u32 i = 0; i < world->bodies_count; i++)
|
||||
{
|
||||
phy_body *body = world->bodies + i;
|
||||
|
||||
body->velocity += world->gravity * body->gravity_multiplier * delta_t;
|
||||
|
||||
body->position += body->velocity * delta_t;
|
||||
body->rotation += body->angular_velocity * delta_t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void phy_simulate(phy_world *world, f64 delta_t)
|
||||
{
|
||||
// @Performance: Grouping for optimizations (active/inactive, constraints)
|
||||
|
||||
phy_integrate(world, delta_t);
|
||||
|
||||
u32 max_pairs = 1000; // @Correctness: this should be dynamic and should reuse memory when possible
|
||||
u32 num_pairs = 0;
|
||||
phy_body_pair *pair_list = PHY_ALLOC(phy_body_pair, max_pairs);
|
||||
phy_collisions_broadphase(world, pair_list, max_pairs, &num_pairs);
|
||||
|
||||
u32 max_collisions = 1000;
|
||||
u32 num_collisions = 0;
|
||||
phy_collision *collision_list = PHY_ALLOC(phy_collision, max_collisions);
|
||||
phy_collisions_detection(world, pair_list, minimum(max_pairs, num_pairs), collision_list, max_collisions, &num_collisions);
|
||||
|
||||
phy_collisions_resolution(world, collision_list, minimum(max_collisions, num_collisions));
|
||||
|
||||
PHY_FREE(pair_list);
|
||||
PHY_FREE(collision_list);
|
||||
}
|
||||
9
code/physics/simulation.h
Normal file
9
code/physics/simulation.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef _PIUMA_PHYSICS_SIMULATION_H_
|
||||
#define _PIUMA_PHYSICS_SIMULATION_H_
|
||||
|
||||
#include "world.h"
|
||||
|
||||
void phy_integrate(phy_world *world, f64 delta_t);
|
||||
void phy_simulate(phy_world *world, f64 delta_t);
|
||||
|
||||
#endif
|
||||
72
code/physics/world.cpp
Normal file
72
code/physics/world.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
#include "world.h"
|
||||
#include "base.h"
|
||||
|
||||
|
||||
phy_world *phy_create_world(v3 gravity)
|
||||
{
|
||||
phy_world *world = PHY_ALLOC(phy_world, 1);
|
||||
world->bodies = NULL;
|
||||
world->bodies_count = 0;
|
||||
world->gravity = gravity;
|
||||
return world;
|
||||
}
|
||||
|
||||
void phy_destroy_world(phy_world *world)
|
||||
{
|
||||
PHY_FREE(world->bodies);
|
||||
world->bodies_count = 0;
|
||||
}
|
||||
|
||||
phy_body_offset phy_new_body(phy_world *world)
|
||||
{
|
||||
phy_body_offset offset = world->bodies_count;
|
||||
world->bodies_count++;
|
||||
world->bodies = PHY_REALLOC(phy_body, world->bodies, world->bodies_count);
|
||||
return offset;
|
||||
}
|
||||
|
||||
void phy_body_init_default(phy_body *body)
|
||||
{
|
||||
body->position = {0, 0, 0};
|
||||
body->rotation = {0, 0, 0};
|
||||
body->mass = 0;
|
||||
body->center_of_mass = {0, 0, 0};
|
||||
|
||||
body->velocity = {0, 0, 0};
|
||||
body->angular_velocity = {0, 0, 0};
|
||||
|
||||
body->gravity_multiplier = 1;
|
||||
|
||||
body->friction = 0;
|
||||
body->bounciness = 1;
|
||||
}
|
||||
|
||||
phy_body_offset phy_create_box(phy_world *world, v3 position, v3 rotation, f32 mass, v3 dimensions)
|
||||
{
|
||||
phy_body_offset offset = phy_new_body(world);
|
||||
phy_body *body = PHY_BODY(world, offset);
|
||||
|
||||
phy_body_init_default(body);
|
||||
body->position = position;
|
||||
body->rotation = rotation;
|
||||
body->mass = mass;
|
||||
body->shape = PHY_SHAPE_BOX;
|
||||
body->box.dimensions = dimensions;
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
phy_body_offset phy_create_sphere(phy_world *world, v3 position, v3 rotation, f32 mass, f32 radius)
|
||||
{
|
||||
phy_body_offset offset = phy_new_body(world);
|
||||
phy_body *body = PHY_BODY(world, offset);
|
||||
|
||||
phy_body_init_default(body);
|
||||
body->position = position;
|
||||
body->rotation = rotation;
|
||||
body->mass = mass;
|
||||
body->shape = PHY_SHAPE_SPHERE;
|
||||
body->sphere.radius = radius;
|
||||
|
||||
return offset;
|
||||
}
|
||||
23
code/physics/world.h
Normal file
23
code/physics/world.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef _PIUMA_PHYSICS_WORLD_H_
|
||||
#define _PIUMA_PHYSICS_WORLD_H_
|
||||
|
||||
#include "body.h"
|
||||
|
||||
struct phy_world
|
||||
{
|
||||
phy_body *bodies;
|
||||
u32 bodies_count;
|
||||
|
||||
v3 gravity;
|
||||
};
|
||||
|
||||
typedef u32 phy_body_offset;
|
||||
#define PHY_BODY(world, offset) (world->bodies + offset)
|
||||
|
||||
phy_world *phy_create_world(v3 gravity);
|
||||
void phy_destroy_world(phy_world *world);
|
||||
|
||||
phy_body_offset phy_create_box(phy_world *world, v3 position, v3 rotation, f32 mass, v3 dimensions);
|
||||
phy_body_offset phy_create_sphere(phy_world *world, v3 position, v3 rotation, f32 mass, f32 radius);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user