home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2007 September / maximum-cd-2007-09.iso / Assets / data / AssaultCube_v0.93.exe / source / src / rendermodel.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2007-06-03  |  8.4 KB  |  275 lines

  1. #include "cube.h"
  2.  
  3. VARP(animationinterpolationtime, 0, 150, 1000);
  4.  
  5. model *loadingmodel = NULL;
  6.  
  7. #include "tristrip.h"
  8. #include "vertmodel.h"
  9. #include "md2.h"
  10. #include "md3.h"
  11.     
  12. #define checkmdl if(!loadingmodel) { conoutf("not loading a model"); return; }
  13.  
  14. void mdlcullface(int cullface)
  15. {
  16.     checkmdl;
  17.     loadingmodel->cullface = cullface!=0;
  18. }
  19.  
  20. COMMAND(mdlcullface, ARG_1INT);
  21.  
  22. void mdlscale(int percent)
  23. {
  24.     checkmdl;
  25.     float scale = 0.3f;
  26.     if(percent>0) scale = percent/100.0f;
  27.     else if(percent<0) scale = 0.0f;
  28.     loadingmodel->scale = scale;
  29. }
  30.  
  31. COMMAND(mdlscale, ARG_1INT);
  32.  
  33. void mdltrans(char *x, char *y, char *z)
  34. {
  35.     checkmdl;
  36.     loadingmodel->translate = vec(atof(x), atof(y), atof(z));
  37. }
  38.  
  39. COMMAND(mdltrans, ARG_3STR);
  40.  
  41. vector<mapmodelinfo> mapmodels;
  42.  
  43. void mapmodel(char *rad, char *h, char *zoff, char *snap, char *name)
  44. {
  45.     mapmodelinfo &mmi = mapmodels.add();
  46.     mmi.rad = atoi(rad);
  47.     mmi.h = atoi(h);
  48.     mmi.zoff = atoi(zoff);
  49.     s_sprintf(mmi.name)("mapmodels/%s", name);
  50. }
  51.  
  52. void mapmodelreset() { mapmodels.setsize(0); }
  53.  
  54. mapmodelinfo &getmminfo(int i) { return mapmodels.inrange(i) ? mapmodels[i] : *(mapmodelinfo *)0; }
  55.  
  56. COMMAND(mapmodel, ARG_5STR);
  57. COMMAND(mapmodelreset, ARG_NONE);
  58.  
  59. hashtable<const char *, model *> mdllookup;
  60.  
  61. model *loadmodel(const char *name, int i)
  62. {
  63.     if(!name)
  64.     {
  65.         if(!mapmodels.inrange(i)) return NULL;
  66.         mapmodelinfo &mmi = mapmodels[i];
  67.         if(mmi.m) return mmi.m;
  68.         name = mmi.name;
  69.     }
  70.     model **mm = mdllookup.access(name);
  71.     model *m;
  72.     if(mm) m = *mm;
  73.     else
  74.     {
  75.         m = new md2(name);
  76.         loadingmodel = m;
  77.         if(!m->load())
  78.         {
  79.             delete m;
  80.             m = new md3(name);
  81.             loadingmodel = m;
  82.             if(!m->load())
  83.             {
  84.                 delete m;
  85.                 loadingmodel = NULL;
  86.                 return NULL;
  87.             }
  88.         }
  89.         loadingmodel = NULL;
  90.         mdllookup.access(m->name(), &m);
  91.     }
  92.     if(mapmodels.inrange(i) && !mapmodels[i].m) mapmodels[i].m = m;
  93.     return m;
  94. }
  95.  
  96. VARP(dynshadow, 0, 40, 100);
  97.  
  98. void rendermodel(char *mdl, int anim, int tex, float rad, float x, float y, float z, float yaw, float pitch, float speed, int basetime, playerent *d, char *vwepmdl, float scale)
  99. {
  100.     model *m = loadmodel(mdl);
  101.     if(!m) return;
  102.  
  103.     if(rad > 0 && isoccluded(camera1->o.x, camera1->o.y, x-rad, y-rad, rad*2)) return;
  104.  
  105.     int ix = (int)x;
  106.     int iy = (int)y;
  107.     vec light(1, 1, 1);
  108.     int varseed = (int)(size_t)d + (d ? d->lastaction : 0);
  109.  
  110.     model *vwep = NULL;
  111.     if(vwepmdl)
  112.     {
  113.         vwep = loadmodel(vwepmdl);
  114.         if(vwep->type()!=m->type()) vwep = NULL;
  115.     }
  116.  
  117.     if(!OUTBORD(ix, iy))
  118.     {
  119.         sqr *s = S(ix, iy);
  120.         float ll = 256.0f; // 0.96f;
  121.         float of = 0.0f; // 0.1f;      
  122.         light.x = s->r/ll+of;
  123.         light.y = s->g/ll+of;
  124.         light.z = s->b/ll+of;
  125.  
  126.         if(dynshadow && m->hasshadows() && (!reflecting || refracting))
  127.         {
  128.             vec center(x, y, s->floor);
  129.             if(s->type==FHF) center.z -= s->vdelta/4.0f;
  130.             if(center.z-0.1f<=z)
  131.             {
  132.                 center.z += 0.1f;
  133.                 glColor4f(0, 0, 0, dynshadow/100.0f);
  134.                 m->rendershadow(anim, varseed, speed, basetime, center, yaw, vwep); 
  135.             }
  136.         } 
  137.     }
  138.  
  139.     glColor3fv(&light.x);
  140.     m->setskin(tex);
  141.  
  142.     if(!m->cullface) glDisable(GL_CULL_FACE);
  143.     else if(anim&ANIM_MIRROR) glCullFace(GL_BACK);
  144.     m->render(anim, varseed, speed, basetime, x, y, z, yaw, pitch, d, vwep, scale);
  145.     if(!m->cullface) glEnable(GL_CULL_FACE);
  146.     else if(anim&ANIM_MIRROR) glCullFace(GL_FRONT);
  147. }
  148.  
  149. int findanim(const char *name)
  150. {
  151.     const char *names[] = { "idle", "run", "attack", "pain", "jump", "land", "flipoff", "salute", "taunt", "wave", "point", "crouch idle", "crouch walk", "crouch attack", "crouch pain", "crouch death", "death", "lying dead", "flag", "gun idle", "gun shoot", "gun reload", "gun throw", "mapmodel", "trigger", "all" };
  152.     loopi(sizeof(names)/sizeof(names[0])) if(!strcmp(name, names[i])) return i;
  153.     return -1;
  154. }
  155.  
  156. void loadskin(const char *dir, const char *altdir, Texture *&skin) // model skin sharing
  157. {
  158.     #define ifnoload if((skin = textureload(path))==crosshair)
  159.     s_sprintfd(path)("packages/models/%s/skin.jpg", dir);
  160.     ifnoload
  161.     {
  162.         strcpy(path+strlen(path)-3, "png");
  163.         ifnoload
  164.         {
  165.             s_sprintf(path)("packages/models/%s/skin.jpg", altdir);
  166.             ifnoload
  167.             {
  168.                 strcpy(path+strlen(path)-3, "png");
  169.                 ifnoload return;
  170.             } 
  171.         } 
  172.     } 
  173. }
  174.  
  175. void preload_playermodels()
  176. {
  177.     model *playermdl = loadmodel("playermodels");
  178.     if(dynshadow && playermdl) playermdl->genshadows(8.0f, 4.0f);
  179.     loopi(NUMGUNS)
  180.     {
  181.         s_sprintfd(vwep)("weapons/%s/world", gunnames[i]);
  182.         model *vwepmdl = loadmodel(vwep);
  183.         if(dynshadow && vwepmdl) vwepmdl->genshadows(8.0f, 4.0f);
  184.     }
  185. }
  186.  
  187. void preload_entmodels()
  188. {
  189.     extern char *entmdlnames[];
  190.     loopi(I_AKIMBO-I_CLIPS+1)
  191.     {
  192.         model *mdl = loadmodel(entmdlnames[i]);
  193.         if(dynshadow && mdl) mdl->genshadows(8.0f, 2.0f);
  194.     }
  195.     static char *bouncemdlnames[] = { "misc/gib01", "misc/gib02", "misc/gib03", "weapons/grenade/static" };
  196.     loopi(sizeof(bouncemdlnames)/sizeof(bouncemdlnames[0]))
  197.     {
  198.         model *mdl = loadmodel(bouncemdlnames[i]);
  199.         if(dynshadow && mdl) mdl->genshadows(8.0f, 2.0f);
  200.     }
  201. }
  202.             
  203. void preload_mapmodels()
  204. {
  205.     int xs, ys;
  206.     loopv(ents)
  207.     {
  208.         entity &e = ents[i];
  209.         if(e.type!=MAPMODEL || !mapmodels.inrange(e.attr2)) continue;
  210.         if(!loadmodel(NULL, e.attr2)) continue;
  211.         if(e.attr4) lookuptexture(e.attr4, xs, ys);
  212.     }
  213. }
  214.  
  215. void renderclient(playerent *d, char *mdlname, char *vwepname, int tex)
  216. {
  217.     int varseed = (int)(size_t)d;
  218.     int anim = ANIM_IDLE|ANIM_LOOP;
  219.     float speed = 0.0;
  220.     float mz = d->o.z-d->eyeheight;
  221.     int basetime = -((int)(size_t)d&0xFFF);
  222.     if(d->state==CS_DEAD)
  223.     {
  224.         loopv(bounceents) if(bounceents[i]->bouncestate==GIB && bounceents[i]->owner==d) return;
  225.         d->pitch = 0.1f;
  226.         int r = 6;
  227.         anim = ANIM_DEATH;
  228.         varseed += d->lastaction;
  229.         basetime = d->lastaction;
  230.         int t = lastmillis-d->lastaction;
  231.         if(t<0 || t>20000) return;
  232.         if(t>(r-1)*100-50)
  233.         {
  234.             anim = ANIM_LYING_DEAD|ANIM_NOINTERP|ANIM_LOOP;
  235.             if(t>(r+10)*100)
  236.             {
  237.                 t -= (r+10)*100;
  238.                 mz -= t*t/10000000000.0f*t;
  239.             }
  240.         }
  241.         //if(mz<-1000) return;
  242.     }
  243.     else if(d->state==CS_EDITING)                   { anim = ANIM_JUMP|ANIM_END; }
  244.     else if(d->state==CS_LAGGED)                    { anim = ANIM_SALUTE|ANIM_LOOP; }
  245.     else if(lastmillis-d->lastpain<300)             { anim = ANIM_PAIN; speed = 300.0f/4; varseed += d->lastpain; basetime = d->lastpain; }
  246.     else if(!d->onfloor && d->timeinair>50)         { anim = ANIM_JUMP|ANIM_END; }
  247.     else if(d->gunselect==d->lastattackgun && lastmillis-d->lastaction<300)
  248.                                                     { anim = ANIM_ATTACK; speed = 300.0f/8; basetime = d->lastaction; }
  249.     else if(!d->move && !d->strafe)                 { anim = ANIM_IDLE|ANIM_LOOP; }
  250.     else                                            { anim = ANIM_RUN|ANIM_LOOP; speed = 1860/d->maxspeed; }
  251.     rendermodel(mdlname, anim, tex, 1.5f, d->o.x, d->o.y, mz, d->yaw+90, d->pitch/4, speed, basetime, d, vwepname);
  252. }
  253.  
  254. extern int democlientnum;
  255.  
  256. void renderclient(playerent *d)
  257. {
  258.     if(!d) return;
  259.  
  260.     int team = team_int(d->team);
  261.     s_sprintfd(skin)("packages/models/playermodels/%s/0%i.jpg", team_string(team), 1 + max(0, min(d->skin, (team==TEAM_CLA ? 3 : 5))));
  262.     string vwep;
  263.     if(d->gunselect>=0 && d->gunselect<NUMGUNS) s_sprintf(vwep)("weapons/%s/world", gunnames[d->gunselect]);
  264.     else vwep[0] = 0;
  265.     renderclient(d, "playermodels", vwep[0] ? vwep : NULL, -(int)textureload(skin)->id);
  266. }
  267.  
  268. void renderclients()
  269. {   
  270.     playerent *d;
  271.     loopv(players) if((d = players[i]) && (!demoplayback || i!=democlientnum)) renderclient(d);
  272.     if(player1->state==CS_DEAD || (reflecting && !refracting) || (demoplayback && !localdemoplayer1st())) renderclient(player1);
  273. }
  274.  
  275.