Blob Blame History Raw
#ifndef PHISICS_H
#define PHISICS_H


#include "common.h"


typedef struct PhLink PhLink;
typedef struct PhNode PhNode;
typedef struct PhGroup PhGroup;
typedef struct Physics Physics;
typedef PhLink *PhCell;

struct PhLink {
  PhNode *node;
  PhCell *cell;
  PhLink *prev, *next;
};

struct PhNode {
  PhGroup *group;
  PhNode *prev, *next;
  PhLink l[4];
  double r;
  Vec p, gp, gk;
  size_t mark; // temporary mark
  PhNode *chain; // temporary chain
};

struct PhGroup {
  Physics *ph;
  PhGroup *prev, *next;
  PhNode *first, *last;
  int cnt;
  Vec go, o, dx;
};

struct Physics {
  PhGroup *first, *last;
  
  double cs;
  int hw, hh;
  PhCell *cells;
  size_t lastMark;
  
  Vec b0, b1;
  int fixangle;
};


void phLinkUnreg(PhLink *l);
void phLinkReg(PhLink *l, PhCell *c);

void phNodeUnregCell(PhNode *n);
void phNodeRegCell(PhNode *n, PhCell *c, int stride);
void phNodeUpdateCell(PhNode *n);
void phNodeUnreg(PhNode *n);
void phNodeReg(PhNode *n, PhGroup *g);
int phNodeBound(PhNode *n, Vec b0, Vec b1);
int phNodeCollision(PhNode *n);


static inline Vec phGroupTrans(PhGroup *g, Vec gp) { return vtrans(vsub(gp, g->go), g->dx, g->o); }
static inline Vec phGroupUntrans(PhGroup *g, Vec p) { return vadd(vuntrans(p, g->dx, g->o), g->go); }

void phGroupUpdateCells(PhGroup *g);
void phGroupUnreg(PhGroup *g);
void phGroupReg(PhGroup *g, Physics *ph);
void phGroupRecalc(PhGroup *g);
void phGroupPlaceNodes(PhGroup *g);
void phGroupFix(PhGroup *g, int fixangle);
void phGroupMove(PhGroup *g, Vec gp, Vec p, int fixangle);
void phGroupMerge(PhGroup *a, PhGroup *b);


void physicsAlloc(Physics *ph, int hw, int hh, double cs);
void physicsFree(Physics *ph);
PhCell* physicsCell(Physics *ph, Vec p);
void physicsClear(Physics *ph);
int physicsUpdate(Physics *ph);

void physicsDrawDebug(Physics *ph);


#endif