diff options
-rw-r--r-- | dat.h | 1 | ||||
-rw-r--r-- | fns.h | 2 | ||||
-rw-r--r-- | mkfile | 2 | ||||
-rw-r--r-- | qball.c (renamed from qb.c) | 40 | ||||
-rw-r--r-- | vis.c | 9 |
5 files changed, 24 insertions, 30 deletions
@@ -28,5 +28,6 @@ enum { Scambx, Scamby, Scambz, Sfps, Sframes, + Sorient, Se }; @@ -2,4 +2,4 @@ void *emalloc(ulong); void *erealloc(void*, ulong); Image *eallocimage(Display*, Rectangle, ulong, int, ulong); Memimage *eallocmemimage(Rectangle, ulong); -void qb(Rectangle, Point, Point, Quaternion*, Quaternion*); +void qball(Rectangle, Point, Point, Quaternion*, Quaternion*); @@ -7,7 +7,7 @@ TARG=\ OFILES=\ alloc.$O\ - qb.$O\ + qball.$O\ HFILES=dat.h fns.h @@ -15,11 +15,7 @@ #include "libgraphics/graphics.h" #include "fns.h" -static int -min(int a, int b) -{ - return a < b? a: b; -} +#define MIN(a, b) ((a)<(b)?(a):(b)) /* * Convert a mouse point into a unit quaternion, flattening if @@ -32,14 +28,13 @@ mouseq(Point2 p, Quaternion *axis) Quaternion q; double rsq = p.x*p.x + p.y*p.y; /* quadrance */ + q.r = 0; if(rsq > 1){ /* outside the sphere */ - rsq = sqrt(rsq); - q.r = 0; - q.i = p.x/rsq; - q.j = p.y/rsq; + rsq = 1/sqrt(rsq); + q.i = p.x*rsq; + q.j = p.y*rsq; q.k = 0; - }else{ /* within the sphere */ - q.r = 0; + }else{ q.i = p.x; q.j = p.y; q.k = sqrt(1 - rsq); @@ -62,25 +57,24 @@ mouseq(Point2 p, Quaternion *axis) } void -qb(Rectangle r, Point p0, Point p1, Quaternion *orient, Quaternion *axis) +qball(Rectangle r, Point p0, Point p1, Quaternion *orient, Quaternion *axis) { - Quaternion q, down; + Quaternion qdown, qdrag; Point2 rmin, rmax; - Point2 s0, s1; /* screen coords */ Point2 v0, v1; /* unit sphere coords */ Point2 ctlcen; /* controller center */ double ctlrad; /* controller radius */ + if(orient == nil) + return; + rmin = Vec2(r.min.x, r.min.y); rmax = Vec2(r.max.x, r.max.y); - s0 = Vec2(p0.x, p0.y); - s1 = Vec2(p1.x, p1.y); ctlcen = divpt2(addpt2(rmin, rmax), 2); - ctlrad = min(Dx(r), Dy(r)); - v0 = divpt2(subpt2(s0, ctlcen), ctlrad); - down = invq(mouseq(v0, axis)); - - q = *orient; - v1 = divpt2(subpt2(s1, ctlcen), ctlrad); - *orient = mulq(q, mulq(down, mouseq(v1, axis))); + ctlrad = MIN(Dx(r)/2, Dy(r)/2); + v0 = divpt2(Vec2(p0.x-ctlcen.x, ctlcen.y-p0.y), ctlrad); + v1 = divpt2(Vec2(p1.x-ctlcen.x, ctlcen.y-p1.y), ctlrad); + qdown = mouseq(v0, axis); + qdrag = mulq(mouseq(v1, axis), qdown); + *orient = mulq(qdrag, *orient); } @@ -50,6 +50,7 @@ Shadertab *shader; Model *model; Entity *subject; Scene *scene; +Mouse om; Quaternion orient = {1,0,0,0}; Camera cams[4], *maincam; @@ -452,6 +453,7 @@ drawstats(void) snprint(stats[Scambz], sizeof(stats[Scambz]), "bz %V", maincam->bz); snprint(stats[Sfps], sizeof(stats[Sfps]), "FPS %.0f/%.0f/%.0f/%.0f", !maincam->stats.max? 0: 1e9/maincam->stats.max, !maincam->stats.avg? 0: 1e9/maincam->stats.avg, !maincam->stats.min? 0: 1e9/maincam->stats.min, !maincam->stats.v? 0: 1e9/maincam->stats.v); snprint(stats[Sframes], sizeof(stats[Sframes]), "frame %llud", maincam->stats.nframes); + snprint(stats[Sorient], sizeof(stats[Sorient]), "ℍ %V", (Point3)orient); for(i = 0; i < Se; i++) stringbg(screen, addpt(screen->r.min, Pt(10,10 + i*font->height)), display->black, ZP, font, stats[i], display->white, ZP); } @@ -518,12 +520,8 @@ drawproc(void *) void lmb(void) { - static Mouse om; - if((om.buttons^mctl->buttons) == 0) - qb(screen->r, om.xy, mctl->xy, &orient, nil); - - om = mctl->Mouse; + qball(screen->r, om.xy, mctl->xy, &orient, nil); } void @@ -602,6 +600,7 @@ mouse(void) zoomin(); if((mctl->buttons & 16) != 0) zoomout(); + om = mctl->Mouse; } void |