summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dat.h1
-rw-r--r--fns.h2
-rw-r--r--mkfile2
-rw-r--r--qball.c (renamed from qb.c)40
-rw-r--r--vis.c9
5 files changed, 24 insertions, 30 deletions
diff --git a/dat.h b/dat.h
index 5c9b45b..bad9c4d 100644
--- a/dat.h
+++ b/dat.h
@@ -28,5 +28,6 @@ enum {
Scambx, Scamby, Scambz,
Sfps,
Sframes,
+ Sorient,
Se
};
diff --git a/fns.h b/fns.h
index d89bef9..a506140 100644
--- a/fns.h
+++ b/fns.h
@@ -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*);
diff --git a/mkfile b/mkfile
index 2c9c8d7..2761b48 100644
--- a/mkfile
+++ b/mkfile
@@ -7,7 +7,7 @@ TARG=\
OFILES=\
alloc.$O\
- qb.$O\
+ qball.$O\
HFILES=dat.h fns.h
diff --git a/qb.c b/qball.c
index 1485b9a..9248f5f 100644
--- a/qb.c
+++ b/qball.c
@@ -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);
}
diff --git a/vis.c b/vis.c
index 96879eb..5796b32 100644
--- a/vis.c
+++ b/vis.c
@@ -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