Initial work on physics
This commit is contained in:
		
							
								
								
									
										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" /> | ||||||
|   | |||||||
| @@ -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. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user