summaryrefslogtreecommitdiff
path: root/src/engine/animmodel.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/animmodel.h')
-rw-r--r--src/engine/animmodel.h817
1 files changed, 216 insertions, 601 deletions
diff --git a/src/engine/animmodel.h b/src/engine/animmodel.h
index 13705f4..51d09e8 100644
--- a/src/engine/animmodel.h
+++ b/src/engine/animmodel.h
@@ -1,93 +1,66 @@
-VARFP(bumpmodels, 0, 1, 1, preloadmodelshaders(true));
+VARFP(bumpmodels, 0, 1, 1, preloadmodelshaders());
VARP(fullbrightmodels, 0, 0, 200);
-struct animmodel : model
-{
- struct animspec
- {
+struct animmodel : model {
+ struct animspec {
int frame, range;
float speed;
int priority;
};
-
- struct animpos
- {
+ struct animpos {
int anim, fr1, fr2;
float t;
-
- void setframes(const animinfo &info)
- {
+ void setframes(const animinfo &info) {
anim = info.anim;
- if(info.range<=1)
- {
+ if(info.range<=1) {
fr1 = 0;
t = 0;
}
- else
- {
+ else {
int time = info.anim&ANIM_SETTIME ? info.basetime : lastmillis-info.basetime;
fr1 = (int)(time/info.speed); // round to full frames
t = (time-fr1*info.speed)/info.speed; // progress of the frame, value from 0.0f to 1.0f
}
- if(info.anim&ANIM_LOOP)
- {
+ if(info.anim&ANIM_LOOP) {
fr1 = fr1%info.range+info.frame;
fr2 = fr1+1;
if(fr2>=info.frame+info.range) fr2 = info.frame;
}
- else
- {
+ else {
fr1 = min(fr1, info.range-1)+info.frame;
fr2 = min(fr1+1, info.frame+info.range-1);
}
- if(info.anim&ANIM_REVERSE)
- {
+ if(info.anim&ANIM_REVERSE) {
fr1 = (info.frame+info.range-1)-(fr1-info.frame);
fr2 = (info.frame+info.range-1)-(fr2-info.frame);
}
}
-
bool operator==(const animpos &a) const { return fr1==a.fr1 && fr2==a.fr2 && (fr1==fr2 || t==a.t); }
bool operator!=(const animpos &a) const { return fr1!=a.fr1 || fr2!=a.fr2 || (fr1!=fr2 && t!=a.t); }
};
-
struct part;
-
- struct animstate
- {
+ struct animstate {
part *owner;
animpos cur, prev;
float interp;
-
bool operator==(const animstate &a) const { return cur==a.cur && (interp<1 ? interp==a.interp && prev==a.prev : a.interp>=1); }
bool operator!=(const animstate &a) const { return cur!=a.cur || (interp<1 ? interp!=a.interp || prev!=a.prev : a.interp<1); }
};
-
struct linkedpart;
struct mesh;
-
- struct shaderparams
- {
+ struct shaderparams {
float spec, ambient, fullbright, scrollu, scrollv, alphatest;
-
shaderparams() : spec(1.0f), ambient(0.3f), fullbright(0), scrollu(0), scrollv(0), alphatest(0.9f) {}
};
-
- struct shaderparamskey
- {
+ struct shaderparamskey {
static hashtable<shaderparams, shaderparamskey> keys;
static int firstversion, lastversion;
-
int version;
-
shaderparamskey() : version(-1) {}
-
- bool checkversion()
- {
+ bool checkversion() {
if(version >= firstversion) return true;
version = lastversion;
- if(++lastversion <= 0)
- {
+ if(++lastversion <= 0) {
enumerate(keys, shaderparamskey, key, key.version = -1);
firstversion = 0;
lastversion = 1;
@@ -95,67 +68,47 @@ struct animmodel : model
}
return false;
}
-
- static inline void invalidate()
- {
+ static inline void invalidate() {
firstversion = lastversion;
}
};
-
- struct skin : shaderparams
- {
+ struct skin : shaderparams {
part *owner;
Texture *tex, *masks, *normalmap;
Shader *shader;
bool alphablend, cullface;
shaderparamskey *key;
-
skin() : owner(0), tex(notexture), masks(notexture), normalmap(NULL), shader(NULL), alphablend(true), cullface(true), key(NULL) {}
-
bool masked() const { return masks != notexture; }
bool bumpmapped() { return normalmap && bumpmodels; }
bool tangents() { return bumpmapped(); }
bool alphatested() const { return alphatest > 0 && tex->type&Texture::ALPHA; }
-
- void setkey()
- {
+ void setkey() {
key = &shaderparamskey::keys[*this];
}
-
- void setshaderparams(mesh *m, const animstate *as)
- {
+ void setshaderparams(mesh *m, const animstate *as) {
if(!Shader::lastshader) return;
-
float mincolor = as->cur.anim&ANIM_FULLBRIGHT ? fullbrightmodels/100.0f : 0.0f;
- if(fullbright)
- {
+ if(fullbright) {
gle::colorf(fullbright/2, fullbright/2, fullbright/2, transparent);
}
- else
- {
+ else {
gle::color(vec(lightcolor).max(mincolor), transparent);
}
-
if(key->checkversion() && Shader::lastshader->owner == key) return;
Shader::lastshader->owner = key;
-
if(alphatested()) LOCALPARAMF(alphatest, alphatest);
-
- if(fullbright)
- {
+ if(fullbright) {
LOCALPARAMF(lightscale, 0, 0, 2);
}
- else
- {
+ else {
float bias = max(mincolor-1.0f, 0.2f), scale = 0.5f*max(0.8f-bias, 0.0f),
minshade = scale*max(ambient, mincolor);
LOCALPARAMF(lightscale, scale - minshade, scale, minshade + bias);
}
LOCALPARAMF(texscroll, scrollu*lastmillis/1000.0f, scrollv*lastmillis/1000.0f);
}
-
- Shader *loadshader()
- {
+ Shader *loadshader() {
#define DOMODELSHADER(name, body) \
do { \
static Shader *name##shader = NULL; \
@@ -165,7 +118,6 @@ struct animmodel : model
#define LOADMODELSHADER(name) DOMODELSHADER(name, return name##shader)
#define SETMODELSHADER(m, name) DOMODELSHADER(name, (m)->setshader(name##shader))
if(shader) return shader;
-
string opts;
int optslen = 0;
if(alphatested()) opts[optslen++] = 'a';
@@ -174,40 +126,27 @@ struct animmodel : model
if(masked()) opts[optslen++] = 'm';
if(!fullbright && (masked() || spec>=0.01f)) opts[optslen++] = 's';
opts[optslen++] = '\0';
-
defformatstring(name, "model%s", opts);
shader = generateshader(name, "modelshader \"%s\"", opts);
return shader;
}
-
- void cleanup()
- {
+ void cleanup() {
if(shader && shader->standard) shader = NULL;
}
-
- void preloadBIH()
- {
+ void preloadBIH() {
if(tex->type&Texture::ALPHA && !tex->alphamask) loadalphamask(tex);
}
-
- void preloadshader(bool force)
- {
- if(force) cleanup();
+ void preloadshader() {
+ //~if(force) cleanup();
loadshader();
}
-
- void setshader(mesh *m, const animstate *as)
- {
+ void setshader(mesh *m, const animstate *as) {
m->setshader(loadshader());
}
-
- void bind(mesh *b, const animstate *as)
- {
+ void bind(mesh *b, const animstate *as) {
if(!cullface && enablecullface) { glDisable(GL_CULL_FACE); enablecullface = false; }
else if(cullface && !enablecullface) { glEnable(GL_CULL_FACE); enablecullface = true; }
-
- if(as->cur.anim&ANIM_NOSKIN)
- {
+ if(as->cur.anim&ANIM_NOSKIN) {
if(enablealphablend) { glDisable(GL_BLEND); enablealphablend = false; }
if(shadowmapping) SETMODELSHADER(b, shadowmapcaster);
else /*if(as->cur.anim&ANIM_SHADOW)*/ SETMODELSHADER(b, notexturemodel);
@@ -216,24 +155,19 @@ struct animmodel : model
setshader(b, as);
setshaderparams(b, as);
int activetmu = 0;
- if(tex!=lasttex)
- {
+ if(tex!=lasttex) {
glBindTexture(GL_TEXTURE_2D, tex->id);
lasttex = tex;
}
- if(bumpmapped() && normalmap !=lastnormalmap)
- {
+ if(bumpmapped() && normalmap !=lastnormalmap) {
glActiveTexture_(GL_TEXTURE3);
activetmu = 3;
glBindTexture(GL_TEXTURE_2D, normalmap->id);
lastnormalmap = normalmap;
}
- if(tex->type&Texture::ALPHA)
- {
- if(alphablend)
- {
- if(!enablealphablend)
- {
+ if(tex->type&Texture::ALPHA) {
+ if(alphablend) {
+ if(!enablealphablend) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
enablealphablend = true;
@@ -242,8 +176,7 @@ struct animmodel : model
else if(enablealphablend) { glDisable(GL_BLEND); enablealphablend = false; }
}
else if(enablealphablend && transparent>=1) { glDisable(GL_BLEND); enablealphablend = false; }
- if(masked() && masks!=lastmasks)
- {
+ if(masked() && masks!=lastmasks) {
glActiveTexture_(GL_TEXTURE1);
activetmu = 1;
glBindTexture(GL_TEXTURE_2D, masks->id);
@@ -252,29 +185,19 @@ struct animmodel : model
if(activetmu != 0) glActiveTexture_(GL_TEXTURE0);
}
};
-
struct meshgroup;
-
- struct mesh
- {
+ struct mesh {
meshgroup *group;
char *name;
bool noclip;
-
- mesh() : group(NULL), name(NULL), noclip(false)
- {
+ mesh() : group(NULL), name(NULL), noclip(false) {
}
-
- virtual ~mesh()
- {
+ virtual ~mesh() {
DELETEA(name);
}
-
virtual void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m) {}
-
virtual void genBIH(BIH::mesh &m) {}
- void genBIH(skin &s, vector<BIH::mesh> &bih, const matrix4x3 &t)
- {
+ void genBIH(skin &s, vector<BIH::mesh> &bih, const matrix4x3 &t) {
BIH::mesh &m = bih.add();
m.xform = t;
m.tex = s.tex;
@@ -282,35 +205,28 @@ struct animmodel : model
if(noclip) m.flags |= BIH::MESH_NOCLIP;
if(s.cullface) m.flags |= BIH::MESH_CULLFACE;
genBIH(m);
- while(bih.last().numtris > BIH::mesh::MAXTRIS)
- {
+ while(bih.last().numtris > BIH::mesh::MAXTRIS) {
BIH::mesh &overflow = bih.dup();
overflow.tris += BIH::mesh::MAXTRIS;
overflow.numtris -= BIH::mesh::MAXTRIS;
bih[bih.length()-2].numtris = BIH::mesh::MAXTRIS;
}
}
-
- virtual void setshader(Shader *s)
- {
+ virtual void setshader(Shader *s) {
s->set();
}
-
- template<class V, class T> void smoothnorms(V *verts, int numverts, T *tris, int numtris, float limit, bool areaweight)
- {
+ template<class V, class T> void smoothnorms(V *verts, int numverts, T *tris, int numtris, float limit, bool areaweight) {
hashtable<vec, int> share;
int *next = new int[numverts];
for(int i=0;i<numverts;++i)next[i]=-1;
//~memset(next, -1, numverts*sizeof(int));
- loopi(numverts)
- {
+ loopi(numverts) {
V &v = verts[i];
v.norm = vec(0, 0, 0);
int idx = share.access(v.pos, i);
if(idx != i) { next[i] = next[idx]; next[idx] = i; }
}
- loopi(numtris)
- {
+ loopi(numtris) {
T &t = tris[i];
V &v1 = verts[t.vert[0]], &v2 = verts[t.vert[1]], &v3 = verts[t.vert[2]];
vec norm;
@@ -323,18 +239,14 @@ struct animmodel : model
vec *norms = new vec[numverts];
for(int i=0;i<numverts;++i)norms[i]=vec(0,0,0);
//~memclear(norms, numverts);
- loopi(numverts)
- {
+ loopi(numverts) {
V &v = verts[i];
norms[i].add(v.norm);
- if(next[i] >= 0)
- {
+ if(next[i] >= 0) {
float vlimit = limit*v.norm.magnitude();
- for(int j = next[i]; j >= 0; j = next[j])
- {
+ for(int j = next[i]; j >= 0; j = next[j]) {
V &o = verts[j];
- if(v.norm.dot(o.norm) >= vlimit*o.norm.magnitude())
- {
+ if(v.norm.dot(o.norm) >= vlimit*o.norm.magnitude()) {
norms[i].add(o.norm);
norms[j].add(v.norm);
}
@@ -345,12 +257,9 @@ struct animmodel : model
delete[] next;
delete[] norms;
}
-
- template<class V, class T> void buildnorms(V *verts, int numverts, T *tris, int numtris, bool areaweight)
- {
+ template<class V, class T> void buildnorms(V *verts, int numverts, T *tris, int numtris, bool areaweight) {
loopi(numverts) verts[i].norm = vec(0, 0, 0);
- loopi(numtris)
- {
+ loopi(numtris) {
T &t = tris[i];
V &v1 = verts[t.vert[0]], &v2 = verts[t.vert[1]], &v3 = verts[t.vert[2]];
vec norm;
@@ -362,26 +271,19 @@ struct animmodel : model
}
loopi(numverts) verts[i].norm.normalize();
}
-
- template<class V, class T> void buildnorms(V *verts, int numverts, T *tris, int numtris, bool areaweight, int numframes)
- {
+ template<class V, class T> void buildnorms(V *verts, int numverts, T *tris, int numtris, bool areaweight, int numframes) {
if(!numverts) return;
loopi(numframes) buildnorms(&verts[i*numverts], numverts, tris, numtris, areaweight);
}
-
- static inline void fixqtangent(quat &q, float bt)
- {
+ static inline void fixqtangent(quat &q, float bt) {
static const float bias = -1.5f/65535, biasscale = sqrtf(1 - bias*bias);
- if(bt < 0)
- {
+ if(bt < 0) {
if(q.w >= 0) q.neg();
if(q.w > bias) { q.mul3(biasscale); q.w = bias; }
}
else if(q.w < 0) q.neg();
}
-
- template<class V> static inline void calctangent(V &v, const vec &n, const vec &t, float bt)
- {
+ template<class V> static inline void calctangent(V &v, const vec &n, const vec &t, float bt) {
matrix3 m;
m.c = n;
m.a = t;
@@ -390,18 +292,14 @@ struct animmodel : model
fixqtangent(q, bt);
v.tangent = q;
}
-
- template<class B, class V, class TC, class T> void calctangents(B *bumpverts, V *verts, TC *tcverts, int numverts, T *tris, int numtris, bool areaweight)
- {
+ template<class B, class V, class TC, class T> void calctangents(B *bumpverts, V *verts, TC *tcverts, int numverts, T *tris, int numtris, bool areaweight) {
vec *tangent = new vec[2*numverts], *bitangent = tangent+numverts;
for(int i=0;i<2*numverts;++i)tangent[i]=vec(0,0,0);
//~memclear(tangent, 2*numverts);
- loopi(numtris)
- {
+ loopi(numtris) {
const T &t = tris[i];
const vec &e0 = verts[t.vert[0]].pos;
vec e1 = vec(verts[t.vert[1]].pos).sub(e0), e2 = vec(verts[t.vert[2]].pos).sub(e0);
-
const vec2 &tc0 = tcverts[t.vert[0]].tc,
&tc1 = tcverts[t.vert[1]].tc,
&tc2 = tcverts[t.vert[2]].tc;
@@ -410,27 +308,20 @@ struct animmodel : model
vec u(e2), v(e2);
u.mul(v1).sub(vec(e1).mul(v2));
v.mul(u1).sub(vec(e1).mul(u2));
-
- if(vec().cross(e2, e1).dot(vec().cross(v, u)) >= 0)
- {
+ if(vec().cross(e2, e1).dot(vec().cross(v, u)) >= 0) {
u.neg();
v.neg();
}
-
- if(!areaweight)
- {
+ if(!areaweight) {
u.normalize();
v.normalize();
}
-
- loopj(3)
- {
+ loopj(3) {
tangent[t.vert[j]].sub(u);
bitangent[t.vert[j]].add(v);
}
}
- loopi(numverts)
- {
+ loopi(numverts) {
const vec &n = verts[i].norm,
&t = tangent[i],
&bt = bitangent[i];
@@ -445,136 +336,97 @@ struct animmodel : model
}
delete[] tangent;
}
-
- template<class B, class V, class TC, class T> void calctangents(B *bumpverts, V *verts, TC *tcverts, int numverts, T *tris, int numtris, bool areaweight, int numframes)
- {
+ template<class B, class V, class TC, class T> void calctangents(B *bumpverts, V *verts, TC *tcverts, int numverts, T *tris, int numtris, bool areaweight, int numframes) {
loopi(numframes) calctangents(&bumpverts[i*numverts], &verts[i*numverts], tcverts, numverts, tris, numtris, areaweight);
}
};
-
- struct meshgroup
- {
+ struct meshgroup {
meshgroup *next;
int shared;
char *name;
vector<mesh *> meshes;
-
- meshgroup() : next(NULL), shared(0), name(NULL)
- {
+ meshgroup() : next(NULL), shared(0), name(NULL) {
}
-
- virtual ~meshgroup()
- {
+ virtual ~meshgroup() {
DELETEA(name);
meshes.deletecontents();
DELETEP(next);
}
-
virtual int findtag(const char *name) { return -1; }
virtual void concattagtransform(part *p, int i, const matrix4x3 &m, matrix4x3 &n) {}
-
- void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m)
- {
+ void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m) {
loopv(meshes) meshes[i]->calcbb(bbmin, bbmax, m);
}
-
- void genBIH(vector<skin> &skins, vector<BIH::mesh> &bih, const matrix4x3 &t)
- {
+ void genBIH(vector<skin> &skins, vector<BIH::mesh> &bih, const matrix4x3 &t) {
loopv(meshes) meshes[i]->genBIH(skins[i], bih, t);
}
-
virtual void *animkey() { return this; }
virtual int totalframes() const { return 1; }
bool hasframe(int i) const { return i>=0 && i<totalframes(); }
bool hasframes(int i, int n) const { return i>=0 && i+n<=totalframes(); }
int clipframes(int i, int n) const { return min(n, totalframes() - i); }
-
virtual void cleanup() {}
virtual void preload(part *p) {}
virtual void render(const animstate *as, float pitch, const vec &axis, const vec &forward, dynent *d, part *p) {}
-
- void bindpos(GLuint ebuf, GLuint vbuf, void *v, int stride)
- {
- if(lastebuf!=ebuf)
- {
+ void bindpos(GLuint ebuf, GLuint vbuf, void *v, int stride) {
+ if(lastebuf!=ebuf) {
gle::bindebo(ebuf);
lastebuf = ebuf;
}
- if(lastvbuf!=vbuf)
- {
+ if(lastvbuf!=vbuf) {
gle::bindvbo(vbuf);
if(!lastvbuf) gle::enablevertex();
gle::vertexpointer(stride, v);
lastvbuf = vbuf;
}
}
-
- void bindtc(void *v, int stride)
- {
- if(!enabletc)
- {
+ void bindtc(void *v, int stride) {
+ if(!enabletc) {
gle::enabletexcoord0();
enabletc = true;
}
- if(lasttcbuf!=lastvbuf)
- {
+ if(lasttcbuf!=lastvbuf) {
gle::texcoord0pointer(stride, v);
lasttcbuf = lastvbuf;
}
}
-
- void bindnormals(void *v, int stride)
- {
- if(!enablenormals)
- {
+ void bindnormals(void *v, int stride) {
+ if(!enablenormals) {
gle::enablenormal();
enablenormals = true;
}
- if(lastnbuf!=lastvbuf)
- {
+ if(lastnbuf!=lastvbuf) {
gle::normalpointer(stride, v);
lastnbuf = lastvbuf;
}
}
-
- void bindtangents(void *v, int stride)
- {
- if(!enabletangents)
- {
+ void bindtangents(void *v, int stride) {
+ if(!enabletangents) {
gle::enabletangent();
enabletangents = true;
}
- if(lastxbuf!=lastvbuf)
- {
+ if(lastxbuf!=lastvbuf) {
gle::tangentpointer(stride, v, GL_SHORT);
lastxbuf = lastvbuf;
}
}
-
- void bindbones(void *wv, void *bv, int stride)
- {
- if(!enablebones)
- {
+ void bindbones(void *wv, void *bv, int stride) {
+ if(!enablebones) {
gle::enableboneweight();
gle::enableboneindex();
enablebones = true;
}
- if(lastbbuf!=lastvbuf)
- {
+ if(lastbbuf!=lastvbuf) {
gle::boneweightpointer(stride, wv);
gle::boneindexpointer(stride, bv);
lastbbuf = lastvbuf;
}
}
};
-
virtual meshgroup *loadmeshes(const char *name, va_list args) { return NULL; }
-
- meshgroup *sharemeshes(const char *name, ...)
- {
+ meshgroup *sharemeshes(const char *name, ...) {
static hashnameset<meshgroup *> meshgroups;
- if(!meshgroups.access(name))
- {
+ if(!meshgroups.access(name)) {
va_list args;
va_start(args, name);
meshgroup *group = loadmeshes(name, args);
@@ -584,20 +436,15 @@ struct animmodel : model
}
return meshgroups[name];
}
-
- struct linkedpart
- {
+ struct linkedpart {
part *p;
int tag, anim, basetime;
vec translate;
vec *pos;
matrix4 matrix;
-
linkedpart() : p(NULL), tag(-1), anim(-1), basetime(0), translate(0, 0, 0), pos(NULL) {}
};
-
- struct part
- {
+ struct part {
animmodel *model;
int index;
meshgroup *meshes;
@@ -607,57 +454,43 @@ struct animmodel : model
int numanimparts;
float pitchscale, pitchoffset, pitchmin, pitchmax;
vec translate;
-
- part(animmodel *model, int index = 0) : model(model), index(index), meshes(NULL), numanimparts(1), pitchscale(1), pitchoffset(0), pitchmin(0), pitchmax(0), translate(0, 0, 0)
- {
+ part(animmodel *model, int index = 0) : model(model), index(index), meshes(NULL), numanimparts(1), pitchscale(1), pitchoffset(0), pitchmin(0), pitchmax(0), translate(0, 0, 0) {
loopk(MAXANIMPARTS) anims[k] = NULL;
}
- virtual ~part()
- {
+ virtual ~part() {
loopk(MAXANIMPARTS) DELETEA(anims[k]);
}
-
- virtual void cleanup()
- {
+ virtual void cleanup() {
if(meshes) meshes->cleanup();
loopv(skins) skins[i].cleanup();
}
-
- void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m)
- {
+ void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m) {
matrix4x3 t = m;
t.scale(model->scale);
t.translate(translate);
meshes->calcbb(bbmin, bbmax, t);
- loopv(links)
- {
+ loopv(links) {
matrix4x3 n;
meshes->concattagtransform(this, links[i].tag, m, n);
n.translate(links[i].translate, model->scale);
links[i].p->calcbb(bbmin, bbmax, n);
}
}
-
- void genBIH(vector<BIH::mesh> &bih, const matrix4x3 &m)
- {
+ void genBIH(vector<BIH::mesh> &bih, const matrix4x3 &m) {
matrix4x3 t = m;
t.scale(model->scale);
t.translate(translate);
meshes->genBIH(skins, bih, t);
- loopv(links)
- {
+ loopv(links) {
matrix4x3 n;
meshes->concattagtransform(this, links[i].tag, m, n);
n.translate(links[i].translate, model->scale);
links[i].p->genBIH(bih, n);
}
}
-
- bool link(part *p, const char *tag, const vec &translate = vec(0, 0, 0), int anim = -1, int basetime = 0, vec *pos = NULL)
- {
+ bool link(part *p, const char *tag, const vec &translate = vec(0, 0, 0), int anim = -1, int basetime = 0, vec *pos = NULL) {
int i = meshes ? meshes->findtag(tag) : -1;
- if(i<0)
- {
+ if(i<0) {
loopv(links) if(links[i].p && links[i].p->link(p, tag, translate, anim, basetime, pos)) return true;
return false;
}
@@ -670,86 +503,62 @@ struct animmodel : model
l.pos = pos;
return true;
}
-
- bool unlink(part *p)
- {
+ bool unlink(part *p) {
loopvrev(links) if(links[i].p==p) { links.remove(i, 1); return true; }
loopv(links) if(links[i].p && links[i].p->unlink(p)) return true;
return false;
}
-
- void initskins(Texture *tex = notexture, Texture *masks = notexture, int limit = 0)
- {
- if(!limit)
- {
+ void initskins(Texture *tex = notexture, Texture *masks = notexture, int limit = 0) {
+ if(!limit) {
if(!meshes) return;
limit = meshes->meshes.length();
}
- while(skins.length() < limit)
- {
+ while(skins.length() < limit) {
skin &s = skins.add();
s.owner = this;
s.tex = tex;
s.masks = masks;
}
}
-
- bool tangents()
- {
+ bool tangents() {
loopv(skins) if(skins[i].tangents()) return true;
return false;
}
-
- void preloadBIH()
- {
+ void preloadBIH() {
loopv(skins) skins[i].preloadBIH();
}
-
- void preloadshaders(bool force)
- {
- loopv(skins) skins[i].preloadshader(force);
+ void preloadshaders() {
+ loopv(skins) skins[i].preloadshader();
}
-
- void preloadmeshes()
- {
+ void preloadmeshes() {
if(meshes) meshes->preload(this);
}
-
- virtual void getdefaultanim(animinfo &info, int anim, uint varseed, dynent *d)
- {
+ virtual void getdefaultanim(animinfo &info, int anim, uint varseed, dynent *d) {
(void) anim; (void) varseed; (void) d;
info.frame = 0;
info.range = 1;
}
-
- bool calcanim(int animpart, int anim, int basetime, int basetime2, dynent *d, int interp, animinfo &info, int &aitime)
- {
+ bool calcanim(int animpart, int anim, int basetime, int basetime2, dynent *d, int interp, animinfo &info, int &aitime) {
uint varseed = uint((size_t)d);
info.anim = anim;
info.basetime = basetime;
info.varseed = varseed;
info.speed = anim&ANIM_SETSPEED ? basetime2 : 100.0f;
- if((anim&ANIM_INDEX)==ANIM_ALL)
- {
+ if((anim&ANIM_INDEX)==ANIM_ALL) {
info.frame = 0;
info.range = meshes->totalframes();
}
- else
- {
+ else {
animspec *spec = NULL;
- if(anims[animpart])
- {
+ if(anims[animpart]) {
int primaryidx = anim&ANIM_INDEX;
- if(primaryidx < NUMANIMS)
- {
+ if(primaryidx < NUMANIMS) {
vector<animspec> &primary = anims[animpart][primaryidx];
if(primary.length()) spec = &primary[uint(varseed + basetime)%primary.length()];
}
- if((anim>>ANIM_SECONDARY)&(ANIM_INDEX|ANIM_DIR))
- {
+ if((anim>>ANIM_SECONDARY)&(ANIM_INDEX|ANIM_DIR)) {
int secondaryidx = (anim>>ANIM_SECONDARY)&ANIM_INDEX;
- if(secondaryidx < NUMANIMS)
- {
+ if(secondaryidx < NUMANIMS) {
vector<animspec> &secondary = anims[animpart][secondaryidx];
if(secondary.length())
{
@@ -764,54 +573,42 @@ struct animmodel : model
}
}
}
- if(spec)
- {
+ if(spec) {
info.frame = spec->frame;
info.range = spec->range;
if(spec->speed>0) info.speed = 1000.0f/spec->speed;
}
else getdefaultanim(info, anim, uint(varseed + info.basetime), d);
}
-
info.anim &= (1<<ANIM_SECONDARY)-1;
info.anim |= anim&ANIM_FLAGS;
- if((info.anim&ANIM_CLAMP) != ANIM_CLAMP)
- {
- if(info.anim&(ANIM_LOOP|ANIM_START|ANIM_END))
- {
+ if((info.anim&ANIM_CLAMP) != ANIM_CLAMP) {
+ if(info.anim&(ANIM_LOOP|ANIM_START|ANIM_END)) {
info.anim &= ~ANIM_SETTIME;
if(!info.basetime) info.basetime = -((int)(size_t)d&0xFFF);
}
- if(info.anim&(ANIM_START|ANIM_END))
- {
+ if(info.anim&(ANIM_START|ANIM_END)) {
if(info.anim&ANIM_END) info.frame += info.range-1;
info.range = 1;
}
}
-
- if(!meshes->hasframes(info.frame, info.range))
- {
+ if(!meshes->hasframes(info.frame, info.range)) {
if(!meshes->hasframe(info.frame)) return false;
info.range = meshes->clipframes(info.frame, info.range);
}
-
- if(d && interp>=0)
- {
+ if(d && interp>=0) {
animinterpinfo &ai = d->animinterp[interp];
if((info.anim&ANIM_CLAMP)==ANIM_CLAMP) aitime = min(aitime, int(info.range*info.speed*0.5e-3f));
void *ak = meshes->animkey();
- if(d->ragdoll && !(anim&ANIM_RAGDOLL))
- {
+ if(d->ragdoll && !(anim&ANIM_RAGDOLL)) {
ai.prev.range = ai.cur.range = 0;
ai.lastswitch = -1;
}
- else if(ai.lastmodel!=ak || ai.lastswitch<0 || lastmillis-d->lastrendered>aitime)
- {
+ else if(ai.lastmodel!=ak || ai.lastswitch<0 || lastmillis-d->lastrendered>aitime) {
ai.prev = ai.cur = info;
ai.lastswitch = lastmillis-aitime*2;
}
- else if(ai.cur!=info)
- {
+ else if(ai.cur!=info) {
if(lastmillis-ai.lastswitch>aitime/2) ai.prev = ai.cur;
ai.cur = info;
ai.lastswitch = lastmillis;
@@ -821,17 +618,12 @@ struct animmodel : model
}
return true;
}
-
- void render(int anim, int basetime, int basetime2, float pitch, const vec &axis, const vec &forward, dynent *d)
- {
+ void render(int anim, int basetime, int basetime2, float pitch, const vec &axis, const vec &forward, dynent *d) {
animstate as[MAXANIMPARTS];
render(anim, basetime, basetime2, pitch, axis, forward, d, as);
}
-
- void render(int anim, int basetime, int basetime2, float pitch, const vec &axis, const vec &forward, dynent *d, animstate *as)
- {
- if(!(anim&ANIM_REUSE)) loopi(numanimparts)
- {
+ void render(int anim, int basetime, int basetime2, float pitch, const vec &axis, const vec &forward, dynent *d, animstate *as) {
+ if(!(anim&ANIM_REUSE)) loopi(numanimparts) {
animinfo info;
int interp = d && index+numanimparts<=MAXANIMPARTS ? index+i : -1, aitime = animationinterpolationtime;
if(!calcanim(i, anim, basetime, basetime2, d, interp, info, aitime)) return;
@@ -839,41 +631,33 @@ struct animmodel : model
p.owner = this;
p.cur.setframes(info);
p.interp = 1;
- if(interp>=0 && d->animinterp[interp].prev.range>0)
- {
+ if(interp>=0 && d->animinterp[interp].prev.range>0) {
int diff = lastmillis-d->animinterp[interp].lastswitch;
- if(diff<aitime)
- {
+ if(diff<aitime) {
p.prev.setframes(d->animinterp[interp].prev);
p.interp = diff/float(aitime);
}
}
}
-
vec oaxis, oforward;
matrixstack[matrixpos].transposedtransformnormal(axis, oaxis);
float pitchamount = pitchscale*pitch + pitchoffset;
if((pitchmin || pitchmax) && pitchmin <= pitchmax) pitchamount = clamp(pitchamount, pitchmin, pitchmax);
if(as->cur.anim&ANIM_NOPITCH || (as->interp < 1 && as->prev.anim&ANIM_NOPITCH))
pitchamount *= (as->cur.anim&ANIM_NOPITCH ? 0 : as->interp) + (as->interp < 1 && as->prev.anim&ANIM_NOPITCH ? 0 : 1-as->interp);
- if(pitchamount)
- {
+ if(pitchamount) {
++matrixpos;
matrixstack[matrixpos] = matrixstack[matrixpos-1];
matrixstack[matrixpos].rotate(pitchamount*RAD, oaxis);
}
matrixstack[matrixpos].transposedtransformnormal(forward, oforward);
-
- if(!(anim&ANIM_NORENDER))
- {
+ if(!(anim&ANIM_NORENDER)) {
matrix4 modelmatrix;
modelmatrix.mul(shadowmapping ? shadowmatrix : camprojmatrix, matrixstack[matrixpos]);
if(model->scale!=1) modelmatrix.scale(model->scale);
if(!translate.iszero()) modelmatrix.translate(translate);
GLOBALPARAM(modelmatrix, modelmatrix);
-
- if(!(anim&ANIM_NOSKIN))
- {
+ if(!(anim&ANIM_NOSKIN)) {
vec odir, ocampos;
matrixstack[matrixpos].transposedtransformnormal(lightdir, odir);
GLOBALPARAM(lightdir, odir);
@@ -882,48 +666,33 @@ struct animmodel : model
GLOBALPARAM(modelcamera, ocampos);
}
}
-
meshes->render(as, pitch, oaxis, oforward, d, this);
-
- if(!(anim&ANIM_REUSE))
- {
- loopv(links)
- {
+ if(!(anim&ANIM_REUSE)) {
+ loopv(links) {
linkedpart &link = links[i];
link.matrix.translate(links[i].translate, model->scale);
-
matrixpos++;
matrixstack[matrixpos].mul(matrixstack[matrixpos-1], link.matrix);
-
if(link.pos) *link.pos = matrixstack[matrixpos].gettranslation();
-
- if(!link.p)
- {
+ if(!link.p) {
matrixpos--;
continue;
}
-
int nanim = anim, nbasetime = basetime, nbasetime2 = basetime2;
- if(link.anim>=0)
- {
+ if(link.anim>=0) {
nanim = link.anim | (anim&ANIM_FLAGS);
nbasetime = link.basetime;
nbasetime2 = 0;
}
link.p->render(nanim, nbasetime, nbasetime2, pitch, axis, forward, d);
-
matrixpos--;
}
}
-
if(pitchamount) matrixpos--;
}
-
- void setanim(int animpart, int num, int frame, int range, float speed, int priority = 0)
- {
+ void setanim(int animpart, int num, int frame, int range, float speed, int priority = 0) {
if(animpart<0 || animpart>=MAXANIMPARTS) return;
- if(frame<0 || range<=0 || !meshes || !meshes->hasframes(frame, range))
- {
+ if(frame<0 || range<=0 || !meshes || !meshes->hasframes(frame, range)) {
conoutf(CON_ERROR, "invalid frame %d, range %d in model %s", frame, range, model->name);
return;
}
@@ -934,99 +703,73 @@ struct animmodel : model
spec.speed = speed;
spec.priority = priority;
}
-
- virtual void loaded()
- {
+ virtual void loaded() {
meshes->shared++;
loopv(skins) skins[i].setkey();
}
};
-
- enum
- {
+ enum {
LINK_TAG = 0,
LINK_COOP,
LINK_REUSE
};
-
virtual int linktype(animmodel *m) const { (void) m; return LINK_TAG; }
-
- void render(int anim, int basetime, int basetime2, float pitch, const vec &axis, const vec &forward, dynent *d, modelattach *a)
- {
+ void render(int anim, int basetime, int basetime2, float pitch, const vec &axis, const vec &forward, dynent *d, modelattach *a) {
int numtags = 0;
- if(a)
- {
+ if(a) {
int index = parts.last()->index + parts.last()->numanimparts;
- for(int i = 0; a[i].tag; i++)
- {
+ for(int i = 0; a[i].tag; i++) {
numtags++;
-
animmodel *m = (animmodel *)a[i].m;
- if(!m)
- {
+ if(!m) {
if(a[i].pos) link(NULL, a[i].tag, vec(0, 0, 0), 0, 0, a[i].pos);
continue;
}
part *p = m->parts[0];
- switch(linktype(m))
- {
+ switch(linktype(m)) {
case LINK_TAG:
p->index = link(p, a[i].tag, vec(0, 0, 0), a[i].anim, a[i].basetime, a[i].pos) ? index : -1;
break;
-
case LINK_COOP:
p->index = index;
break;
-
default:
continue;
}
index += p->numanimparts;
}
}
-
animstate as[MAXANIMPARTS];
parts[0]->render(anim, basetime, basetime2, pitch, axis, forward, d, as);
-
- if(a) for(int i = numtags-1; i >= 0; i--)
- {
+ if(a) for(int i = numtags-1; i >= 0; i--) {
animmodel *m = (animmodel *)a[i].m;
- if(!m)
- {
+ if(!m) {
if(a[i].pos) unlink(NULL);
continue;
}
part *p = m->parts[0];
- switch(linktype(m))
- {
+ switch(linktype(m)) {
case LINK_TAG:
if(p->index >= 0) unlink(p);
p->index = 0;
break;
-
case LINK_COOP:
p->render(anim, basetime, basetime2, pitch, axis, forward, d);
p->index = 0;
break;
-
case LINK_REUSE:
p->render(anim | ANIM_REUSE, basetime, basetime2, pitch, axis, forward, d, as);
break;
}
}
}
-
- void render(int anim, int basetime, int basetime2, const vec &o, float yaw, float pitch, dynent *d, modelattach *a, const vec &color, const vec &dir, float trans)
- {
+ void render(int anim, int basetime, int basetime2, const vec &o, float yaw, float pitch, dynent *d, modelattach *a, const vec &color, const vec &dir, float trans) {
yaw += spinyaw*lastmillis/1000.0f;
pitch += offsetpitch + spinpitch*lastmillis/1000.0f;
-
vec axis(0, -1, 0), forward(1, 0, 0);
-
matrixpos = 0;
matrixstack[0].identity();
- if(!d || !d->ragdoll || anim&ANIM_RAGDOLL)
- {
+ if(!d || !d->ragdoll || anim&ANIM_RAGDOLL) {
matrixstack[0].settranslation(o);
matrixstack[0].rotate_around_z(yaw*RAD);
matrixstack[0].transformnormal(vec(axis), axis);
@@ -1034,138 +777,96 @@ struct animmodel : model
if(offsetyaw) matrixstack[0].rotate_around_z(offsetyaw*RAD);
}
else pitch = 0;
-
- if(anim&ANIM_NORENDER)
- {
+ if(anim&ANIM_NORENDER) {
render(anim, basetime, basetime2, pitch, axis, forward, d, a);
if(d) d->lastrendered = lastmillis;
return;
}
-
- if(!(anim&ANIM_NOSKIN))
- {
+ if(!(anim&ANIM_NOSKIN)) {
transparent = trans;
lightdir = dir;
lightcolor = color;
}
-
- if(depthoffset && !enabledepthoffset)
- {
+ if(depthoffset && !enabledepthoffset) {
enablepolygonoffset(GL_POLYGON_OFFSET_FILL);
enabledepthoffset = true;
}
-
- if(transparent<1)
- {
- if(anim&ANIM_GHOST)
- {
+ if(transparent<1) {
+ if(anim&ANIM_GHOST) {
glDepthFunc(GL_GREATER);
glDepthMask(GL_FALSE);
}
- else if(alphadepth)
- {
+ else if(alphadepth) {
glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
render(anim|ANIM_NOSKIN, basetime, basetime2, pitch, axis, forward, d, a);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
-
glDepthFunc(GL_LEQUAL);
}
-
- if(!enablealphablend)
- {
+ if(!enablealphablend) {
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
enablealphablend = true;
}
}
-
render(anim, basetime, basetime2, pitch, axis, forward, d, a);
-
- if(transparent<1 && (alphadepth || anim&ANIM_GHOST))
- {
+ if(transparent<1 && (alphadepth || anim&ANIM_GHOST)) {
glDepthFunc(GL_LESS);
if(anim&ANIM_GHOST) glDepthMask(GL_TRUE);
}
-
if(d) d->lastrendered = lastmillis;
}
-
vector<part *> parts;
-
- animmodel(const char *name) : model(name)
- {
+ animmodel(const char *name) : model(name) {
}
-
- ~animmodel()
- {
+ ~animmodel() {
parts.deletecontents();
}
-
- void cleanup()
- {
+ void cleanup() {
loopv(parts) parts[i]->cleanup();
}
-
virtual void flushpart() {}
-
- part &addpart()
- {
+ part &addpart() {
flushpart();
part *p = new part(this, parts.length());
parts.add(p);
return *p;
}
-
- void initmatrix(matrix4x3 &m)
- {
+ void initmatrix(matrix4x3 &m) {
m.identity();
if(offsetyaw) m.rotate_around_z(offsetyaw*RAD);
if(offsetpitch) m.rotate_around_y(-offsetpitch*RAD);
}
-
- void genBIH(vector<BIH::mesh> &bih)
- {
+ void genBIH(vector<BIH::mesh> &bih) {
if(parts.empty()) return;
matrix4x3 m;
initmatrix(m);
parts[0]->genBIH(bih, m);
}
-
- void preloadBIH()
- {
+ void preloadBIH() {
model::preloadBIH();
if(bih) loopv(parts) parts[i]->preloadBIH();
}
-
- BIH *setBIH()
- {
+ BIH *setBIH() {
if(bih) return bih;
vector<BIH::mesh> meshes;
genBIH(meshes);
bih = new BIH(meshes);
return bih;
}
-
- bool link(part *p, const char *tag, const vec &translate = vec(0, 0, 0), int anim = -1, int basetime = 0, vec *pos = NULL)
- {
+ bool link(part *p, const char *tag, const vec &translate = vec(0, 0, 0), int anim = -1, int basetime = 0, vec *pos = NULL) {
if(parts.empty()) return false;
return parts[0]->link(p, tag, translate, anim, basetime, pos);
}
-
- bool unlink(part *p)
- {
+ bool unlink(part *p) {
if(parts.empty()) return false;
return parts[0]->unlink(p);
}
-
virtual bool flipy() const { return false; }
virtual bool loadconfig() { return false; }
virtual bool loaddefaultparts() { return false; }
virtual void startload() {}
virtual void endload() {}
-
- bool load()
- {
+ bool load() {
startload();
bool success = loadconfig() && parts.length(); // configured model, will call the model commands below
if(!success)
@@ -1173,68 +874,46 @@ struct animmodel : model
flushpart();
endload();
if(flipy()) translate.y = -translate.y;
-
if(!success) return false;
loopv(parts) if(!parts[i]->meshes) return false;
-
loaded();
return true;
}
-
- void preloadshaders(bool force)
- {
- loopv(parts) parts[i]->preloadshaders(force);
+ void preloadshaders() {
+ loopv(parts) parts[i]->preloadshaders();
}
-
- void preloadmeshes()
- {
+ void preloadmeshes() {
loopv(parts) parts[i]->preloadmeshes();
}
-
- void setshader(Shader *shader)
- {
+ void setshader(Shader *shader) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].shader = shader;
}
-
- void setspec(float spec)
- {
+ void setspec(float spec) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].spec = spec;
}
-
- void setambient(float ambient)
- {
+ void setambient(float ambient) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].ambient = ambient;
}
-
- void setalphatest(float alphatest)
- {
+ void setalphatest(float alphatest) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].alphatest = alphatest;
}
-
- void setalphablend(bool alphablend)
- {
+ void setalphablend(bool alphablend) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].alphablend = alphablend;
}
-
- void setfullbright(float fullbright)
- {
+ void setfullbright(float fullbright) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].fullbright = fullbright;
}
-
- void setcullface(bool cullface)
- {
+ void setcullface(bool cullface) {
if(parts.empty()) loaddefaultparts();
loopv(parts) loopvj(parts[i]->skins) parts[i]->skins[j].cullface = cullface;
}
-
- void calcbb(vec &center, vec &radius)
- {
+ void calcbb(vec &center, vec &radius) {
if(parts.empty()) return;
vec bbmin(1e16f, 1e16f, 1e16f), bbmax(-1e16f, -1e16f, -1e16f);
matrix4x3 m;
@@ -1246,14 +925,11 @@ struct animmodel : model
center = bbmin;
center.add(radius);
}
-
- virtual void loaded()
- {
+ virtual void loaded() {
scale /= 4;
if(parts.length()) parts[0]->translate = translate;
loopv(parts) parts[i]->loaded();
}
-
static bool enabletc, enablealphablend, enablecullface, enablenormals, enabletangents, enablebones, enabledepthoffset;
static vec lightdir, lightcolor;
static float transparent, lastalphatest;
@@ -1261,9 +937,7 @@ struct animmodel : model
static Texture *lasttex, *lastmasks, *lastnormalmap;
static int matrixpos;
static matrix4 matrixstack[64];
-
- void startrender()
- {
+ void startrender() {
enabletc = enablealphablend = enablenormals = enabletangents = enablebones = enabledepthoffset = false;
enablecullface = true;
lastalphatest = -1;
@@ -1272,37 +946,26 @@ struct animmodel : model
transparent = 1;
shaderparamskey::invalidate();
}
-
- static void disablebones()
- {
+ static void disablebones() {
gle::disableboneweight();
gle::disableboneindex();
enablebones = false;
}
-
- static void disabletangents()
- {
+ static void disabletangents() {
gle::disabletangent();
enabletangents = false;
}
-
- static void disabletc()
- {
+ static void disabletc() {
gle::disabletexcoord0();
enabletc = false;
}
-
- static void disablenormals()
- {
+ static void disablenormals() {
gle::disablenormal();
enablenormals = false;
}
-
- static void disablevbo()
- {
+ static void disablevbo() {
if(lastebuf) gle::clearebo();
- if(lastvbuf)
- {
+ if(lastvbuf) {
gle::clearvbo();
gle::disablevertex();
}
@@ -1312,9 +975,7 @@ struct animmodel : model
if(enablebones) disablebones();
lastvbuf = lasttcbuf = lastxbuf = lastnbuf = lastbbuf = lastebuf = 0;
}
-
- void endrender()
- {
+ void endrender() {
if(lastvbuf || lastebuf) disablevbo();
if(enablealphablend) glDisable(GL_BLEND);
if(!enablecullface) glEnable(GL_CULL_FACE);
@@ -1333,45 +994,33 @@ Texture *animmodel::lasttex = NULL, *animmodel::lastmasks = NULL, *animmodel::la
int animmodel::matrixpos = 0;
matrix4 animmodel::matrixstack[64];
-static inline uint hthash(const animmodel::shaderparams &k)
-{
+static inline uint hthash(const animmodel::shaderparams &k) {
return memhash(&k, sizeof(k));
}
-static inline bool htcmp(const animmodel::shaderparams &x, const animmodel::shaderparams &y)
-{
+static inline bool htcmp(const animmodel::shaderparams &x, const animmodel::shaderparams &y) {
return !memcmp(&x, &y, sizeof(animmodel::shaderparams));
}
hashtable<animmodel::shaderparams, animmodel::shaderparamskey> animmodel::shaderparamskey::keys;
int animmodel::shaderparamskey::firstversion = 0, animmodel::shaderparamskey::lastversion = 1;
-template<class MDL, class BASE> struct modelloader : BASE
-{
+template<class MDL, class BASE> struct modelloader : BASE {
static MDL *loading;
static string dir;
-
modelloader(const char *name) : BASE(name) {}
-
static bool animated() { return true; }
static bool multiparted() { return true; }
static bool multimeshed() { return true; }
-
- void startload()
- {
+ void startload() {
loading = (MDL *)this;
}
-
- void endload()
- {
+ void endload() {
loading = NULL;
}
-
- bool loadconfig()
- {
+ bool loadconfig() {
formatstring(dir, "packages/models/%s", BASE::name);
defformatstring(cfgname, "packages/models/%s/%s.cfg", BASE::name, MDL::formatname());
-
identflags &= ~IDF_PERSIST;
bool success = execfile(cfgname, false);
identflags |= IDF_PERSIST;
@@ -1382,118 +1031,84 @@ template<class MDL, class BASE> struct modelloader : BASE
template<class MDL, class BASE> MDL *modelloader<MDL, BASE>::loading = NULL;
template<class MDL, class BASE> string modelloader<MDL, BASE>::dir = {'\0'}; // crashes clang if "" is used here
-template<class MDL, class MESH> struct modelcommands
-{
+template<class MDL, class MESH> struct modelcommands {
typedef struct MDL::part part;
typedef struct MDL::skin skin;
-
- static void setdir(char *name)
- {
+ static void setdir(char *name) {
if(!MDL::loading) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
formatstring(MDL::dir, "packages/models/%s", name);
}
-
#define loopmeshes(meshname, m, body) \
if(!MDL::loading || MDL::loading->parts.empty()) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; } \
part &mdl = *MDL::loading->parts.last(); \
if(!mdl.meshes) return; \
- loopv(mdl.meshes->meshes) \
- { \
+ loopv(mdl.meshes->meshes) { \
+ \
MESH &m = *(MESH *)mdl.meshes->meshes[i]; \
- if(!strcmp(meshname, "*") || (m.name && !strcmp(m.name, meshname))) \
- { \
+ if(!strcmp(meshname, "*") || (m.name && !strcmp(m.name, meshname))) { \
+ \
body; \
} \
}
-
#define loopskins(meshname, s, body) loopmeshes(meshname, m, { skin &s = mdl.skins[i]; body; })
-
- static void setskin(char *meshname, char *tex, char *masks, float *envmapmax, float *envmapmin)
- {(void)envmapmax;(void)envmapmin;
+ static void setskin(char *meshname, char *tex, char *masks, float *envmapmax, float *envmapmin) {
+ (void)envmapmax;(void)envmapmin;
loopskins(meshname, s,
s.tex = textureload(makerelpath(MDL::dir, tex), 0, true, false);
- if(*masks)
- {
+ if(*masks) {
s.masks = textureload(makerelpath(MDL::dir, masks), 0, true, false);
}
);
}
-
- static void setspec(char *meshname, int *percent)
- {
+ static void setspec(char *meshname, int *percent) {
float spec = 1.0f;
if(*percent>0) spec = *percent/100.0f;
else if(*percent<0) spec = 0.0f;
loopskins(meshname, s, s.spec = spec);
}
-
- static void setambient(char *meshname, int *percent)
- {
+ static void setambient(char *meshname, int *percent) {
float ambient = 0.3f;
if(*percent>0) ambient = *percent/100.0f;
else if(*percent<0) ambient = 0.0f;
loopskins(meshname, s, s.ambient = ambient);
}
-
- static void setalphatest(char *meshname, float *cutoff)
- {
+ static void setalphatest(char *meshname, float *cutoff) {
loopskins(meshname, s, s.alphatest = max(0.0f, min(1.0f, *cutoff)));
}
-
- static void setalphablend(char *meshname, int *blend)
- {
+ static void setalphablend(char *meshname, int *blend) {
loopskins(meshname, s, s.alphablend = *blend!=0);
}
-
- static void setcullface(char *meshname, int *cullface)
- {
+ static void setcullface(char *meshname, int *cullface) {
loopskins(meshname, s, s.cullface = *cullface!=0);
}
-
- static void setbumpmap(char *meshname, char *normalmapfile)
- {
+ static void setbumpmap(char *meshname, char *normalmapfile) {
Texture *normalmaptex = textureload(makerelpath(MDL::dir, normalmapfile), 0, true, false);
loopskins(meshname, s, s.normalmap = normalmaptex);
}
-
- static void setfullbright(char *meshname, float *fullbright)
- {
+ static void setfullbright(char *meshname, float *fullbright) {
loopskins(meshname, s, s.fullbright = *fullbright);
}
-
- static void setshader(char *meshname, char *shader)
- {
+ static void setshader(char *meshname, char *shader) {
loopskins(meshname, s, s.shader = lookupshaderbyname(shader));
}
-
- static void setscroll(char *meshname, float *scrollu, float *scrollv)
- {
+ static void setscroll(char *meshname, float *scrollu, float *scrollv) {
loopskins(meshname, s, { s.scrollu = *scrollu; s.scrollv = *scrollv; });
}
-
- static void setnoclip(char *meshname, int *noclip)
- {
+ static void setnoclip(char *meshname, int *noclip) {
loopmeshes(meshname, m, m.noclip = *noclip!=0);
}
-
- static void setlink(int *parent, int *child, char *tagname, float *x, float *y, float *z)
- {
+ static void setlink(int *parent, int *child, char *tagname, float *x, float *y, float *z) {
if(!MDL::loading) { conoutf(CON_ERROR, "not loading an %s", MDL::formatname()); return; }
if(!MDL::loading->parts.inrange(*parent) || !MDL::loading->parts.inrange(*child)) { conoutf(CON_ERROR, "no models loaded to link"); return; }
if(!MDL::loading->parts[*parent]->link(MDL::loading->parts[*child], tagname, vec(*x, *y, *z))) conoutf(CON_ERROR, "could not link model %s", MDL::loading->name);
}
-
- template<class F> void modelcommand(F *fun, const char *suffix, const char *args)
- {
+ template<class F> void modelcommand(F *fun, const char *suffix, const char *args) {
defformatstring(name, "%s%s", MDL::formatname(), suffix);
addcommand(newstring(name), (void (*)())fun, args);
}
-
- modelcommands()
- {
+ modelcommands() {
modelcommand(setdir, "dir", "s");
- if(MDL::multimeshed())
- {
+ if(MDL::multimeshed()) {
modelcommand(setskin, "skin", "sssff");
modelcommand(setspec, "spec", "si");
modelcommand(setambient, "ambient", "si");