shithub: 3dee

Download patch

ref: ecdeed125c0fe00b6a90f85db44ad37f0913e992
parent: 093323c36fa083a897dc371b36889296d1069715
author: rodri <rgl@antares-labs.eu>
date: Sun Jun 16 05:57:11 EDT 2024

vis,med: make qball rotations position-independent.

the camera no longer needs to be on the first
quadrant for the qball to work.

--- a/med.c
+++ b/med.c
@@ -179,6 +179,7 @@
 	memset(t, 0, sizeof t);
 	t[0].type = t[1].type = PTriangle;
 
+	/* build the first face/quad, facing the positive z axis */
 	p = Vec3(-0.5,-0.5,0.5);
 	v1 = Vec3(1,0,0);
 	v2 = Vec3(0,1,0);
@@ -193,10 +194,11 @@
 	t[1].v[2].p = addpt3(center, addpt3(p, v2));
 	t[1].v[2].n = addpt3(p, v2);
 
+	/* make a cube by rotating the reference face */
 	for(i = 0; i < 6; i++){
-		for(j = 0; j < 2; j++)
-			for(k = 0; k < 3; k++)
-				if(i > 0){
+		if(i > 0)
+			for(j = 0; j < 2; j++)
+				for(k = 0; k < 3; k++){
 					t[j].v[k].p = qrotate(t[j].v[k].p, axis[i%3], PI/2);
 					t[j].v[k].n = qrotate(t[j].v[k].n, axis[i%3], PI/2);
 				}
@@ -209,6 +211,34 @@
 	}
 }
 
+static void
+addbasis(void)
+{
+	Entity *e;
+	Model *m;
+	Primitive prims[3];
+
+	m = newmodel();
+	e = newentity(m);
+	e->RFrame3 = subject->RFrame3;
+
+	memset(prims, 0, sizeof prims);
+	prims[0].type = prims[1].type = prims[2].type = PLine;
+	prims[0].v[0].p = prims[1].v[0].p = prims[2].v[0].p = center;
+	prims[0].v[0].c = prims[1].v[0].c = prims[2].v[0].c = Pt3(0,0,0,1);
+	prims[0].v[1].p = addpt3(center, e->bx);
+	prims[0].v[1].c = Pt3(1,0,0,1);
+	prims[1].v[1].p = addpt3(center, e->by);
+	prims[1].v[1].c = Pt3(0,1,0,1);
+	prims[2].v[1].p = addpt3(center, e->bz);
+	prims[2].v[1].c = Pt3(0,0,1,1);
+
+	m->prims = erealloc(m->prims, (m->nprims += 3)*sizeof(*m->prims));
+	memmove(m->prims, prims, sizeof prims);
+
+	scene->addent(scene, e);
+}
+
 Point3
 gouraudvshader(VSparams *sp)
 {
@@ -496,14 +526,18 @@
 lmb(void)
 {
 	Quaternion Δorient;
+	Entity *e;
 
 	if((om.buttons^mctl->buttons) == 0){
 		Δorient = orient;
 		qball(screen->r, om.xy, mctl->xy, &orient, nil);
 		Δorient = mulq(orient, invq(Δorient));
-		subject->bx = Vecquat(mulq(mulq(Δorient, Quatvec(0, subject->bx)), invq(Δorient)));
-		subject->by = Vecquat(mulq(mulq(Δorient, Quatvec(0, subject->by)), invq(Δorient)));
-		subject->bz = Vecquat(mulq(mulq(Δorient, Quatvec(0, subject->bz)), invq(Δorient)));
+
+		for(e = scene->ents.next; e != &scene->ents; e = e->next){
+			e->bx = vcs2world(&cam, Vecquat(mulq(mulq(Δorient, Quatvec(0, world2vcs(&cam, e->bx))), invq(Δorient))));
+			e->by = vcs2world(&cam, Vecquat(mulq(mulq(Δorient, Quatvec(0, world2vcs(&cam, e->by))), invq(Δorient))));
+			e->bz = vcs2world(&cam, Vecquat(mulq(mulq(Δorient, Quatvec(0, world2vcs(&cam, e->bz))), invq(Δorient))));
+		}
 	}
 }
 
@@ -758,6 +792,7 @@
 	model = newmodel();
 	subject = newentity(model);
 	scene->addent(scene, subject);
+	addbasis();
 
 	if(memimageinit() != 0)
 		sysfatal("memimageinit: %r");
--- a/vis.c
+++ b/vis.c
@@ -569,9 +569,9 @@
 		Δorient = mulq(orient, invq(Δorient));
 
 		for(e = scene->ents.next; e != &scene->ents; e = e->next){
-			e->bx = Vecquat(mulq(mulq(Δorient, Quatvec(0, e->bx)), invq(Δorient)));
-			e->by = Vecquat(mulq(mulq(Δorient, Quatvec(0, e->by)), invq(Δorient)));
-			e->bz = Vecquat(mulq(mulq(Δorient, Quatvec(0, e->bz)), invq(Δorient)));
+			e->bx = vcs2world(maincam, Vecquat(mulq(mulq(Δorient, Quatvec(0, world2vcs(maincam, e->bx))), invq(Δorient))));
+			e->by = vcs2world(maincam, Vecquat(mulq(mulq(Δorient, Quatvec(0, world2vcs(maincam, e->by))), invq(Δorient))));
+			e->bz = vcs2world(maincam, Vecquat(mulq(mulq(Δorient, Quatvec(0, world2vcs(maincam, e->bz))), invq(Δorient))));
 		}
 	}else{
 		Framebuf *fb;