Initial work on physics
This commit is contained in:
parent
8e6b6cec9b
commit
e8f0b0c63a
86
Component_Physics.c
Normal file
86
Component_Physics.c
Normal file
@ -0,0 +1,86 @@
|
||||
|
||||
#include "Component_Physics.h"
|
||||
#include "Entity.h"
|
||||
#include "Types.h"
|
||||
#include "util/tree.h"
|
||||
#include "util/vector.h"
|
||||
#include "util/assert.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
double physics_Gravity = 5.0;
|
||||
|
||||
|
||||
System_Physics *physics_NewSystem() {
|
||||
System_Physics *sys = malloc(sizeof(System_Physics));
|
||||
|
||||
sys->pos = tree_Create(sizeof(uintptr_t));
|
||||
sys->hit = tree_Create(sizeof(uintptr_t));
|
||||
sys->flaggedDelete = vector_Create(sizeof(uintptr_t));
|
||||
|
||||
return sys;
|
||||
}
|
||||
|
||||
void physics_DeleteSystem(System_Physics *sys) {
|
||||
tree_Destroy(sys->pos);
|
||||
tree_Destroy(sys->hit);
|
||||
vector_Destroy(sys->flaggedDelete);
|
||||
}
|
||||
|
||||
|
||||
void physics_AddEntity(System_Physics *sys, Entity *e) {
|
||||
if (e->position)
|
||||
memcpy(tree_Insert(sys->pos, e->id, NULL), &e->position, sizeof(uintptr_t));
|
||||
if (e->hitbox) {
|
||||
ASSERT(!e->hitbox->fixed && !e->position && "Entity has non-Fixed Hitbox but no position");
|
||||
memcpy(tree_Insert(sys->hit, e->id, NULL), &e->hitbox, sizeof(uintptr_t));
|
||||
}
|
||||
}
|
||||
|
||||
void physics_DeleteEntity(System_Physics *sys, uintptr_t id) {
|
||||
vector_Push(sys->flaggedDelete, &id);
|
||||
}
|
||||
|
||||
|
||||
inline void _physics_AdvanceEntity(Entity *e, Duration deltaTime) {
|
||||
if (!e->position)
|
||||
return;
|
||||
|
||||
// Short path
|
||||
if (!e->hitbox || e->hitbox->fixed) {
|
||||
e->position->position =
|
||||
vec2_Add(
|
||||
e->position->position,
|
||||
vec2_Scale(
|
||||
e->position->velocity,
|
||||
duration_Seconds(deltaTime)));
|
||||
return;
|
||||
}
|
||||
|
||||
// Long path
|
||||
}
|
||||
|
||||
|
||||
void physics_Advance(System_Physics *sys, Duration deltaTime) {
|
||||
// Delete flagged entities
|
||||
while (vector_Size(sys->flaggedDelete)) {
|
||||
uintptr_t id;
|
||||
vector_Pop(sys->flaggedDelete, &id);
|
||||
|
||||
tree_Node *n;
|
||||
n = tree_FindNode(sys->pos, id);
|
||||
if (n)
|
||||
tree_Delete(sys->pos, n);
|
||||
n = tree_FindNode(sys->hit, id);
|
||||
if (n)
|
||||
tree_Delete(sys->hit, n);
|
||||
}
|
||||
|
||||
for (tree_Node *i = tree_FirstNode(sys->pos);
|
||||
i != NULL;
|
||||
i = tree_Node_Next(i)) {
|
||||
Component_Position *pos = *((Component_Position **)i->data);
|
||||
_physics_AdvanceEntity(pos->super, deltaTime);
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "util/tree.h"
|
||||
#include "util/vector.h"
|
||||
#include "Types.h"
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
@ -9,14 +11,15 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct Entity;
|
||||
extern double Physics_Gravity;
|
||||
typedef struct _Entity Entity;
|
||||
|
||||
extern double physics_Gravity;
|
||||
|
||||
|
||||
typedef struct {
|
||||
Entity *super;
|
||||
double x, y;
|
||||
double vecX, vecY;
|
||||
Vec2 position;
|
||||
Vec2 velocity;
|
||||
} Component_Position;
|
||||
|
||||
|
||||
@ -31,6 +34,27 @@ typedef struct {
|
||||
} Component_Hitbox;
|
||||
|
||||
|
||||
// Physics manager
|
||||
typedef struct {
|
||||
// Every Position & Hitbox components
|
||||
tree_Tree *pos, *hit;
|
||||
vector_Vector *flaggedDelete;
|
||||
} System_Physics;
|
||||
|
||||
// Returns an empty physics system.
|
||||
System_Physics *physics_NewSystem();
|
||||
// Frees a physics system.
|
||||
void physics_DeleteSystem(System_Physics *sys);
|
||||
|
||||
// Adds an entity.
|
||||
void physics_AddEntity(System_Physics *sys, Entity *e);
|
||||
// Deletes an entity.
|
||||
void physics_DeleteEntity(System_Physics *sys, uintptr_t id);
|
||||
|
||||
// Advance is called on every frame.
|
||||
void physics_Advance(System_Physics *sys, Duration deltaTime);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
8
Entity.h
8
Entity.h
@ -2,6 +2,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include "util/vector.h"
|
||||
#include "Component_Physics.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -10,12 +11,15 @@ extern "C" {
|
||||
|
||||
|
||||
// Entity.
|
||||
typedef struct {
|
||||
typedef struct _Entity {
|
||||
uintptr_t id;
|
||||
uintptr_t type;
|
||||
const char *name;
|
||||
|
||||
} Entity;
|
||||
Component_Position *position;
|
||||
Component_Hitbox *hitbox;
|
||||
|
||||
} Entity;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -138,6 +138,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Types.c" />
|
||||
<ClCompile Include="Component_Physics.c" />
|
||||
<ClCompile Include="util\queue.c" />
|
||||
<ClCompile Include="util\tree.c" />
|
||||
<ClCompile Include="util\vector.c" />
|
||||
|
@ -55,6 +55,9 @@
|
||||
</ClCompile>
|
||||
<ClCompile Include="Types.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Component_Physics.c">
|
||||
<Filter>源文件</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
8
Types.h
8
Types.h
@ -29,6 +29,14 @@ typedef struct {
|
||||
bool box2_Intersects(const Box2 x, const Box2 y, Box2 *out_intersection);
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint64_t microseconds;
|
||||
} Duration;
|
||||
|
||||
static inline double duration_Seconds(const Duration t) { return ((double)t.microseconds) / 1000.0 / 1000.0; }
|
||||
static inline double duration_Milliseconds(const Duration t) { return ((double)t.microseconds) / 1000.0; }
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
21
util/assert.h
Normal file
21
util/assert.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
inline static void __panicf(const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
int ret = vfprintf(stderr, fmt, args);
|
||||
va_end(args);
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
#define ASSERT(expr) \
|
||||
do { \
|
||||
if (!(expr)) \
|
||||
__panicf("Assertion failed: " __FILE__ ":%d[%s]\n Expression: %s", __LINE__, __func__, #expr); \
|
||||
} while (0)
|
@ -36,6 +36,18 @@ void *vector_Push(vector_Vector *vec, const void *data) {
|
||||
return vec->data + vec->size - vec->objectSize;
|
||||
}
|
||||
|
||||
bool vector_Pop(vector_Vector *vec, void *out_data) {
|
||||
if (!vector_Size(vec))
|
||||
return false;
|
||||
|
||||
if (out_data)
|
||||
memcpy(out_data, vec->data + (vec->size - vec->objectSize), vec->objectSize);
|
||||
|
||||
vector_Resize(vec, vector_Size(vec) - 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void vector_Append(vector_Vector *vec, const void *data, uintptr_t n) {
|
||||
uintptr_t oldsize = vec->size, addsize = vec->objectSize * n;
|
||||
vector_Resize(vec, oldsize + addsize);
|
||||
|
@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -27,6 +28,14 @@ void vector_Destroy(vector_Vector *vec);
|
||||
// Returns a pointer to data.
|
||||
void *vector_Push(vector_Vector *vec, const void *data);
|
||||
|
||||
// Pop pops one object at the back of the vector.
|
||||
//
|
||||
// If out_data is not NULL, the popped data is copied.
|
||||
//
|
||||
// If the vector is already empty, return false.
|
||||
// Returns true otherwise.
|
||||
bool vector_Pop(vector_Vector *vec, void *out_data);
|
||||
|
||||
// Append pushes multiple objects at the back of the buffer.
|
||||
//
|
||||
// If data is NULL, the data is zeroed.
|
||||
|
Loading…
Reference in New Issue
Block a user