From 2ed1e7366d90a2423b1a643e8d56de2cca68f661 Mon Sep 17 00:00:00 2001 From: Lee Salzman Date: Sun, 30 Mar 2008 02:42:49 +0000 Subject: [PATCH] better tag support git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@1728 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- source/src/md2.h | 22 +++++++++++++------ source/src/md3.h | 27 ++++++++++++++++++----- source/src/menus.cpp | 11 +++++++++- source/src/model.h | 15 +++++++++++-- source/src/protos.h | 2 +- source/src/rendermodel.cpp | 44 +++++++++++++++++++++++++------------- source/src/vertmodel.h | 2 +- 7 files changed, 91 insertions(+), 32 deletions(-) diff --git a/source/src/md2.h b/source/src/md2.h index be3b8cd9..042342b9 100644 --- a/source/src/md2.h +++ b/source/src/md2.h @@ -177,7 +177,7 @@ struct md2 : vertmodel } }; - void render(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, float pitch, dynent *d, model *vwepmdl, float scale) + void render(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, float pitch, dynent *d, modelattach *a, float scale) { if(!loaded) return; @@ -195,20 +195,28 @@ struct md2 : vertmodel if(!cullface) glEnable(GL_CULL_FACE); else if(anim&ANIM_MIRROR) glCullFace(GL_FRONT); - if(vwepmdl) + if(a) for(int i = 0; a[i].name; i++) { - ((md2 *)vwepmdl)->parts[0]->index = parts.length(); - vwepmdl->setskin(); - vwepmdl->render(anim, varseed, speed, basetime, o, yaw, pitch, d, NULL, scale); + vertmodel *m = (vertmodel *)a[i].m; + if(!m) continue; + m->parts[0]->index = parts.length()+i; + m->setskin(); + m->render(anim, varseed, speed, basetime, o, yaw, pitch, d, NULL, scale); } if(d) d->lastrendered = lastmillis; } - void rendershadow(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, model *vwepmdl) + void rendershadow(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, modelattach *a) { parts[0]->rendershadow(anim, varseed, speed, basetime, o, yaw); - if(vwepmdl) ((md2 *)vwepmdl)->parts[0]->rendershadow(anim, varseed, speed, basetime, o, yaw); + if(a) for(int i = 0; a[i].name; i++) + { + vertmodel *m = (vertmodel *)a[i].m; + if(!m) continue; + part *p = m->parts[0]; + p->rendershadow(anim, varseed, speed, basetime, o, yaw); + } } bool load() diff --git a/source/src/md3.h b/source/src/md3.h index 0abcd4aa..90a0a676 100644 --- a/source/src/md3.h +++ b/source/src/md3.h @@ -150,14 +150,21 @@ struct md3 : vertmodel } }; - void render(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, float pitch, dynent *d, model *vwepmdl, float scale) + void render(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, float pitch, dynent *d, modelattach *a, float scale) { if(!loaded) return; - if(vwepmdl) // cross link the vwep to this model + if(a) for(int i = 0; a[i].name; i++) { - part *vwep = ((md3 *)vwepmdl)->parts[0]; - if(link(vwep, "tag_weapon")) vwep->index = parts.length(); + vertmodel *m = (vertmodel *)a[i].m; + if(!m) continue;; + part *p = m->parts[0]; + switch(a[i].type) + { + case MDL_ATTACH_VWEP: + if(link(p, "tag_weapon")) p->index = parts.length()+i; + break; + } } if(!cullface) glDisable(GL_CULL_FACE); @@ -177,10 +184,20 @@ struct md3 : vertmodel if(!cullface) glEnable(GL_CULL_FACE); else if(anim&ANIM_MIRROR) glCullFace(GL_FRONT); + if(a) for(int i = 0; a[i].name; i++) + { + switch(a[i].type) + { + case MDL_ATTACH_VWEP: + link(NULL, "tag_weapon"); + break; + } + } + if(d) d->lastrendered = lastmillis; } - void rendershadow(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, model *vwepmdl) + void rendershadow(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, modelattach *a) { if(parts.length()>1) return; parts[0]->rendershadow(anim, varseed, speed, basetime, o, yaw); diff --git a/source/src/menus.cpp b/source/src/menus.cpp index 54b771b6..a6813c51 100644 --- a/source/src/menus.cpp +++ b/source/src/menus.cpp @@ -636,7 +636,16 @@ void rendermenumdl() s_sprintfd(skin)("packages/models/%s.jpg", m.mdl); tex = -(int)textureload(skin)->id; } - rendermodel(isplayermodel ? (char *)"playermodels" : m.mdl, m.anim, tex, 0, pos, yaw, 0, 0, 0, NULL, isplayermodel ? (char*)"weapons/subgun/world" : NULL, m.scale ? m.scale/25.0f : 1.0f); + modelattach a[2] = { { NULL }, { NULL } }; + if(isplayermodel) + { + a[0].name = "weapons/subgun/world"; + a[0].type = MDL_ATTACH_VWEP; + a[0].anim = m.anim; + a[0].basetime = 0; + a[0].speed = 0; + } + rendermodel(isplayermodel ? "playermodels" : m.mdl, m.anim, tex, 0, pos, yaw, 0, 0, 0, NULL, a, m.scale ? m.scale/25.0f : 1.0f); glPopMatrix(); } diff --git a/source/src/model.h b/source/src/model.h index df1b1cfb..7b2e3781 100644 --- a/source/src/model.h +++ b/source/src/model.h @@ -23,6 +23,17 @@ struct animstate // used for animation blending o enum { MDL_MD2 = 1, MDL_MD3 }; +enum { MDL_ATTACH_VWEP = 0 }; + +struct model; +struct modelattach +{ + const char *name; + int type, anim, basetime; + float speed; + model *m; +}; + struct dynent; struct model @@ -41,11 +52,11 @@ struct model virtual void cleanup() = 0; - virtual void render(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, float pitch, dynent *d, model *vwepmdl = NULL, float scale = 1.0f) = 0; + virtual void render(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, float pitch, dynent *d, modelattach *a = NULL, float scale = 1.0f) = 0; virtual void setskin(int tex = 0) = 0; virtual void genshadows(float height, float rad) {} - virtual void rendershadow(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, model *vwepmdl = NULL) {} + virtual void rendershadow(int anim, int varseed, float speed, int basetime, const vec &o, float yaw, modelattach *a = NULL) {} virtual bool hasshadows() { return false; } virtual void startrender() {} diff --git a/source/src/protos.h b/source/src/protos.h index 6c0e8e3d..41a6d414 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -428,7 +428,7 @@ extern void music(char *name, char *cmd); extern void clearmapsounds(); // rendermodel -extern void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, float yaw, float pitch, float speed = 0, int basetime = 0, playerent *d = NULL, const char *vwepmdl = NULL, float scale = 1.0f); +extern void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, float yaw, float pitch, float speed = 0, int basetime = 0, playerent *d = NULL, modelattach *a = NULL, float scale = 1.0f); extern void startmodelbatches(); extern void endmodelbatches(); extern mapmodelinfo &getmminfo(int i); diff --git a/source/src/rendermodel.cpp b/source/src/rendermodel.cpp index 0bdff895..3d560ecd 100644 --- a/source/src/rendermodel.cpp +++ b/source/src/rendermodel.cpp @@ -116,7 +116,7 @@ struct batchedmodel float yaw, pitch, speed; int basetime; playerent *d; - model *vwep; + int attached; float scale; }; struct modelbatch @@ -125,11 +125,13 @@ struct modelbatch vector batched; }; static vector batches; +static vector modelattached; static int numbatches = -1; void startmodelbatches() { numbatches = 0; + modelattached.setsizenodelete(0); } batchedmodel &addbatchedmodel(model *m) @@ -162,10 +164,12 @@ void renderbatchedmodel(model *m, batchedmodel &b) m->setskin(b.tex); + modelattach *a = NULL; + if(b.attached>=0) a = &modelattached[b.attached]; if(b.anim&ANIM_TRANSLUCENT) { glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - m->render(b.anim|ANIM_NOSKIN, b.varseed, b.speed, b.basetime, b.o, b.yaw, b.pitch, b.d, b.vwep, b.scale); + m->render(b.anim|ANIM_NOSKIN, b.varseed, b.speed, b.basetime, b.o, b.yaw, b.pitch, b.d, a, b.scale); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthFunc(GL_LEQUAL); @@ -177,7 +181,7 @@ void renderbatchedmodel(model *m, batchedmodel &b) glColor4f(color[0], color[1], color[2], m->translucency); } - m->render(b.anim, b.varseed, b.speed, b.basetime, b.o, b.yaw, b.pitch, b.d, b.vwep, b.scale); + m->render(b.anim, b.varseed, b.speed, b.basetime, b.o, b.yaw, b.pitch, b.d, a, b.scale); if(b.anim&ANIM_TRANSLUCENT) { @@ -195,7 +199,9 @@ void renderbatchedmodelshadow(model *m, batchedmodel &b) if(s->type==FHF) center.z -= s->vdelta/4.0f; if(center.z-0.1f>b.o.z) return; center.z += 0.1f; - m->rendershadow(b.anim, b.varseed, b.speed, b.basetime, center, b.yaw, b.vwep); + modelattach *a = NULL; + if(b.attached>=0) a = &modelattached[b.attached]; + m->rendershadow(b.anim, b.varseed, b.speed, b.basetime, center, b.yaw, a); } static int sortbatchedmodels(const batchedmodel *x, const batchedmodel *y) @@ -272,7 +278,7 @@ void endmodelbatches() numbatches = -1; } -void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, float yaw, float pitch, float speed, int basetime, playerent *d, const char *vwepmdl, float scale) +void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, float yaw, float pitch, float speed, int basetime, playerent *d, modelattach *a, float scale) { model *m = loadmodel(mdl); if(!m) return; @@ -287,11 +293,10 @@ void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, fl default: varseed = (int)(size_t)d + d->lastaction; break; } - model *vwep = NULL; - if(vwepmdl) + if(a) for(int i = 0; a[i].name; i++) { - vwep = loadmodel(vwepmdl); - if(vwep->type()!=m->type()) vwep = NULL; + a[i].m = loadmodel(a[i].name); + //if(a[i].m && a[i].m->type()!=m->type()) a[i].m = NULL; } if(numbatches>=0) @@ -306,7 +311,8 @@ void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, fl b.speed = speed; b.basetime = basetime; b.d = d; - b.vwep = vwep; + b.attached = a ? modelattached.length() : -1; + if(a) for(int i = 0;; i++) { modelattached.add(a[i]); if(!a[i].name) break; } b.scale = scale; return; } @@ -325,7 +331,7 @@ void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, fl { center.z += 0.1f; glColor4f(0, 0, 0, dynshadow/100.0f); - m->rendershadow(anim, varseed, speed, basetime, center, yaw, vwep); + m->rendershadow(anim, varseed, speed, basetime, center, yaw, a); } } glColor3ub(s->r, s->g, s->b); @@ -337,7 +343,7 @@ void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, fl if(anim&ANIM_TRANSLUCENT) { glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); - m->render(anim|ANIM_NOSKIN, varseed, speed, basetime, o, yaw, pitch, d, vwep, scale); + m->render(anim|ANIM_NOSKIN, varseed, speed, basetime, o, yaw, pitch, d, a, scale); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glDepthFunc(GL_LEQUAL); @@ -349,7 +355,7 @@ void rendermodel(const char *mdl, int anim, int tex, float rad, const vec &o, fl glColor4f(color[0], color[1], color[2], m->translucency); } - m->render(anim, varseed, speed, basetime, o, yaw, pitch, d, vwep, scale); + m->render(anim, varseed, speed, basetime, o, yaw, pitch, d, a, scale); if(anim&ANIM_TRANSLUCENT) { @@ -461,8 +467,16 @@ void renderclient(playerent *d, const char *mdlname, const char *vwepname, int t else if(d->weaponsel==d->lastattackweapon && lastmillis-d->lastaction<300) { anim = d->crouching ? ANIM_CROUCH_ATTACK : ANIM_ATTACK; speed = 300.0f/8; basetime = d->lastaction; } else if(!d->move && !d->strafe) { anim = (d->crouching ? ANIM_CROUCH_IDLE : ANIM_IDLE)|ANIM_LOOP; } else { anim = (d->crouching ? ANIM_CROUCH_WALK : ANIM_RUN)|ANIM_LOOP; speed = 1860/d->maxspeed; } - - rendermodel(mdlname, anim, tex, 1.5f, o, d->yaw+90, d->pitch/4, speed, basetime, d, vwepname); + modelattach a[2] = { { NULL }, { NULL } }; + if(vwepname) + { + a[0].name = vwepname; + a[0].type = MDL_ATTACH_VWEP; + a[0].anim = anim; + a[0].basetime = basetime; + a[0].speed = speed; + } + rendermodel(mdlname, anim, tex, 1.5f, o, d->yaw+90, d->pitch/4, speed, basetime, d, a); if(isteam(player1->team, d->team)) renderaboveheadicon(d); } diff --git a/source/src/vertmodel.h b/source/src/vertmodel.h index 025974df..56c62bcd 100644 --- a/source/src/vertmodel.h +++ b/source/src/vertmodel.h @@ -598,7 +598,7 @@ struct vertmodel : model return false; } - void setskin(int tex) + void setskin(int tex = 0) { if(parts.length()!=1 || parts[0]->meshes.length()!=1) return; mesh &m = *parts[0]->meshes[0];