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
|
#pragma once
|
||||||
|
|
||||||
|
#include "util/tree.h"
|
||||||
|
#include "util/vector.h"
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@ -9,14 +11,15 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct Entity;
|
typedef struct _Entity Entity;
|
||||||
extern double Physics_Gravity;
|
|
||||||
|
extern double physics_Gravity;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Entity *super;
|
Entity *super;
|
||||||
double x, y;
|
Vec2 position;
|
||||||
double vecX, vecY;
|
Vec2 velocity;
|
||||||
} Component_Position;
|
} Component_Position;
|
||||||
|
|
||||||
|
|
||||||
@ -26,11 +29,32 @@ typedef struct {
|
|||||||
// Moving hitboxes only hits fixed hitboxes
|
// Moving hitboxes only hits fixed hitboxes
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Entity *super;
|
Entity *super;
|
||||||
Box2 box;
|
Box2 box;
|
||||||
bool fixed;
|
bool fixed;
|
||||||
} Component_Hitbox;
|
} 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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
10
Entity.h
10
Entity.h
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "util/vector.h"
|
#include "util/vector.h"
|
||||||
|
#include "Component_Physics.h"
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -10,12 +11,15 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
// Entity.
|
// Entity.
|
||||||
typedef struct {
|
typedef struct _Entity {
|
||||||
uintptr_t type;
|
uintptr_t id;
|
||||||
|
uintptr_t type;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
|
||||||
} Entity;
|
Component_Position *position;
|
||||||
|
Component_Hitbox *hitbox;
|
||||||
|
|
||||||
|
} Entity;
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -138,6 +138,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="Types.c" />
|
<ClCompile Include="Types.c" />
|
||||||
|
<ClCompile Include="Component_Physics.c" />
|
||||||
<ClCompile Include="util\queue.c" />
|
<ClCompile Include="util\queue.c" />
|
||||||
<ClCompile Include="util\tree.c" />
|
<ClCompile Include="util\tree.c" />
|
||||||
<ClCompile Include="util\vector.c" />
|
<ClCompile Include="util\vector.c" />
|
||||||
@ -145,4 +146,4 @@
|
|||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -55,6 +55,9 @@
|
|||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Types.c">
|
<ClCompile Include="Types.c">
|
||||||
<Filter>源文件</Filter>
|
<Filter>源文件</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="Component_Physics.c">
|
||||||
|
<Filter>源文件</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</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);
|
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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#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;
|
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) {
|
void vector_Append(vector_Vector *vec, const void *data, uintptr_t n) {
|
||||||
uintptr_t oldsize = vec->size, addsize = vec->objectSize * n;
|
uintptr_t oldsize = vec->size, addsize = vec->objectSize * n;
|
||||||
vector_Resize(vec, oldsize + addsize);
|
vector_Resize(vec, oldsize + addsize);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -27,6 +28,14 @@ void vector_Destroy(vector_Vector *vec);
|
|||||||
// Returns a pointer to data.
|
// Returns a pointer to data.
|
||||||
void *vector_Push(vector_Vector *vec, const void *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.
|
// Append pushes multiple objects at the back of the buffer.
|
||||||
//
|
//
|
||||||
// If data is NULL, the data is zeroed.
|
// If data is NULL, the data is zeroed.
|
||||||
|
Loading…
Reference in New Issue
Block a user