diff options
| author | xolatile | 2025-07-20 12:18:48 +0200 |
|---|---|---|
| committer | xolatile | 2025-07-20 12:18:48 +0200 |
| commit | c46daa31f8e0339aed12736699d0003d27f1fc7e (patch) | |
| tree | 11083f9c5eced31cf246c5feadc2c96d66e165cb /src/engine | |
| parent | e9ad09c58820b31743251f793f30e5d4d49a0dca (diff) | |
| download | xolatile-badassbug-c46daa31f8e0339aed12736699d0003d27f1fc7e.tar.xz xolatile-badassbug-c46daa31f8e0339aed12736699d0003d27f1fc7e.tar.zst | |
Most warnings fixed, ignoring one warning for now...
Diffstat (limited to 'src/engine')
| -rw-r--r-- | src/engine/decal.cpp | 46 | ||||
| -rw-r--r-- | src/engine/engine.h.gch | bin | 78745159 -> 0 bytes | |||
| -rw-r--r-- | src/engine/iqm.h | 396 | ||||
| -rw-r--r-- | src/engine/main.cpp | 17 | ||||
| -rw-r--r-- | src/engine/md3.h | 24 | ||||
| -rw-r--r-- | src/engine/model.h | 2 | ||||
| -rw-r--r-- | src/engine/obj.h | 191 | ||||
| -rw-r--r-- | src/engine/physics.cpp | 2 | ||||
| -rw-r--r-- | src/engine/rendergl.cpp | 9 | ||||
| -rw-r--r-- | src/engine/rendermodel.cpp | 4 | ||||
| -rw-r--r-- | src/engine/worldio.cpp | 102 |
11 files changed, 440 insertions, 353 deletions
diff --git a/src/engine/decal.cpp b/src/engine/decal.cpp index 98787dd..fb70ebf 100644 --- a/src/engine/decal.cpp +++ b/src/engine/decal.cpp @@ -73,7 +73,7 @@ struct decalrenderer maxdecals = tris; tex = textureload(texname, 3); maxverts = tris*3 + 3; - availverts = maxverts - 3; + availverts = maxverts - 3; verts = new decalvert[maxverts]; } @@ -102,7 +102,7 @@ struct decalrenderer decalinfo &d = decals[startdecal]; startdecal++; if(startdecal >= maxdecals) startdecal = 0; - + int removed = d.endvert < d.startvert ? maxverts - (d.startvert - d.endvert) : d.endvert - d.startvert; startvert = d.endvert; if(startvert==endvert) startvert = endvert = lastvert = 0; @@ -123,7 +123,7 @@ struct decalrenderer bvec4 color(rgb, alpha); decalvert *vert = &verts[d.startvert], - *end = &verts[d.endvert < d.startvert ? maxverts : d.endvert]; + *end = &verts[d.endvert < d.startvert ? maxverts : d.endvert]; while(vert < end) { vert->color = color; @@ -162,7 +162,7 @@ struct decalrenderer availverts = endvert < startvert ? startvert - endvert - 3 : maxverts - 3 - (endvert - startvert); dirty = true; } - + void fadeindecals() { if(!fadeintime) return; @@ -214,7 +214,7 @@ struct decalrenderer } } } - + static void setuprenderstate() { enablepolygonoffset(GL_POLYGON_OFFSET_FILL); @@ -245,12 +245,12 @@ struct decalrenderer { if(startvert==endvert) return; - if(flags&DF_OVERBRIGHT) + if(flags&DF_OVERBRIGHT) { - glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); + glBlendFunc(GL_DST_COLOR, GL_SRC_COLOR); SETSHADER(overbrightdecal); } - else + else { if(flags&DF_INVMOD) { glBlendFunc(GL_ZERO, GL_ONE_MINUS_SRC_COLOR); zerofogcolor(); } else if(flags&DF_ADD) { glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_COLOR); zerofogcolor(); } @@ -264,7 +264,7 @@ struct decalrenderer if(!vbo) { glGenBuffers_(1, &vbo); dirty = true; } gle::bindvbo(vbo); - + int count = endvert < startvert ? maxverts - startvert : endvert - startvert; if(dirty) { @@ -388,9 +388,9 @@ struct decalrenderer void gentris(cube &cu, int orient, const ivec &o, int size, materialsurface *mat = NULL, int vismask = 0) { - vec pos[MAXFACEVERTS+4]; + vec pos[MAXFACEVERTS+4] = { vec(0, 0, 0) }; int numverts = 0, numplanes = 1; - vec planes[2]; + vec planes[2] = { vec(0, 0, 0) }; if(mat) { planes[0] = vec(0, 0, 0); @@ -405,7 +405,7 @@ struct decalrenderer pos[numverts++] = vec(x xv, y yv, z zv); GENFACEVERTS(o.x, o.x, o.y, o.y, o.z, o.z, , + mat->csize, , + mat->rsize, + 0.1f, - 0.1f); #undef GENFACEORIENT - #undef GENFACEVERT + #undef GENFACEVERT } } else if(cu.texture[orient] == DEFAULT_SKY) return; @@ -434,7 +434,7 @@ struct decalrenderer if(vis&2) pos[numverts++] = vec(v[(order+3)&3]).mul(size/8.0f).add(vo); planes[0].cross(pos[0], pos[1], pos[2]).normalize(); if(convex) { planes[1].cross(pos[0], pos[2], pos[3]).normalize(); numplanes++; } - } + } else return; loopl(numplanes) @@ -467,7 +467,7 @@ struct decalrenderer int numv; if(numplanes >= 2) { - if(l) { pos[1] = pos[2]; pos[2] = pos[3]; } + if(l) { pos[1] = pos[2]; pos[2] = pos[3]; } numv = clip(pos, 3, pt, ptc - decalradius, ptc + decalradius, v1); if(numv<3) continue; } @@ -521,13 +521,13 @@ struct decalrenderer m.o[r] + m.rsize >= bbmin[r] && m.o[r] <= bbmax[r]) { static cube dummy; - gentris(dummy, m.orient, m.o, max(m.csize, m.rsize), &m); + gentris(dummy, m.orient, m.o, max(m.csize, m.rsize), &m); } if(i+1 >= matsurfs) break; materialsurface &n = matbuf[i+1]; if(n.material != m.material || n.orient != m.orient) break; i++; - } + } } } @@ -535,8 +535,8 @@ struct decalrenderer { loopi(8) { - if(escaped&(1<<i)) - { + if(escaped&(1<<i)) + { ivec co(i, o, size); if(cu[i].children) findescaped(cu[i].children, co, size>>1, cu[i].escaped); else @@ -544,14 +544,14 @@ struct decalrenderer int vismask = cu[i].merged; if(vismask) loopj(6) if(vismask&(1<<j)) gentris(cu[i], j, co, size); } - } + } } } void gentris(cube *cu, const ivec &o, int size, int escaped = 0) { int overlap = octaboxoverlap(o, size, bbmin, bbmax); - loopi(8) + loopi(8) { if(overlap&(1<<i)) { @@ -559,7 +559,7 @@ struct decalrenderer if(cu[i].ext && cu[i].ext->va && cu[i].ext->va->matsurfs) findmaterials(cu[i].ext->va); if(cu[i].children) gentris(cu[i].children, co, size>>1, cu[i].escaped); - else + else { int vismask = cu[i].visible; if(vismask&0xC0) @@ -578,7 +578,7 @@ struct decalrenderer int vismask = cu[i].merged; if(vismask) loopj(6) if(vismask&(1<<j)) gentris(cu[i], j, co, size); } - } + } } } }; @@ -639,4 +639,4 @@ void adddecal(int type, const vec ¢er, const vec &surface, float radius, con decalrenderer &d = decals[type]; d.adddecal(center, surface, radius, color, info); } - + diff --git a/src/engine/engine.h.gch b/src/engine/engine.h.gch Binary files differdeleted file mode 100644 index 372a18b..0000000 --- a/src/engine/engine.h.gch +++ /dev/null diff --git a/src/engine/iqm.h b/src/engine/iqm.h new file mode 100644 index 0000000..f426a6b --- /dev/null +++ b/src/engine/iqm.h @@ -0,0 +1,396 @@ +struct iqm; + +struct iqmheader +{ + char magic[16]; + uint version; + uint filesize; + uint flags; + uint num_text, ofs_text; + uint num_meshes, ofs_meshes; + uint num_vertexarrays, num_vertexes, ofs_vertexarrays; + uint num_triangles, ofs_triangles, ofs_adjacency; + uint num_joints, ofs_joints; + uint num_poses, ofs_poses; + uint num_anims, ofs_anims; + uint num_frames, num_framechannels, ofs_frames, ofs_bounds; + uint num_comment, ofs_comment; + uint num_extensions, ofs_extensions; +}; + +struct iqmmesh +{ + uint name; + uint material; + uint first_vertex, num_vertexes; + uint first_triangle, num_triangles; +}; + +enum +{ + IQM_POSITION = 0, + IQM_TEXCOORD = 1, + IQM_NORMAL = 2, + IQM_TANGENT = 3, + IQM_BLENDINDEXES = 4, + IQM_BLENDWEIGHTS = 5, + IQM_COLOR = 6, + IQM_CUSTOM = 0x10 +}; + +enum +{ + IQM_BYTE = 0, + IQM_UBYTE = 1, + IQM_SHORT = 2, + IQM_USHORT = 3, + IQM_INT = 4, + IQM_UINT = 5, + IQM_HALF = 6, + IQM_FLOAT = 7, + IQM_DOUBLE = 8, +}; + +struct iqmtriangle +{ + uint vertex[3]; +}; + +struct iqmjoint +{ + uint name; + int parent; + vec pos; + quat orient; + vec size; +}; + +struct iqmpose +{ + int parent; + uint mask; + vec offsetpos; + vec4 offsetorient; + vec offsetsize; + vec scalepos; + vec4 scaleorient; + vec scalesize; +}; + +struct iqmanim +{ + uint name; + uint first_frame, num_frames; + float framerate; + uint flags; +}; + +struct iqmvertexarray +{ + uint type; + uint flags; + uint format; + uint size; + uint offset; +}; + +struct iqm : skelloader<iqm> +{ + iqm(const char *name) : skelloader(name) {} + + static const char *formatname() { return "iqm"; } + int type() const { return MDL_IQM; } + + struct iqmmeshgroup : skelmeshgroup + { + iqmmeshgroup() + { + } + + bool loadiqmmeshes(const char *filename, const iqmheader &hdr, uchar *buf) + { + lilswap((uint *)&buf[hdr.ofs_vertexarrays], hdr.num_vertexarrays*sizeof(iqmvertexarray)/sizeof(uint)); + lilswap((uint *)&buf[hdr.ofs_triangles], hdr.num_triangles*sizeof(iqmtriangle)/sizeof(uint)); + lilswap((uint *)&buf[hdr.ofs_meshes], hdr.num_meshes*sizeof(iqmmesh)/sizeof(uint)); + lilswap((uint *)&buf[hdr.ofs_joints], hdr.num_joints*sizeof(iqmjoint)/sizeof(uint)); + + const char *str = hdr.ofs_text ? (char *)&buf[hdr.ofs_text] : ""; + float *vpos = NULL, *vnorm = NULL, *vtan = NULL, *vtc = NULL; + uchar *vindex = NULL, *vweight = NULL; + iqmvertexarray *vas = (iqmvertexarray *)&buf[hdr.ofs_vertexarrays]; + loopi(hdr.num_vertexarrays) + { + iqmvertexarray &va = vas[i]; + switch(va.type) + { + case IQM_POSITION: if(va.format != IQM_FLOAT || va.size != 3) return false; vpos = (float *)&buf[va.offset]; lilswap(vpos, 3*hdr.num_vertexes); break; + case IQM_NORMAL: if(va.format != IQM_FLOAT || va.size != 3) return false; vnorm = (float *)&buf[va.offset]; lilswap(vnorm, 3*hdr.num_vertexes); break; + case IQM_TANGENT: if(va.format != IQM_FLOAT || va.size != 4) return false; vtan = (float *)&buf[va.offset]; lilswap(vtan, 4*hdr.num_vertexes); break; + case IQM_TEXCOORD: if(va.format != IQM_FLOAT || va.size != 2) return false; vtc = (float *)&buf[va.offset]; lilswap(vtc, 2*hdr.num_vertexes); break; + case IQM_BLENDINDEXES: if(va.format != IQM_UBYTE || va.size != 4) return false; vindex = (uchar *)&buf[va.offset]; break; + case IQM_BLENDWEIGHTS: if(va.format != IQM_UBYTE || va.size != 4) return false; vweight = (uchar *)&buf[va.offset]; break; + } + } + if(!vpos) return false; + + iqmtriangle *tris = (iqmtriangle *)&buf[hdr.ofs_triangles]; + iqmmesh *imeshes = (iqmmesh *)&buf[hdr.ofs_meshes]; + iqmjoint *joints = (iqmjoint *)&buf[hdr.ofs_joints]; + + if(hdr.num_joints) + { + if(skel->numbones <= 0) + { + skel->numbones = hdr.num_joints; + skel->bones = new boneinfo[skel->numbones]; + loopi(hdr.num_joints) + { + iqmjoint &j = joints[i]; + boneinfo &b = skel->bones[i]; + if(!b.name) b.name = newstring(&str[j.name]); + b.parent = j.parent; + if(skel->shared <= 1) + { + j.pos.y = -j.pos.y; + j.orient.x = -j.orient.x; + j.orient.z = -j.orient.z; + j.orient.normalize(); + b.base = dualquat(j.orient, j.pos); + if(b.parent >= 0) b.base.mul(skel->bones[b.parent].base, dualquat(b.base)); + (b.invbase = b.base).invert(); + } + } + } + + if(skel->shared <= 1) + skel->linkchildren(); + } + + loopi(hdr.num_meshes) + { + iqmmesh &im = imeshes[i]; + skelmesh *m = new skelmesh; + m->group = this; + meshes.add(m); + m->name = newstring(&str[im.name]); + m->numverts = im.num_vertexes; + int noblend = -1; + if(m->numverts) + { + m->verts = new vert[m->numverts]; + if(vtan) m->bumpverts = new bumpvert[m->numverts]; + if(!vindex || !vweight) + { + blendcombo c; + c.finalize(0); + noblend = m->addblendcombo(c); + } + } + int fv = im.first_vertex; + float *mpos = vpos + 3*fv, + *mnorm = vnorm ? vnorm + 3*fv : NULL, + *mtan = vtan ? vtan + 4*fv : NULL, + *mtc = vtc ? vtc + 2*fv : NULL; + uchar *mindex = vindex ? vindex + 4*fv : NULL, *mweight = vweight ? vweight + 4*fv : NULL; + loopj(im.num_vertexes) + { + vert &v = m->verts[j]; + v.pos = vec(mpos[0], -mpos[1], mpos[2]); + mpos += 3; + if(mtc) + { + v.tc = vec2(mtc[0], mtc[1]); + mtc += 2; + } + else v.tc = vec2(0, 0); + if(mnorm) + { + v.norm = vec(mnorm[0], -mnorm[1], mnorm[2]); + mnorm += 3; + if(mtan) + { + m->calctangent(m->bumpverts[j], v.norm, vec(mtan[0], -mtan[1], mtan[2]), mtan[3]); + mtan += 4; + } + } + else v.norm = vec(0, 0, 0); + if(noblend < 0) + { + blendcombo c; + int sorted = 0; + loopk(4) sorted = c.addweight(sorted, mweight[k], mindex[k]); + mweight += 4; + mindex += 4; + c.finalize(sorted); + v.blend = m->addblendcombo(c); + } + else v.blend = noblend; + } + m->numtris = im.num_triangles; + if(m->numtris) m->tris = new tri[m->numtris]; + iqmtriangle *mtris = tris + im.first_triangle; + loopj(im.num_triangles) + { + tri &t = m->tris[j]; + t.vert[0] = mtris->vertex[0] - fv; + t.vert[1] = mtris->vertex[1] - fv; + t.vert[2] = mtris->vertex[2] - fv; + ++mtris; + } + if(!m->numtris || !m->numverts) + { + conoutf(CON_WARN, "empty mesh in %s", filename); + meshes.removeobj(m); + delete m; + } + } + + sortblendcombos(); + + return true; + } + + bool loadiqmanims(const char *filename, const iqmheader &hdr, uchar *buf) + { + lilswap((uint *)&buf[hdr.ofs_poses], hdr.num_poses*sizeof(iqmpose)/sizeof(uint)); + lilswap((uint *)&buf[hdr.ofs_anims], hdr.num_anims*sizeof(iqmanim)/sizeof(uint)); + lilswap((ushort *)&buf[hdr.ofs_frames], hdr.num_frames*hdr.num_framechannels); + + const char *str = hdr.ofs_text ? (char *)&buf[hdr.ofs_text] : ""; + iqmpose *poses = (iqmpose *)&buf[hdr.ofs_poses]; + iqmanim *anims = (iqmanim *)&buf[hdr.ofs_anims]; + ushort *frames = (ushort *)&buf[hdr.ofs_frames]; + loopi(hdr.num_anims) + { + iqmanim &a = anims[i]; + string name; + copystring(name, filename); + concatstring(name, ":"); + concatstring(name, &str[a.name]); + skelanimspec *sa = skel->findskelanim(name); + if(sa) continue; + sa = &skel->addskelanim(name); + sa->frame = skel->numframes; + sa->range = a.num_frames; + dualquat *animbones = new dualquat[(skel->numframes+a.num_frames)*skel->numbones]; + if(skel->bones) + { + memcpy(animbones, skel->framebones, skel->numframes*skel->numbones*sizeof(dualquat)); + delete[] skel->framebones; + } + skel->framebones = animbones; + animbones += skel->numframes*skel->numbones; + skel->numframes += a.num_frames; + ushort *animdata = &frames[a.first_frame*hdr.num_framechannels]; + loopj(a.num_frames) + { + dualquat *frame = &animbones[j*skel->numbones]; + loopk(skel->numbones) + { + iqmpose &p = poses[k]; + vec pos; + quat orient; + pos.x = p.offsetpos.x; if(p.mask&0x01) pos.x += *animdata++ * p.scalepos.x; + pos.y = -p.offsetpos.y; if(p.mask&0x02) pos.y -= *animdata++ * p.scalepos.y; + pos.z = p.offsetpos.z; if(p.mask&0x04) pos.z += *animdata++ * p.scalepos.z; + orient.x = -p.offsetorient.x; if(p.mask&0x08) orient.x -= *animdata++ * p.scaleorient.x; + orient.y = p.offsetorient.y; if(p.mask&0x10) orient.y += *animdata++ * p.scaleorient.y; + orient.z = -p.offsetorient.z; if(p.mask&0x20) orient.z -= *animdata++ * p.scaleorient.z; + orient.w = p.offsetorient.w; if(p.mask&0x40) orient.w += *animdata++ * p.scaleorient.w; + orient.normalize(); + if(p.mask&0x380) + { + if(p.mask&0x80) animdata++; + if(p.mask&0x100) animdata++; + if(p.mask&0x200) animdata++; + } + frame[k] = dualquat(orient, pos); + if(adjustments.inrange(k)) adjustments[k].adjust(frame[k]); + boneinfo &b = skel->bones[k]; + frame[k].mul(b.invbase); + if(b.parent >= 0) frame[k].mul(skel->bones[b.parent].base, dualquat(frame[k])); + frame[k].fixantipodal(skel->framebones[k]); + } + } + } + + return true; + } + + bool loadiqm(const char *filename, bool doloadmesh, bool doloadanim) + { + stream *f = openfile(filename, "rb"); + if(!f) return false; + + uchar *buf = NULL; + iqmheader hdr; + if(f->read(&hdr, sizeof(hdr)) != sizeof(hdr) || memcmp(hdr.magic, "INTERQUAKEMODEL", sizeof(hdr.magic))) goto error; + lilswap(&hdr.version, (sizeof(hdr) - sizeof(hdr.magic))/sizeof(uint)); + if(hdr.version != 2) goto error; + if(hdr.filesize > (16<<20)) goto error; // sanity check... don't load files bigger than 16 MB + buf = new (false) uchar[hdr.filesize]; + if(!buf || f->read(buf + sizeof(hdr), hdr.filesize - sizeof(hdr)) != hdr.filesize - sizeof(hdr)) goto error; + + if(doloadmesh && !loadiqmmeshes(filename, hdr, buf)) goto error; + if(doloadanim && !loadiqmanims(filename, hdr, buf)) goto error; + + delete[] buf; + delete f; + return true; + + error: + if(buf) delete[] buf; + delete f; + return false; + } + + bool loadmesh(const char *filename) + { + name = newstring(filename); + + return loadiqm(filename, true, false); + } + + skelanimspec *loadanim(const char *animname) + { + const char *sep = strchr(animname, ':'); + skelanimspec *sa = skel->findskelanim(animname, sep ? '\0' : ':'); + if(!sa) + { + string filename; + copystring(filename, animname); + if(sep) filename[sep - animname] = '\0'; + if(loadiqm(filename, false, true)) + sa = skel->findskelanim(animname, sep ? '\0' : ':'); + } + return sa; + } + }; + + meshgroup *loadmeshes(const char *name, va_list args) + { + iqmmeshgroup *group = new iqmmeshgroup; + group->shareskeleton(va_arg(args, char *)); + if(!group->loadmesh(name)) { delete group; return NULL; } + return group; + } + + bool loaddefaultparts() + { + skelpart &mdl = addpart(); + mdl.pitchscale = mdl.pitchoffset = mdl.pitchmin = mdl.pitchmax = 0; + adjustments.setsize(0); + const char *fname = name + strlen(name); + do --fname; while(fname >= name && *fname!='/' && *fname!='\\'); + fname++; + defformatstring(meshname, "packages/models/%s/%s.iqm", name, fname); + mdl.meshes = sharemeshes(path(meshname), NULL); + if(!mdl.meshes) return false; + mdl.initanimparts(); + mdl.initskins(); + return true; + } +}; + +skelcommands<iqm> iqmcommands; + diff --git a/src/engine/main.cpp b/src/engine/main.cpp index 968c8e6..d12a38b 100644 --- a/src/engine/main.cpp +++ b/src/engine/main.cpp @@ -177,13 +177,6 @@ void bgquad(float x, float y, float w, float h, float tx = 0, float ty = 0, floa gle::end(); } -#include <sys/stat.h> - -static bool file_does_indeed_exist(const char *name) { - struct stat buffer; - return !stat(name, & buffer); -} - void renderbackground(const char *caption, Texture *mapshot, const char *mapname, const char *mapinfo, bool restore, bool force) { if(!inbetweenframes && !force) return; @@ -196,7 +189,7 @@ void renderbackground(const char *caption, Texture *mapshot, const char *mapname gettextres(w, h); static int lastupdate = -1, lastw = -1, lasth = -1; - static float backgroundu = 0, backgroundv = 0, detailu = 0, detailv = 0; + //~static float backgroundu = 0, backgroundv = 0, detailu = 0, detailv = 0; static int numdecals = 0; static struct decal { float x, y, size; int side; } decals[12]; if((renderedframe && !mainmenu && lastupdate != lastmillis) || lastw != w || lasth != h) @@ -205,10 +198,10 @@ void renderbackground(const char *caption, Texture *mapshot, const char *mapname lastw = w; lasth = h; - backgroundu = rndscale(1); - backgroundv = rndscale(1); - detailu = rndscale(1); - detailv = rndscale(1); + //~backgroundu = rndscale(1); + //~backgroundv = rndscale(1); + //~detailu = rndscale(1); + //~detailv = rndscale(1); numdecals = sizeof(decals)/sizeof(decals[0]); numdecals = numdecals/3 + rnd((numdecals*2)/3 + 1); float maxsize = min(w, h)/16.0f; diff --git a/src/engine/md3.h b/src/engine/md3.h index d560255..7e098bb 100644 --- a/src/engine/md3.h +++ b/src/engine/md3.h @@ -63,10 +63,10 @@ struct md3 : vertloader<md3> lilswap(&header.version, 1); lilswap(&header.flags, 9); if(strncmp(header.id, "IDP3", 4) != 0 || header.version != 15) // header check - { + { delete f; - conoutf(CON_ERROR, "md3: corrupted header"); - return false; + conoutf(CON_ERROR, "md3: corrupted header"); + return false; } name = newstring(path); @@ -83,16 +83,16 @@ struct md3 : vertloader<md3> md3meshheader mheader; f->seek(mesh_offset, SEEK_SET); f->read(&mheader, sizeof(md3meshheader)); - lilswap(&mheader.flags, 10); + lilswap(&mheader.flags, 10); m.name = newstring(mheader.name); - - m.numtris = mheader.numtriangles; + + m.numtris = mheader.numtriangles; m.tris = new tri[m.numtris]; f->seek(mesh_offset + mheader.ofs_triangles, SEEK_SET); loopj(m.numtris) { - md3triangle tri; + md3triangle tri = { 0 }; f->read(&tri, sizeof(md3triangle)); // read the triangles lilswap(tri.vertexindices, 3); loopk(3) m.tris[j].vert[k] = (ushort)tri.vertexindices[k]; @@ -100,15 +100,15 @@ struct md3 : vertloader<md3> m.numverts = mheader.numvertices; m.tcverts = new tcvert[m.numverts]; - f->seek(mesh_offset + mheader.ofs_uv , SEEK_SET); + f->seek(mesh_offset + mheader.ofs_uv , SEEK_SET); f->read(m.tcverts, m.numverts*2*sizeof(float)); // read the UV data lilswap(&m.tcverts[0].tc.x, 2*m.numverts); - + m.verts = new vert[numframes*m.numverts]; - f->seek(mesh_offset + mheader.ofs_vertices, SEEK_SET); + f->seek(mesh_offset + mheader.ofs_vertices, SEEK_SET); loopj(numframes*m.numverts) { - md3vertex v; + md3vertex v = { 0 }; f->read(&v, sizeof(md3vertex)); // read the vertices lilswap(v.vertex, 4); @@ -151,7 +151,7 @@ struct md3 : vertloader<md3> return true; } }; - + meshgroup *loadmeshes(const char *name, va_list args) { md3meshgroup *group = new md3meshgroup; diff --git a/src/engine/model.h b/src/engine/model.h index cd75c9d..f1effd1 100644 --- a/src/engine/model.h +++ b/src/engine/model.h @@ -1,4 +1,4 @@ -enum { MDL_MD3, MDL_MD5, MDL_OBJ, MDL_SMD, NUMMODELTYPES }; +enum { MDL_MD3, MDL_MD5, MDL_IQM, MDL_SMD, NUMMODELTYPES }; struct model { diff --git a/src/engine/obj.h b/src/engine/obj.h deleted file mode 100644 index 9cdf46a..0000000 --- a/src/engine/obj.h +++ /dev/null @@ -1,191 +0,0 @@ -struct obj; - -struct obj : vertloader<obj> -{ - obj(const char *name) : vertloader(name) {} - - static const char *formatname() { return "obj"; } - static bool animated() { return false; } - bool flipy() const { return true; } - int type() const { return MDL_OBJ; } - - struct objmeshgroup : vertmeshgroup - { - void parsevert(char *s, vector<vec> &out) - { - vec &v = out.add(vec(0, 0, 0)); - while(isalpha(*s)) s++; - loopi(3) - { - v[i] = strtod(s, &s); - while(isspace(*s)) s++; - if(!*s) break; - } - } - - bool load(const char *filename, float smooth) - { - int len = strlen(filename); - if(len < 4 || strcasecmp(&filename[len-4], ".obj")) return false; - - stream *file = openfile(filename, "rb"); - if(!file) return false; - - name = newstring(filename); - - numframes = 1; - - vector<vec> attrib[3]; - char buf[512]; - - hashtable<ivec, int> verthash; - vector<vert> verts; - vector<tcvert> tcverts; - vector<tri> tris; - - #define STARTMESH do { \ - vertmesh &m = *new vertmesh; \ - m.group = this; \ - m.name = meshname[0] ? newstring(meshname) : NULL; \ - meshes.add(&m); \ - curmesh = &m; \ - verthash.clear(); \ - verts.setsize(0); \ - tcverts.setsize(0); \ - tris.setsize(0); \ - } while(0) - - #define FLUSHMESH do { \ - curmesh->numverts = verts.length(); \ - if(verts.length()) \ - { \ - curmesh->verts = new vert[verts.length()]; \ - memcpy(curmesh->verts, verts.getbuf(), verts.length()*sizeof(vert)); \ - curmesh->tcverts = new tcvert[verts.length()]; \ - memcpy(curmesh->tcverts, tcverts.getbuf(), tcverts.length()*sizeof(tcvert)); \ - } \ - curmesh->numtris = tris.length(); \ - if(tris.length()) \ - { \ - curmesh->tris = new tri[tris.length()]; \ - memcpy(curmesh->tris, tris.getbuf(), tris.length()*sizeof(tri)); \ - } \ - if(attrib[2].empty()) \ - { \ - if(smooth <= 1) curmesh->smoothnorms(smooth); \ - else curmesh->buildnorms(); \ - } \ - } while(0) - - string meshname = ""; - vertmesh *curmesh = NULL; - while(file->getline(buf, sizeof(buf))) - { - char *c = buf; - while(isspace(*c)) c++; - switch(*c) - { - case '#': continue; - case 'v': - if(isspace(c[1])) parsevert(c, attrib[0]); - else if(c[1]=='t') parsevert(c, attrib[1]); - else if(c[1]=='n') parsevert(c, attrib[2]); - break; - case 'g': - { - while(isalpha(*c)) c++; - while(isspace(*c)) c++; - char *name = c; - size_t namelen = strlen(name); - while(namelen > 0 && isspace(name[namelen-1])) namelen--; - copystring(meshname, name, min(namelen+1, sizeof(meshname))); - - if(curmesh) FLUSHMESH; - curmesh = NULL; - break; - } - case 'f': - { - if(!curmesh) STARTMESH; - int v0 = -1, v1 = -1; - while(isalpha(*c)) c++; - for(;;) - { - while(isspace(*c)) c++; - if(!*c) break; - ivec vkey(-1, -1, -1); - loopi(3) - { - vkey[i] = strtol(c, &c, 10); - if(vkey[i] < 0) vkey[i] = attrib[i].length() + vkey[i]; - else vkey[i]--; - if(!attrib[i].inrange(vkey[i])) vkey[i] = -1; - if(*c!='/') break; - c++; - } - int *index = verthash.access(vkey); - if(!index) - { - index = &verthash[vkey]; - *index = verts.length(); - vert &v = verts.add(); - v.pos = vkey.x < 0 ? vec(0, 0, 0) : attrib[0][vkey.x]; - v.pos = vec(v.pos.z, -v.pos.x, v.pos.y); - v.norm = vkey.z < 0 ? vec(0, 0, 0) : attrib[2][vkey.z]; - v.norm = vec(v.norm.z, -v.norm.x, v.norm.y); - tcvert &tcv = tcverts.add(); - tcv.tc = vkey.y < 0 ? vec2(0, 0) : vec2(attrib[1][vkey.y].x, 1-attrib[1][vkey.y].y); - } - if(v0 < 0) v0 = *index; - else if(v1 < 0) v1 = *index; - else - { - tri &t = tris.add(); - t.vert[0] = ushort(*index); - t.vert[1] = ushort(v1); - t.vert[2] = ushort(v0); - v1 = *index; - } - } - break; - } - } - } - - if(curmesh) FLUSHMESH; - - delete file; - - return true; - } - }; - - meshgroup *loadmeshes(const char *name, va_list args) - { - objmeshgroup *group = new objmeshgroup; - if(!group->load(name, va_arg(args, double))) { delete group; return NULL; } - return group; - } - - bool loaddefaultparts() - { - part &mdl = addpart(); - const char *pname = parentdir(name); - defformatstring(name1, "packages/models/%s/tris.obj", name); - mdl.meshes = sharemeshes(path(name1), 2.0); - if(!mdl.meshes) - { - defformatstring(name2, "packages/models/%s/tris.obj", pname); // try obj in parent folder (vert sharing) - mdl.meshes = sharemeshes(path(name2), 2.0); - if(!mdl.meshes) return false; - } - Texture *tex, *masks; - loadskin(name, pname, tex, masks); - mdl.initskins(tex, masks); - if(tex==notexture) conoutf(CON_ERROR, "could not load model skin for %s", name1); - return true; - } -}; - -vertcommands<obj> objcommands; - diff --git a/src/engine/physics.cpp b/src/engine/physics.cpp index e1cd04d..4a30130 100644 --- a/src/engine/physics.cpp +++ b/src/engine/physics.cpp @@ -1342,7 +1342,7 @@ bool move(physent *d, vec &dir) { vec old(d->o); bool collided = false, slidecollide = false; - vec obstacle; + vec obstacle = vec(0, 0, 0); d->o.add(dir); if(collide(d, dir) || ((d->type==ENT_AI || d->type==ENT_INANIMATE) && collide(d, vec(0, 0, 0), 0, false))) { diff --git a/src/engine/rendergl.cpp b/src/engine/rendergl.cpp index 5ada421..d8057f2 100644 --- a/src/engine/rendergl.cpp +++ b/src/engine/rendergl.cpp @@ -1270,15 +1270,6 @@ static void setfog(int fogmat, float below = 1, int abovemat = MAT_AIR) resetfog(); } -static void setnofog(const vec &color = vec(0, 0, 0)) -{ - curfogstart = 0; - curfogend = 1000000; - curfogcolor = color; - - resetfog(); -} - static void blendfogoverlay(int fogmat, float blend, vec &overlay) { float maxc; diff --git a/src/engine/rendermodel.cpp b/src/engine/rendermodel.cpp index d79a422..ccbc58b 100644 --- a/src/engine/rendermodel.cpp +++ b/src/engine/rendermodel.cpp @@ -27,12 +27,12 @@ UNUSED static int __dummy__##modelclass = addmodeltype((modeltype), __loadmodel_ #include "md3.h" #include "md5.h" -#include "obj.h" +#include "iqm.h" #include "smd.h" MODELTYPE(MDL_MD3, md3); MODELTYPE(MDL_MD5, md5); -MODELTYPE(MDL_OBJ, obj); +MODELTYPE(MDL_IQM, iqm); MODELTYPE(MDL_SMD, smd); #define checkmdl if(!loadingmodel) { conoutf(CON_ERROR, "not loading a model"); return; } diff --git a/src/engine/worldio.cpp b/src/engine/worldio.cpp index 393bfa5..ee936f0 100644 --- a/src/engine/worldio.cpp +++ b/src/engine/worldio.cpp @@ -1282,107 +1282,5 @@ void savemap(char *mname) { save_world(mname); } COMMAND(savemap, "s"); COMMAND(savecurrentmap, ""); -void writeobj(char *name) -{ - defformatstring(fname, "%s.obj", name); - stream *f = openfile(path(fname), "w"); - if(!f) return; - f->printf("# obj file of Cube 2 level\n\n"); - defformatstring(mtlname, "%s.mtl", name); - path(mtlname); - f->printf("mtllib %s\n\n", mtlname); - vector<vec> verts; - vector<vec2> texcoords; - hashtable<vec, int> shareverts(1<<16); - hashtable<vec2, int> sharetc(1<<16); - hashtable<int, vector<ivec2> > mtls(1<<8); - vector<int> usedmtl; - vec bbmin(1e16f, 1e16f, 1e16f), bbmax(-1e16f, -1e16f, -1e16f); - loopv(valist) - { - vtxarray &va = *valist[i]; - ushort *edata = NULL; - vertex *vdata = NULL; - if(!readva(&va, edata, vdata)) continue; - ushort *idx = edata; - loopj(va.texs) - { - elementset &es = va.eslist[j]; - if(usedmtl.find(es.texture) < 0) usedmtl.add(es.texture); - vector<ivec2> &keys = mtls[es.texture]; - loopk(es.length[1]) - { - int n = idx[k] - va.voffset; - const vertex &v = vdata[n]; - const vec &pos = v.pos; - const vec2 &tc = v.tc; - ivec2 &key = keys.add(); - key.x = shareverts.access(pos, verts.length()); - if(key.x == verts.length()) - { - verts.add(pos); - loopl(3) - { - bbmin[l] = min(bbmin[l], pos[l]); - bbmax[l] = max(bbmax[l], pos[l]); - } - } - key.y = sharetc.access(tc, texcoords.length()); - if(key.y == texcoords.length()) texcoords.add(tc); - } - idx += es.length[1]; - } - delete[] edata; - delete[] vdata; - } - - vec center(-(bbmax.x + bbmin.x)/2, -(bbmax.y + bbmin.y)/2, -bbmin.z); - loopv(verts) - { - vec v = verts[i]; - v.add(center); - if(v.y != floor(v.y)) f->printf("v %.3f ", -v.y); else f->printf("v %d ", int(-v.y)); - if(v.z != floor(v.z)) f->printf("%.3f ", v.z); else f->printf("%d ", int(v.z)); - if(v.x != floor(v.x)) f->printf("%.3f\n", v.x); else f->printf("%d\n", int(v.x)); - } - f->printf("\n"); - loopv(texcoords) - { - const vec2 &tc = texcoords[i]; - f->printf("vt %.6f %.6f\n", tc.x, 1-tc.y); - } - f->printf("\n"); - - usedmtl.sort(); - loopv(usedmtl) - { - vector<ivec2> &keys = mtls[usedmtl[i]]; - f->printf("g slot%d\n", usedmtl[i]); - f->printf("usemtl slot%d\n\n", usedmtl[i]); - for(int i = 0; i < keys.length(); i += 3) - { - f->printf("f"); - loopk(3) f->printf(" %d/%d", keys[i+2-k].x+1, keys[i+2-k].y+1); - f->printf("\n"); - } - f->printf("\n"); - } - delete f; - - f = openfile(mtlname, "w"); - if(!f) return; - f->printf("# mtl file of Cube 2 level\n\n"); - loopv(usedmtl) - { - VSlot &vslot = lookupvslot(usedmtl[i], false); - f->printf("newmtl slot%d\n", usedmtl[i]); - f->printf("map_Kd %s\n", vslot.slot->sts.empty() ? notexture->name : path(makerelpath("packages", vslot.slot->sts[0].name))); - f->printf("\n"); - } - delete f; -} - -COMMAND(writeobj, "s"); - #endif |
