shithub: musw

Download patch

ref: 6d1aff1af30525e3dccc1ba6cb51704d0168f1d6
parent: 9e5da826ebcec801b11eefca036bfa408492d4c6
author: rodri <[email protected]>
date: Thu Feb 2 16:45:22 EST 2023

vmodeled: fixed object scaling and rotation without affecting coords. created initial object structure.

--- a/vmodeled/main.c
+++ b/vmodeled/main.c
@@ -22,8 +22,15 @@
 	char *strokefmt;
 };
 
+typedef struct Object Object;
+struct Object
+{
+	RFrame;
+	VModel *mdl;
+};
+
 RFrame worldrf;
-VModel *model;
+Object mainobj;
 double θ;
 double scale = 1;
 
@@ -72,6 +79,25 @@
 	return rframexform(Pt2(p.x,p.y,1), worldrf);
 }
 
+void
+rotateobj(double θ)
+{
+	Matrix R = {
+		cos(θ), -sin(θ), 0,
+		sin(θ),  cos(θ), 0,
+		0, 0, 1,
+	};
+	mainobj.bx = xform(mainobj.bx, R);
+	mainobj.by = xform(mainobj.by, R);
+}
+
+void
+zoomobj(double z)
+{
+	mainobj.bx = mulpt2(mainobj.bx, z);
+	mainobj.by = mulpt2(mainobj.by, z);
+}
+
 VModel *
 readvmodel(char *file)
 {
@@ -121,8 +147,16 @@
 	return mdl;
 }
 
+int
+writevmodel(VModel *mdl, char *file)
+{
+	USED(mdl);
+	USED(file);
+	return -1;
+}
+
 void
