summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile29
-rw-r--r--src/common.h14
-rw-r--r--src/graphics.c72
-rw-r--r--src/graphics.h5
-rw-r--r--src/graphics_x11.c68
-rw-r--r--src/hackvr.c40
l---------src/hackvr_headless.c1
l---------src/hackvr_opengl.c1
l---------src/hackvr_x11.c1
-rw-r--r--src/math.c38
-rw-r--r--src/math.h18
11 files changed, 184 insertions, 103 deletions
diff --git a/src/Makefile b/src/Makefile
index 4e93005..1366de2 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2,27 +2,32 @@
### and add graphics.o to hackvr build target.
### fuck it. I'll fix it later.
CFLAGS=-Wall -pedantic -std=c99 -DGRAPHICAL -ffast-math
-#CFLAGS=-std=c99 -DGRAPHICAL -ffast-math
-all: hackvr slowcat
+all: hackvr_headless hackvr_x11 hackvr_opengl slowcat
-#for x11
-hackvr: LDLIBS=-lm -lX11
-#for opengl
-#hackvr: LDLIBS=-lm -lGL -lGLU -lglut
+hackvr_headless: LDLIBS=-lm
+hackvr_headless: CFLAGS=-Wall -pedantic -std=c99 -ffast-math
+hackvr_headless: hackvr_headless.o math.o
-hackvr: hackvr.o graphics.o graphics_x11.o
-#hackvr: hackvr.o graphics.o graphics_opengl.o
+hackvr_x11: LDLIBS=-lm -lX11
+hackvr_x11: hackvr_x11.o graphics.o graphics_x11.o math.o
-graphics_opengl.o: LDLIBS=-lm -lGL -lGLU -lglut
-
-graphics_x11.o: LDLIBS=-lm -lX11
+hackvr_opengl: LDLIBS=-lm -lGL -lGLU -lglut
+hackvr_opengl: hackvr_opengl.o graphics.o graphics_opengl.o math.o
-hackvr.o: LDLIBS=-lm -lX11
+hackvr_opengl.o: LDLIBS=-lm -lGL -lGLU -lglut
+hackvr_x11.o: LDLIBS=-lm -lX11
+hackvr_headless.o: LDLIBS=-lm
graphics.o: LDLIBS=-lm -lX11
+graphics_x11.o: LDLIBS=-lm -lX11
+graphics_opengl.o: LDLIBS=-lm -lGL -lGLU -lglut
+math.o: LDLIBS=-lm
clean:
rm -f hackvr
+ rm -f hackvr_headless
+ rm -f hackvr_opengl
+ rm -f hackvr_x11
rm -f slowcat
rm -f *.o
diff --git a/src/common.h b/src/common.h
index 35d6bcd..e8896ed 100644
--- a/src/common.h
+++ b/src/common.h
@@ -10,6 +10,14 @@
typedef double long real;
typedef struct {
+ real r;
+} radians;
+
+typedef struct {
+ int d;
+} degrees;
+
+typedef struct {
real x;
real y;
real z;
@@ -27,9 +35,9 @@ typedef struct {
struct camera {
c3_t p;
- int xr;//rotations
- int yr;
- int zr;
+ degrees xr;//rotations
+ degrees yr;
+ degrees zr;
real zoom;
} camera;
diff --git a/src/graphics.c b/src/graphics.c
index 1d4da11..b5f05c2 100644
--- a/src/graphics.c
+++ b/src/graphics.c
@@ -53,24 +53,26 @@ cs_t c2_to_cs(c2_t p) {
c2_t cs_to_c2(cs_t p) {
return (c2_t){s2cX(p.x),s2cY(p.y)};
}
-
+/*
real distance2(c2_t p1,c2_t p2) {
return sqrtl(( (p1.x-p2.x)*(p1.x-p2.x) )+( (p1.y-p2.y)*(p1.y-p2.y) ));
}
-
+*/
real distance3(c3_t p1,c3_t p2) {
return sqrtl(( (p1.x-p2.x)*(p1.x-p2.x) )+( (p1.y-p2.y)*(p1.y-p2.y) )+( (p1.z-p2.z)*(p1.z-p2.z) ));
}
+/*
real points_to_angle(c2_t p1,c2_t p2) {
real a=atan2l(p2.y-p1.y,p2.x-p1.x);
return a>=0?a:M_PIl+M_PIl+a;
}
-
+*/
+/*
real d2r(int d) {
while(d<0) d+=360;
return (real)(d%360) / (real)180 * M_PIl;
-}
+}*/
int r2d(real r) {
return r / M_PIl * 180;
}
@@ -202,7 +204,8 @@ void draw_graph(real (*fun)(real x)) {
}
}
-c2_t rotate_c2(c2_t p1,c2_t p2,real dr) {
+/*
+c2_t rotate_c2(c2_t p1,c2_t p2,real dr) {//dr is in radians
c2_t p3;
real d=distance2(p1,p2);
real r=points_to_angle(p1,p2);
@@ -227,7 +230,7 @@ c3_t rotate_c3_zr(c3_t p1,c3_t p2,real zr) {//rotate x and y around camera based
tmp=rotate_c2((c2_t){p1.x,p1.y},(c2_t){p2.x,p2.y},zr);
return (c3_t){tmp.x,tmp.y,p1.z};
}
-
+*/
c2_t c3_to_c2(c3_t p3) { //DO NOT DRAW STUFF IN HERE
c2_t p2;
// c3_t tmp1;
@@ -235,7 +238,7 @@ c2_t c3_to_c2(c3_t p3) { //DO NOT DRAW STUFF IN HERE
// c3_t tmp3;
c3_t final;
//these rotations need to be about the previous axis after the axis itself has been rotated.
- final=rotate_c3_yr(p3,camera.p,d2r(camera.yr));//rotate everything around the camera's location.
+ final=rotate_c3_yr(p3,camera.p,d2r(camera.yr.d));//rotate everything around the camera's location.
// final=rotate_c3_yr(p3,(c3_t){0,0,0},d2r(camera.yr));//rotate everything around the center no matter what.
// tmp2=rotate_c3_xr(tmp1,camera.p,d2r(camera.xr));
// final=rotate_c3_zr(tmp2,camera.p,d2r(camera.zr));
@@ -257,8 +260,8 @@ void draw_c3_line(c3_t p1,c3_t p2) {
draw_c2_line((c2_t){p1.x*global.mmz,p1.z*global.mmz},(c2_t){p2.x*global.mmz,p2.z*global.mmz});
}
if(gra_global.drawminimap == 2) {//map rotates.
- c3_t t1=rotate_c3_yr(p1,camera.p,d2r(camera.yr));
- c3_t t2=rotate_c3_yr(p2,camera.p,d2r(camera.yr));
+ c3_t t1=rotate_c3_yr(p1,camera.p,d2r(camera.yr.d));
+ c3_t t2=rotate_c3_yr(p2,camera.p,d2r(camera.yr.d));
draw_c2_line((c2_t){t1.x*global.mmz,t1.z*global.mmz},(c2_t){t2.x*global.mmz,t2.z*global.mmz});
}
if(gra_global.draw3d != 0) draw_c2_line(c3_to_c2(p1),c3_to_c2(p2));
@@ -283,7 +286,7 @@ real shitdist(struct c3_shape *s,c3_t p) {
real total=0;
for(i=0;i< s->len+(s->len==1);i++) {
// total=total+shitdist2(rotate_c3_yr(s->p[i],(c3_t){0,0,0},d2r(camera.yr)),camera.p);
- total=total+shitdist2(rotate_c3_yr(s->p[i],camera.p,d2r(camera.yr)),camera.p);
+ total=total+shitdist2(rotate_c3_yr(s->p[i],camera.p,d2r(camera.yr.d)),camera.p);
}
return (total) / (real)(s->len+(s->len==1));
}
@@ -363,7 +366,7 @@ int selfcommand(char *s) {
#endif
void draw_screen() {
- int i,j;
+ int i;
int cn=0;//camera number.
char tmp[256];
zsort_t zs[SHAPES];
@@ -371,10 +374,11 @@ void draw_screen() {
real oldx=camera.p.x;
real oldz=camera.p.z;
if(gra_global.split_screen > 1) {
- camera.p.z-=(gra_global.split_flip)*((gra_global.split/gra_global.split_screen)*cosl(d2r(camera.yr+180)));
- camera.p.x-=(gra_global.split_flip)*((gra_global.split/gra_global.split_screen)*sinl(d2r(camera.yr+180)));
+ camera.p.z-=(gra_global.split_flip)*((gra_global.split/gra_global.split_screen)*cosl(d2r(camera.yr.d+180)));
+ camera.p.x-=(gra_global.split_flip)*((gra_global.split/gra_global.split_screen)*sinl(d2r(camera.yr.d+180)));
}
for(cn=0;cn<gra_global.split_screen;cn++) {
+ set_color();//restart each draw with the default color.
if(gra_global.red_and_blue) {
//set color for left half to red and right half to blue
//and draw mode for the gc to GXOr
@@ -409,7 +413,7 @@ void draw_screen() {
draw_cs_text((cs_t){gra_global.xoff,(gra_global.height/2)+20},tmp);
snprintf(tmp,sizeof(tmp)-1,"cx: %Lf cy: %Lf cz: %Lf",camera.p.x,camera.p.y,camera.p.z);
draw_cs_text((cs_t){gra_global.xoff,(gra_global.height/2)+30},tmp);
- snprintf(tmp,sizeof(tmp)-1,"xr: %d yr: %d zr: %d",camera.xr,camera.yr,camera.zr);
+ snprintf(tmp,sizeof(tmp)-1,"xr: %d yr: %d zr: %d",camera.xr.d,camera.yr.d,camera.zr.d);
draw_cs_text((cs_t){gra_global.xoff,(gra_global.height/2)+40},tmp);
}
@@ -423,34 +427,6 @@ void draw_screen() {
// draw_c2_line((c2_t){10,10},(c2_t){-10,10});
// }
-/* cube
- draw_c3_line((c3_t){-3,0,-3},(c3_t){-3,0,3});
- draw_c3_line((c3_t){-3,0,-3},(c3_t){-3,6,-3});
- draw_c3_line((c3_t){-3,0,-3},(c3_t){3,0,-3});
-
- draw_c3_line((c3_t){3,6,3},(c3_t){3,6,-3});
- draw_c3_line((c3_t){3,6,3},(c3_t){-3,6,3});
- draw_c3_line((c3_t){3,6,3},(c3_t){3,0,3});
-
- draw_c3_line((c3_t){-3,0,3},(c3_t){3,0,3});
- draw_c3_line((c3_t){-3,0,3},(c3_t){-3,6,3});
-
- draw_c3_line((c3_t){-3,6,-3},(c3_t){-3,6,3});
- draw_c3_line((c3_t){-3,6,-3},(c3_t){3,6,-3});
-
- draw_c3_line((c3_t){3,0,-3},(c3_t){3,0,3});
- draw_c3_line((c3_t){3,0,-3},(c3_t){3,6,-3});
-*/
-
- //floor grid
-/* for(i=-21;i<21;i+=3) {
- for(j=-21;j<21;j+=3) {
- //draw_c3_triangle((struct c3_triangle){"id",(c3_t){i,0,j},(c3_t){i,0,j+3},(c3_t){i+3,0,j}});
- draw_c3_line((c3_t){i,0,j},(c3_t){i,0,j+3});
- draw_c3_line((c3_t){i,0,j},(c3_t){i+3,0,j});
- }
- }*/
-
//apply rotation?
// load up the triangles to render... after applying rotation?
for(i=0;global.shape[i];i++) {
@@ -468,6 +444,10 @@ void draw_screen() {
strcpy(global.selected_object,zs[i-1].s->id);//0th is farthest. fixme.
}
//draw all triangles
+ if(global.debug) {
+ snprintf(tmp,sizeof(tmp)-1,"selected object: %s",global.selected_object);
+ draw_cs_text((cs_t){gra_global.xoff,(gra_global.height/2)+50},tmp);
+ }
for(i=0;global.shape[i];i++) {
//now we pick the color of this triangle!
if(gra_global.red_and_blue) {
@@ -492,12 +472,8 @@ void draw_screen() {
//}
}
// XSetForeground(global.dpy, global.backgc, global.green.pixel);
- if(global.debug) {
- snprintf(tmp,sizeof(tmp)-1,"selected object: %s",global.selected_object);
- draw_cs_text((cs_t){gra_global.xoff,(gra_global.height/2)+50},tmp);
- }
- camera.p.z+=(gra_global.split_flip)*(gra_global.split*cosl(d2r(camera.yr+180)));
- camera.p.x+=(gra_global.split_flip)*(gra_global.split*sinl(d2r(camera.yr+180)));
+ camera.p.z+=(gra_global.split_flip)*(gra_global.split*cosl(d2r(camera.yr.d+180)));
+ camera.p.x+=(gra_global.split_flip)*(gra_global.split*sinl(d2r(camera.yr.d+180)));
}
//TODO: figure out what all this shit is and either update or remove.
diff --git a/src/graphics.h b/src/graphics.h
index 99b9fc2..b351d2c 100644
--- a/src/graphics.h
+++ b/src/graphics.h
@@ -44,7 +44,10 @@ int selfcommand(char *s);
cs_t c3_to_cs(c3_t p);
real d2r(int d);
real shitdist(struct c3_shape *s,c3_t p);
-
+c3_t rotate_c3_xr(c3_t p1,c3_t p2,real xr);
+c3_t rotate_c3_yr(c3_t p1,c3_t p2,real yr);
+c3_t rotate_c3_zr(c3_t p1,c3_t p2,real zr);
+real points_to_angle(c2_t p1,c2_t p2);
int compar(zsort_t *a,zsort_t *b);
diff --git a/src/graphics_x11.c b/src/graphics_x11.c
index 45994dd..f342089 100644
--- a/src/graphics_x11.c
+++ b/src/graphics_x11.c
@@ -39,6 +39,26 @@ struct x11_global x11_global;
#ifdef GRAPHICAL
+/*
+struct plane {
+ c3_t p;
+ real xr;
+ real yr;
+ real zr;
+}
+
+void calculate_shape_color(c3_s_t s,real d) {
+//given: at least 3 points on a plane.
+//needed: angles of the plane.
+//
+ xa=
+ ya=
+ za=
+ for(i=0;i<;i++) {
+ s.p.x
+ }
+}
+*/
void set_color_based_on_distance(real d) {
int i=100-((int)((d+100.0) * 16.0) % 100);
XSetForeground(x11_global.dpy,x11_global.backgc,x11_global.colors[i].pixel);
@@ -114,7 +134,7 @@ void red_and_blue_magic() {
}
void draw_sky() {
- XCopyArea(x11_global.dpy,skypixmap,x11_global.backbuffer,x11_global.backgc,((camera.yr*5)+SKYW)%SKYW,0,WIDTH,gra_global.height/2,0,0);
+ XCopyArea(x11_global.dpy,skypixmap,x11_global.backbuffer,x11_global.backgc,((camera.yr.d*5)+SKYW)%SKYW,0,WIDTH,gra_global.height/2,0,0);
}
void set_color() {
@@ -146,32 +166,32 @@ int keypress_handler(int sym) {
selfcommand(line);
break;
case XK_Up:
- tmpx=WALK_SPEED*sinl(d2r(camera.yr+90));
- tmpz=WALK_SPEED*cosl(d2r(camera.yr+90));
+ tmpx=WALK_SPEED*sinl(d2r(camera.yr.d+90));
+ tmpz=WALK_SPEED*cosl(d2r(camera.yr.d+90));
camera.p.x+=tmpx;
camera.p.z+=tmpz;
snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
selfcommand(line);
break;
case XK_Down:
- tmpx=WALK_SPEED*sinl(d2r(camera.yr+270));
- tmpz=WALK_SPEED*cosl(d2r(camera.yr+270));
+ tmpx=WALK_SPEED*sinl(d2r(camera.yr.d+270));
+ tmpz=WALK_SPEED*cosl(d2r(camera.yr.d+270));
camera.p.x+=tmpx;
camera.p.z+=tmpz;
snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
selfcommand(line);
break;
case XK_Left:
- tmpx=WALK_SPEED*sinl(d2r(camera.yr));
- tmpz=WALK_SPEED*cosl(d2r(camera.yr));
+ tmpx=WALK_SPEED*sinl(d2r(camera.yr.d));
+ tmpz=WALK_SPEED*cosl(d2r(camera.yr.d));
camera.p.x+=tmpx;
camera.p.z+=tmpz;
snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
selfcommand(line);
break;
case XK_Right:
- tmpx=WALK_SPEED*sinl(d2r(camera.yr+180));
- tmpz=WALK_SPEED*cosl(d2r(camera.yr+180));
+ tmpx=WALK_SPEED*sinl(d2r(camera.yr.d+180));
+ tmpz=WALK_SPEED*cosl(d2r(camera.yr.d+180));
camera.p.x+=tmpx;
camera.p.z+=tmpz;
snprintf(line,sizeof(line)-1,"%s move %Lf 0 %Lf 0 0 0 0 0 0\n",global.user,tmpx,tmpz);
@@ -188,28 +208,28 @@ int keypress_handler(int sym) {
selfcommand(line);
break;
case XK_r:
- camera.xr+=5;
- while(camera.xr > 360) camera.xr-=360;
+ camera.xr.d+=5;
+ while(camera.xr.d > 360) camera.xr.d-=360;
break;
case XK_y:
- camera.xr-=5;
- while(camera.xr < 0) camera.xr+=360;
+ camera.xr.d-=5;
+ while(camera.xr.d < 0) camera.xr.d+=360;
break;
case XK_q:
- camera.yr+=5;
- while(camera.yr > 360) camera.yr-=360;
+ camera.yr.d+=5;
+ while(camera.yr.d > 360) camera.yr.d-=360;
break;
case XK_e:
- camera.yr-=5;
- while(camera.yr < 0) camera.yr+=360;
+ camera.yr.d-=5;
+ while(camera.yr.d < 0) camera.yr.d+=360;
break;
case XK_u:
- camera.zr+=5;
- while(camera.zr > 360) camera.zr-=360;
+ camera.zr.d+=5;
+ while(camera.zr.d > 360) camera.zr.d-=360;
break;
case XK_o:
- camera.zr-=5;
- while(camera.zr < 0) camera.zr+=360;
+ camera.zr.d-=5;
+ while(camera.zr.d < 0) camera.zr.d+=360;
break;
case XK_z: camera.zoom+=1; break;
case XK_x: camera.zoom-=1; break;
@@ -339,9 +359,9 @@ int graphics_init() {
//this should be in graphics.c ?
camera.zoom=30.0l;
- camera.xr=270;
- camera.yr=90;
- camera.zr=0;
+ camera.xr.d=270;
+ camera.yr.d=90;
+ camera.zr.d=0;
global.mmz=1;
camera.p.x=0;
camera.p.z=-6;
diff --git a/src/hackvr.c b/src/hackvr.c
index e2a0593..b1819cb 100644
--- a/src/hackvr.c
+++ b/src/hackvr.c
@@ -14,6 +14,7 @@
#include "config.h"
#include "common.h"
+#include "math.h"
#ifdef GRAPHICAL
#include "graphics.h"
extern struct gra_global gra_global;
@@ -209,9 +210,9 @@ int load_stdin() {
printf("%s set camera.p.x %Lf\n",global.user,camera.p.x);
printf("%s set camera.p.y %Lf\n",global.user,camera.p.y);
printf("%s set camera.p.z %Lf\n",global.user,camera.p.z);
- printf("%s set camera.xr %d\n",global.user,camera.xr);
- printf("%s set camera.yr %d\n",global.user,camera.yr);
- printf("%s set camera.zr %d\n",global.user,camera.zr);
+ printf("%s set camera.xr %d\n",global.user,camera.xr.d);
+ printf("%s set camera.yr %d\n",global.user,camera.yr.d);
+ printf("%s set camera.zr %d\n",global.user,camera.zr.d);
printf("%s set camera.zoom %Lf\n",global.user,camera.zoom);
continue;
}
@@ -221,13 +222,16 @@ int load_stdin() {
if(!strcmp(command,"set")) { //set variable //TODO: add more things to this.
if(len != 3 && len != 4) continue;
if(len == 4) {
- if(!strcmp(a[2],"camera.p.x")) camera.p.x=strtold(a[3],0);
+ if(0);
+#ifdef GRAPHICAL
+ else if(!strcmp(a[2],"camera.p.x")) camera.p.x=strtold(a[3],0);
else if(!strcmp(a[2],"camera.p.y")) camera.p.y=strtold(a[3],0);
else if(!strcmp(a[2],"camera.p.z")) camera.p.z=strtold(a[3],0);
else if(!strcmp(a[2],"camera.zoom")) camera.zoom=strtold(a[3],0);
- else if(!strcmp(a[2],"camera.xr")) camera.xr=atoi(a[3]);
- else if(!strcmp(a[2],"camera.yr")) camera.yr=atoi(a[3]);
- else if(!strcmp(a[2],"camera.zr")) camera.zr=atoi(a[3]);
+ else if(!strcmp(a[2],"camera.xr")) camera.xr.d=atoi(a[3]);
+ else if(!strcmp(a[2],"camera.yr")) camera.yr.d=atoi(a[3]);
+ else if(!strcmp(a[2],"camera.zr")) camera.zr.d=atoi(a[3]);
+#endif
else printf("# unknown variable: %s\n",a[2]);
continue;
}
@@ -286,6 +290,19 @@ int load_stdin() {
}
continue;
}
+ if(!strcmp(command,"rotate")) {
+ if(len > 4) {
+ for(i=0;global.shape[i];i++) {
+ if(!strcmp(global.shape[i]->id,id)) {
+ for(j=0;j < global.shape[i]->len+(global.shape[i]->len==1);j++) {
+ global.shape[i]->p[j]=rotate_c3_yr(global.shape[i]->p[j],(c3_t){0,0,0},points_to_angle((c2_t){global.shape[i]->p[j].x,global.shape[i]->p[j].z},(c2_t){0,0})+d2r(atoi(a[2])));
+ //global.shape[i]->p[j]=rotate_c3_yr(global.shape[i]->p[j],(c3_t){0,0,0},d2r(atoi(a[3])));
+ //global.shape[i]->p[j]=rotate_c3_zr(global.shape[i]->p[j],(c3_t){0,0,0},d2r(atoi(a[4])));
+ }
+ }
+ }
+ }
+ }
if(!strcmp(command,"move")) {
if(len > 4) {
for(i=0;global.shape[i];i++) {
@@ -301,16 +318,9 @@ int load_stdin() {
else {
printf("# ERROR: wrong amount of parts for move. got: %d expected: 11\n",len);
}
- continue;
+ continue;//???
}
printf("# I don't know what command you're talking about. %s\n",command);
-/* if(!strcmp(command,"rotate")) {
- for(i=0;global.shape[i];i++) {
- global.shape[i]->p1=rotate_c3_about()
- global.shape[i]->p2=
- global.shape[i]->p3=
- }
-*/
free(line);
if(a) free(a);
}
diff --git a/src/hackvr_headless.c b/src/hackvr_headless.c
new file mode 120000
index 0000000..e4c9ddd
--- /dev/null
+++ b/src/hackvr_headless.c
@@ -0,0 +1 @@
+hackvr.c \ No newline at end of file
diff --git a/src/hackvr_opengl.c b/src/hackvr_opengl.c
new file mode 120000
index 0000000..e4c9ddd
--- /dev/null
+++ b/src/hackvr_opengl.c
@@ -0,0 +1 @@
+hackvr.c \ No newline at end of file
diff --git a/src/hackvr_x11.c b/src/hackvr_x11.c
new file mode 120000
index 0000000..e4c9ddd
--- /dev/null
+++ b/src/hackvr_x11.c
@@ -0,0 +1 @@
+hackvr.c \ No newline at end of file
diff --git a/src/math.c b/src/math.c
new file mode 100644
index 0000000..491d6a3
--- /dev/null
+++ b/src/math.c
@@ -0,0 +1,38 @@
+#include "math.h"
+
+c3_t rotate_c3_xr(c3_t p1,c3_t p2,real xr) {//rotate y and z around camera based on xr (looking up and down)
+ c2_t tmp;
+ tmp=rotate_c2((c2_t){p1.y,p1.z},(c2_t){p2.y,p2.z},xr);
+ return (c3_t){p1.x,tmp.x,tmp.y};
+}
+c3_t rotate_c3_yr(c3_t p1,c3_t p2,real yr) {//rotate x and z around camera based on yr (looking left and right)
+ c2_t tmp;
+ tmp=rotate_c2((c2_t){p1.x,p1.z},(c2_t){p2.x,p2.z},yr);
+ return (c3_t){tmp.x,p1.y,tmp.y};
+}
+c3_t rotate_c3_zr(c3_t p1,c3_t p2,real zr) {//rotate x and y around camera based on zr (cocking your head to a side)
+ c2_t tmp;
+ tmp=rotate_c2((c2_t){p1.x,p1.y},(c2_t){p2.x,p2.y},zr);
+ return (c3_t){tmp.x,tmp.y,p1.z};
+}
+
+c2_t rotate_c2(c2_t p1,c2_t p2,real dr) {//dr is in radians
+ c2_t p3;
+ real d=distance2(p1,p2);
+ real r=points_to_angle(p1,p2);
+ r=r+dr;
+ p3.x=(sinl(r) * d) + p2.x;
+ p3.y=(cosl(r) * d) + p2.y;
+ return p3;
+}
+real distance2(c2_t p1,c2_t p2) {
+ return sqrtl(( (p1.x-p2.x)*(p1.x-p2.x) )+( (p1.y-p2.y)*(p1.y-p2.y) ));
+}
+real d2r(int d) {
+ while(d<0) d+=360;
+ return (real)(d%360) / (real)180 * M_PIl;
+}
+real points_to_angle(c2_t p1,c2_t p2) {
+ real a=atan2l(p2.y-p1.y,p2.x-p1.x);
+ return a>=0?a:M_PIl+M_PIl+a;
+}
diff --git a/src/math.h b/src/math.h
new file mode 100644
index 0000000..1afe959
--- /dev/null
+++ b/src/math.h
@@ -0,0 +1,18 @@
+#ifndef _HACKVR_MATH_H_
+#define _HACKVR_MATH_H_
+
+#include "common.h" //should define c3_t
+
+#define __USE_GNU
+#include <math.h>
+#undef __USE_GNU
+
+real distance2(c2_t p1,c2_t p2);
+c2_t rotate_c2(c2_t p1,c2_t p2,real dr);
+c3_t rotate_c3_xr(c3_t p1,c3_t p2,real xr);
+c3_t rotate_c3_yr(c3_t p1,c3_t p2,real yr);
+c3_t rotate_c3_zr(c3_t p1,c3_t p2,real zr);
+real d2r(int d);
+real points_to_angle(c2_t p1,c2_t p2);
+
+#endif