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