-drawvmodel(Image *dst, VModel *mdl)
+drawvmodel(Image *dst, VModel *mdl, int t)
 {
 	int i;
 	char *s;
@@ -129,26 +163,33 @@
 	Point pts[3];
 	Point2 *p;
 	Matrix S = {
-		scale, 0, 1,
-		0, scale, 1,
+		1/scale, 0, 0,
+		0, 1/scale, 0,
 		0, 0, 1,
 	}, R = {
-		cos(θ), -sin(θ), 1,
-		sin(θ),  cos(θ), 1,
+		cos(θ), -sin(θ), 0,
+		sin(θ),  cos(θ), 0,
 		0, 0, 1,
 	};
 
-	mulm(S, R);
+	if(t)
+		mulm(S, R);
 	p = mdl->pts;
 	for(s = mdl->strokefmt; s != 0 && p-mdl->pts < mdl->npts; s++)
 		switch(*s){
 		case 'l':
-			line(dst, toscreen(xform(p[0], S)), toscreen(xform(p[1], S)), 0, 0, 0, display->white, ZP);
+			if(t)
+				line(dst, toscreen(invrframexform(xform(p[0], S), mainobj)), toscreen(invrframexform(xform(p[1], S), mainobj)), 0, 0, 0, display->white, ZP);
+			else
+				line(dst, toscreen(invrframexform(p[0], mainobj)), toscreen(invrframexform(p[1], mainobj)), 0, 0, 0, display->white, ZP);
 			p += 2;
 			break;
 		case 'c':
 			for(i = 0; i < nelem(pts); i++)
-				pts[i] = toscreen(xform(p[i], S));
+				if(t)
+					pts[i] = toscreen(invrframexform(xform(p[i], S), mainobj));
+				else
+					pts[i] = toscreen(invrframexform(p[i], mainobj));
 			bezspline(dst, pts, nelem(pts), 0, 0, 0, display->white, ZP);
 			p += 3;
 			break;
@@ -163,53 +204,60 @@
 }
 
 void
-redraw(void)
+drawinfo(void)
 {
+	Point p;
+	char buf[128];
+
+	p = Pt(10,3);
+
+	snprint(buf, sizeof buf, "wbx %v", worldrf.bx);
+	string(screen, addpt(screen->r.min, p), display->white, ZP, font, buf);
+	p.y += font->height;
+	snprint(buf, sizeof buf, "wby %v", worldrf.by);
+	string(screen, addpt(screen->r.min, p), display->white, ZP, font, buf);
+	p.y += font->height;
+	snprint(buf, sizeof buf, "s %g", scale);
+	string(screen, addpt(screen->r.min, p), display->white, ZP, font, buf);
+	p.y += font->height;
+	snprint(buf, sizeof buf, "θ %g", θ);
+	string(screen, addpt(screen->r.min, p), display->white, ZP, font, buf);
+	p.y += font->height;
+	snprint(buf, sizeof buf, "obx %v", mainobj.bx);
+	string(screen, addpt(screen->r.min, p), display->white, ZP, font, buf);
+	p.y += font->height;
+	snprint(buf, sizeof buf, "oby %v", mainobj.by);
+	string(screen, addpt(screen->r.min, p), display->white, ZP, font, buf);
+}
+
+void
+redraw(int t)
+{
 	lockdisplay(display);
 	draw(screen, screen->r, display->black, nil, ZP);
 	drawaxes();
-	drawvmodel(screen, model);
+	drawvmodel(screen, mainobj.mdl, t);
+	drawinfo();
 	flushimage(display, 1);
 	unlockdisplay(display);
 }
 
 void
-rmb(Mousectl *mc, Keyboardctl *)
-{
-	Point2 p;
-	double oldmθ, oldθ;
-
-	p = fromscreen(mc->xy);
-	oldmθ = atan2(p.y, p.x);
-	oldθ = θ;
-
-	for(;;){
-		readmouse(mc);
-		if(mc->buttons != 4)
-			break;
-		p = fromscreen(mc->xy);
-		θ = oldθ + (atan2(p.y, p.x) - oldmθ);
-		fprint(2, "θ %g\n", θ);
-		redraw();
-	}
-}
-
-void
 lmb(Mousectl *mc, Keyboardctl *)
 {
 	Point2 mpos;
 
 	mpos = fromscreen(mc->xy);
-	fprint(2, "mpos %v\n", mpos);
+	fprint(2, "wp %v\n", mpos);
+	fprint(2, "op %v\n", rframexform(mpos, mainobj));
 }
 
 void
 zoom(Mousectl *mc)
 {
-	double oldscale, z;
+	double z;
 	Point oldxy, Δxy;
 
-	oldscale = scale;
 	oldxy = mc->xy;
 
 	for(;;){
@@ -218,12 +266,36 @@
 			break;
 		Δxy = subpt(mc->xy, oldxy);
 		z = tanh((double)Δxy.y/100) + 1;
-		scale = z*oldscale;
-		redraw();
+		scale = z;
+		redraw(1);
 	}
+	zoomobj(scale);
+	scale = 1;
 }
 
 void
+rmb(Mousectl *mc, Keyboardctl *)
+{
+	Point2 p;
+	double oldpθ, oldθ;
+
+	p = rframexform(fromscreen(mc->xy), mainobj);
+	oldpθ = atan2(p.y, p.x);
+	oldθ = θ;
+
+	for(;;){
+		readmouse(mc);
+		if(mc->buttons != 4)
+			break;
+		p = rframexform(fromscreen(mc->xy), mainobj);
+		θ = oldθ + atan2(p.y, p.x) - oldpθ;
+		redraw(1);
+	}
+	rotateobj(θ);
+	θ = 0;
+}
+
+void
 mouse(Mousectl *mc, Keyboardctl *kc)
 {
 	if((mc->buttons&1) != 0)
@@ -277,14 +349,16 @@
 	worldrf.p = Pt2(screen->r.min.x+Dx(screen->r)/2,screen->r.max.y-Dy(screen->r)/2,1);
 	worldrf.bx = Vec2(1, 0);
 	worldrf.by = Vec2(0,-1);
+	mainobj.bx = Vec2(1, 0);
+	mainobj.by = Vec2(0, 1);
 
-	model = readvmodel("../assets/mdl/wedge.vmdl");
-	if(model == nil)
+	mainobj.mdl = readvmodel("../assets/mdl/wedge.vmdl");
+	if(mainobj.mdl == nil)
 		sysfatal("readvmodel: %r");
 
 	display->locking = 1;
 	unlockdisplay(display);
-	redraw();
+	redraw(0);
 
 	for(;;){
 		enum { MOUSE, RESIZE, KEYBOARD };
@@ -307,7 +381,7 @@
 			break;
 		}
 
-		redraw();
+		redraw(0);
 	}
 }
 
@@ -319,5 +393,5 @@
 		sysfatal("couldn't resize");
 	unlockdisplay(display);
 	worldrf.p = Pt2(screen->r.min.x+Dx(screen->r)/2,screen->r.max.y-Dy(screen->r)/2,1);
-	redraw();
+	redraw(0);
 }
--- a/vmodeled/mkfile
+++ b/vmodeled/mkfile
@@ -6,3 +6,6 @@
 	main.$O\
 
 </sys/src/cmd/mkone
+
+syms:V:
+	$CC -a main.c > syms