shithub: tinygl

Download patch

ref: 8f4a6a0aafc7e4fc354183b73568e6d2e1a556a1
parent: 86c69551a61c44bcc13882fc8f7d4d5988320e90
author: MHS <gek@katherine>
date: Mon Mar 22 13:03:19 EDT 2021

Automatic commit.

--- a/include-demo/chadphys.h
+++ b/include-demo/chadphys.h
@@ -1,28 +1,127 @@
 #ifndef CHAD_PHYS_H
 #define CHAD_PHYS_H
-
 #include "3dMath.h"
 typedef struct {
 	aabb shape; //c.d[3] is sphere radius. 
-		//if it's zero or less, it's not a sphere, it's a box
-	f_ mass; //0 means kinematic, or static. Defaults to zero.
-	f_ bounciness; //default 0, put portion of displacement into velocity.
-	f_ airfriction; //default 1, multiplied by velocity every time timestep.
-	f_ friction; //default 0.1
+				//if it's zero or less, it's not a sphere, it's a box
 	mat4 localt; //Local Transform.
 	vec3 v; //velocity
 	vec3 a; //Body specific acceleration, combined with gravity
 	void* d; //User defined pointer.
+	f_ mass; //0 means kinematic, or static. Defaults to zero.
+	f_ bounciness; //default 0, put portion of displacement into velocity.
+	f_ airfriction; //default 1, multiplied by velocity every time timestep.
+	f_ friction; //default 0.1
 } phys_body;
 typedef struct{
-	phys_body* abodies; //mass non-zero
-	phys_body* sbodies; //mass zero
-	uint nabodies; //number of abodies
-	uint nsbodies; //number of sbodies
 	vec3 g; //gravity
+	phys_body* bodies;
 	f_ ms; //max speed
+	uint nbodies; //number of bodies
 } phys_world;
-//TODO: implement functions
+typedef struct{
+	phys_body** data;
+	uint capacity;
+} phys_cell;
+typedef struct{
+	phys_cell* data;
+	f_ celldim;
+	uint xcells;
+	uint ycells;
+	uint zcells;
+	vec3 offset;
+} phys_spatialhash;
+static inline phys_spatialhash spatialhash_init(uint x, uint y, uint z, f_ celldim, vec3 offset){
+	phys_spatialhash ret = {0};
+	ret.xcells = x;
+	ret.ycells = y;
+	ret.zcells = z;
+	ret.celldim = celldim;
+	ret.offset = offset;
+	ret.data = calloc(1,sizeof(phys_cell) * x * y * z);
+	return ret;
+}
+static inline void destroy_spatialhash(phys_spatialhash* p){
+	if(p->data) free(p->data);
+	p->data = NULL;
+}
+static inline uint phys_cell_insert(phys_cell* c, phys_body* b){ //1 = error.
+	uint inserted = 0;
+	while(!inserted){
+		for(uint b_ = 0; b_ < c->capacity; b_++)
+			if(c->data[b_]==NULL)
+			{
+				c->data[b_] = b;
+				inserted = 1;
+				return 0;
+			}
+		phys_body** old = c->data;
+		
+		
+		c->data = calloc(1,((c->capacity)<<1) * sizeof(phys_body*));
+		if(c->data == NULL) { //The malloc failed! Wowza!
+			if(old)//In case we had something there...
+				free(old);
+			return 1;
+		}
+		memcpy(c->data, old, c->capacity);
+		c->capacity <<= 1;
+		free(old);
+	}
+	return 1; //Unreachable.
+}
+//update the placement of this body b in the spatial hash.
+static inline void spatialhash_clear(phys_spatialhash* h){
+#pragma omp parallel for collapse(4)
+	for(uint i = 0; i < h->xcells; i++)
+	for(uint j = 0; j < h->ycells; j++)
+	for(uint k = 0; k < h->zcells; k++)
+	for(uint b_cell = 0; b_cell < h->data[i+ j*h->xcells + k*h->xcells*h->ycells].capacity; b_cell++)
+			h->data[i+ j*h->xcells + k*h->xcells*h->ycells].data[b_cell] = NULL;
+}
+
+
+static inline uint spatialhash_update(phys_spatialhash* h, phys_body* b){
+	//Assumes that the spatial hash was cleared this frame- no duplicates.
+	vec3 b1c = downv4(b->shape.c);
+	f_ rad = 0;
+	if(b->shape.c.d[3] == 0){
+		vec3 b1max = addv3(b1c,b->shape.e);
+		rad = MAX(MAX(b1max.d[0],b1max.d[1]),b1max.d[2]);
+	} else {
+		rad = b->shape.c.d[3];
+	}
+	rad /= h->celldim;
+	b1c = addv3(h->offset, b1c);
+	b1c = scalev3(1.0/h->celldim, b1c);
+	ivec3 beg, end;
+#pragma omp simd
+	for(int i = 0; i < 3; i++){
+		beg.d[i] = b1c.d[i] - rad;
+		end.d[i] = b1c.d[i] + rad;
+	}
+//error checking.
+	for(int i = 0; i < 3; i++)
+		if(beg.d[i] < 0 || end.d[i] < 0) return 1;
+	if(	end.d[0] > h->xcells ||
+		end.d[1] > h->ycells ||
+		end.d[2] > h->zcells)
+			return 1;
+	if(	beg.d[0] > h->xcells ||
+		beg.d[1] > h->ycells ||
+		beg.d[2] > h->zcells)
+				return 1;
+#pragma omp parallel for collapse(3)
+	for(uint i = beg.d[0]; i < h->xcells && i<=end.d[0]; i++)
+	for(uint j = beg.d[1]; j < h->ycells && j<=end.d[1]; j++)
+	for(uint k = beg.d[2]; k < h->zcells && k<=end.d[2]; k++){
+		phys_cell_insert(h->data+i+ j*h->xcells + k*h->xcells*h->ycells, b);
+	}
+	return 0;
+}
+
+
+
 static inline void initPhysBody(phys_body* body){
 	body->shape = (aabb){
 		.c=(vec4){.d[0] = 0,.d[1] = 0,.d[2] = 0,.d[3] = 0},