ref: 699e5d2bb6e9c2daea77457f0b0aea19cc4b1498
parent: ff88c093d0092176e173e1bf6cbcd96df07f7e0c
author: rodri <rgl@antares-labs.eu>
date: Sun Aug 25 12:07:25 EDT 2024
solar: improve planet selection.
--- a/solar.c
+++ b/solar.c
@@ -172,7 +172,93 @@
return a > b? a: b;
}
+static Point3
+minpt3(Point3 a, Point3 b)
+{
+ return (Point3){
+ fmin(a.x, b.x),
+ fmin(a.y, b.y),
+ fmin(a.z, b.z),
+ fmin(a.w, b.w)
+ };
+}
+
+static Point3
+maxpt3(Point3 a, Point3 b)
+{
+ return (Point3){
+ fmax(a.x, b.x),
+ fmax(a.y, b.y),
+ fmax(a.z, b.z),
+ fmax(a.w, b.w)
+ };
+}
+
static void
+selectplanet(Planet *p)
+{
+ static Planet *oldp;
+ struct { Point3 min, max; } aabb;
+ Entity *e, *esel;
+ Model *msel;
+ Primitive l;
+ int i, j;
+
+ if(p == oldp)
+ return;
+
+ oldp = selplanet = p;
+ esel = scene->getent(scene, "selection");
+ if(esel != nil)
+ scene->delent(scene, esel);
+ if(p == nil)
+ return;
+
+ e = p->body;
+ msel = newmodel();
+ esel = newentity("selection", msel);
+ esel->RFrame3 = e->RFrame3;
+
+ memset(&aabb, 0, sizeof aabb);
+ for(i = 0; i < e->mdl->nprims; i++)
+ for(j = 0; j < e->mdl->prims[i].type+1; j++){
+ aabb.min = minpt3(aabb.min, e->mdl->prims[i].v[j].p);
+ aabb.max = maxpt3(aabb.max, e->mdl->prims[i].v[j].p);
+ }
+ aabb.min = mulpt3(aabb.min, p->scale*0.8);
+ aabb.max = mulpt3(aabb.max, p->scale*0.8);
+ aabb.min.w = aabb.max.w = 1;
+
+ memset(&l, 0, sizeof l);
+ l.type = PLine;
+ l.v[0].c = l.v[1].c = Pt3(0.2666, 0.5333, 0.2666, 1);
+ /* bottom */
+ l.v[0].p = aabb.min; l.v[1].p = qrotate(aabb.min, Vec3(0,1,0), PI/2);
+ msel->addprim(msel, l);
+ for(i = 0; i < 3; i++){
+ l.v[0].p = l.v[1].p; l.v[1].p = qrotate(l.v[1].p, Vec3(0,1,0), PI/2);
+ msel->addprim(msel, l);
+ }
+ /* top */
+ l.v[0].p = aabb.max; l.v[1].p = qrotate(aabb.max, Vec3(0,1,0), PI/2);
+ msel->addprim(msel, l);
+ for(i = 0; i < 3; i++){
+ l.v[0].p = l.v[1].p; l.v[1].p = qrotate(l.v[1].p, Vec3(0,1,0), PI/2);
+ msel->addprim(msel, l);
+ }
+ /* struts */
+ l.v[0].p = aabb.min; l.v[1].p = qrotate(aabb.max, Vec3(0,1,0), PI);
+ msel->addprim(msel, l);
+ for(i = 0; i < 3; i++){
+ l.v[0].p = qrotate(l.v[0].p, Vec3(0,1,0), PI/2);
+ l.v[1].p = qrotate(l.v[1].p, Vec3(0,1,0), PI/2);
+ msel->addprim(msel, l);
+ }
+
+ scene->addent(scene, esel);
+}
+
+static void
sailor(void *arg)
{
char buf[128], pidstr[8];
@@ -284,18 +370,20 @@
Point3 pos;
p = getplanet(sp->su->entity->name);
- assert(p != nil);
- Matrix3 S = {
- p->scale, 0, 0, 0,
- 0, p->scale, 0, 0,
- 0, 0, p->scale, 0,
- 0, 0, 0, 1,
- };
- pos = xform3(sp->v->p, S);
+ if(p != nil){
+ Matrix3 S = {
+ p->scale, 0, 0, 0,
+ 0, p->scale, 0, 0,
+ 0, 0, p->scale, 0,
+ 0, 0, 0, 1,
+ };
+ pos = xform3(sp->v->p, S);
+ sp->v->mtl = p->mtl;
+ sp->v->c = p->mtl->diffuse;
+ }else
+ pos = sp->v->p;
- sp->v->mtl = p->mtl;
- sp->v->c = p->mtl->diffuse;
return world2clip(sp->su->camera, model2world(sp->su->entity, pos));
}
@@ -496,8 +584,7 @@
p = &planets[i];
}
}
- if(p != nil)
- selplanet = p;
+ selectplanet(p);
return;
}