diff options
Diffstat (limited to 'src/engine')
| -rw-r--r-- | src/engine/animmodel.h | 67 | ||||
| -rw-r--r-- | src/engine/bih.cpp | 4 | ||||
| -rw-r--r-- | src/engine/command.cpp | 26 | ||||
| -rw-r--r-- | src/engine/engine.h | 22 | ||||
| -rw-r--r-- | src/engine/lightmap.cpp | 8 | ||||
| -rw-r--r-- | src/engine/lightmap.h | 2 | ||||
| -rw-r--r-- | src/engine/main.cpp | 2 | ||||
| -rw-r--r-- | src/engine/material.cpp | 4 | ||||
| -rw-r--r-- | src/engine/md5.h | 1 | ||||
| -rw-r--r-- | src/engine/model.h | 12 | ||||
| -rw-r--r-- | src/engine/octa.h | 2 | ||||
| -rw-r--r-- | src/engine/octaedit.cpp | 2 | ||||
| -rw-r--r-- | src/engine/octarender.cpp | 30 | ||||
| -rw-r--r-- | src/engine/physics.cpp | 200 | ||||
| -rw-r--r-- | src/engine/ragdoll.h | 424 | ||||
| -rw-r--r-- | src/engine/rendergl.cpp | 5 | ||||
| -rw-r--r-- | src/engine/rendermodel.cpp | 203 | ||||
| -rw-r--r-- | src/engine/renderparticles.cpp | 5 | ||||
| -rw-r--r-- | src/engine/renderva.cpp | 78 | ||||
| -rw-r--r-- | src/engine/shader.cpp | 54 | ||||
| -rw-r--r-- | src/engine/shadowmap.cpp | 224 | ||||
| -rw-r--r-- | src/engine/skelmodel.h | 107 | ||||
| -rw-r--r-- | src/engine/texture.cpp | 2 | ||||
| -rw-r--r-- | src/engine/texture.h | 2 | ||||
| -rw-r--r-- | src/engine/world.cpp | 3 |
25 files changed, 166 insertions, 1323 deletions
diff --git a/src/engine/animmodel.h b/src/engine/animmodel.h index e94aea5..da90969 100644 --- a/src/engine/animmodel.h +++ b/src/engine/animmodel.h @@ -133,9 +133,6 @@ struct animmodel : model { void cleanup() { if(shader && shader->standard) shader = NULL; } - void preloadBIH() { - if(tex->type&Texture::ALPHA && !tex->alphamask) loadalphamask(tex); - } void preloadshader() { //~if(force) cleanup(); loadshader(); @@ -148,8 +145,7 @@ struct animmodel : model { else if(cullface && !enablecullface) { glEnable(GL_CULL_FACE); enablecullface = true; } 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); + else SETMODELSHADER(b, notexturemodel); return; } setshader(b); @@ -196,22 +192,6 @@ struct animmodel : model { DELETEA(name); } virtual void calcbb(vec &bbmin, vec &bbmax, const matrix4x3 &m) = 0; - virtual void genBIH(BIH::mesh &m) = 0; - void genBIH(skin &s, vector<BIH::mesh> &bih, const matrix4x3 &t) { - BIH::mesh &m = bih.add(); - m.xform = t; - m.tex = s.tex; - if(s.tex->type&Texture::ALPHA) m.flags |= BIH::MESH_ALPHA; - if(noclip) m.flags |= BIH::MESH_NOCLIP; - if(s.cullface) m.flags |= BIH::MESH_CULLFACE; - genBIH(m); - 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) { s->set(); } @@ -357,9 +337,6 @@ struct animmodel : model { 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) { - 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(); } @@ -476,18 +453,6 @@ struct animmodel : model { links[i].p->calcbb(bbmin, bbmax, n); } } - 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) { - 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) { int i = meshes ? meshes->findtag(tag) : -1; if(i<0) { @@ -524,9 +489,6 @@ struct animmodel : model { loopv(skins) if(skins[i].tangents()) return true; return false; } - void preloadBIH() { - loopv(skins) skins[i].preloadBIH(); - } void preloadshaders() { loopv(skins) skins[i].preloadshader(); } @@ -600,11 +562,7 @@ struct animmodel : model { 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)) { - ai.prev.range = ai.cur.range = 0; - ai.lastswitch = -1; - } - else if(ai.lastmodel!=ak || ai.lastswitch<0 || lastmillis-d->lastrendered>aitime) { + if(ai.lastmodel!=ak || ai.lastswitch<0 || lastmillis-d->lastrendered>aitime) { ai.prev = ai.cur = info; ai.lastswitch = lastmillis-aitime*2; } @@ -653,7 +611,7 @@ struct animmodel : model { matrixstack[matrixpos].transposedtransformnormal(forward, oforward); if(!(anim&ANIM_NORENDER)) { matrix4 modelmatrix; - modelmatrix.mul(shadowmapping ? shadowmatrix : camprojmatrix, matrixstack[matrixpos]); + modelmatrix.mul(camprojmatrix, matrixstack[matrixpos]); if(model->scale!=1) modelmatrix.scale(model->scale); if(!translate.iszero()) modelmatrix.translate(translate); GLOBALPARAM(modelmatrix, modelmatrix); @@ -769,7 +727,7 @@ struct animmodel : model { vec axis(0, -1, 0), forward(1, 0, 0); matrixpos = 0; matrixstack[0].identity(); - if(!d || !d->ragdoll || anim&ANIM_RAGDOLL) { + if(!d) { matrixstack[0].settranslation(o); matrixstack[0].rotate_around_z(yaw*RAD); matrixstack[0].transformnormal(vec(axis), axis); @@ -836,23 +794,6 @@ struct animmodel : model { if(offsetyaw) m.rotate_around_z(offsetyaw*RAD); if(offsetpitch) m.rotate_around_y(-offsetpitch*RAD); } - void genBIH(vector<BIH::mesh> &bih) { - if(parts.empty()) return; - matrix4x3 m; - initmatrix(m); - parts[0]->genBIH(bih, m); - } - void preloadBIH() { - model::preloadBIH(); - if(bih) loopv(parts) parts[i]->preloadBIH(); - } - 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) { if(parts.empty()) return false; return parts[0]->link(p, tag, translate, anim, basetime, pos); diff --git a/src/engine/bih.cpp b/src/engine/bih.cpp index e406008..e5c6e2a 100644 --- a/src/engine/bih.cpp +++ b/src/engine/bih.cpp @@ -262,9 +262,6 @@ BIH::~BIH() { bool mmintersect(const extentity &e, const vec &o, const vec &ray, float maxdist, int mode, float &dist) { model *m = loadmapmodel(e.attr2); if(!m) return false; - if(mode&RAY_SHADOW) { - if(!m->shadow || e.flags&EF_NOSHADOW) return false; - } else if((mode&RAY_ENTS)!=RAY_ENTS && (!m->collide || e.flags&EF_NOCOLLIDE)) return false; if(!m->bih && (lightmapping > 1 || !m->setBIH())) return false; vec mo = vec(o).sub(e.o), mray(ray); @@ -278,4 +275,3 @@ bool mmintersect(const extentity &e, const vec &o, const vec &ray, float maxdist } return m->bih->traverse(mo, mray, maxdist ? maxdist : 1e16f, dist, mode); } - diff --git a/src/engine/command.cpp b/src/engine/command.cpp index 5248899..20312a7 100644 --- a/src/engine/command.cpp +++ b/src/engine/command.cpp @@ -919,23 +919,23 @@ static void compilelookup(vector<uint> &code, const char *&p, int ltype) { case ID_SVAR: code.add(CODE_SVAR|((ltype >= VAL_ANY ? VAL_STR : ltype)<<CODE_RET)|(id->index<<8)); goto done; case ID_ALIAS: code.add((id->index < MAXARGS ? CODE_LOOKUPARG : CODE_LOOKUP)|((ltype >= VAL_ANY ? VAL_STR : ltype)<<CODE_RET)|(id->index<<8)); goto done; case ID_COMMAND: { - int comtype = CODE_COM, numargs = 0; + int comtype = CODE_COM; code.add(CODE_ENTER); for(const char *fmt = id->args; *fmt; fmt++) switch(*fmt) { - case 's': compilestr(code, NULL, 0, true); numargs++; break; - case 'i': compileint(code); numargs++; break; - case 'b': compileint(code, INT_MIN); numargs++; break; - case 'f': compilefloat(code); numargs++; break; - case 't': compilenull(code); numargs++; break; - case 'e': compileblock(code); numargs++; break; - case 'r': compileident(code); numargs++; break; - case '$': compileident(code, id); numargs++; break; - case 'N': compileint(code, -1); numargs++; break; + case 's': compilestr(code, NULL, 0, true); break; + case 'i': compileint(code); break; + case 'b': compileint(code, INT_MIN); break; + case 'f': compilefloat(code); break; + case 't': compilenull(code); break; + case 'e': compileblock(code); break; + case 'r': compileident(code); break; + case '$': compileident(code, id); break; + case 'N': compileint(code, -1); break; #ifndef STANDALONE - case 'D': comtype = CODE_COMD; numargs++; break; + case 'D': comtype = CODE_COMD; break; #endif - case 'C': comtype = CODE_COMC; numargs = 1; goto endfmt; - case 'V': comtype = CODE_COMV; numargs = 2; goto endfmt; + case 'C': comtype = CODE_COMC; goto endfmt; + case 'V': comtype = CODE_COMV; goto endfmt; case '1': case '2': case '3': case '4': break; } endfmt: diff --git a/src/engine/engine.h b/src/engine/engine.h index 1b1d82f..c4a534a 100644 --- a/src/engine/engine.h +++ b/src/engine/engine.h @@ -8,7 +8,6 @@ #include "octa.h" #include "lightmap.h" -#include "bih.h" #include "texture.h" #include "model.h" @@ -82,20 +81,6 @@ extern int compactvslots(); extern void reloadtextures(); extern void cleanuptextures(); -// shadowmap - -extern int shadowmap, shadowmapcasters; -extern bool shadowmapping; -extern matrix4 shadowmatrix; - -extern bool isshadowmapcaster(const vec &o, float rad); -extern bool addshadowmapcaster(const vec &o, float xyrad, float zrad); -extern bool isshadowmapreceiver(vtxarray *va); -extern void rendershadowmap(); -extern void pushshadowmap(); -extern void rendershadowmapreceivers(); -extern void guessshadowdir(); - // rendergl extern bool hasVAO, hasFBO, hasAFBO, hasDS, hasTF, hasTRG, hasTSW, hasS3TC, hasFXT1, hasLATC, hasRGTC, hasAF, hasFBB, hasUBO, hasMBR; extern int glversion, glslversion, glcompat; @@ -353,11 +338,6 @@ extern void mousemove(int dx, int dy); extern bool overlapsdynent(const vec &o, float radius); extern void rotatebb(vec ¢er, vec &radius, int yaw); extern float shadowray(const vec &o, const vec &ray, float radius, int mode, extentity *t = NULL); -struct ShadowRayCache; -extern ShadowRayCache *newshadowraycache(); -extern void freeshadowraycache(ShadowRayCache *&cache); -extern void resetshadowraycache(ShadowRayCache *cache); -extern float shadowray(ShadowRayCache *cache, const vec &o, const vec &ray, float radius, int mode, extentity *t = NULL); // world @@ -381,7 +361,7 @@ extern mapmodelinfo *getmminfo(int i); extern void startmodelquery(occludequery *query); extern void endmodelquery(); extern void preloadmodelshaders(); -extern void preloadusedmapmodels(bool msg = false, bool bih = false); +extern void preloadusedmapmodels(bool msg = false); static inline model *loadmapmodel(int n) { extern vector<mapmodelinfo> mapmodels; diff --git a/src/engine/lightmap.cpp b/src/engine/lightmap.cpp index 3840d58..9cc835e 100644 --- a/src/engine/lightmap.cpp +++ b/src/engine/lightmap.cpp @@ -20,7 +20,6 @@ struct lightmapworker { VSlot *vslot; Slot *slot; vector<const extentity *> lights; - ShadowRayCache *shadowraycache; bool needspace, doneworking; SDL_cond *spacecond; SDL_Thread *thread; @@ -377,7 +376,7 @@ static uint generatelumel(lightmapworker *w, const float tolerance, uint lightma float angle = -ray.dot(normal); if(angle <= 0) continue; if(lmshadows && mag) { - float dist = shadowray(w->shadowraycache, light.o, ray, mag - tolerance, RAY_SHADOW | (lmshadows > 1 ? RAY_ALPHAPOLY : 0)); + float dist = shadowray(light.o, ray, mag - tolerance, RAY_SHADOW | (lmshadows > 1 ? RAY_ALPHAPOLY : 0)); if(dist < mag - tolerance) continue; } lightused |= 1<<i; @@ -1354,7 +1353,6 @@ lightmapworker::lightmapworker() { blur = new uchar[4*(LM_MAXW + 4)*(LM_MAXH + 4)]; colordata = new vec[4*(LM_MAXW+1 + 4)*(LM_MAXH+1 + 4)]; raydata = new vec[(LM_MAXW + 4)*(LM_MAXH + 4)]; - shadowraycache = newshadowraycache(); needspace = doneworking = false; spacecond = NULL; thread = NULL; @@ -1367,7 +1365,6 @@ lightmapworker::~lightmapworker() { delete[] blur; delete[] colordata; delete[] raydata; - freeshadowraycache(shadowraycache); } void lightmapworker::cleanupthread() { @@ -1379,7 +1376,6 @@ void lightmapworker::reset() { bufstart = bufused = 0; firstlightmap = lastlightmap = curlightmaps = NULL; needspace = doneworking = false; - resetshadowraycache(shadowraycache); } bool lightmapworker::setupthread() { @@ -1474,7 +1470,7 @@ void calclight(int *quality) { mpremip(true); loadlayermasks(); int numthreads = lightthreads > 0 ? lightthreads : numcpus; - if(numthreads > 1) preloadusedmapmodels(false, true); + if(numthreads > 1) preloadusedmapmodels(false); resetlightmaps(false); clearsurfaces(worldroot); taskprogress = progress = 0; diff --git a/src/engine/lightmap.h b/src/engine/lightmap.h index d15c6a7..2744257 100644 --- a/src/engine/lightmap.h +++ b/src/engine/lightmap.h @@ -100,9 +100,7 @@ extern void lerpnormal(float u, float v, const lerpvert *lv, int numv, lerpbound #define CHECK_CALCLIGHT_PROGRESS_LOCKED(exit, show_calclight_progress, before, after) \ if(check_calclight_progress) { \ - \ if(!calclight_canceled) { \ - \ before; \ show_calclight_progress(); \ check_calclight_canceled(); \ diff --git a/src/engine/main.cpp b/src/engine/main.cpp index 83aebaa..a3d4c09 100644 --- a/src/engine/main.cpp +++ b/src/engine/main.cpp @@ -593,14 +593,12 @@ void resetgl() { extern void cleanupdecals(); extern void cleanupmodels(); extern void cleanuplightmaps(); - extern void cleanshadowmap(); cleanupva(); cleanupparticles(); cleanupdecals(); cleanupmodels(); cleanuptextures(); cleanuplightmaps(); - cleanshadowmap(); cleanupshaders(); cleanupgl(); setupscreen(); diff --git a/src/engine/material.cpp b/src/engine/material.cpp index 55151a1..222d93b 100644 --- a/src/engine/material.cpp +++ b/src/engine/material.cpp @@ -251,16 +251,12 @@ int optimizematsurfs(materialsurface *matbuf, int matsurfs) { } void setupmaterials(int start, int len) { - int hasmat = 0; - unionfind uf; if(!len) len = valist.length(); for(int i = start; i < len; i++) { vtxarray *va = valist[i]; materialsurface *skip = NULL; loopj(va->matsurfs) { materialsurface &m = va->matbuf[j]; - int matvol = 0; - if(matvol) hasmat |= 1<<m.material; m.skip = 0; if(skip && m.material == skip->material && m.orient == skip->orient && skip->skip < 0xFFFF) skip->skip++; diff --git a/src/engine/md5.h b/src/engine/md5.h index e508cb3..f7e32b0 100644 --- a/src/engine/md5.h +++ b/src/engine/md5.h @@ -326,4 +326,3 @@ struct md5 : skelloader<md5> { }; skelcommands<md5> md5commands; - diff --git a/src/engine/model.h b/src/engine/model.h index 16f1629..40b8b00 100644 --- a/src/engine/model.h +++ b/src/engine/model.h @@ -3,20 +3,21 @@ enum { MDL_MD5, MDL_IQM, NUMMODELTYPES }; struct model { char *name; float spinyaw, spinpitch, offsetyaw, offsetpitch; - bool collide, ellipsecollide, shadow, alphadepth, depthoffset; + bool collide, ellipsecollide, alphadepth, depthoffset; float scale; vec translate; - BIH *bih; vec bbcenter, bbradius, bbextend, collidecenter, collideradius; float rejectradius, eyeheight, collidexyradius, collideheight; int batch; - model(const char *name) : name(name ? newstring(name) : NULL), spinyaw(0), spinpitch(0), offsetyaw(0), offsetpitch(0), collide(true), ellipsecollide(false), shadow(true), alphadepth(true), depthoffset(false), scale(1.0f), translate(0, 0, 0), bih(0), bbcenter(0, 0, 0), bbradius(-1, -1, -1), bbextend(0, 0, 0), collidecenter(0, 0, 0), collideradius(-1, -1, -1), rejectradius(-1), eyeheight(0.9f), collidexyradius(0), collideheight(0), batch(-1) {} - virtual ~model() { DELETEA(name); DELETEP(bih); } + model(const char *name) : name(name ? newstring(name) : NULL), spinyaw(0), spinpitch(0), offsetyaw(0), offsetpitch(0), collide(true), ellipsecollide(false), + alphadepth(true), depthoffset(false), scale(1.0f), translate(0, 0, 0), bbcenter(0, 0, 0), bbradius(-1, -1, -1), bbextend(0, 0, 0), + collidecenter(0, 0, 0), collideradius(-1, -1, -1), rejectradius(-1), eyeheight(0.9f), collidexyradius(0), collideheight(0), batch(-1) {} + + virtual ~model() { DELETEA(name); } virtual void calcbb(vec ¢er, vec &radius) = 0; virtual void render(int anim, int basetime, int basetime2, const vec &o, float yaw, float pitch, dynent *d, modelattach *a = NULL, const vec &color = vec(0, 0, 0), const vec &dir = vec(0, 0, 0), float transparent = 1) = 0; virtual bool load() = 0; virtual int type() const = 0; - virtual BIH *setBIH() { return 0; } virtual bool skeletal() const { return false; } virtual void setshader(Shader *) {} virtual void setspec(float) {} @@ -25,7 +26,6 @@ struct model { virtual void setalphablend(bool) {} virtual void setfullbright(float) {} virtual void setcullface(bool) {} - virtual void preloadBIH() { if(!bih) setBIH(); } virtual void preloadshaders() {} virtual void preloadmeshes() {} virtual void cleanup() {} diff --git a/src/engine/octa.h b/src/engine/octa.h index 0bc4762..82d194d 100644 --- a/src/engine/octa.h +++ b/src/engine/octa.h @@ -103,14 +103,12 @@ struct vtxarray { ivec o; int size; // location and size of cube. ivec geommin, geommax; // BB of geom - ivec shadowmapmin, shadowmapmax; // BB of shadowmapped surfaces ivec matmin, matmax; // BB of any materials ivec bbmin, bbmax; // BB of everything including children uchar curvfc, occluded; occludequery *query; vector<octaentities *> mapmodels; int hasmerges, mergelevel; - bool shadowed; }; struct cube; diff --git a/src/engine/octaedit.cpp b/src/engine/octaedit.cpp index 4ba5e17..8652ed6 100644 --- a/src/engine/octaedit.cpp +++ b/src/engine/octaedit.cpp @@ -1610,7 +1610,7 @@ void rendertexturepanel(int w, int h) { hudmatrix.scale(h/1800.0f, h/1800.0f, 1); flushhudmatrix(false); SETSHADER(hudrgb); - int y = 50, gap = 10; + int y = 50, gap = 10;(void)y; gle::defvertex(2); gle::deftexcoord0(); loopi(7) { diff --git a/src/engine/octarender.cpp b/src/engine/octarender.cpp index aa1da76..7096f47 100644 --- a/src/engine/octarender.cpp +++ b/src/engine/octarender.cpp @@ -390,29 +390,6 @@ int recalcprogress = 0; vector<tjoint> tjoints; -vec shadowmapmin, shadowmapmax; - -int calcshadowmask(vec *pos, int numpos) { - extern vec shadowdir; - int mask = 0, used = 1; - vec pe = vec(pos[1]).sub(pos[0]); - loopk(numpos-2) { - vec e = vec(pos[k+2]).sub(pos[0]); - if(vec().cross(pe, e).dot(shadowdir)>0) { - mask |= 1<<k; - used |= 6<<k; - } - pe = e; - } - if(!mask) return 0; - loopk(numpos) if(used&(1<<k)) { - const vec &v = pos[k]; - shadowmapmin.min(v); - shadowmapmax.max(v); - } - return mask; -} - VARFP(filltjoints, 0, 1, 1, allchanged()); void reduceslope(ivec &n) { @@ -594,7 +571,7 @@ void guessnormals(const vec *pos, int numverts, vec *normals) { void addcubeverts(VSlot &vslot, int orient, int size, vec *pos, ushort texture, ushort lmid, vertinfo *vinfo, int numverts, int tj = -1, bool alpha = false, int layer = LAYER_TOP) { (void) size; int dim = dimension(orient); - int shadowmask = alpha ? 0 : calcshadowmask(pos, numverts); + int shadowmask = 0; LightMap *lm = NULL; LightMapTexture *lmtex = NULL; if(lightmaps.inrange(lmid-LMID_RESERVED)) { @@ -1047,8 +1024,6 @@ void setva(cube &c, const ivec &co, int size, int csi) { loopi(MAXMERGELEVEL+1) vamergeoffset[i] = vamerges[i].length(); vc.origin = co; vc.size = size; - shadowmapmin = vec(co).add(size); - shadowmapmax = vec(co); int maxlevel = -1; rendercube(c, co, size, csi, maxlevel); ivec bbmin, bbmax; @@ -1059,8 +1034,6 @@ void setva(cube &c, const ivec &co, int size, int csi) { va->geommin = bbmin; va->geommax = bbmax; calcmatbb(co, size, va->matmin, va->matmax); - va->shadowmapmin = ivec(shadowmapmin.mul(8)).shr(3); - va->shadowmapmax = ivec(shadowmapmax.mul(8)).add(7).shr(3); va->hasmerges = vahasmerges; va->mergelevel = vamergemax; } @@ -1233,7 +1206,6 @@ void allchanged(bool load) { clearvas(worldroot); resetqueries(); resetclipplanes(); - guessshadowdir(); entitiesinoctanodes(); tjoints.setsize(0); if(filltjoints) findtjoints(); diff --git a/src/engine/physics.cpp b/src/engine/physics.cpp index f7e5342..5fa7c3f 100644 --- a/src/engine/physics.cpp +++ b/src/engine/physics.cpp @@ -95,38 +95,35 @@ extern void entselectionbox(const entity &e, vec &eo, vec &es); float hitentdist; int hitent, hitorient; -static float disttoent(octaentities *oc, const vec &o, const vec &ray, float radius, int mode, extentity *t) { - vec eo, es; - int orient = -1; - float dist = radius, f = 0.0f; - const vector<extentity *> &ents = entities::getents(); - #define entintersect(mask, type, func) {\ - if((mode&(mask))==(mask)) loopv(oc->type) { \ - \ - extentity &e = *ents[oc->type[i]]; \ - if(!(e.flags&EF_OCTA) || &e==t) continue; \ - func; \ - if(f<dist && f>0 && vec(ray).mul(f).add(o).insidebb(oc->o, oc->size)) { \ - \ - hitentdist = dist = f; \ - hitent = oc->type[i]; \ - hitorient = orient; \ - } \ - } \ - } - entintersect(RAY_POLY, mapmodels, - if(!mmintersect(e, o, ray, radius, mode, f)) continue; - ); - entintersect(RAY_ENTS, other, - entselectionbox(e, eo, es); - if(!rayboxintersect(eo, es, o, ray, f, orient)) continue; - ); - entintersect(RAY_ENTS, mapmodels, - entselectionbox(e, eo, es); - if(!rayboxintersect(eo, es, o, ray, f, orient)) continue; - ); - return dist; -} +//~static float disttoent(octaentities *oc, const vec &o, const vec &ray, float radius, int mode, extentity *t) { + //~vec eo, es; + //~int orient = -1; + //~float dist = radius, f = 0.0f; + //~const vector<extentity *> &ents = entities::getents(); + //~#define entintersect(mask, type, func) {\ + //~if((mode&(mask))==(mask)) loopv(oc->type) { \ + //~\ + //~extentity &e = *ents[oc->type[i]]; \ + //~if(!(e.flags&EF_OCTA) || &e==t) continue; \ + //~func; \ + //~if(f<dist && f>0 && vec(ray).mul(f).add(o).insidebb(oc->o, oc->size)) { \ + //~\ + //~hitentdist = dist = f; \ + //~hitent = oc->type[i]; \ + //~hitorient = orient; \ + //~} \ + //~} \ + //~} + //~entintersect(RAY_ENTS, other, + //~entselectionbox(e, eo, es); + //~if(!rayboxintersect(eo, es, o, ray, f, orient)) continue; + //~); + //~entintersect(RAY_ENTS, mapmodels, + //~entselectionbox(e, eo, es); + //~if(!rayboxintersect(eo, es, o, ray, f, orient)) continue; + //~); + //~return dist; +//~} static float disttooutsideent(const vec &o, const vec &ray, float radius, extentity *t) { vec eo, es; @@ -147,19 +144,6 @@ static float disttooutsideent(const vec &o, const vec &ray, float radius, extent return dist; } -// optimized shadow version -static float shadowent(octaentities *oc, const vec &o, const vec &ray, float radius, int mode, extentity *t) { - float dist = radius, f = 0.0f; - const vector<extentity *> &ents = entities::getents(); - loopv(oc->mapmodels) { - extentity &e = *ents[oc->mapmodels[i]]; - if(!(e.flags&EF_OCTA) || &e==t) continue; - if(!mmintersect(e, o, ray, radius, mode, f)) continue; - if(f>0 && f<dist) dist = f; - } - return dist; -} - #define INITRAYCUBE \ float dist = 0, dent = radius > 0 ? radius : 1e16f; \ vec v(o), invray(ray.x ? 1/ray.x : 1e16f, ray.y ? 1/ray.y : 1e16f, ray.z ? 1/ray.z : 1e16f); \ @@ -167,6 +151,7 @@ static float shadowent(octaentities *oc, const vec &o, const vec &ray, float rad levels[worldscale] = worldroot; \ int lshift = worldscale, elvl = mode&RAY_BB ? worldscale : 0; \ ivec lsizemask(invray.x>0 ? 1 : 0, invray.y>0 ? 1 : 0, invray.z>0 ? 1 : 0); \ + (void) elvl; (void) dent; #define CHECKINSIDEWORLD \ if(!insideworld(o)) { \ @@ -189,26 +174,25 @@ static float shadowent(octaentities *oc, const vec &o, const vec &ray, float rad dist += disttoworld; \ } -#define DOWNOCTREE(disttoent, earlyexit) \ - cube *lc = levels[lshift]; \ - for(;;) { \ - \ - lshift--; \ - lc += octastep(x, y, z, lshift); \ - if(lc->ext && lc->ext->ents && lshift < elvl) { \ - \ - float edist = disttoent(lc->ext->ents, o, ray, dent, mode, t); \ - if(edist < dent) { \ - \ - earlyexit return min(edist, dist); \ - elvl = lshift; \ - dent = min(dent, edist); \ - } \ - } \ - if(lc->children==NULL) break; \ - lc = lc->children; \ - levels[lshift] = lc; \ - } +//~#define DOWNOCTREE(disttoent, earlyexit) \ + //~cube *lc = levels[lshift]; \ + //~for(;;) { \ + //~lshift--; \ + //~lc += octastep(x, y, z, lshift); \ + //~if(lc->ext && lc->ext->ents && lshift < elvl) { \ + //~\ + //~float edist = disttoent(lc->ext->ents, o, ray, dent, mode, t); \ + //~if(edist < dent) { \ + //~\ + //~earlyexit return min(edist, dist); \ + //~elvl = lshift; \ + //~dent = min(dent, edist); \ + //~} \ + //~} \ + //~if(lc->children==NULL) break; \ + //~lc = lc->children; \ + //~levels[lshift] = lc; \ + //~} #define FINDCLOSEST(xclosest, yclosest, zclosest) \ float dx = (lo.x+(lsizemask.x<<lshift)-v.x)*invray.x, \ @@ -242,7 +226,23 @@ float raycube(const vec &o, const vec &ray, float radius, int mode, int size, ex CHECKINSIDEWORLD; int closest = -1, x = int(v.x), y = int(v.y), z = int(v.z); for(;;) { - DOWNOCTREE(disttoent, if(mode&RAY_SHADOW)); + cube *lc = levels[lshift]; + for(;;) { + lshift--; + lc += octastep(x, y, z, lshift); + //~if(lc->ext && lc->ext->ents && lshift < elvl) { + //~float edist = disttoent(lc->ext->ents, o, ray, dent, mode, t); + //~if(edist < dent) { + //~return min(edist, dist); + //~elvl = lshift; + //~dent = min(dent, edist); + //~} + //~} + if(lc->children==NULL) break; + lc = lc->children; + levels[lshift] = lc; + } + int lsize = 1<<lshift; cube &c = *lc; if((dist>0 || !(mode&RAY_SKIPFIRST)) && @@ -267,60 +267,31 @@ float raycube(const vec &o, const vec &ray, float radius, int mode, int size, ex } // optimized version for lightmap shadowing... every cycle here counts!!! + float shadowray(const vec &o, const vec &ray, float radius, int mode, extentity *t) { INITRAYCUBE; CHECKINSIDEWORLD; int side = O_BOTTOM, x = int(v.x), y = int(v.y), z = int(v.z); (void) side; for(;;) { - DOWNOCTREE(shadowent, ); - cube &c = *lc; - ivec lo(x&(~0U<<lshift), y&(~0U<<lshift), z&(~0U<<lshift)); - if(!isempty(c) && !(c.material&MAT_ALPHA)) { - if(isentirelysolid(c)) { - return dist; - } - else { - const clipplanes &p = getclipplanes(c, lo, 1<<lshift, false, 1); - INTERSECTPLANES(side = p.side[i], goto nextcube); - INTERSECTBOX(side = (i<<1) + 1 - lsizemask[i], goto nextcube); - if(exitdist >= 0) { - return dist+max(enterdist+0.1f, 0.0f); - } - } + //~DOWNOCTREE(shadowent, ); + + cube *lc = levels[lshift]; + for(;;) { + lshift--; + lc += octastep(x, y, z, lshift); + //~if(lc->ext && lc->ext->ents && lshift < elvl) { + //~float edist = shadowent(lc->ext->ents, o, ray, dent, mode, t); + //~if(edist < dent) { + //~return min(edist, dist); + //~elvl = lshift; + //~dent = min(dent, edist); + //~} + //~} + if(lc->children==NULL) break; + lc = lc->children; + levels[lshift] = lc; } - nextcube: - FINDCLOSEST(side = O_RIGHT - lsizemask.x, side = O_FRONT - lsizemask.y, side = O_TOP - lsizemask.z); - if(dist>=radius) return dist; - UPOCTREE(return radius); - } -} - -// thread safe version -struct ShadowRayCache { - clipplanes clipcache[MAXCLIPPLANES]; - int version; - ShadowRayCache() : version(-1) {} -}; - -ShadowRayCache *newshadowraycache() { return new ShadowRayCache; } - -void freeshadowraycache(ShadowRayCache *&cache) { delete cache; cache = NULL; } - -void resetshadowraycache(ShadowRayCache *cache) { - cache->version++; - if(!cache->version) { - memclear(cache->clipcache); - cache->version = 1; - } -} - -float shadowray(ShadowRayCache *cache, const vec &o, const vec &ray, float radius, int mode, extentity *t) { - INITRAYCUBE; - CHECKINSIDEWORLD; - int side = O_BOTTOM, x = int(v.x), y = int(v.y), z = int(v.z); (void) side; - for(;;) { - DOWNOCTREE(shadowent, ); cube &c = *lc; ivec lo(x&(~0U<<lshift), y&(~0U<<lshift), z&(~0U<<lshift)); if(!isempty(c) && !(c.material&MAT_ALPHA)) { @@ -328,8 +299,7 @@ float shadowray(ShadowRayCache *cache, const vec &o, const vec &ray, float radiu return dist; } else { - clipplanes &p = cache->clipcache[int(&c - worldroot)&(MAXCLIPPLANES-1)]; - if(p.owner != &c || p.version != cache->version) { p.owner = &c; p.version = cache->version; genclipplanes(c, lo, 1<<lshift, p, false); } + const clipplanes &p = getclipplanes(c, lo, 1<<lshift, false, 1); INTERSECTPLANES(side = p.side[i], goto nextcube); INTERSECTBOX(side = (i<<1) + 1 - lsizemask[i], goto nextcube); if(exitdist >= 0) { diff --git a/src/engine/ragdoll.h b/src/engine/ragdoll.h deleted file mode 100644 index 915076e..0000000 --- a/src/engine/ragdoll.h +++ /dev/null @@ -1,424 +0,0 @@ -struct ragdollskel { - struct vert { - vec pos; - float radius, weight; - }; - struct tri { - int vert[3]; - bool shareverts(const tri &t) const { - loopi(3) loopj(3) if(vert[i] == t.vert[j]) return true; - return false; - } - }; - struct distlimit { - int vert[2]; - float mindist, maxdist; - }; - struct rotlimit { - int tri[2]; - float maxangle; - matrix3 middle; - }; - struct rotfriction { - int tri[2]; - matrix3 middle; - }; - struct joint { - int bone, tri, vert[3]; - float weight; - matrix4x3 orient; - }; - struct reljoint { - int bone, parent; - }; - bool loaded, animjoints; - int eye; - vector<vert> verts; - vector<tri> tris; - vector<distlimit> distlimits; - vector<rotlimit> rotlimits; - vector<rotfriction> rotfrictions; - vector<joint> joints; - vector<reljoint> reljoints; - ragdollskel() : loaded(false), animjoints(false), eye(-1) {} - void setupjoints() { - loopv(verts) verts[i].weight = 0; - loopv(joints) { - joint &j = joints[i]; - j.weight = 0; - vec pos(0, 0, 0); - loopk(3) if(j.vert[k]>=0) { - pos.add(verts[j.vert[k]].pos); - j.weight++; - verts[j.vert[k]].weight++; - } - if(j.weight) j.weight = 1/j.weight; - pos.mul(j.weight); - tri &t = tris[j.tri]; - matrix4x3 &m = j.orient; - const vec &v1 = verts[t.vert[0]].pos, - &v2 = verts[t.vert[1]].pos, - &v3 = verts[t.vert[2]].pos; - m.a = vec(v2).sub(v1).normalize(); - m.c.cross(m.a, vec(v3).sub(v1)).normalize(); - m.b.cross(m.c, m.a); - m.d = pos; - m.transpose(); - } - loopv(verts) if(verts[i].weight) verts[i].weight = 1/verts[i].weight; - reljoints.shrink(0); - } - void setuprotfrictions() { - rotfrictions.shrink(0); - loopv(tris) for(int j = i+1; j < tris.length(); j++) if(tris[i].shareverts(tris[j])) { - rotfriction &r = rotfrictions.add(); - r.tri[0] = i; - r.tri[1] = j; - } - } - void setup() { - setupjoints(); - setuprotfrictions(); - loaded = true; - } - void addreljoint(int bone, int parent) { - reljoint &r = reljoints.add(); - r.bone = bone; - r.parent = parent; - } -}; - -struct ragdolldata { - struct vert { - vec oldpos, pos, newpos; - float weight; - bool collided, stuck; - vert() : pos(0, 0, 0), newpos(0, 0, 0), weight(0), collided(false), stuck(true) {} - }; - ragdollskel *skel; - int millis, collidemillis, collisions, floating, lastmove, unsticks; - vec offset, center; - float radius, timestep, scale; - vert *verts; - matrix3 *tris; - matrix4x3 *animjoints; - dualquat *reljoints; - ragdolldata(ragdollskel *skel, float scale = 1) - : skel(skel), - millis(lastmillis), - collidemillis(0), - collisions(0), - floating(0), - lastmove(lastmillis), - unsticks(INT_MAX), - radius(0), - timestep(0), - scale(scale), - verts(new vert[skel->verts.length()]), - tris(new matrix3[skel->tris.length()]), - animjoints(!skel->animjoints || skel->joints.empty() ? NULL : new matrix4x3[skel->joints.length()]), - reljoints(skel->reljoints.empty() ? NULL : new dualquat[skel->reljoints.length()]) { - } - ~ragdolldata() { - delete[] verts; - delete[] tris; - if(animjoints) delete[] animjoints; - if(reljoints) delete[] reljoints; - } - void calcanimjoint(int i, const matrix4x3 &anim) { - if(!animjoints) return; - ragdollskel::joint &j = skel->joints[i]; - vec pos(0, 0, 0); - loopk(3) if(j.vert[k]>=0) pos.add(verts[j.vert[k]].pos); - pos.mul(j.weight); - ragdollskel::tri &t = skel->tris[j.tri]; - matrix4x3 m; - const vec &v1 = verts[t.vert[0]].pos, - &v2 = verts[t.vert[1]].pos, - &v3 = verts[t.vert[2]].pos; - m.a = vec(v2).sub(v1).normalize(); - m.c.cross(m.a, vec(v3).sub(v1)).normalize(); - m.b.cross(m.c, m.a); - m.d = pos; - animjoints[i].transposemul(m, anim); - } - void calctris() { - loopv(skel->tris) { - ragdollskel::tri &t = skel->tris[i]; - matrix3 &m = tris[i]; - const vec &v1 = verts[t.vert[0]].pos, - &v2 = verts[t.vert[1]].pos, - &v3 = verts[t.vert[2]].pos; - m.a = vec(v2).sub(v1).normalize(); - m.c.cross(m.a, vec(v3).sub(v1)).normalize(); - m.b.cross(m.c, m.a); - } - } - void calcboundsphere() { - center = vec(0, 0, 0); - loopv(skel->verts) center.add(verts[i].pos); - center.div(skel->verts.length()); - radius = 0; - loopv(skel->verts) radius = max(radius, verts[i].pos.dist(center)); - } - void init(dynent *d) { - extern int ragdolltimestepmin; - float ts = ragdolltimestepmin/1000.0f; - loopv(skel->verts) (verts[i].oldpos = verts[i].pos).sub(vec(d->vel).add(d->falling).mul(ts)); - timestep = ts; - calctris(); - calcboundsphere(); - offset = d->o; - offset.sub(skel->eye >= 0 ? verts[skel->eye].pos : center); - offset.z += (d->eyeheight + d->aboveeye)/2; - } - void move(dynent *pl, float ts); - void updatepos(); - void constrain(); - void constraindist(); - void applyrotlimit(ragdollskel::tri &t1, ragdollskel::tri &t2, float angle, const vec &axis); - void constrainrot(); - void calcrotfriction(); - void applyrotfriction(float ts); - void tryunstick(float speed); - static inline bool collidevert(const vec &pos, const vec &dir, float radius) { - static struct vertent : physent { - vertent() { - type = ENT_BOUNCE; - radius = xradius = yradius = eyeheight = aboveeye = 1; - } - } v; - v.o = pos; - if(v.radius != radius) v.radius = v.xradius = v.yradius = v.eyeheight = v.aboveeye = radius; - return collide(&v, dir, 0, false); - } -}; - -/* - seed particle position = avg(modelview * base2anim * spherepos) - mapped transform = invert(curtri) * origtrig - parented transform = parent{invert(curtri) * origtrig} * (invert(parent{base2anim}) * base2anim) -*/ - -void ragdolldata::constraindist() { - float invscale = 1.0f/scale; - loopv(skel->distlimits) { - ragdollskel::distlimit &d = skel->distlimits[i]; - vert &v1 = verts[d.vert[0]], &v2 = verts[d.vert[1]]; - vec dir = vec(v2.pos).sub(v1.pos); - float dist = dir.magnitude()*invscale, cdist; - if(dist < d.mindist) cdist = d.mindist; - else if(dist > d.maxdist) cdist = d.maxdist; - else continue; - if(dist > 1e-4f) dir.mul(cdist*0.5f/dist); - else dir = vec(0, 0, cdist*0.5f/invscale); - vec center = vec(v1.pos).add(v2.pos).mul(0.5f); - v1.newpos.add(vec(center).sub(dir)); - v1.weight++; - v2.newpos.add(vec(center).add(dir)); - v2.weight++; - } -} - -inline void ragdolldata::applyrotlimit(ragdollskel::tri &t1, ragdollskel::tri &t2, float angle, const vec &axis) { - vert &v1a = verts[t1.vert[0]], &v1b = verts[t1.vert[1]], &v1c = verts[t1.vert[2]], - &v2a = verts[t2.vert[0]], &v2b = verts[t2.vert[1]], &v2c = verts[t2.vert[2]]; - vec m1 = vec(v1a.pos).add(v1b.pos).add(v1c.pos).div(3), - m2 = vec(v2a.pos).add(v2b.pos).add(v2c.pos).div(3), - q1a, q1b, q1c, q2a, q2b, q2c; - float w1 = q1a.cross(axis, vec(v1a.pos).sub(m1)).magnitude() + - q1b.cross(axis, vec(v1b.pos).sub(m1)).magnitude() + - q1c.cross(axis, vec(v1c.pos).sub(m1)).magnitude(), - w2 = q2a.cross(axis, vec(v2a.pos).sub(m2)).magnitude() + - q2b.cross(axis, vec(v2b.pos).sub(m2)).magnitude() + - q2c.cross(axis, vec(v2c.pos).sub(m2)).magnitude(); - angle /= w1 + w2 + 1e-9f; - float a1 = angle*w2, a2 = -angle*w1, - s1 = sinf(a1), s2 = sinf(a2); - vec c1 = vec(axis).mul(1 - cosf(a1)), c2 = vec(axis).mul(1 - cosf(a2)); - v1a.newpos.add(vec().cross(c1, q1a).madd(q1a, s1).add(v1a.pos)); - v1a.weight++; - v1b.newpos.add(vec().cross(c1, q1b).madd(q1b, s1).add(v1b.pos)); - v1b.weight++; - v1c.newpos.add(vec().cross(c1, q1c).madd(q1c, s1).add(v1c.pos)); - v1c.weight++; - v2a.newpos.add(vec().cross(c2, q2a).madd(q2a, s2).add(v2a.pos)); - v2a.weight++; - v2b.newpos.add(vec().cross(c2, q2b).madd(q2b, s2).add(v2b.pos)); - v2b.weight++; - v2c.newpos.add(vec().cross(c2, q2c).madd(q2c, s2).add(v2c.pos)); - v2c.weight++; -} - -void ragdolldata::constrainrot() { - loopv(skel->rotlimits) { - ragdollskel::rotlimit &r = skel->rotlimits[i]; - matrix3 rot; - rot.mul(tris[r.tri[0]], r.middle); - rot.multranspose(tris[r.tri[1]]); - vec axis; - float angle; - if(!rot.calcangleaxis(angle, axis)) continue; - angle = r.maxangle - fabs(angle); - if(angle >= 0) continue; - angle += 1e-3f; - applyrotlimit(skel->tris[r.tri[0]], skel->tris[r.tri[1]], angle, axis); - } -} - -VAR(ragdolltimestepmin, 1, 5, 50); -VAR(ragdolltimestepmax, 1, 10, 50); -FVAR(ragdollrotfric, 0, 0.85f, 1); -FVAR(ragdollrotfricstop, 0, 0.1f, 1); - -void ragdolldata::calcrotfriction() { - loopv(skel->rotfrictions) { - ragdollskel::rotfriction &r = skel->rotfrictions[i]; - r.middle.transposemul(tris[r.tri[0]], tris[r.tri[1]]); - } -} - -void ragdolldata::applyrotfriction(float ts) { - calctris(); - float stopangle = 2*M_PI*ts*ragdollrotfricstop, rotfric = 1.0f - pow(ragdollrotfric, ts*1000.0f/ragdolltimestepmin); - loopv(skel->rotfrictions) { - ragdollskel::rotfriction &r = skel->rotfrictions[i]; - matrix3 rot; - rot.mul(tris[r.tri[0]], r.middle); - rot.multranspose(tris[r.tri[1]]); - vec axis; - float angle; - if(rot.calcangleaxis(angle, axis)) { - angle *= -(fabs(angle) >= stopangle ? rotfric : 1.0f); - applyrotlimit(skel->tris[r.tri[0]], skel->tris[r.tri[1]], angle, axis); - } - } - loopv(skel->verts) { - vert &v = verts[i]; - if(v.weight) v.pos = v.newpos.div(v.weight); - v.newpos = vec(0, 0, 0); - v.weight = 0; - } -} - -void ragdolldata::tryunstick(float speed) { - vec unstuck(0, 0, 0); - int stuck = 0; - loopv(skel->verts) { - vert &v = verts[i]; - if(v.stuck) { - if(collidevert(v.pos, vec(0, 0, 0), skel->verts[i].radius)) { stuck++; continue; } - v.stuck = false; - } - unstuck.add(v.pos); - } - unsticks = 0; - if(!stuck || stuck >= skel->verts.length()) return; - unstuck.div(skel->verts.length() - stuck); - loopv(skel->verts) { - vert &v = verts[i]; - if(v.stuck) { - v.pos.add(vec(unstuck).sub(v.pos).rescale(speed)); - unsticks++; - } - } -} - -void ragdolldata::updatepos() { - loopv(skel->verts) { - vert &v = verts[i]; - if(v.weight) { - v.newpos.div(v.weight); - if(!collidevert(v.newpos, vec(v.newpos).sub(v.pos), skel->verts[i].radius)) v.pos = v.newpos; - else { - vec dir = vec(v.newpos).sub(v.oldpos); - if(dir.dot(collidewall) < 0) v.oldpos = vec(v.pos).sub(dir.reflect(collidewall)); - v.collided = true; - } - } - v.newpos = vec(0, 0, 0); - v.weight = 0; - } -} - -VAR(ragdollconstrain, 1, 5, 100); - -void ragdolldata::constrain() { - loopi(ragdollconstrain) { - constraindist(); - updatepos(); - calctris(); - constrainrot(); - updatepos(); - } -} - -FVAR(ragdollbodyfric, 0, 0.95f, 1); -FVAR(ragdollbodyfricscale, 0, 2, 10); -FVAR(ragdollgroundfric, 0, 0.8f, 1); -FVAR(ragdollairfric, 0, 0.996f, 1); -FVAR(ragdollunstick, 0, 10, 1e3f); -VAR(ragdollexpireoffset, 0, 1500, 30000); - -void ragdolldata::move(dynent *pl, float ts) { - extern const float GRAVITY; - if(collidemillis && lastmillis > collidemillis) return; - pl->inwater = MAT_AIR; - calcrotfriction(); - float tsfric = timestep ? ts/timestep : 1, - airfric = ragdollairfric + min((ragdollbodyfricscale*collisions)/skel->verts.length(), 1.0f)*(ragdollbodyfric - ragdollairfric); - collisions = 0; - loopv(skel->verts) { - vert &v = verts[i]; - vec dpos = vec(v.pos).sub(v.oldpos); - dpos.z -= GRAVITY*ts*ts; - dpos.mul(pow(1.0f * (v.collided ? ragdollgroundfric : airfric), ts*1000.0f/ragdolltimestepmin)*tsfric); - v.oldpos = v.pos; - v.pos.add(dpos); - } - applyrotfriction(ts); - loopv(skel->verts) { - vert &v = verts[i]; - if(v.pos.z < 0) { v.pos.z = 0; v.oldpos = v.pos; collisions++; } - vec dir = vec(v.pos).sub(v.oldpos); - v.collided = collidevert(v.pos, dir, skel->verts[i].radius); - if(v.collided) { - v.pos = v.oldpos; - v.oldpos.sub(dir.reflect(collidewall)); - collisions++; - } - } - if(unsticks && ragdollunstick) tryunstick(ts*ragdollunstick); - timestep = ts; - if(collisions) { - floating = 0; - if(!collidemillis) collidemillis = lastmillis + ragdollexpireoffset; - } - else if(++floating > 1 && lastmillis < collidemillis) collidemillis = 0; - constrain(); - calctris(); - calcboundsphere(); -} - -FVAR(ragdolleyesmooth, 0, 0.5f, 1); -VAR(ragdolleyesmoothmillis, 1, 250, 10000); - -void moveragdoll(dynent *d) { - if(!curtime || !d->ragdoll) return; - if(!d->ragdoll->collidemillis || lastmillis < d->ragdoll->collidemillis) { - int lastmove = d->ragdoll->lastmove; - while(d->ragdoll->lastmove + (lastmove == d->ragdoll->lastmove ? ragdolltimestepmin : ragdolltimestepmax) <= lastmillis) { - int timestep = min(ragdolltimestepmax, lastmillis - d->ragdoll->lastmove); - d->ragdoll->move(d, timestep/1000.0f); - d->ragdoll->lastmove += timestep; - } - } - vec eye = d->ragdoll->skel->eye >= 0 ? d->ragdoll->verts[d->ragdoll->skel->eye].pos : d->ragdoll->center; - eye.add(d->ragdoll->offset); - float k = pow(ragdolleyesmooth, float(curtime)/ragdolleyesmoothmillis); - d->o.mul(k).add(eye.mul(1-k)); -} - -void cleanragdoll(dynent *d) { - DELETEP(d->ragdoll); -} diff --git a/src/engine/rendergl.cpp b/src/engine/rendergl.cpp index e448415..2cdfff7 100644 --- a/src/engine/rendergl.cpp +++ b/src/engine/rendergl.cpp @@ -308,9 +308,6 @@ void gl_checkextensions() { hwcubetexsize = val; if(glversion >= 300 || hasext("GL_ARB_texture_float") || hasext("GL_ATI_texture_float")) { hasTF = true; - shadowmap = 1; - extern int smoothshadowmappeel; - smoothshadowmappeel = 1; } if(glversion >= 300 || hasext("GL_ARB_texture_rg")) { hasTRG = true; @@ -876,7 +873,7 @@ bool renderedgame = false; void rendergame(bool mainpass) { game::rendergame(mainpass); - if(!shadowmapping) renderedgame = true; + renderedgame = true; } int drawtex = 0; diff --git a/src/engine/rendermodel.cpp b/src/engine/rendermodel.cpp index 8174e22..eb75b69 100644 --- a/src/engine/rendermodel.cpp +++ b/src/engine/rendermodel.cpp @@ -5,7 +5,6 @@ VAR(animationinterpolationtime, 0, 150, 1000); model *loadingmodel = NULL; -#include "ragdoll.h" #include "animmodel.h" #include "skelmodel.h" @@ -152,13 +151,6 @@ void mdlpitch(float *angle) { COMMAND(mdlpitch, "f"); -void mdlshadow(int *shadow) { - checkmdl; - loadingmodel->shadow = *shadow!=0; -} - -COMMAND(mdlshadow, "i"); - void mdlbb(float *rad, float *h, float *eyeheight) { checkmdl; loadingmodel->collidexyradius = *rad; @@ -182,79 +174,6 @@ void mdlname() { COMMAND(mdlname, ""); -#define checkragdoll \ - checkmdl; \ - if(!loadingmodel->skeletal()) { conoutf(CON_ERROR, "not loading a skeletal model"); return; } \ - skelmodel *m = (skelmodel *)loadingmodel; \ - if(m->parts.empty()) return; \ - skelmodel::skelmeshgroup *meshes = (skelmodel::skelmeshgroup *)m->parts.last()->meshes; \ - if(!meshes) return; \ - skelmodel::skeleton *skel = meshes->skel; \ - if(!skel->ragdoll) skel->ragdoll = new ragdollskel; \ - ragdollskel *ragdoll = skel->ragdoll; \ - if(ragdoll->loaded) return; - -void rdvert(float *x, float *y, float *z, float *radius) { - checkragdoll; - ragdollskel::vert &v = ragdoll->verts.add(); - v.pos = vec(*x, *y, *z); - v.radius = *radius > 0 ? *radius : 1; -} -COMMAND(rdvert, "ffff"); - -void rdeye(int *v) { - checkragdoll; - ragdoll->eye = *v; -} -COMMAND(rdeye, "i"); - -void rdtri(int *v1, int *v2, int *v3) { - checkragdoll; - ragdollskel::tri &t = ragdoll->tris.add(); - t.vert[0] = *v1; - t.vert[1] = *v2; - t.vert[2] = *v3; -} -COMMAND(rdtri, "iii"); - -void rdjoint(int *n, int *t, int *v1, int *v2, int *v3) { - checkragdoll; - if(*n < 0 || *n >= skel->numbones) return; - ragdollskel::joint &j = ragdoll->joints.add(); - j.bone = *n; - j.tri = *t; - j.vert[0] = *v1; - j.vert[1] = *v2; - j.vert[2] = *v3; -} -COMMAND(rdjoint, "iibbb"); - -void rdlimitdist(int *v1, int *v2, float *mindist, float *maxdist) { - checkragdoll; - ragdollskel::distlimit &d = ragdoll->distlimits.add(); - d.vert[0] = *v1; - d.vert[1] = *v2; - d.mindist = *mindist; - d.maxdist = max(*maxdist, *mindist); -} -COMMAND(rdlimitdist, "iiff"); - -void rdlimitrot(int *t1, int *t2, float *maxangle, float *qx, float *qy, float *qz, float *qw) { - checkragdoll; - ragdollskel::rotlimit &r = ragdoll->rotlimits.add(); - r.tri[0] = *t1; - r.tri[1] = *t2; - r.maxangle = *maxangle * RAD; - r.middle = matrix3(quat(*qx, *qy, *qz, *qw)); -} -COMMAND(rdlimitrot, "iifffff"); - -void rdanimjoints(int *on) { - checkragdoll; - ragdoll->animjoints = *on!=0; -} -COMMAND(rdanimjoints, "i"); - // mapmodels vector<mapmodelinfo> mapmodels; @@ -303,7 +222,7 @@ void flushpreloadedmodels(bool msg) { loadprogress = 0; } -void preloadusedmapmodels(bool msg, bool bih) { +void preloadusedmapmodels(bool msg) { vector<extentity *> &ents = entities::getents(); vector<int> mapmodels; loopv(ents) { @@ -317,7 +236,6 @@ void preloadusedmapmodels(bool msg, bool bih) { if(!mmi) { if(msg) conoutf(CON_WARN, "could not find map model: %d", mmindex); } else if(mmi->name[0] && !loadmodel(NULL, mmindex, msg)) { if(msg) conoutf(CON_WARN, "could not load model: %s", mmi->name); } else if(mmi->m) { - if(bih) mmi->m->preloadBIH(); mmi->m->preloadmeshes(); } } @@ -471,14 +389,8 @@ void renderbatchedmodel(model *m, batchedmodel &b) { modelattach *a = NULL; if(b.attached>=0) a = &modelattached[b.attached]; int anim = b.anim; - if(shadowmapping) { - anim |= ANIM_NOSKIN; - GLOBALPARAMF(shadowintensity, b.transparent); - } - else { - if(b.flags&MDL_FULLBRIGHT) anim |= ANIM_FULLBRIGHT; - if(b.flags&MDL_GHOST) anim |= ANIM_GHOST; - } + if(b.flags&MDL_FULLBRIGHT) anim |= ANIM_FULLBRIGHT; + if(b.flags&MDL_GHOST) anim |= ANIM_GHOST; m->render(anim, b.basetime, b.basetime2, b.pos, b.yaw, b.pitch, b.d, a, b.color, b.dir, b.transparent); } @@ -519,11 +431,10 @@ void endmodelbatches() { query = bm.query; if(query) startquery(query); } - if(bm.transparent < 1 && (!query || query->owner==bm.d) && !shadowmapping) { + if(bm.transparent < 1 && (!query || query->owner==bm.d)) { transparentmodel &tm = transparent.add(); tm.m = b.m; tm.batched = &bm; - tm.dist = camera1->o.dist(bm.d && bm.d->ragdoll ? bm.d->ragdoll->center : bm.pos); continue; } if(!rendered) { b.m->startrender(); rendered = true; } @@ -617,17 +528,7 @@ static inline void disablecullmodelquery() { static inline int cullmodel(const vec ¢er, float radius, int flags, dynent *d = NULL) { if(flags&MDL_CULL_DIST && center.dist(camera1->o)/radius>maxmodelradiusdistance) return MDL_CULL_DIST; - if(flags&MDL_CULL_VFC) { - if(shadowmapping && !isshadowmapcaster(center, radius)) return MDL_CULL_VFC; - } - if(shadowmapping) { - if(d) { - if(flags&MDL_CULL_OCCLUDED && d->occluded>=OCCLUDE_PARENT) return MDL_CULL_OCCLUDED; - if(flags&MDL_CULL_QUERY && d->occluded+1>=OCCLUDE_BB && d->query && d->query->owner==d && checkquery(d->query)) return MDL_CULL_QUERY; - } - if(!addshadowmapcaster(center, radius, radius)) return MDL_CULL_VFC; - } - else if(flags&MDL_CULL_OCCLUDED && modeloccluded(center, radius)) { + if(flags&MDL_CULL_OCCLUDED && modeloccluded(center, radius)) { if(d) d->occluded = OCCLUDE_PARENT; return MDL_CULL_OCCLUDED; } @@ -639,26 +540,18 @@ static inline int cullmodel(const vec ¢er, float radius, int flags, dynent * } void rendermodel(entitylight *light, const char *mdl, int anim, const vec &o, float yaw, float pitch, int flags, dynent *d, modelattach *a, int basetime, int basetime2, float trans) { - if(shadowmapping && !(flags&(MDL_SHADOW|MDL_DYNSHADOW))) return; model *m = loadmodel(mdl); if(!m) return; vec center(0, 0, 0), bbradius(0, 0, 0); float radius = 0; - bool shadow = !shadowmap && (flags&(MDL_SHADOW|MDL_DYNSHADOW)); - if(flags&(MDL_CULL_VFC|MDL_CULL_DIST|MDL_CULL_OCCLUDED|MDL_CULL_QUERY|MDL_SHADOW|MDL_DYNSHADOW)) { + if(flags&(MDL_CULL_VFC|MDL_CULL_DIST|MDL_CULL_OCCLUDED|MDL_CULL_QUERY)) { if(flags&MDL_CULL_QUERY) { if(!oqfrags || !oqdynent || !d) flags &= ~MDL_CULL_QUERY; } m->boundbox(center, bbradius); radius = bbradius.magnitude(); - if(d && d->ragdoll) { - radius = max(radius, d->ragdoll->radius); - center = d->ragdoll->center; - } - else { - center.rotate_around_z(yaw*RAD); - center.add(o); - } + center.rotate_around_z(yaw*RAD); + center.add(o); int culled = cullmodel(center, radius, flags, d); if(culled) { if(culled&(MDL_CULL_OCCLUDED|MDL_CULL_QUERY) && flags&MDL_CULL_QUERY) { @@ -668,10 +561,9 @@ void rendermodel(entitylight *light, const char *mdl, int anim, const vec &o, fl } return; } - if(shadowmapping) flags &= ~MDL_CULL_QUERY; } if(flags&MDL_NORENDER) anim |= ANIM_NORENDER; - else if(showboundingbox && !shadowmapping && editmode) { + else if(showboundingbox && editmode) { notextureshader->set(); if(d && showboundingbox==1) { render3dbox(d->o, d->eyeheight, d->aboveeye, d->radius); @@ -687,32 +579,26 @@ void rendermodel(entitylight *light, const char *mdl, int anim, const vec &o, fl } } vec lightcolor(1, 1, 1), lightdir(0, 0, 1); - if(!shadowmapping) { - vec pos = o; - if(d) { - d->occluded = OCCLUDE_NOTHING; - if(!light) light = &d->light; - if(flags&MDL_LIGHT && light->millis!=lastmillis) { - if(d->ragdoll) { - pos = d->ragdoll->center; - pos.z += radius/2; - } - else if(d->type < ENT_CAMERA) pos.z += 0.75f*(d->eyeheight + d->aboveeye); - lightreaching(pos, light->color, light->dir); - light->millis = lastmillis; - } + vec pos = o; + if(d) { + d->occluded = OCCLUDE_NOTHING; + if(!light) light = &d->light; + if(flags&MDL_LIGHT && light->millis!=lastmillis) { + if(d->type < ENT_CAMERA) pos.z += 0.75f*(d->eyeheight + d->aboveeye); + lightreaching(pos, light->color, light->dir); + light->millis = lastmillis; } - else if(flags&MDL_LIGHT) { - if(!light) { - lightreaching(pos, lightcolor, lightdir); - } - else if(light->millis!=lastmillis) { - lightreaching(pos, light->color, light->dir); - light->millis = lastmillis; - } + } + else if(flags&MDL_LIGHT) { + if(!light) { + lightreaching(pos, lightcolor, lightdir); + } + else if(light->millis!=lastmillis) { + lightreaching(pos, light->color, light->dir); + light->millis = lastmillis; } - if(light) { lightcolor = light->color; lightdir = light->dir; } } + if(light) { lightcolor = light->color; lightdir = light->dir; } if(a) for(int i = 0; a[i].tag; i++) { if(a[i].name) a[i].m = loadmodel(a[i].name); //if(a[i].m && a[i].m->type()!=m->type()) a[i].m = NULL; @@ -731,10 +617,7 @@ void rendermodel(entitylight *light, const char *mdl, int anim, const vec &o, fl b.basetime2 = basetime2; b.transparent = trans; b.flags = flags & ~(MDL_CULL_VFC | MDL_CULL_DIST | MDL_CULL_OCCLUDED); - if(!shadow) { - b.flags &= ~(MDL_SHADOW|MDL_DYNSHADOW); - if(flags&MDL_CULL_VFC) b.flags |= MDL_CULL_VFC; - } + if(flags&MDL_CULL_VFC) b.flags |= MDL_CULL_VFC; mb.flags |= b.flags; b.d = d; b.attached = a ? modelattached.length() : -1; @@ -743,14 +626,8 @@ void rendermodel(entitylight *light, const char *mdl, int anim, const vec &o, fl return; } m->startrender(); - if(shadowmapping) { - anim |= ANIM_NOSKIN; - GLOBALPARAMF(shadowintensity, trans); - } - else { - if(flags&MDL_FULLBRIGHT) anim |= ANIM_FULLBRIGHT; - if(flags&MDL_GHOST) anim |= ANIM_GHOST; - } + if(flags&MDL_FULLBRIGHT) anim |= ANIM_FULLBRIGHT; + if(flags&MDL_GHOST) anim |= ANIM_GHOST; if(flags&MDL_CULL_QUERY) { d->query = newquery(d); if(d->query) startquery(d->query); @@ -760,12 +637,6 @@ void rendermodel(entitylight *light, const char *mdl, int anim, const vec &o, fl m->endrender(); } -void abovemodel(vec &o, const char *mdl) { - model *m = loadmodel(mdl); - if(!m) return; - o.z += m->above(); -} - bool matchanim(const char *name, const char *pattern) { for(;; pattern++) { const char *s = name; @@ -831,7 +702,7 @@ VAR(animoverride, -1, 0, NUMANIMS-1); VAR(testanims, 0, 0, 1); VAR(testpitch, -90, 0, 90); -void renderclient(dynent *d, const char *mdlname, modelattach *attachments, int hold, int attack, int attackdelay, int lastaction, int lastpain, float fade, bool ragdoll) { +void renderclient(dynent *d, const char *mdlname, modelattach *attachments, int hold, int attack, int attackdelay, int lastaction, int lastpain, float fade) { int anim = hold ? hold : ANIM_IDLE|ANIM_LOOP; float yaw = testanims && d==player ? 0 : d->yaw+90, pitch = testpitch && d==player ? testpitch : d->pitch; @@ -841,13 +712,7 @@ void renderclient(dynent *d, const char *mdlname, modelattach *attachments, int else if(d->state==CS_DEAD) { anim = ANIM_DYING|ANIM_NOPITCH; basetime = lastpain; - if(ragdoll) { - if(!d->ragdoll || d->ragdoll->millis < basetime) { - DELETEP(d->ragdoll); - anim |= ANIM_RAGDOLL; - } - } - else if(lastmillis-basetime>1000) anim = ANIM_DEAD|ANIM_LOOP|ANIM_NOPITCH; + if(lastmillis-basetime>1000) anim = ANIM_DEAD|ANIM_LOOP|ANIM_NOPITCH; } else if(d->state==CS_EDITING || d->state==CS_SPECTATOR) anim = ANIM_EDIT|ANIM_LOOP; else if(d->state==CS_LAGGED) anim = ANIM_LAG|ANIM_LOOP; @@ -872,15 +737,13 @@ void renderclient(dynent *d, const char *mdlname, modelattach *attachments, int } if((anim&ANIM_INDEX)==ANIM_IDLE && (anim>>ANIM_SECONDARY)&ANIM_INDEX) anim >>= ANIM_SECONDARY; } - if(d->ragdoll && (!ragdoll || (anim&ANIM_INDEX)!=ANIM_DYING)) DELETEP(d->ragdoll); if(!((anim>>ANIM_SECONDARY)&ANIM_INDEX)) anim |= (ANIM_IDLE|ANIM_LOOP)<<ANIM_SECONDARY; int flags = MDL_LIGHT; - if(d!=player && !(anim&ANIM_RAGDOLL)) flags |= MDL_CULL_VFC | MDL_CULL_OCCLUDED | MDL_CULL_QUERY; + if(d!=player) flags |= MDL_CULL_VFC | MDL_CULL_OCCLUDED | MDL_CULL_QUERY; if(d->type==ENT_PLAYER) flags |= MDL_FULLBRIGHT; else flags |= MDL_CULL_DIST; if(d->state==CS_LAGGED) fade = min(fade, 0.3f); - else flags |= MDL_DYNSHADOW; - if(drawtex == DRAWTEX_MODELPREVIEW) flags &= ~(MDL_LIGHT | MDL_FULLBRIGHT | MDL_CULL_VFC | MDL_CULL_OCCLUDED | MDL_CULL_QUERY | MDL_CULL_DIST | MDL_DYNSHADOW); + if(drawtex == DRAWTEX_MODELPREVIEW) flags &= ~(MDL_LIGHT | MDL_FULLBRIGHT | MDL_CULL_VFC | MDL_CULL_OCCLUDED | MDL_CULL_QUERY | MDL_CULL_DIST); rendermodel(NULL, mdlname, anim, o, yaw, pitch, flags, d, attachments, basetime, 0, fade); } diff --git a/src/engine/renderparticles.cpp b/src/engine/renderparticles.cpp index a3cc91f..f96dc45 100644 --- a/src/engine/renderparticles.cpp +++ b/src/engine/renderparticles.cpp @@ -800,7 +800,7 @@ static void regularsplash(int type, int color, int radius, int num, int fade, co } bool canaddparticles() { - return !renderedgame && !shadowmapping && !minimized; + return !renderedgame && !minimized; } void regular_particle_splash(int type, int num, int fade, const vec &p, int color, float size, int radius, int gravity, int delay) { @@ -1099,18 +1099,15 @@ void updateparticles() { } else canemit = false; if(!editmode || showparticles) { - int emitted = 0, replayed = 0; addedparticles = 0; loopv(emitters) { particleemitter &pe = emitters[i]; extentity &e = *pe.ent; if(e.o.dist(camera1->o) > maxparticledistance) { pe.lastemit = lastmillis; continue; } makeparticles(e); - emitted++; if(replayparticles && pe.maxfade > 5 && pe.lastcull > pe.lastemit) { for(emitoffset = max(pe.lastemit + emitmillis - lastmillis, -pe.maxfade); emitoffset < 0; emitoffset += emitmillis) { makeparticles(e); - replayed++; } emitoffset = 0; } diff --git a/src/engine/renderva.cpp b/src/engine/renderva.cpp index be57ab3..16ad334 100644 --- a/src/engine/renderva.cpp +++ b/src/engine/renderva.cpp @@ -30,11 +30,6 @@ int isvisiblesphere(float rad, const vec &cv) { return v; } -static inline int ishiddencube(const ivec &o, int size) { - loopi(5) if(o.dist(vfcP[i]) < -vfcDfar[i]*size) return true; - return false; -} - int isvisiblecube(const ivec &o, int size) { int v = VFC_FULL_VISIBLE; float dist; @@ -477,41 +472,6 @@ void renderoutline() { gle::disablevertex(); } -void rendershadowmapreceivers() { - SETSHADER(shadowmapreceiver); - gle::enablevertex(); - glCullFace(GL_FRONT); - glDepthMask(GL_FALSE); - glDepthFunc(GL_GREATER); - extern int ati_minmax_bug; - if(!ati_minmax_bug) glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_FALSE); - glEnable(GL_BLEND); - glBlendEquation_(GL_MAX); - glBlendFunc(GL_ONE, GL_ONE); - vtxarray *prev = NULL; - for(vtxarray *va = visibleva; va; va = va->next) { - if(!va->texs || !isshadowmapreceiver(va)) continue; - if(!prev || va->vbuf != prev->vbuf) { - gle::bindvbo(va->vbuf); - gle::bindebo(va->ebuf); - const vertex *ptr = 0; - gle::vertexpointer(sizeof(vertex), ptr->pos.v); - } - drawvatris(va, 3*va->tris, va->edata); - xtravertsva += va->verts; - prev = va; - } - glDisable(GL_BLEND); - glBlendEquation_(GL_FUNC_ADD); - glCullFace(GL_BACK); - glDepthMask(GL_TRUE); - glDepthFunc(GL_LESS); - if(!ati_minmax_bug) glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); - gle::clearvbo(); - gle::clearebo(); - gle::disablevertex(); -} - VAR(oqdist, 0, 256, 1024); VAR(zpass, 0, 1, 1); VAR(envpass, 0, 1, 1); @@ -528,7 +488,8 @@ struct renderstate { VSlot *vslot, *texgenvslot; vec2 texgenscroll; int texgendim; - renderstate() : colormask(true), depthmask(true), blending(false), alphaing(0), vbuf(0), vattribs(false), vquery(false), colorscale(1, 1, 1), alphascale(0), slot(NULL), texgenslot(NULL), vslot(NULL), texgenvslot(NULL), texgenscroll(0, 0), texgendim(-1) { + renderstate() : colormask(true), depthmask(true), blending(false), alphaing(0), vbuf(0), vattribs(false), vquery(false), colorscale(1, 1, 1), alphascale(0), + slot(NULL), texgenslot(NULL), vslot(NULL), texgenvslot(NULL), texgenscroll(0, 0), texgendim(-1) { loopk(8) textures[k] = 0; } }; @@ -779,33 +740,19 @@ static void changetexgen(renderstate &cur, int dim, Slot &slot, VSlot &vslot) { } static void renderbatch(geombatch &b) { - geombatch *shadowed = NULL; int rendered = -1; for(geombatch *curbatch = &b;; curbatch = &geombatches[curbatch->batch]) { - ushort len = curbatch->es.length[curbatch->va->shadowed ? 0 : 1]; + ushort len = curbatch->es.length[1]; if(len) { if(rendered < 0) { rendered = 0; gbatches++; } ushort minvert = curbatch->es.minvert[0], maxvert = curbatch->es.maxvert[0]; - if(!curbatch->va->shadowed) { minvert = min(minvert, curbatch->es.minvert[1]); maxvert = max(maxvert, curbatch->es.maxvert[1]); } + minvert = min(minvert, curbatch->es.minvert[1]); maxvert = max(maxvert, curbatch->es.maxvert[1]); drawtris(len, curbatch->edata, minvert, maxvert); vtris += len/3; } - if(curbatch->es.length[1] > len && !shadowed) shadowed = curbatch; - if(curbatch->batch < 0) break; - } - if(shadowed) for(geombatch *curbatch = shadowed;; curbatch = &geombatches[curbatch->batch]) { - if(curbatch->va->shadowed && curbatch->es.length[1] > curbatch->es.length[0]) { - if(rendered < 1) { - rendered = 1; - gbatches++; - } - ushort len = curbatch->es.length[1] - curbatch->es.length[0]; - drawtris(len, curbatch->edata + curbatch->es.length[0], curbatch->es.minvert[1], curbatch->es.maxvert[1]); - vtris += len/3; - } if(curbatch->batch < 0) break; } } @@ -854,10 +801,9 @@ void renderzpass(renderstate &cur, vtxarray *va) { if(cur.vbuf!=va->vbuf) changevbuf(cur, RENDERPASS_Z, va); if(!cur.depthmask) { cur.depthmask = true; glDepthMask(GL_TRUE); } if(cur.colormask) { cur.colormask = false; glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); } - int firsttex = 0, numtris = va->tris; + int numtris = va->tris; ushort *edata = va->edata; if(cur.alphaing) { - firsttex += va->texs + va->blends; edata += 3*(va->tris + va->blendtris); numtris = va->alphatris; xtravertsva += 3*numtris; @@ -891,10 +837,6 @@ void renderva(renderstate &cur, vtxarray *va, int pass = RENDERPASS_LIGHTMAP, bo switch(pass) { case RENDERPASS_LIGHTMAP: if(!cur.alphaing) vverts += va->verts; - va->shadowed = false; - if(!drawtex && !cur.alphaing) { - va->shadowed = isshadowmapreceiver(va); - } if(doquery) startvaquery(va, { if(geombatches.length()) renderbatches(cur, pass); }); mergetexs(cur, va); if(doquery) endvaquery(va, { if(geombatches.length()) renderbatches(cur, pass); }); @@ -939,17 +881,14 @@ VAR(oqgeom, 0, 1, 1); void rendergeom(void) { bool mainpass = !drawtex, doOQ = oqfrags && oqgeom && mainpass, - doZP = doOQ && zpass, - doSM = shadowmap && !drawtex; + doZP = doOQ && zpass; renderstate cur; if(mainpass) { flipqueries(); vtris = vverts = 0; } if(!doZP) { - if(shadowmap && mainpass) rendershadowmap(); setupgeom(); - if(doSM) pushshadowmap(); } resetbatches(); int blends = 0; @@ -974,8 +913,7 @@ void rendergeom(void) { } continue; } - } - else { + } else { va->query = NULL; va->occluded = OCCLUDE_NOTHING; } @@ -991,9 +929,7 @@ void rendergeom(void) { bool multipassing = false; if(doZP) { glFlush(); - if(shadowmap && mainpass) rendershadowmap(); setupgeom(); - if(doSM) pushshadowmap(); if(!multipassing) { multipassing = true; glDepthFunc(GL_LEQUAL); } cur.texgendim = -1; for(vtxarray *va = visibleva; va; va = va->next) { diff --git a/src/engine/shader.cpp b/src/engine/shader.cpp index eb10720..6d88f9f 100644 --- a/src/engine/shader.cpp +++ b/src/engine/shader.cpp @@ -302,7 +302,6 @@ void Shader::allocparams(Slot *slot) { tmu++; } else UNIFORMTEX("lightmap", 1); - UNIFORMTEX("shadowmap", 7); int stex = 0; loopv(slot->sts) { Slot::Tex &t = slot->sts[i]; @@ -622,56 +621,6 @@ static void gengenericvariant(Shader &s, const char *sname, const char *vs, cons newshader(s.type, varname, vschanged ? vsv.getbuf() : reuse, pschanged ? psv.getbuf() : reuse, &s, row); } -static void genshadowmapvariant(Shader &s, const char *sname, const char *vs, const char *ps, int row = 1) { - const char *vspragma = strstr(vs, "//:shadowmap"), *pspragma = strstr(ps, "//:shadowmap"); - if(!vspragma || !pspragma) return; - string pslight; - vspragma += strcspn(vspragma, "\n"); - if(*vspragma) vspragma++; - if(sscanf(pspragma, "//:shadowmap %100s", pslight)!=1) return; - pspragma += strcspn(pspragma, "\n"); - if(*pspragma) pspragma++; - const char *vsmain = findglslmain(vs), *psmain = findglslmain(ps); - if(vsmain > vspragma) vsmain = vs; - if(psmain > pspragma) psmain = ps; - vector<char> vssm, pssm; - if(vsmain >= vs) vssm.put(vs, vsmain - vs); - if(psmain >= ps) pssm.put(ps, psmain - ps); - const char *vsdecl = - "uniform mat4 shadowmapproject;\n" - "varying vec3 shadowmaptc;\n"; - vssm.put(vsdecl, strlen(vsdecl)); - const char *psdecl = - "uniform sampler2D shadowmap;\n" - "uniform vec4 shadowmapambient;\n" - "varying vec3 shadowmaptc;\n"; - pssm.put(psdecl, strlen(psdecl)); - vssm.put(vsmain, vspragma-vsmain); - pssm.put(psmain, pspragma-psmain); - extern int smoothshadowmappeel; - const char *tcgen = - "shadowmaptc = vec3(shadowmapproject * vvertex);\n"; - vssm.put(tcgen, strlen(tcgen)); - const char *sm = - smoothshadowmappeel ? - "vec4 smvals = texture2D(shadowmap, shadowmaptc.xy);\n" - "vec2 smdiff = clamp(smvals.xz - shadowmaptc.zz*smvals.y, 0.0, 1.0);\n" - "float shadowed = clamp((smdiff.x > 0.0 ? smvals.w : 0.0) - 8.0*smdiff.y, 0.0, 1.0);\n" : - "vec4 smvals = texture2D(shadowmap, shadowmaptc.xy);\n" - "float smtest = shadowmaptc.z*smvals.y;\n" - "float shadowed = smtest < smvals.x && smtest > smvals.z ? smvals.w : 0.0;\n"; - pssm.put(sm, strlen(sm)); - defformatstring(smlight, - "%s.rgb -= shadowed*clamp(%s.rgb - shadowmapambient.rgb, 0.0, 1.0);\n", - pslight, pslight); - pssm.put(smlight, strlen(smlight)); - vssm.put(vspragma, strlen(vspragma)+1); - pssm.put(pspragma, strlen(pspragma)+1); - defformatstring(name, "<shadowmap>%s", sname); - Shader *variant = newshader(s.type, name, vssm.getbuf(), pssm.getbuf(), &s, row); - if(!variant) return; -} - static void genuniformdefs(vector<char> &vsbuf, vector<char> &psbuf, const char *vs, const char *ps, Shader *variant = NULL) { if(variant ? variant->defaultparams.empty() : slotparams.empty()) return; const char *vsmain = findglslmain(vs), *psmain = findglslmain(ps); @@ -785,9 +734,6 @@ void shader(int *type, char *name, char *vs, char *ps) { } GENSHADER(slotparams.length(), genuniformdefs(vsbuf, psbuf, vs, ps)); Shader *s = newshader(*type, name, vs, ps); - if(s) { - if(strstr(vs, "//:shadowmap")) genshadowmapvariant(*s, s->name, vs, ps); - } slotparams.shrink(0); } diff --git a/src/engine/shadowmap.cpp b/src/engine/shadowmap.cpp deleted file mode 100644 index e86f65f..0000000 --- a/src/engine/shadowmap.cpp +++ /dev/null @@ -1,224 +0,0 @@ -#include "engine.h" -#include "rendertarget.h" - -VARP(shadowmap, 0, 0, 1); - -extern void cleanshadowmap(); -VARFP(shadowmapsize, 7, 9, 11, cleanshadowmap()); -VARP(shadowmapradius, 64, 96, 256); -VAR(shadowmapheight, 0, 32, 128); -VARP(shadowmapdist, 128, 256, 512); -VARFP(fpshadowmap, 0, 0, 1, cleanshadowmap()); -VARFP(shadowmapprecision, 0, 0, 1, cleanshadowmap()); -bvec shadowmapambientcolor(0, 0, 0); -HVARFR(shadowmapambient, 0, 0, 0xFFFFFF, { - if(shadowmapambient <= 255) shadowmapambient |= (shadowmapambient<<8) | (shadowmapambient<<16); - shadowmapambientcolor = bvec((shadowmapambient>>16)&0xFF, (shadowmapambient>>8)&0xFF, shadowmapambient&0xFF); -}); -VARP(shadowmapintensity, 0, 40, 100); - -VARP(blurshadowmap, 0, 1, 3); -VARP(blursmsigma, 1, 100, 200); - -#define SHADOWSKEW 0.7071068f - -vec shadowoffset(0, 0, 0), shadowfocus(0, 0, 0), shadowdir(0, SHADOWSKEW, 1); -VAR(shadowmapcasters, 1, 0, 0); -float shadowmapmaxz = 0; - -void setshadowdir(int angle) { - shadowdir = vec(0, SHADOWSKEW, 1); - shadowdir.rotate_around_z(angle*RAD); -} - -VARFR(shadowmapangle, 0, 0, 360, setshadowdir(shadowmapangle)); - -void guessshadowdir() { - if(shadowmapangle) return; - vec dir; { - vec lightpos(0, 0, 0), casterpos(0, 0, 0); - int numlights = 0, numcasters = 0; - const vector<extentity *> &ents = entities::getents(); - loopv(ents) { - extentity &e = *ents[i]; - switch(e.type) { - case ET_LIGHT: - if(!e.attr1) { lightpos.add(e.o); numlights++; } - break; - case ET_MAPMODEL: - casterpos.add(e.o); - numcasters++; - break; - default: - if(e.type<ET_GAMESPECIFIC) break; - casterpos.add(e.o); - numcasters++; - break; - } - } - if(!numlights || !numcasters) return; - lightpos.div(numlights); - casterpos.div(numcasters); - dir = vec(lightpos).sub(casterpos); - } - dir.z = 0; - if(dir.iszero()) return; - dir.normalize(); - dir.mul(SHADOWSKEW); - dir.z = 1; - shadowdir = dir; -} - -bool shadowmapping = false; - -matrix4 shadowmatrix; - -VARP(shadowmapbias, 0, 5, 1024); -VARP(shadowmappeelbias, 0, 20, 1024); -VAR(smdepthpeel, 0, 1, 1); -VAR(smoothshadowmappeel, 1, 0, 0); - -static struct shadowmaptexture : rendertarget { - const GLenum *colorformats() const { - static const GLenum rgbafmts[] = { GL_RGBA16F, GL_RGBA16, GL_RGBA, GL_RGBA8, GL_FALSE }; - return &rgbafmts[fpshadowmap && hasTF ? 0 : (shadowmapprecision ? 1 : 2)]; - } - bool swaptexs() const { return true; } - bool scissorblur(int &x, int &y, int &w, int &h) { - x = max(int(floor((scissorx1+1)/2*vieww)) - 2*blursize, 2); - y = max(int(floor((scissory1+1)/2*viewh)) - 2*blursize, 2); - w = min(int(ceil((scissorx2+1)/2*vieww)) + 2*blursize, vieww-2) - x; - h = min(int(ceil((scissory2+1)/2*viewh)) + 2*blursize, viewh-2) - y; - return true; - } - bool scissorrender(int &x, int &y, int &w, int &h) { - x = y = 2; - w = vieww - 2*2; - h = viewh - 2*2; - return true; - } - void doclear() { - glClearColor(0, 0, 0, 0); - glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); - } - bool dorender() { - vec skewdir(shadowdir); - skewdir.rotate_around_z(-camera1->yaw*RAD); - vec dir; - vecfromyawpitch(camera1->yaw, camera1->pitch, 1, 0, dir); - dir.z = 0; - dir.mul(shadowmapradius); - vec dirx, diry; - vecfromyawpitch(camera1->yaw, 0, 0, 1, dirx); - vecfromyawpitch(camera1->yaw, 0, 1, 0, diry); - shadowoffset.x = -fmod(dirx.dot(camera1->o) - skewdir.x*camera1->o.z, 2.0f*shadowmapradius/vieww); - shadowoffset.y = -fmod(diry.dot(camera1->o) - skewdir.y*camera1->o.z, 2.0f*shadowmapradius/viewh); - shadowmatrix.ortho(-shadowmapradius, shadowmapradius, -shadowmapradius, shadowmapradius, -shadowmapdist, shadowmapdist); - shadowmatrix.mul(matrix3(vec(1, 0, 0), vec(0, 1, 0), vec(skewdir.x, skewdir.y, 1))); - shadowmatrix.translate(skewdir.x*shadowmapheight + shadowoffset.x, skewdir.y*shadowmapheight + shadowoffset.y + dir.magnitude(), -shadowmapheight); - shadowmatrix.rotate_around_z((camera1->yaw+180)*-RAD); - shadowmatrix.translate(vec(camera1->o).neg()); - GLOBALPARAM(shadowmatrix, shadowmatrix); - shadowfocus = camera1->o; - shadowfocus.add(dir); - shadowfocus.add(vec(shadowdir).mul(shadowmapheight)); - shadowfocus.add(dirx.mul(shadowoffset.x)); - shadowfocus.add(diry.mul(shadowoffset.y)); - gle::colorf(0, 0, 0); - GLOBALPARAMF(shadowmapbias, -shadowmapbias/float(shadowmapdist), 1 - (shadowmapbias + (smoothshadowmappeel ? 0 : shadowmappeelbias))/float(shadowmapdist)); - shadowmapcasters = 0; - shadowmapmaxz = shadowfocus.z - shadowmapdist; - shadowmapping = true; - rendergame(); - shadowmapping = false; - shadowmapmaxz = min(shadowmapmaxz, shadowfocus.z); - if(shadowmapcasters && smdepthpeel) { - int sx, sy, sw, sh; - bool scissoring = rtscissor && scissorblur(sx, sy, sw, sh) && sw > 0 && sh > 0; - if(scissoring) glScissor(sx, sy, sw, sh); - if(!rtscissor || scissoring) rendershadowmapreceivers(); - } - return shadowmapcasters>0; - } -} shadowmaptex; - -void cleanshadowmap() { - shadowmaptex.cleanup(true); -} - -void calcshadowmapbb(const vec &o, float xyrad, float zrad, float &x1, float &y1, float &x2, float &y2) { - vec skewdir(shadowdir); - skewdir.rotate_around_z(-camera1->yaw*RAD); - vec ro(o); - ro.sub(camera1->o); - ro.rotate_around_z(-(camera1->yaw+180)*RAD); - ro.x += ro.z * skewdir.x + shadowoffset.x; - ro.y += ro.z * skewdir.y + shadowmapradius * cosf(camera1->pitch*RAD) + shadowoffset.y; - vec high(ro), low(ro); - high.x += zrad * skewdir.x; - high.y += zrad * skewdir.y; - low.x -= zrad * skewdir.x; - low.y -= zrad * skewdir.y; - x1 = (min(high.x, low.x) - xyrad) / shadowmapradius; - y1 = (min(high.y, low.y) - xyrad) / shadowmapradius; - x2 = (max(high.x, low.x) + xyrad) / shadowmapradius; - y2 = (max(high.y, low.y) + xyrad) / shadowmapradius; -} - -bool addshadowmapcaster(const vec &o, float xyrad, float zrad) { - if(o.z + zrad <= shadowfocus.z - shadowmapdist || o.z - zrad >= shadowfocus.z) return false; - shadowmapmaxz = max(shadowmapmaxz, o.z + zrad); - float x1, y1, x2, y2; - calcshadowmapbb(o, xyrad, zrad, x1, y1, x2, y2); - if(!shadowmaptex.addblurtiles(x1, y1, x2, y2, 2)) return false; - shadowmapcasters++; - return true; -} - -bool isshadowmapreceiver(vtxarray *va) { - if(!shadowmap || !shadowmapcasters) return false; - if(va->shadowmapmax.z <= shadowfocus.z - shadowmapdist || va->shadowmapmin.z >= shadowmapmaxz) return false; - float xyrad = SQRT2*0.5f*max(va->shadowmapmax.x-va->shadowmapmin.x, va->shadowmapmax.y-va->shadowmapmin.y), - zrad = 0.5f*(va->shadowmapmax.z-va->shadowmapmin.z), - x1, y1, x2, y2; - if(xyrad<0 || zrad<0) return false; - vec center = vec(va->shadowmapmin).add(vec(va->shadowmapmax)).mul(0.5f); - calcshadowmapbb(center, xyrad, zrad, x1, y1, x2, y2); - return shadowmaptex.checkblurtiles(x1, y1, x2, y2, 2); -} - -bool isshadowmapcaster(const vec &o, float rad) { - // cheaper inexact test - float dz = o.z - shadowfocus.z; - float cx = shadowfocus.x + dz*shadowdir.x, cy = shadowfocus.y + dz*shadowdir.y; - float skew = rad*SHADOWSKEW; - if(!shadowmapping || - o.z + rad <= shadowfocus.z - shadowmapdist || o.z - rad >= shadowfocus.z || - o.x + rad <= cx - shadowmapradius-skew || o.x - rad >= cx + shadowmapradius+skew || - o.y + rad <= cy - shadowmapradius-skew || o.y - rad >= cy + shadowmapradius+skew) - return false; - return true; -} - -void pushshadowmap() { - if(!shadowmap || !shadowmaptex.rendertex) return; - glActiveTexture_(GL_TEXTURE7); - glBindTexture(GL_TEXTURE_2D, shadowmaptex.rendertex); - matrix4 m = shadowmatrix; - m.projective(-1, 1-shadowmapbias/float(shadowmapdist)); - GLOBALPARAM(shadowmapproject, m); - glActiveTexture_(GL_TEXTURE0); - float r, g, b; - if(!shadowmapambient) { - r = max(25.0f, 2.0f*ambientcolor[0]); - g = max(25.0f, 2.0f*ambientcolor[1]); - b = max(25.0f, 2.0f*ambientcolor[2]); - } - else { r = shadowmapambientcolor[0]; g = shadowmapambientcolor[1]; b = shadowmapambientcolor[2]; } - GLOBALPARAMF(shadowmapambient, r/255.0f, g/255.0f, b/255.0f); -} - -void rendershadowmap() { - if(!shadowmap) return; - shadowmaptex.render(1<<shadowmapsize, 1<<shadowmapsize, blurshadowmap, blursmsigma/100.0f); -} diff --git a/src/engine/skelmodel.h b/src/engine/skelmodel.h index 140acf8..dfa0f69 100644 --- a/src/engine/skelmodel.h +++ b/src/engine/skelmodel.h @@ -93,13 +93,9 @@ struct skelmodel : animmodel { float pitch; int millis; uchar *partmask; - ragdolldata *ragdoll; - animcacheentry() : ragdoll(NULL) { - loopk(MAXANIMPARTS) as[k].cur.fr1 = as[k].prev.fr1 = -1; - } bool operator==(const animcacheentry &c) const { loopi(MAXANIMPARTS) if(as[i]!=c.as[i]) return false; - return pitch==c.pitch && partmask==c.partmask && ragdoll==c.ragdoll && (!ragdoll || min(millis, c.millis) >= ragdoll->lastmove); + return pitch==c.pitch && partmask==c.partmask; } }; struct vbocacheentry : animcacheentry { @@ -160,14 +156,6 @@ struct skelmodel : animmodel { } } } - void genBIH(BIH::mesh &m) { - m.tris = (const BIH::tri *)tris; - m.numtris = numtris; - m.pos = (const uchar *)&verts->pos; - m.posstride = sizeof(vert); - m.tc = (const uchar *)&verts->tc; - m.tcstride = sizeof(vert); - } static inline void assignvert(vvertn &vv, int j, vert &v, blendcombo &c) { (void)j;(void)c; vv.pos = v.pos; @@ -312,10 +300,10 @@ struct skelmodel : animmodel { }; struct boneinfo { const char *name; - int parent, children, next, group, scheduled, interpindex, interpparent, ragdollindex, correctindex; + int parent, children, next, group, scheduled, interpindex, interpparent, correctindex; float pitchscale, pitchoffset, pitchmin, pitchmax; dualquat base, invbase; - boneinfo() : name(NULL), parent(-1), children(-1), next(-1), group(INT_MAX), scheduled(-1), interpindex(-1), interpparent(-1), ragdollindex(-1), correctindex(-1), pitchscale(0), pitchoffset(0), pitchmin(0), pitchmax(0) {} + boneinfo() : name(NULL), parent(-1), children(-1), next(-1), group(INT_MAX), scheduled(-1), interpindex(-1), interpparent(-1), correctindex(-1), pitchscale(0), pitchoffset(0), pitchmin(0), pitchmax(0) {} ~boneinfo() { DELETEA(name); } @@ -348,20 +336,18 @@ struct skelmodel : animmodel { vector<skelanimspec> skelanims; vector<tag> tags; vector<antipode> antipodes; - ragdollskel *ragdoll; vector<pitchdep> pitchdeps; vector<pitchtarget> pitchtargets; vector<pitchcorrect> pitchcorrects; bool usegpuskel; vector<skelcacheentry> skelcache; hashtable<GLuint, int> blendoffsets; - skeleton() : name(NULL), shared(0), bones(NULL), numbones(0), numinterpbones(0), numgpubones(0), numframes(0), framebones(NULL), ragdoll(NULL), usegpuskel(false), blendoffsets(32) { + skeleton() : name(NULL), shared(0), bones(NULL), numbones(0), numinterpbones(0), numgpubones(0), numframes(0), framebones(NULL), usegpuskel(false), blendoffsets(32) { } ~skeleton() { DELETEA(name); DELETEA(bones); DELETEA(framebones); - DELETEP(ragdoll); loopv(skelcache) { DELETEA(skelcache[i].bdata); } @@ -440,7 +426,6 @@ struct skelmodel : animmodel { loopi(numbones) { boneinfo &info = bones[i]; info.interpindex = -1; - info.ragdollindex = -1; } numgpubones = 0; loopv(users) { @@ -471,13 +456,6 @@ struct skelmodel : animmodel { boneinfo &info = bones[tags[i].bone]; if(info.interpindex < 0) info.interpindex = numinterpbones++; } - if(ragdoll) { - loopv(ragdoll->joints) { - boneinfo &info = bones[ragdoll->joints[i].bone]; - if(info.interpindex < 0) info.interpindex = numinterpbones++; - info.ragdollindex = i; - } - } loopi(numbones) { boneinfo &info = bones[i]; if(info.interpindex < 0) continue; @@ -489,15 +467,6 @@ struct skelmodel : animmodel { if(info.interpindex < 0) continue; info.interpparent = info.parent >= 0 ? bones[info.parent].interpindex : -1; } - if(ragdoll) { - loopi(numbones) { - boneinfo &info = bones[i]; - if(info.interpindex < 0 || info.ragdollindex >= 0) continue; - for(int parent = info.parent; parent >= 0; parent = bones[parent].parent) { - if(bones[parent].ragdollindex >= 0) { ragdoll->addreljoint(i, bones[parent].ragdollindex); break; } - } - } - } calcantipodes(); } @@ -572,7 +541,6 @@ struct skelmodel : animmodel { } void optimize() { cleanup(); - if(ragdoll) ragdoll->setup(); remapbones(); initpitchdeps(); } @@ -694,56 +662,6 @@ struct skelmodel : animmodel { } loopv(antipodes) sc.bdata[antipodes[i].child].fixantipodal(sc.bdata[antipodes[i].parent]); } - void initragdoll(ragdolldata &d, skelcacheentry &sc, part *p) { - const dualquat *bdata = sc.bdata; - loopv(ragdoll->joints) { - const ragdollskel::joint &j = ragdoll->joints[i]; - const boneinfo &b = bones[j.bone]; - const dualquat &q = bdata[b.interpindex]; - loopk(3) if(j.vert[k] >= 0) { - ragdollskel::vert &v = ragdoll->verts[j.vert[k]]; - ragdolldata::vert &dv = d.verts[j.vert[k]]; - dv.pos.add(q.transform(v.pos).mul(v.weight)); - } - } - if(ragdoll->animjoints) loopv(ragdoll->joints) { - const ragdollskel::joint &j = ragdoll->joints[i]; - const boneinfo &b = bones[j.bone]; - const dualquat &q = bdata[b.interpindex]; - d.calcanimjoint(i, matrix4x3(q)); - } - loopv(ragdoll->verts) { - ragdolldata::vert &dv = d.verts[i]; - matrixstack[matrixpos].transform(vec(dv.pos).add(p->translate).mul(p->model->scale), dv.pos); - } - loopv(ragdoll->reljoints) { - const ragdollskel::reljoint &r = ragdoll->reljoints[i]; - const ragdollskel::joint &j = ragdoll->joints[r.parent]; - const boneinfo &br = bones[r.bone], &bj = bones[j.bone]; - d.reljoints[i].mul(dualquat(bdata[bj.interpindex]).invert(), bdata[br.interpindex]); - } - } - void genragdollbones(ragdolldata &d, skelcacheentry &sc, part *p) { - if(!sc.bdata) sc.bdata = new dualquat[numinterpbones]; - sc.nextversion(); - loopv(ragdoll->joints) { - const ragdollskel::joint &j = ragdoll->joints[i]; - const boneinfo &b = bones[j.bone]; - vec pos(0, 0, 0); - loopk(3) if(j.vert[k]>=0) pos.add(d.verts[j.vert[k]].pos); - pos.mul(j.weight/p->model->scale).sub(p->translate); - matrix4x3 m; - m.mul(d.tris[j.tri], pos, d.animjoints ? d.animjoints[i] : j.orient); - sc.bdata[b.interpindex] = dualquat(m); - } - loopv(ragdoll->reljoints) { - const ragdollskel::reljoint &r = ragdoll->reljoints[i]; - const ragdollskel::joint &j = ragdoll->joints[r.parent]; - const boneinfo &br = bones[r.bone], &bj = bones[j.bone]; - sc.bdata[br.interpindex].mul(sc.bdata[bj.interpindex], d.reljoints[i]); - } - loopv(antipodes) sc.bdata[antipodes[i].child].fixantipodal(sc.bdata[antipodes[i].parent]); - } void concattagtransform(part *p, int i, const matrix4x3 &m, matrix4x3 &n) { (void)i;(void)m;(void)n;(void)p; matrix4x3 t; @@ -781,7 +699,8 @@ struct skelmodel : animmodel { usegpuskel = gpuaccelerate(); } } - skelcacheentry &checkskelcache(part *p, const animstate *as, float pitch, const vec &axis, const vec &forward, ragdolldata *rdata) { + skelcacheentry &checkskelcache(part *p, const animstate *as, float pitch, const vec &axis, const vec &forward) { + (void) p; if(skelcache.empty()) { usegpuskel = gpuaccelerate(); } @@ -792,7 +711,7 @@ struct skelmodel : animmodel { loopv(skelcache) { skelcacheentry &c = skelcache[i]; loopj(numanimparts) if(c.as[j]!=as[j]) goto mismatch; - if(c.pitch != pitch || c.partmask != partmask || c.ragdoll != rdata || (rdata && c.millis < rdata->lastmove)) goto mismatch; + if(c.pitch != pitch || c.partmask != partmask) goto mismatch; match = true; sc = &c; break; @@ -804,9 +723,7 @@ struct skelmodel : animmodel { loopi(numanimparts) sc->as[i] = as[i]; sc->pitch = pitch; sc->partmask = partmask; - sc->ragdoll = rdata; - if(rdata) genragdollbones(*rdata, *sc, p); - else interpbones(as, pitch, axis, forward, numanimparts, partmask, *sc); + interpbones(as, pitch, axis, forward, numanimparts, partmask, *sc); } sc->millis = lastmillis; return *sc; @@ -1117,7 +1034,7 @@ struct skelmodel : animmodel { skel->calctags(p); return; } - skelcacheentry &sc = skel->checkskelcache(p, as, pitch, axis, forward, as->cur.anim&ANIM_RAGDOLL || !d || !d->ragdoll || d->ragdoll->skel != skel->ragdoll ? NULL : d->ragdoll); + skelcacheentry &sc = skel->checkskelcache(p, as, pitch, axis, forward); if(!(as->cur.anim&ANIM_NORENDER)) { int owner = &sc-&skel->skelcache[0]; vbocacheentry &vc = skel->usegpuskel ? *vbocache : checkvbocache(sc, owner); @@ -1152,11 +1069,6 @@ struct skelmodel : animmodel { } } skel->calctags(p, &sc); - if(as->cur.anim&ANIM_RAGDOLL && skel->ragdoll && !d->ragdoll) { - d->ragdoll = new ragdolldata(skel->ragdoll, p->model->scale); - skel->initragdoll(*d->ragdoll, sc, p); - d->ragdoll->init(d); - } } }; struct animpartmask { @@ -1429,4 +1341,3 @@ template<class MDL> struct skelcommands : modelcommands<MDL, struct MDL::skelmes } } }; - diff --git a/src/engine/texture.cpp b/src/engine/texture.cpp index e372815..24c5230 100644 --- a/src/engine/texture.cpp +++ b/src/engine/texture.cpp @@ -1832,13 +1832,11 @@ static void addname(vector<char> &key, Slot::Tex &t, bool combined = false, cons static void texcombine(Slot &s, int index, Slot::Tex &t, bool forceload = false) { vector<char> key; addname(key, t); - int texmask = 0; if(!forceload) switch(t.type) { case TEX_DIFFUSE: case TEX_NORMAL: { int i = findtextype(s, t.type==TEX_DIFFUSE ? (s.texmask&(1<<TEX_SPEC) ? 1<<TEX_SPEC : 1<<TEX_ALPHA) : (s.texmask&(1<<TEX_DEPTH) ? 1<<TEX_DEPTH : 1<<TEX_ALPHA)); if(i<0) break; - texmask |= 1<<s.sts[i].type; s.sts[i].combined = index; addname(key, s.sts[i], true); break; diff --git a/src/engine/texture.h b/src/engine/texture.h index ef5a57b..371e223 100644 --- a/src/engine/texture.h +++ b/src/engine/texture.h @@ -256,7 +256,7 @@ struct GlobalShaderParam { g->uval[3] = w; } template<class T> - T *reserve(int n = 1) { return (T *)resolve()->buf; } + T *reserve(int n = 1) { (void)n;return (T *)resolve()->buf; } }; struct LocalShaderParam { diff --git a/src/engine/world.cpp b/src/engine/world.cpp index d2941d0..a410c69 100644 --- a/src/engine/world.cpp +++ b/src/engine/world.cpp @@ -323,7 +323,6 @@ void entselectionbox(const entity &e, vec &eo, vec &es) { } VAR(entselsnap, 0, 0, 1); -VAR(entmovingshadow, 0, 1, 1); extern void boxs(int orient, vec o, const vec &s, float size); extern void boxs(int orient, vec o, const vec &s); @@ -475,7 +474,7 @@ void renderentselection(bool entmoving) { gle::colorub(0, 40, 0); entfocus(enthover, entselectionbox(e, eo, es)); // also ensures enthover is back in focus boxs3D(eo, es, 1); - if(entmoving && entmovingshadow==1) { + if(entmoving) { vec a, b; gle::colorub(20, 20, 20); (a = eo).x = eo.x - fmod(eo.x, worldsize); (b = es).x = a.x + worldsize; boxs3D(a, b, 1); |
