summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile6
-rw-r--r--src/Makefile45
-rw-r--r--src/common.h3
-rw-r--r--src/graphics_cs_x11.c46
-rw-r--r--src/math.c93
-rw-r--r--src/math.h4
6 files changed, 150 insertions, 47 deletions
diff --git a/Makefile b/Makefile
index 3b9f51a..131f46a 100644
--- a/Makefile
+++ b/Makefile
@@ -1,11 +1,9 @@
+PREFIX:=/usr/local
+
all: hackvr hackvr_term
.PHONY: hackvr hackvr_term clean install uninstall all
-ifeq ($(PREFIX),)
-$(error the PREFIX variable is NOT set)
-endif
-
hackvr:
$(MAKE) -C src all
diff --git a/src/Makefile b/src/Makefile
index f43ceb3..4b31ed5 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2,7 +2,7 @@
PREFIX:=/usr/local/
-CFLAGS=-Wall -pedantic -std=c99 -DGRAPHICAL -ffast-math -I$(PREFIX)/include
+CFLAGS+=-Wall -pedantic -std=c99 -DGRAPHICAL -ffast-math -I$(PREFIX)/include
LDFLAGS=-L$(PREFIX)/lib
#all: hackvr_headless hackvr_x11 hackvr_opengl slowcat ### when hackvr_opengl gets useful at all I'll start including it in default build.
@@ -12,59 +12,60 @@ all: hackvr_headless hackvr_x11 slowcat nonblocktail
nonblocktail: LDLIBS=-lidc
nonblocktail: nonblocktail.c
-hackvr_headless: LDLIBS=-lm -lidc
+hackvr_headless: LDLIBS=-lm -lidc -lhashtable
hackvr_headless: hackvr_headless.o math.o physics.o
-hackvr_x11: LDLIBS=-lm -lidc -lX11
+hackvr_x11: LDLIBS=-lm -lidc -lX11 -lhashtable
hackvr_x11: hackvr_x11.o graphics_c3.o graphics_c2.o graphics_cs_x11.o math.o physics.o keyboard.o mouse_x11.o keyboard_x11.o input.o
#notice how all the targets have generic graphics objects up until a specific one.
-hackvr_fb: LDLIBS=-lm -lidc
+hackvr_fb: LDLIBS=-lm -lidc -lhashtable
hackvr_fb: hackvr_fb.o graphics_c3.o graphics_c2.o graphics_cs_fb.o math.o physics.o keyboard_die.o keyboard.o mouse_die.o
-hackvr_opengl: LDLIBS=-lm -lidc -lGL -lGLU -lglut
+hackvr_opengl: LDLIBS=-lm -lidc -lGL -lGLU -lglut -lhashtable
hackvr_opengl: hackvr_opengl.o graphics_c3.o graphics_c2_opengl.o graphics_cs_opengl.o math.o physics.o
-hackvr_freeglut: LDLIBS=-lm -lidc -lGL -lGLU -lglut
+hackvr_freeglut: LDLIBS=-lm -lidc -lGL -lGLU -lglut -lhashtable
hackvr_freeglut: hackvr_freeglut.o graphics_c3_freeglut.o math.o physics.o keyboard.o mouse_die.o keyboard_die.o
-hackvr_freeglut.o: LDLIBS=-lm -lidc -lGL -lGLU -lglut
+hackvr_freeglut.o: LDLIBS=-lm -lidc -lGL -lGLU -lglut -lhashtable
hackvr_freeglut.o: CFLAGS+='-DHVR_VERSION="freeglut"'
hackvr_fb.o: CFLAGS+='-DHVR_VERSION="framebuffer"'
-graphics_c3_freeglut.o: LDLIBS=-lm -lidc -lGL -lGLU -lglut
+graphics_c3_freeglut.o: LDLIBS=-lm -lidc -lGL -lGLU -lglut -lhashtable
-hackvr_opengl.o: LDLIBS=-lm -lidc -lGL -lGLU -lglut
+hackvr_opengl.o: LDLIBS=-lm -lidc -lGL -lGLU -lglut -lhashtable
hackvr_opengl.o: CFLAGS+='-DHVR_VERSION="opengl"'
-hackvr_x11.o: LDLIBS=-lm -lidc -lX11
+hackvr_x11.o: LDLIBS=-lm -lidc -lX11 -lhashtable
hackvr_x11.o: CFLAGS+='-DHVR_VERSION="x11"'
hackvr_headless.o: CFLAGS=-Wall -pedantic -std=c99 -ffast-math -I$(PREFIX)/include
hackvr_headless.o: CFLAGS+='-DHVR_VERSION="headless"'
-hackvr_headless.o: LDLIBS=-lm -lidc
+hackvr_headless.o: LDLIBS=-lm -lidc -lhashtable
-graphics_c3.o: LDLIBS=-lm -lidc
-graphics_c2.o: LDLIBS=-lm -lidc
+graphics_c3.o: LDLIBS=-lm -lidc -lhashtable
+graphics_c2.o: LDLIBS=-lm -lidc -lhashtable
-physics.o: LDLIBS=-lm -lidc
+physics.o: LDLIBS=-lm -lidc -lhashtable
-keyboard.o: LDLIBS=-lm -lidc
+keyboard.o: LDLIBS=-lm -lidc -lhashtable
-input.o: LDLIBS=-lm -lidc
+input.o: LDLIBS=-lm -lidc -lhashtable
-graphics_cs_x11.o: LDLIBS=-lm -lidc -lX11
-mouse_x11.o:LDLIBS=-lX11
-keyboard_x11.o:LDLIBS=-lX11
+graphics_cs_x11.o: LDLIBS=-lm -lidc -lX11 -lhashtable
+mouse_x11.o:LDLIBS=-lX11 -lhashtable
+keyboard_x11.o:LDLIBS=-lX11 -lhashtable
-graphics_c2_opengl.o: LDLIBS=-lm -lidc -lGL -lGLU -lglut
-graphics_cs_opengl.o: LDLIBS=-lm -lidc -lGL -lGLU -lglut
-math.o: LDLIBS=-lm -lidc
+graphics_c2_opengl.o: LDLIBS=-lm -lidc -lGL -lGLU -lglut -lhashtable
+graphics_cs_opengl.o: LDLIBS=-lm -lidc -lGL -lGLU -lglut -lhashtable
+math.o: LDLIBS=-lm -lidc -lhashtable
install: all
mkdir -p $(PREFIX)/bin
install hackvr $(PREFIX)/bin/hackvr
+ install -t $(PREFIX)/bin hackvr_uri
install hackvr_headless $(PREFIX)/bin/hackvr_headless
install hackvr_x11 $(PREFIX)/bin/hackvr_x11
install slowcat $(PREFIX)/bin/slowcat
diff --git a/src/common.h b/src/common.h
index b5054a7..a555cb1 100644
--- a/src/common.h
+++ b/src/common.h
@@ -6,6 +6,8 @@
#ifndef _HACKVR_COMMON_H_
#define _HACKVR_COMMON_H_
+#include <hashtable.h>
+
#define TOP 240.0
#define BOTTOM -240.0
#define RIGHT 320.0
@@ -110,6 +112,7 @@ struct hvr_global {
struct c3_shape *shape[SHAPES];
int shapes;
c3_group_rot_t *group_rot[SHAPES];//there can be less of these.
+ struct hashtable ht_group;
c3_group_rot_t camera;
real zoom;
int derp;
diff --git a/src/graphics_cs_x11.c b/src/graphics_cs_x11.c
index be008bf..f58600b 100644
--- a/src/graphics_cs_x11.c
+++ b/src/graphics_cs_x11.c
@@ -86,7 +86,7 @@ void draw_cs_text(cs_t p,char *text) {
void draw_cs_shape(cs_s_t s) {//this is implemented as draw_cs_line... hrm. it could be moved up to graphics.c? probl no.
//test in here whether a mouse click is within this shape's... bounding box? sure.
- cs_s_t bb;//bounding box
+ //cs_s_t bb;//bounding box
cs_t smouse=c2_to_cs(gra_global.mouse);
int minx=s.p[0].x;
int miny=s.p[0].y;
@@ -115,26 +115,30 @@ void draw_cs_shape(cs_s_t s) {//this is implemented as draw_cs_line... hrm. it c
maxy=(s.p[i].y>maxy)?s.p[i].y:maxy;
draw_cs_line(s.p[i],s.p[(i+1)%(s.len+(s.len==1))]);
}
+ //fix the comparison here and also fix the hilighting shape
if(smouse.x >= minx && //gra_global is a c2_t and these are in cs_t
- smouse.y >= miny &&
- smouse.x <= maxx &&
- smouse.y <= maxy) {
- if(gra_global.mousemap[0]==-1) {//if we're inside the bounding box let's make SOMETHING happen.
- gra_global.mousemap[0]=0;
- printf("%s action %s\n",global.user,s.id);
+ smouse.y >= miny &&
+ smouse.x <= maxx &&
+ smouse.y <= maxy) {
+// if(wn_PnPoly(smouse,s.p,s.len) != 0 && s.len > 2) {
+ if(gra_global.mousemap[0] == -1) {//if we're inside the bounding box let's make SOMETHING happen.
+ gra_global.mousemap[0]=0;
+ printf("%s action %s\n",global.user,s.id);
+// }
+/* bb.id=strdup("boundingbox");
+ bb.len=4;
+ bb.p[0].x=minx;
+ bb.p[0].y=miny;
+ bb.p[1].x=minx;
+ bb.p[1].y=maxy;
+ bb.p[2].x=maxx;
+ bb.p[2].y=maxy;
+ bb.p[3].x=maxx;
+ bb.p[3].y=miny;
+ draw_cs_filled_shape(bb);
+ free(bb.id);
+*/
}
- bb.id=strdup("boundingbox");
- bb.len=4;
- bb.p[0].x=minx;
- bb.p[0].y=miny;
- bb.p[1].x=minx;
- bb.p[1].y=maxy;
- bb.p[2].x=maxx;
- bb.p[2].y=maxy;
- bb.p[3].x=maxx;
- bb.p[3].y=miny;
- draw_cs_filled_shape(bb);
- free(bb.id);
}
break;
}
@@ -505,7 +509,7 @@ int graphics_event_handler(int world_changed) { //should calling draw_screen be
}
while(XCheckMaskEvent(x11_global.dpy,HV_GRAPHICS_X11_EVENT_MASK,&e)) {//we should squish all of the window events. they just cause a redraw anyway
switch(e.type) {
- case Expose:
+ case Expose: case NoExpose: case MapNotify:
//if(e.xexpose.count == 0) redraw=1;
redraw=1;
break;
@@ -531,7 +535,7 @@ int graphics_event_handler(int world_changed) { //should calling draw_screen be
break;
default:
-// fprintf(stderr,"# received unknown event with type: %d\n",e.type);
+ fprintf(stderr,"# received unknown event with type: %d\n",e.type);
break;
}
}
diff --git a/src/math.c b/src/math.c
index d05789d..318465d 100644
--- a/src/math.c
+++ b/src/math.c
@@ -9,8 +9,18 @@ extern struct hvr_global global;
//might change this to use hashtables for faster lookups.
c3_group_rot_t *get_group_relative(char *id) {//crashes in here somehwere...
int i;
+ c3_group_rot_t *gr;
+ struct entry *tmp;
+ if((tmp=ht_getnode(&global.ht_group,id))) {
+ gr=tmp->target;
+ return gr;
+ }//if this didn't work, do fallback...
for(i=0;global.group_rot[i];i++) {
if(!strcmp(global.group_rot[i]->id,id)) {//should I use glob here and return an array?
+ if(gr != global.group_rot[i]) {
+ fprintf(stderr,"# %s ? %s ? %s\n",tmp->original,gr->id,global.group_rot[i]->id);
+ fprintf(stderr,"# %16x != %16x. wtf?\n",gr,global.group_rot[i]);
+ }
return global.group_rot[i];
}
}
@@ -135,6 +145,7 @@ c3_s_t apply_group_relative(c3_s_t s,c3_group_rot_t *group_rot) {
int i;
s2.len=s.len;
s2.id=s.id;
+ s2.attrib=s.attrib;
if(group_rot) {
gr=group_rot;
} else {
@@ -183,3 +194,85 @@ c3_t c3_add(c3_t p1,c3_t p2) {
real distance3(c3_t p1,c3_t p2) {
return sqrt(( (p1.x-p2.x)*(p1.x-p2.x) )+( (p1.y-p2.y)*(p1.y-p2.y) )+( (p1.z-p2.z)*(p1.z-p2.z) ));
}
+
+/* epoch copied this from: http://geomalgorithms.com/a03-_inclusion.html */
+/* then edited it to work with hackvr ofc */
+
+// Copyright 2000 softSurfer, 2012 Dan Sunday
+// This code may be freely used and modified for any purpose
+// providing that this copyright notice is included with it.
+// SoftSurfer makes no warranty for this code, and cannot be held
+// liable for any real or imagined damage resulting from its use.
+// Users of this code must verify correctness for their application.
+
+
+// a Point is defined by its coordinates {int x, y;}
+//===================================================================
+
+
+// isLeft(): tests if a point is Left|On|Right of an infinite line.
+// Input: three points P0, P1, and P2
+// Return: >0 for P2 left of the line through P0 and P1
+// =0 for P2 on the line
+// <0 for P2 right of the line
+// See: Algorithm 1 "Area of Triangles and Polygons"
+inline int
+isLeft( cs_t P0, cs_t P1, cs_t P2 )
+{
+ return ( (P1.x - P0.x) * (P2.y - P0.y)
+ - (P2.x - P0.x) * (P1.y - P0.y) );
+}
+//===================================================================
+
+
+// cn_PnPoly(): crossing number test for a point in a polygon
+// Input: P = a point,
+// V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
+// Return: 0 = outside, 1 = inside
+// This code is patterned after [Franklin, 2000]
+int
+cn_PnPoly( cs_t P, cs_t *V, int n )
+{
+ int cn = 0; // the crossing number counter
+
+ // loop through all edges of the polygon
+ for (int i=0; i<n; i++) { // edge from V[i] to V[i+1]
+ if (((V[i].y <= P.y) && (V[i+1].y > P.y)) // an upward crossing
+ || ((V[i].y > P.y) && (V[i+1].y <= P.y))) { // a downward crossing
+ // compute the actual edge-ray intersect x-coordinate
+ float vt = (float)(P.y - V[i].y) / (V[i+1].y - V[i].y);
+ if (P.x < V[i].x + vt * (V[i+1].x - V[i].x)) // P.x < intersect
+ ++cn; // a valid crossing of y=P.y right of P.x
+ }
+ }
+ return (cn&1); // 0 if even (out), and 1 if odd (in)
+
+}
+//===================================================================
+
+
+// wn_PnPoly(): winding number test for a point in a polygon
+// Input: P = a point,
+// V[] = vertex points of a polygon V[n+1] with V[n]=V[0]
+// Return: wn = the winding number (=0 only when P is outside)
+int
+wn_PnPoly( cs_t P, cs_t *V, int n )
+{
+ int wn = 0; // the winding number counter
+
+ // loop through all edges of the polygon
+ for (int i=0; i<(n-1); i++) { // edge from V[i] to V[i+1]
+ if (V[i].y <= P.y) { // start y <= P.y
+ if (V[i+1].y > P.y) // an upward crossing
+ if (isLeft( V[i], V[i+1], P) > 0) // P left of edge
+ ++wn; // have a valid up intersect
+ }
+ else { // start y > P.y (no test needed)
+ if (V[i+1].y <= P.y) // a downward crossing
+ if (isLeft( V[i], V[i+1], P) < 0) // P right of edge
+ --wn; // have a valid down intersect
+ }
+ }
+ return wn;
+}
+//===================================================================
diff --git a/src/math.h b/src/math.h
index 8d058cc..e7b5249 100644
--- a/src/math.h
+++ b/src/math.h
@@ -24,4 +24,8 @@ c3_t c3_add(c3_t p1,c3_t p2);
real distance3(c3_t p1,c3_t p2);
void print_point(c3_t p);
+int isLeft(cs_t, cs_t, cs_t);
+int cn_PnPoly(cs_t, cs_t *, int);
+int wn_PnPoly(cs_t, cs_t *, int);
+
#endif