ref: d0874baf0a5eccf203c9a06c99400adfc388d35d
parent: f90ec866fe2d4b019c25bd013e538b770d09a5b2
author: rodri <rgl@antares-labs.eu>
date: Sun Mar 22 20:20:52 EDT 2026
adapt to new changes in libgraphics. fix solar's planet model instancing changes to the way materials are stored. solar used to look for the right material in the vertex shader which is unacceptable. now we create a proper instance of the planet model, copy the primitives and change their material to point at the one corresponding to the planet.
--- a/obj.c
+++ b/obj.c
@@ -141,8 +141,9 @@
OBJIndexArray *idxtab;
OBJ2MtlMap mtlmap;
OBJMaterial *objmtl;
- Material *mtl;
- int i, idx, nt, maxnt, hastexcoords, neednormal, gottaclean;
+ Material mtl;
+ int i, idx, nt, maxnt;
+ int hastexcoords, neednormal, gottaclean;
int defcolidx, nidx; /* default color and normal indices */
pverts = obj->vertdata[OBJVGeometric].verts;
@@ -154,36 +155,36 @@
mtlmap.head = nil;
for(i = 0; obj->materials != nil && i < nelem(obj->materials->mattab); i++)
for(objmtl = obj->materials->mattab[i]; objmtl != nil; objmtl = objmtl->next){- mtlmap.mtls = m->materials = erealloc(m->materials, ++m->nmaterials*sizeof(*m->materials));
- mtl = &m->materials[m->nmaterials-1];
- memset(mtl, 0, sizeof *mtl);
-
- mtl->name = estrdup(objmtl->name);
+ memset(&mtl, 0, sizeof mtl);
+ mtl.name = estrdup(objmtl->name);
if(objmtl->Ka.a > 0)
- mtl->ambient = objmtl->Ka;
+ mtl.ambient = objmtl->Ka;
if(objmtl->Kd.a > 0)
- mtl->diffuse = objmtl->Kd;
+ mtl.diffuse = objmtl->Kd;
if(objmtl->Ks.a > 0)
- mtl->specular = objmtl->Ks;
- mtl->shininess = objmtl->Ns;
+ mtl.specular = objmtl->Ks;
+ mtl.shininess = objmtl->Ns;
if(objmtl->map_Kd != nil){- mtl->diffusemap = alloctexture(sRGBTexture, nil);
- mtl->diffusemap->image = dupmemimage(objmtl->map_Kd->image);
+ mtl.diffusemap = alloctexture(sRGBTexture, nil);
+ mtl.diffusemap->image = dupmemimage(objmtl->map_Kd->image);
}
if(objmtl->map_Ks != nil){- mtl->specularmap = alloctexture(sRGBTexture, nil);
- mtl->specularmap->image = dupmemimage(objmtl->map_Ks->image);
+ mtl.specularmap = alloctexture(sRGBTexture, nil);
+ mtl.specularmap->image = dupmemimage(objmtl->map_Ks->image);
}
if(objmtl->norm != nil){- mtl->normalmap = alloctexture(RAWTexture, nil);
- mtl->normalmap->image = dupmemimage(objmtl->norm->image);
+ mtl.normalmap = alloctexture(RAWTexture, nil);
+ mtl.normalmap->image = dupmemimage(objmtl->norm->image);
}
- addmtlmap(&mtlmap, objmtl, m->nmaterials-1);
+ idx = m->addmaterial(m, mtl);
+ addmtlmap(&mtlmap, objmtl, idx);
}
+ if(m->materials->nitems > 0)
+ mtlmap.mtls = m->materials->items;
for(i = 0; i < obj->vertdata[OBJVGeometric].nvert; i++)
m->addposition(m, VGP3(pverts[i]));
--- a/solar.c
+++ b/solar.c
@@ -64,7 +64,6 @@
char *name;
double scale;
Entity *body;
- Material *mtl;
};
struct Camcfg
@@ -475,13 +474,6 @@
Point3
identvshader(Shaderparams *sp)
{- Planet *p;
-
- p = getplanet(sp->entity->name);
- if(p != nil){- sp->v->mtl = p->mtl;
- sp->v->c = p->mtl->diffuse;
- }
return world2clip(sp->camera, model2world(sp->entity, sp->v->p));
}
@@ -879,10 +871,10 @@
Renderer *rctl;
Channel *keyc;
Entity *subject;
- Model *model;
+ Model *model, *mdl;
Point3 *p, *lastp;
Point lblsiz;
- int fd, i, j;
+ int fd, i;
tmfmtinstall();
GEOMfmtinstall();
@@ -915,16 +907,29 @@
}
scene = newscene(nil);
for(i = 0; i < nelem(planets); i++){- subject = newentity(planets[i].name, model);
+ Primitive *prim, *prime;
+ Material *mtl;
+
+ /* create instances of the model for each planet */
+ mdl = newmodel();
+ copymodel(model, mdl);
+ rmitemarray(mdl->prims);
+ mdl->prims = mkitemarray(0);
+ copyitemarray(model->prims, mdl->prims);
+
+ /* and attach the material corresponding to their planet */
+ mtl = mdl->getmaterial(mdl, planets[i].name);
+ prim = mdl->prims->items;
+ for(prime = prim + mdl->prims->nitems; prim < prime; prim++)
+ prim->mtl = mtl;
+
+ subject = newentity(planets[i].name, mdl);
scene->addent(scene, subject);
planets[i].body = subject;
planets[i].scale /= ↓scale;
- for(j = 0; j < model->nmaterials; j++)
- if(strcmp(planets[i].name, model->materials[j].name) == 0)
- planets[i].mtl = &model->materials[j];
- if(i == 0){+ if(i == 0)
subject->p = Pt3(0,0,0,1);
- }else if(museummode)
+ else if(museummode)
subject->p.x = planets[i-1].body->p.x + 1.5*planets[i-1].scale + planets[i].scale;
subject->bx = mulpt3(subject->bx, planets[i].scale);
subject->by = mulpt3(subject->by, planets[i].scale);
--- a/toobj.c
+++ b/toobj.c
@@ -41,12 +41,13 @@
OBJElem *e;
OBJObject *o;
OBJMaterial *objmtl;
- Material *mtl;
+ Material *mtl, *lastmtl;
int i;
- if(m->nmaterials > 0)
+ if(m->materials->nitems > 0)
obj->materials = objallocmtl("main.mtl");- for(mtl = m->materials; mtl < m->materials + m->nmaterials; mtl++){+ mtl = m->materials->items;
+ for(lastmtl = mtl + m->materials->nitems; mtl < lastmtl; mtl++){objmtl = objallocmt(mtl->name);
if(mtl->ambient.a > 0)
--- a/vis.c
+++ b/vis.c
@@ -320,9 +320,9 @@
sysfatal("readmemimage: %r");model->addmaterial(model, *mtl);
free(mtl);
- mtl = &model->materials[model->nmaterials-1];
+ mtl = itemarrayget(model->materials, model->materials->nitems-1);
lastprim = itemarrayget(model->prims, model->prims->nitems-1);
- for(prim = model->prims->items; prim <= lastprim; prim++)
+ for(prim = model->prims->items; prim && prim <= lastprim; prim++)
prim->mtl = mtl;
}
@@ -883,9 +883,9 @@
if((tmpmtl->diffusemap->image = readmemimage(fd)) == nil)
sysfatal("readmemimage: %r");close(fd);
- model->addmaterial(model, *tmpmtl);
+ i = model->addmaterial(model, *tmpmtl);
free(tmpmtl);
- tmpmtl = &model->materials[model->nmaterials-1];
+ tmpmtl = itemarrayget(model->materials, i);
lastprim = itemarrayget(model->prims, model->prims->nitems-1);
for(prim = model->prims->items; prim <= lastprim; prim++)
prim->mtl = tmpmtl;
--
⑨