model roll

master
Lee Salzman 2013-05-15 19:52:38 +03:00
parent c4b8fa99bd
commit 1a21d747cf
18 changed files with 140 additions and 81 deletions

View File

@ -380,7 +380,7 @@ struct gui : g3d_gui
float dist = 2.0f*max(radius.magnitude2(), 1.1f*radius.z),
yaw = fmod(lastmillis/10000.0f*360.0f, 360.0f);
vec o(-center.x, dist - center.y, -0.1f*dist - center.z);
rendermodel(name, anim, o, yaw, 0, 0, NULL, NULL, 0);
rendermodel(name, anim, o, yaw, 0, 0, 0, NULL, NULL, 0);
}
modelpreview::end();
hudshader->set();

View File

@ -1044,25 +1044,31 @@ struct animmodel : model
static int intersectresult, intersectmode;
static float intersectdist, intersectscale;
int intersect(int anim, int basetime, int basetime2, const vec &pos, float yaw, float pitch, dynent *d, modelattach *a, float size, const vec &o, const vec &ray, float &dist, int mode)
int intersect(int anim, int basetime, int basetime2, const vec &pos, float yaw, float pitch, float roll, dynent *d, modelattach *a, float size, const vec &o, const vec &ray, float &dist, int mode)
{
if(!loaded) return -1;
yaw += spinyaw*lastmillis/1000.0f;
pitch += spinpitch*lastmillis/1000.0f;
vec axis(1, 0, 0), forward(0, 1, 0);
matrixpos = 0;
matrixstack[0].identity();
if(!d || !d->ragdoll || anim&ANIM_RAGDOLL)
{
float secs = lastmillis/1000.0f;
yaw += spinyaw*secs;
pitch += spinpitch*secs;
roll += spinroll*secs;
matrixstack[0].settranslation(pos);
matrixstack[0].rotate_around_z(yaw*RAD);
bool usepitch = pitched();
if(roll && !usepitch) matrixstack[0].rotate_around_y(-roll*RAD);
matrixstack[0].transformnormal(vec(axis), axis);
matrixstack[0].transformnormal(vec(forward), forward);
if(roll && usepitch) matrixstack[0].rotate_around_y(-roll*RAD);
if(offsetyaw) matrixstack[0].rotate_around_z(offsetyaw*RAD);
if(offsetpitch) matrixstack[0].rotate_around_x(offsetpitch*RAD);
if(offsetroll) matrixstack[0].rotate_around_y(-offsetroll*RAD);
}
else
{
@ -1163,25 +1169,31 @@ struct animmodel : model
}
}
void render(int anim, int basetime, int basetime2, const vec &o, float yaw, float pitch, dynent *d, modelattach *a, float size, float trans)
void render(int anim, int basetime, int basetime2, const vec &o, float yaw, float pitch, float roll, dynent *d, modelattach *a, float size, float trans)
{
if(!loaded) return;
yaw += spinyaw*lastmillis/1000.0f;
pitch += spinpitch*lastmillis/1000.0f;
vec axis(1, 0, 0), forward(0, 1, 0);
matrixpos = 0;
matrixstack[0].identity();
if(!d || !d->ragdoll || anim&ANIM_RAGDOLL)
{
float secs = lastmillis/1000.0f;
yaw += spinyaw*secs;
pitch += spinpitch*secs;
roll += spinroll*secs;
matrixstack[0].settranslation(o);
matrixstack[0].rotate_around_z(yaw*RAD);
bool usepitch = pitched();
if(roll && !usepitch) matrixstack[0].rotate_around_y(-roll*RAD);
matrixstack[0].transformnormal(vec(axis), axis);
matrixstack[0].transformnormal(vec(forward), forward);
if(roll && usepitch) matrixstack[0].rotate_around_y(-roll*RAD);
if(offsetyaw) matrixstack[0].rotate_around_z(offsetyaw*RAD);
if(offsetpitch) matrixstack[0].rotate_around_x(offsetpitch*RAD);
if(offsetroll) matrixstack[0].rotate_around_y(-offsetroll*RAD);
}
else
{
@ -1249,6 +1261,7 @@ struct animmodel : model
m.identity();
if(offsetyaw) m.rotate_around_z(offsetyaw*RAD);
if(offsetpitch) m.rotate_around_x(offsetpitch*RAD);
if(offsetroll) m.rotate_around_y(-offsetroll*RAD);
m.translate(translate, scale);
}
@ -1307,10 +1320,15 @@ struct animmodel : model
bool animated() const
{
if(spinyaw || spinpitch) return true;
if(spinyaw || spinpitch || spinroll) return true;
loopv(parts) if(parts[i]->animated()) return true;
return false;
}
bool pitched() const
{
return parts[0]->pitchscale != 0;
}
virtual bool loaddefaultparts()
{

View File

@ -261,11 +261,11 @@ BIH::BIH(vector<tri> *t)
bool mmintersect(const extentity &e, const vec &o, const vec &ray, float maxdist, int mode, float &dist)
{
extern vector<mapmodelinfo> mapmodels;
if(!mapmodels.inrange(e.attr2)) return false;
model *m = mapmodels[e.attr2].m;
if(!mapmodels.inrange(e.attr1)) return false;
model *m = mapmodels[e.attr1].m;
if(!m)
{
m = loadmodel(NULL, e.attr2);
m = loadmodel(NULL, e.attr1);
if(!m) return false;
}
if(mode&RAY_SHADOW)
@ -275,11 +275,11 @@ bool mmintersect(const extentity &e, const vec &o, const vec &ray, float maxdist
else if((mode&RAY_ENTS)!=RAY_ENTS && (!m->collide || e.flags&extentity::F_NOCOLLIDE)) return false;
if(!m->bih && !m->setBIH()) return false;
vec mo = vec(o).sub(e.o), mray(ray);
int scale = e.attr4;
int scale = e.attr5;
if(scale > 0) mo.mul(100.0f/scale);
float v = mo.dot(mray), inside = m->bih->radius - mo.squaredlen();
if((inside < 0 && v > 0) || inside + v*v < 0) return false;
int yaw = e.attr1, pitch = e.attr3;
int yaw = e.attr2, pitch = e.attr3, roll = e.attr4;
if(yaw != 0)
{
if(yaw < 0) yaw = 360 + yaw%360;
@ -296,6 +296,14 @@ bool mmintersect(const extentity &e, const vec &o, const vec &ray, float maxdist
mo.rotate_around_x(rot.x, -rot.y);
mray.rotate_around_x(rot.x, -rot.y);
}
if(roll != 0)
{
if(roll < 0) roll = 360 + roll%360;
else if(roll >= 360) roll %= 360;
const vec2 &rot = sincos360[roll];
mo.rotate_around_y(rot.x, rot.y);
mray.rotate_around_y(rot.x, rot.y);
}
if(m->bih->traverse(mo, mray, maxdist ? maxdist : 1e16f, dist, mode))
{
if(scale > 0) dist *= scale/100.0f;

View File

@ -608,7 +608,7 @@ extern void clearchanges(int type);
extern void mousemove(int dx, int dy);
extern bool pointincube(const clipplanes &p, const vec &v);
extern bool overlapsdynent(const vec &o, float radius);
extern void rotatebb(vec &center, vec &radius, int yaw, int pitch);
extern void rotatebb(vec &center, vec &radius, int yaw, int pitch, int roll = 0);
extern float shadowray(const vec &o, const vec &ray, float radius, int mode, extentity *t = NULL);
struct ShadowRayCache;
extern ShadowRayCache *newshadowraycache();
@ -646,7 +646,7 @@ extern void shadowmaskbatchedmodels(bool dynshadow = true);
extern void rendermapmodelbatches();
extern void rendermodelbatches();
extern void rendertransparentmodelbatches();
extern void rendermapmodel(int idx, int anim, const vec &o, float yaw = 0, float pitch = 0, int flags = MDL_CULL_VFC | MDL_CULL_DIST, int basetime = 0, float size = 1);
extern void rendermapmodel(int idx, int anim, const vec &o, float yaw = 0, float pitch = 0, float roll = 0, int flags = MDL_CULL_VFC | MDL_CULL_DIST, int basetime = 0, float size = 1);
extern void clearbatchedmapmodels();
extern void preloadusedmapmodels(bool msg = false, bool bih = false);
extern int batcheddynamicmodels();

View File

@ -2,7 +2,7 @@ enum { MDL_MD2 = 0, MDL_MD3, MDL_MD5, MDL_OBJ, MDL_SMD, MDL_IQM, NUMMODELTYPES }
struct model
{
float spinyaw, spinpitch, offsetyaw, offsetpitch;
float spinyaw, spinpitch, spinroll, offsetyaw, offsetpitch, offsetroll;
bool collide, ellipsecollide, shadow, depthoffset;
float scale;
vec translate;
@ -11,11 +11,11 @@ struct model
float eyeheight, collideradius, collideheight;
int batch;
model() : spinyaw(0), spinpitch(0), offsetyaw(0), offsetpitch(0), collide(true), ellipsecollide(false), shadow(true), depthoffset(false), scale(1.0f), translate(0, 0, 0), bih(0), bbcenter(0, 0, 0), bbradius(-1, -1, -1), bbextend(0, 0, 0), eyeheight(0.9f), collideradius(0), collideheight(0), batch(-1) {}
model() : spinyaw(0), spinpitch(0), spinroll(0), offsetyaw(0), offsetpitch(0), offsetroll(0), collide(true), ellipsecollide(false), shadow(true), depthoffset(false), scale(1.0f), translate(0, 0, 0), bih(0), bbcenter(0, 0, 0), bbradius(-1, -1, -1), bbextend(0, 0, 0), eyeheight(0.9f), collideradius(0), collideheight(0), batch(-1) {}
virtual ~model() { DELETEP(bih); }
virtual void calcbb(vec &center, vec &radius) = 0;
virtual int intersect(int anim, int basetime, int basetime2, const vec &pos, float yaw, float pitch, dynent *d, modelattach *a, float size, const vec &o, const vec &ray, float &dist, int mode) = 0;
virtual void render(int anim, int basetime, int basetime2, const vec &o, float yaw, float pitch, dynent *d, modelattach *a = NULL, float size = 1, float trans = 1) = 0;
virtual int intersect(int anim, int basetime, int basetime2, const vec &pos, float yaw, float pitch, float roll, dynent *d, modelattach *a, float size, const vec &o, const vec &ray, float &dist, int mode) = 0;
virtual void render(int anim, int basetime, int basetime2, const vec &o, float yaw, float pitch, float roll, dynent *d, modelattach *a = NULL, float size = 1, float trans = 1) = 0;
virtual bool load() = 0;
virtual const char *name() const = 0;
virtual int type() const = 0;
@ -23,6 +23,7 @@ struct model
virtual bool envmapped() { return false; }
virtual bool skeletal() const { return false; }
virtual bool animated() const { return false; }
virtual bool pitched() const { return true; }
virtual void setshader(Shader *shader) {}
virtual void setenvmap(float envmapmin, float envmapmax, Texture *envmap) {}

View File

@ -197,9 +197,10 @@ namespace mpr
vec o, radius;
quat orient;
ModelOBB(const vec &ent, const vec &center, const vec &radius, float yaw, float pitch) : o(ent), radius(radius), orient(vec(0, 0, 1), yaw*RAD)
ModelOBB(const vec &ent, const vec &center, const vec &radius, float yaw, float pitch, float roll) : o(ent), radius(radius), orient(vec(0, 0, 1), yaw*RAD)
{
if(pitch) orient.mul(quat(vec(1, 0, 0), pitch*RAD), quat(orient));
if(roll) orient.mul(quat(vec(0, -1, 0), roll*RAD), quat(orient));
o.add(orient.rotate(center));
}
@ -238,9 +239,10 @@ namespace mpr
vec o, radius;
quat orient;
ModelEllipse(const vec &ent, const vec &center, const vec &radius, float yaw, float pitch) : o(ent), radius(radius), orient(vec(0, 0, 1), yaw*RAD)
ModelEllipse(const vec &ent, const vec &center, const vec &radius, float yaw, float pitch, float roll) : o(ent), radius(radius), orient(vec(0, 0, 1), yaw*RAD)
{
if(pitch) orient.mul(quat(vec(1, 0, 0), pitch*RAD), quat(orient));
if(roll) orient.mul(quat(vec(0, -1, 0), roll*RAD), quat(orient));
o.add(orient.rotate(center));
}

View File

@ -715,8 +715,18 @@ bool plcollide(physent *d, const vec &dir) // collide with player or monster
return true;
}
void rotatebb(vec &center, vec &radius, int yaw, int pitch)
void rotatebb(vec &center, vec &radius, int yaw, int pitch, int roll)
{
if(roll)
{
if(roll < 0) roll = 360 + roll%360;
else if(roll >= 360) roll %= 360;
const vec2 &rot = sincos360[roll];
center.rotate_around_y(rot.x, -rot.y);
vec2 oldradius(radius.x, radius.z);
radius.x = fabs(oldradius.x*rot.x) + fabs(oldradius.y*rot.y);
radius.z = fabs(oldradius.y*rot.x) + fabs(oldradius.x*rot.y);
}
if(pitch)
{
if(pitch < 0) pitch = 360 + pitch%360;
@ -740,10 +750,10 @@ void rotatebb(vec &center, vec &radius, int yaw, int pitch)
}
template<class E, class M>
static inline bool mmcollide(physent *d, const vec &dir, const extentity &e, const vec &center, const vec &radius, float yaw, float pitch)
static inline bool mmcollide(physent *d, const vec &dir, const extentity &e, const vec &center, const vec &radius, float yaw, float pitch, float roll)
{
E entvol(d);
M mdlvol(e.o, center, radius, yaw, pitch);
M mdlvol(e.o, center, radius, yaw, pitch, roll);
vec cp;
if(mpr::collide(entvol, mdlvol, NULL, NULL, &cp))
{
@ -762,34 +772,34 @@ bool mmcollide(physent *d, const vec &dir, octaentities &oc) // co
{
extentity &e = *ents[oc.mapmodels[i]];
if(e.flags&extentity::F_NOCOLLIDE) continue;
model *m = loadmodel(NULL, e.attr2);
model *m = loadmodel(NULL, e.attr1);
if(!m || !m->collide) continue;
vec center, radius;
m->collisionbox(center, radius);
if(e.attr4 > 0) { float scale = e.attr4/100.f; center.mul(scale); radius.mul(scale); }
int yaw = e.attr1, pitch = e.attr3;
if(e.attr5 > 0) { float scale = e.attr5/100.f; center.mul(scale); radius.mul(scale); }
int yaw = e.attr2, pitch = e.attr3, roll = e.attr4;
switch(d->collidetype)
{
case COLLIDE_ELLIPSE:
if(pitch) rotatebb(center, radius, 0, pitch);
if(pitch || roll) rotatebb(center, radius, 0, pitch, roll);
if(m->ellipsecollide)
{
//if(!mmcollide<mpr::EntCylinder, mpr::ModelEllipse>(d, dir, e, center, radius, yaw, pitch)) return false;
//if(!mmcollide<mpr::EntCylinder, mpr::ModelEllipse>(d, dir, e, center, radius, yaw, pitch, roll)) return false;
if(!ellipsecollide(d, dir, e.o, center, yaw, radius.x, radius.y, radius.z, radius.z)) return false;
}
//else if(!mmcollide<mpr::EntCylinder, mpr::ModelOBB>(d, dir, e, center, radius, yaw, pitch)) return false;
//else if(!mmcollide<mpr::EntCylinder, mpr::ModelOBB>(d, dir, e, center, radius, yaw, pitch, roll)) return false;
else if(!ellipserectcollide(d, dir, e.o, center, yaw, radius.x, radius.y, radius.z, radius.z)) return false;
break;
case COLLIDE_OBB:
if(m->ellipsecollide)
{
if(!mmcollide<mpr::EntOBB, mpr::ModelEllipse>(d, dir, e, center, radius, yaw, pitch)) return false;
if(!mmcollide<mpr::EntOBB, mpr::ModelEllipse>(d, dir, e, center, radius, yaw, pitch, roll)) return false;
}
else if(!mmcollide<mpr::EntOBB, mpr::ModelOBB>(d, dir, e, center, radius, yaw, pitch)) return false;
else if(!mmcollide<mpr::EntOBB, mpr::ModelOBB>(d, dir, e, center, radius, yaw, pitch, roll)) return false;
break;
case COLLIDE_AABB:
default:
rotatebb(center, radius, yaw, pitch);
rotatebb(center, radius, yaw, pitch, roll);
if(!rectcollide(d, dir, center.add(e.o), radius.x, radius.y, radius.z, radius.z)) return false;
break;
}

View File

@ -148,14 +148,15 @@ void mdlshader(char *shader)
COMMAND(mdlshader, "s");
void mdlspin(float *yaw, float *pitch)
void mdlspin(float *yaw, float *pitch, float *roll)
{
checkmdl;
loadingmodel->spinyaw = *yaw;
loadingmodel->spinpitch = *pitch;
loadingmodel->spinroll = *roll;
}
COMMAND(mdlspin, "ff");
COMMAND(mdlspin, "fff");
void mdlscale(int *percent)
{
@ -192,6 +193,14 @@ void mdlpitch(float *angle)
COMMAND(mdlpitch, "f");
void mdlroll(float *angle)
{
checkmdl;
loadingmodel->offsetroll = *angle;
}
COMMAND(mdlroll, "f");
void mdlshadow(int *shadow)
{
checkmdl;
@ -454,7 +463,7 @@ bool modeloccluded(const vec &center, float radius)
struct batchedmodel
{
vec pos, center;
float radius, yaw, pitch, sizescale, transparent;
float radius, yaw, pitch, roll, sizescale, transparent;
int anim, basetime, basetime2, flags, attached;
union
{
@ -511,7 +520,7 @@ static inline void renderbatchedmodel(model *m, batchedmodel &b)
if(b.flags&MDL_FULLBRIGHT) anim |= ANIM_FULLBRIGHT;
}
m->render(anim, b.basetime, b.basetime2, b.pos, b.yaw, b.pitch, b.d, a, b.sizescale, b.transparent);
m->render(anim, b.basetime, b.basetime2, b.pos, b.yaw, b.pitch, b.roll, b.d, a, b.sizescale, b.transparent);
}
VARP(maxmodelradiusdistance, 10, 200, 1000);
@ -872,7 +881,7 @@ void clearbatchedmapmodels()
batchedmodels.setsize(len);
}
void rendermapmodel(int idx, int anim, const vec &o, float yaw, float pitch, int flags, int basetime, float size)
void rendermapmodel(int idx, int anim, const vec &o, float yaw, float pitch, float roll, int flags, int basetime, float size)
{
if(!mapmodels.inrange(idx)) return;
mapmodelinfo &mmi = mapmodels[idx];
@ -883,6 +892,8 @@ void rendermapmodel(int idx, int anim, const vec &o, float yaw, float pitch, int
m->boundbox(center, bbradius);
float radius = bbradius.magnitude();
center.mul(size);
if(roll) center.rotate_around_y(-roll*RAD);
if(pitch && m->pitched()) center.rotate_around_x(pitch*RAD);
center.rotate_around_z(yaw*RAD);
center.add(o);
radius *= size;
@ -904,6 +915,7 @@ void rendermapmodel(int idx, int anim, const vec &o, float yaw, float pitch, int
b.anim = anim;
b.yaw = yaw;
b.pitch = pitch;
b.roll = roll;
b.basetime = basetime;
b.basetime2 = 0;
b.sizescale = size;
@ -915,7 +927,7 @@ void rendermapmodel(int idx, int anim, const vec &o, float yaw, float pitch, int
addbatchedmodel(m, b, batchedmodels.length()-1);
}
void rendermodel(const char *mdl, int anim, const vec &o, float yaw, float pitch, int flags, dynent *d, modelattach *a, int basetime, int basetime2, float size, float trans)
void rendermodel(const char *mdl, int anim, const vec &o, float yaw, float pitch, float roll, int flags, dynent *d, modelattach *a, int basetime, int basetime2, float size, float trans)
{
model *m = loadmodel(mdl);
if(!m) return;
@ -931,6 +943,8 @@ void rendermodel(const char *mdl, int anim, const vec &o, float yaw, float pitch
else
{
center.mul(size);
if(roll) center.rotate_around_y(-roll*RAD);
if(pitch && m->pitched()) center.rotate_around_x(pitch*RAD);
center.rotate_around_z(yaw*RAD);
center.add(o);
}
@ -970,7 +984,7 @@ void rendermodel(const char *mdl, int anim, const vec &o, float yaw, float pitch
m->startrender();
setaamask(true);
if(flags&MDL_FULLBRIGHT) anim |= ANIM_FULLBRIGHT;
m->render(anim, basetime, basetime2, o, yaw, pitch, d, a, size);
m->render(anim, basetime, basetime2, o, yaw, pitch, roll, d, a, size);
m->endrender();
if(flags&MDL_CULL_QUERY && d->query) endquery(d->query);
return;
@ -984,6 +998,7 @@ void rendermodel(const char *mdl, int anim, const vec &o, float yaw, float pitch
b.anim = anim;
b.yaw = yaw;
b.pitch = pitch;
b.roll = roll;
b.basetime = basetime;
b.basetime2 = basetime2;
b.sizescale = size;
@ -996,7 +1011,7 @@ void rendermodel(const char *mdl, int anim, const vec &o, float yaw, float pitch
addbatchedmodel(m, b, batchedmodels.length()-1);
}
int intersectmodel(const char *mdl, int anim, const vec &pos, float yaw, float pitch, const vec &o, const vec &ray, float &dist, int mode, dynent *d, modelattach *a, int basetime, int basetime2, float size)
int intersectmodel(const char *mdl, int anim, const vec &pos, float yaw, float pitch, float roll, const vec &o, const vec &ray, float &dist, int mode, dynent *d, modelattach *a, int basetime, int basetime2, float size)
{
model *m = loadmodel(mdl);
if(!m) return -1;
@ -1004,7 +1019,7 @@ int intersectmodel(const char *mdl, int anim, const vec &pos, float yaw, float p
{
if(a[i].name) a[i].m = loadmodel(a[i].name);
}
return m->intersect(anim, basetime, basetime2, pos, yaw, pitch, d, a, size, o, ray, dist, mode);
return m->intersect(anim, basetime, basetime2, pos, yaw, pitch, roll, d, a, size, o, ray, dist, mode);
}
void abovemodel(vec &o, const char *mdl)
@ -1144,7 +1159,7 @@ void renderclient(dynent *d, const char *mdlname, modelattach *attachments, int
else flags |= MDL_CULL_DIST;
if(drawtex == DRAWTEX_MODELPREVIEW) flags &= ~(MDL_FULLBRIGHT | MDL_CULL_VFC | MDL_CULL_OCCLUDED | MDL_CULL_QUERY | MDL_CULL_DIST);
if(d->state == CS_LAGGED) trans = min(trans, 0.3f);
rendermodel(mdlname, anim, o, yaw, pitch, flags, d, attachments, basetime, 0, scale, trans);
rendermodel(mdlname, anim, o, yaw, pitch, 0, flags, d, attachments, basetime, 0, scale, trans);
}
void setbbfrommodel(dynent *d, const char *mdl)

View File

@ -407,7 +407,7 @@ static inline void rendermapmodel(extentity &e)
{
int anim = ANIM_MAPMODEL|ANIM_LOOP, basetime = 0;
if(e.flags&extentity::F_ANIM) entities::animatemapmodel(e, anim, basetime);
rendermapmodel(e.attr2, anim, e.o, e.attr1, e.attr3, MDL_CULL_VFC | MDL_CULL_DIST, basetime, e.attr4 > 0 ? e.attr4/100.0f : 1.0f);
rendermapmodel(e.attr1, anim, e.o, e.attr2, e.attr3, e.attr4, MDL_CULL_VFC | MDL_CULL_DIST, basetime, e.attr5 > 0 ? e.attr5/100.0f : 1.0f);
}
void rendermapmodels()

View File

@ -18,18 +18,18 @@ bool getentboundingbox(extentity &e, ivec &o, ivec &r)
return false;
case ET_MAPMODEL:
{
model *m = loadmodel(NULL, e.attr2);
model *m = loadmodel(NULL, e.attr1);
if(m)
{
vec center, radius;
m->boundbox(center, radius);
if(e.attr4 > 0)
if(e.attr5 > 0)
{
float scale = e.attr4/100.0f;
float scale = e.attr5/100.0f;
center.mul(scale);
radius.mul(scale);
}
rotatebb(center, radius, e.attr1, e.attr3);
rotatebb(center, radius, e.attr2, e.attr3, e.attr4);
o = e.o;
o.add(center);
r = radius;
@ -70,7 +70,7 @@ void modifyoctaentity(int flags, int id, extentity &e, cube *c, const ivec &cor,
switch(e.type)
{
case ET_MAPMODEL:
if(loadmodel(NULL, e.attr2))
if(loadmodel(NULL, e.attr1))
{
if(va)
{
@ -98,7 +98,7 @@ void modifyoctaentity(int flags, int id, extentity &e, cube *c, const ivec &cor,
switch(e.type)
{
case ET_MAPMODEL:
if(loadmodel(NULL, e.attr2))
if(loadmodel(NULL, e.attr1))
{
oe.mapmodels.removeobj(id);
if(va)
@ -479,11 +479,11 @@ void entselectionbox(const entity &e, vec &eo, vec &es)
eo.y += e.o.y;
eo.z = e.o.z - entselradius + es.z;
}
else if(e.type == ET_MAPMODEL && (m = loadmodel(NULL, e.attr2)))
else if(e.type == ET_MAPMODEL && (m = loadmodel(NULL, e.attr1)))
{
m->collisionbox(eo, es);
if(e.attr4 > 0) { float scale = e.attr4/100.0f; eo.mul(scale); es.mul(scale); }
rotatebb(eo, es, e.attr1, e.attr3);
if(e.attr5 > 0) { float scale = e.attr5/100.0f; eo.mul(scale); es.mul(scale); }
rotatebb(eo, es, e.attr2, e.attr3, e.attr4);
#if 0
if(m->collide)
eo.z -= player->aboveeye; // wacky but true. see physics collide
@ -654,6 +654,15 @@ void renderentradius(extentity &e, bool color)
}
case ET_MAPMODEL:
{
if(color) gle::colorf(0, 1, 1);
entities::entradius(e, color);
vec dir;
vecfromyawpitch(e.attr2, e.attr3, 1, 0, dir);
renderentarrow(e, dir, 4);
break;
}
case ET_PLAYERSTART:
{
if(color) gle::colorf(0, 1, 1);
@ -812,13 +821,13 @@ bool dropentity(entity &e, int drop = -1)
if(drop<0) drop = entdrop;
if(e.type == ET_MAPMODEL)
{
model *m = loadmodel(NULL, e.attr2);
model *m = loadmodel(NULL, e.attr1);
if(m)
{
vec center;
m->boundbox(center, radius);
if(e.attr4 > 0) { float scale = e.attr4/100.0f; center.mul(scale); radius.mul(scale); }
rotatebb(center, radius, e.attr1, e.attr3);
if(e.attr5 > 0) { float scale = e.attr5/100.0f; center.mul(scale); radius.mul(scale); }
rotatebb(center, radius, e.attr2, e.attr3, e.attr4);
radius.x += fabs(center.x);
radius.y += fabs(center.y);
}
@ -896,6 +905,8 @@ extentity *newentity(bool local, const vec &o, int type, int v1, int v2, int v3,
switch(type)
{
case ET_MAPMODEL:
e.attr2 = (int)camera1->yaw;
break;
case ET_PLAYERSTART:
e.attr5 = e.attr4;
e.attr4 = e.attr3;

View File

@ -350,7 +350,7 @@ struct captureclientmode : clientmode
baseinfo &b = bases[i];
if(!b.valid()) continue;
const char *basename = b.owner[0] ? (strcmp(b.owner, player1->team) ? "base/red" : "base/blue") : "base/neutral";
rendermodel(basename, ANIM_MAPMODEL|ANIM_LOOP, b.o, 0, 0, MDL_CULL_VFC | MDL_CULL_OCCLUDED);
rendermodel(basename, ANIM_MAPMODEL|ANIM_LOOP, b.o, 0, 0, 0, MDL_CULL_VFC | MDL_CULL_OCCLUDED);
float fradius = 1.0f, fheight = 0.5f;
regular_particle_flame(PART_FLAME, vec(b.ammopos.x, b.ammopos.y, b.ammopos.z - 4.5f), fradius, fheight, b.owner[0] ? (strcmp(b.owner, player1->team) ? 0x802020 : 0x2020FF) : 0x208020, 3, 2.0f);
//regular_particle_flame(PART_SMOKE, vec(b.ammopos.x, b.ammopos.y, b.ammopos.z - 4.5f + 4.0f*min(fradius, fheight)), fradius, fheight, 0x303020, 1, 4.0f, 100.0f, 2000.0f, -20);
@ -364,7 +364,7 @@ struct captureclientmode : clientmode
abovemodel(height, ammoname);
vec ammopos(b.ammopos);
ammopos.z -= height.z/2 + sinf(lastmillis/100.0f)/20;
rendermodel(ammoname, ANIM_MAPMODEL|ANIM_LOOP, ammopos, lastmillis/10.0f, 0, MDL_CULL_VFC | MDL_CULL_OCCLUDED);
rendermodel(ammoname, ANIM_MAPMODEL|ANIM_LOOP, ammopos, lastmillis/10.0f, 0, 0, MDL_CULL_VFC | MDL_CULL_OCCLUDED);
}
else loopj(b.ammo)
{
@ -373,7 +373,7 @@ struct captureclientmode : clientmode
ammopos.x += 10*cosf(angle);
ammopos.y += 10*sinf(angle);
ammopos.z += 4;
rendermodel(entities::entmdlname(I_SHELLS+b.ammotype-1), ANIM_MAPMODEL|ANIM_LOOP, ammopos, 0, 0, MDL_CULL_VFC | MDL_CULL_OCCLUDED);
rendermodel(entities::entmdlname(I_SHELLS+b.ammotype-1), ANIM_MAPMODEL|ANIM_LOOP, ammopos, 0, 0, 0, MDL_CULL_VFC | MDL_CULL_OCCLUDED);
}
int tcolor = 0x1EC850, mtype = -1, mcolor = 0xFFFFFF, mcolor2 = 0;

View File

@ -511,13 +511,13 @@ struct collectclientmode : clientmode
{
base &b = bases[i];
const char *basename = b.team==team ? "base/blue" : "base/red";
rendermodel(basename, ANIM_MAPMODEL|ANIM_LOOP, b.o, 0, 0, MDL_CULL_VFC | MDL_CULL_OCCLUDED);
rendermodel(basename, ANIM_MAPMODEL|ANIM_LOOP, b.o, 0, 0, 0, MDL_CULL_VFC | MDL_CULL_OCCLUDED);
float fradius = 1.0f, fheight = 0.5f;
regular_particle_flame(PART_FLAME, vec(b.tokenpos.x, b.tokenpos.y, b.tokenpos.z - 4.5f), fradius, fheight, b.team==team ? 0x2020FF : 0x802020, 3, 2.0f);
vec tokenpos(b.tokenpos);
tokenpos.z -= theight.z/2 + sinf(lastmillis/100.0f)/20;
float alpha = player1->state == CS_ALIVE && player1->tokens <= 0 && lastmillis < b.laststeal + STEALTOKENTIME ? 0.5f : 1.0f;
rendermodel(b.team==team ? "skull/blue" : "skull/red", ANIM_MAPMODEL|ANIM_LOOP, tokenpos, lastmillis/10.0f, 0, MDL_CULL_VFC | MDL_CULL_OCCLUDED, NULL, NULL, 0, 0, alpha);
rendermodel(b.team==team ? "skull/blue" : "skull/red", ANIM_MAPMODEL|ANIM_LOOP, tokenpos, lastmillis/10.0f, 0, 0, MDL_CULL_VFC | MDL_CULL_OCCLUDED, NULL, NULL, 0, 0, alpha);
formatstring(b.info)("%d", totalscore(b.team));
vec above(b.tokenpos);
above.z += TOKENHEIGHT;
@ -528,7 +528,7 @@ struct collectclientmode : clientmode
token &t = tokens[i];
vec p = t.o;
p.z += 1+sinf(lastmillis/100.0+t.o.x+t.o.y)/20;
rendermodel(t.team == team || (t.team < 0 && -t.team != team) ? "skull/blue" : "skull/red", ANIM_MAPMODEL|ANIM_LOOP, p, lastmillis/10.0f, 0, MDL_CULL_VFC | MDL_CULL_DIST | MDL_CULL_OCCLUDED);
rendermodel(t.team == team || (t.team < 0 && -t.team != team) ? "skull/blue" : "skull/red", ANIM_MAPMODEL|ANIM_LOOP, p, lastmillis/10.0f, 0, 0, MDL_CULL_VFC | MDL_CULL_DIST | MDL_CULL_OCCLUDED);
}
fpsent *exclude = isthirdperson() ? NULL : hudplayer();
loopv(players)
@ -539,7 +539,7 @@ struct collectclientmode : clientmode
int dteam = collectteambase(d->team);
loopj(d->tokens)
{
rendermodel(dteam != team ? "skull/blue" : "skull/red", ANIM_MAPMODEL|ANIM_LOOP, pos, d->yaw, 0, MDL_CULL_VFC | MDL_CULL_DIST | MDL_CULL_OCCLUDED);
rendermodel(dteam != team ? "skull/blue" : "skull/red", ANIM_MAPMODEL|ANIM_LOOP, pos, d->yaw, 0, 0, MDL_CULL_VFC | MDL_CULL_DIST | MDL_CULL_OCCLUDED);
pos.z += TOKENHEIGHT + 1;
}
}

View File

@ -610,12 +610,12 @@ struct ctfclientmode : clientmode
#if 0
if(m_hold)
rendermodel(flagname, ANIM_MAPMODEL|ANIM_LOOP,
pos, angle, 0,
pos, angle, 0, 0,
MDL_GHOST | MDL_CULL_VFC,
NULL, NULL, 0, 0, 0.5f + 0.5f*(2*fabs(fmod(lastmillis/1000.0f, 1.0f) - 0.5f)));
#endif
rendermodel(flagname, ANIM_MAPMODEL|ANIM_LOOP,
pos, angle, 0,
pos, angle, 0, 0,
MDL_CULL_VFC | MDL_CULL_OCCLUDED,
NULL, NULL, 0, 0, 0.3f + (f.vistime ? 0.7f*min((lastmillis - f.vistime)/1000.0f, 1.0f) : 0.0f));

View File

@ -115,7 +115,7 @@ namespace entities
{
vec p = e.o;
p.z += 1+sinf(lastmillis/100.0+e.o.x+e.o.y)/20;
rendermodel(mdlname, ANIM_MAPMODEL|ANIM_LOOP, p, lastmillis/(float)revs, 0, MDL_CULL_VFC | MDL_CULL_DIST | MDL_CULL_OCCLUDED);
rendermodel(mdlname, ANIM_MAPMODEL|ANIM_LOOP, p, lastmillis/(float)revs, 0, 0, MDL_CULL_VFC | MDL_CULL_DIST | MDL_CULL_OCCLUDED);
}
}
}

View File

@ -24,7 +24,7 @@ enum // static entity types
{
NOTUSED = ET_EMPTY, // entity slot not in use in map
LIGHT = ET_LIGHT, // lightsource, attr1 = radius, attr2 = intensity
MAPMODEL = ET_MAPMODEL, // attr1 = angle, attr2 = idx
MAPMODEL = ET_MAPMODEL, // attr1 = idx, attr2 = yaw, attr3 = pitch, attr4 = roll, attr5 = scale
PLAYERSTART, // attr1 = angle, attr2 = team
ENVMAP = ET_ENVMAP, // attr1 = radius
PARTICLES = ET_PARTICLES,

View File

@ -177,12 +177,6 @@ namespace game
case 2: mdlname = mdl.redteam; break;
}
renderclient(d, mdlname, a[0].tag ? a : NULL, hold, attack, delay, lastaction, intermission && d->state!=CS_DEAD ? 0 : d->lastpain, fade, ragdoll && mdl.ragdoll);
#if 0
if(d->state!=CS_DEAD && d->quadmillis)
{
rendermodel("quadrings", ANIM_MAPMODEL|ANIM_LOOP, vec(d->o).sub(vec(0, 0, d->eyeheight/2)), 360*lastmillis/1000.0f, 0, MDL_CULL_VFC | MDL_CULL_DIST);
}
#endif
}
VARP(teamskins, 0, 0, 1);
@ -310,7 +304,7 @@ namespace game
base = 0;
interp = &guninterp;
}
rendermodel(gunname, anim, sway, testhudgun ? 0 : d->yaw, testhudgun ? 0 : d->pitch, MDL_NOBATCH, interp, a, base, (int)ceil(speed));
rendermodel(gunname, anim, sway, testhudgun ? 0 : d->yaw, testhudgun ? 0 : d->pitch, 0, MDL_NOBATCH, interp, a, base, (int)ceil(speed));
if(d->muzzle.x >= 0) d->muzzle = calcavatarpos(d->muzzle, 12);
}

View File

@ -842,7 +842,7 @@ namespace game
}
pitch = -bnc.roll;
if(bnc.bouncetype==BNC_GRENADE)
rendermodel("projectiles/grenade", ANIM_MAPMODEL|ANIM_LOOP, pos, yaw, pitch, MDL_CULL_VFC|MDL_CULL_OCCLUDED);
rendermodel("projectiles/grenade", ANIM_MAPMODEL|ANIM_LOOP, pos, yaw, pitch, 0, MDL_CULL_VFC|MDL_CULL_OCCLUDED);
else
{
const char *mdl = NULL;
@ -856,7 +856,7 @@ namespace game
case BNC_BARRELDEBRIS: mdl = barreldebrisnames[bnc.variant]; break;
default: continue;
}
rendermodel(mdl, ANIM_MAPMODEL|ANIM_LOOP, pos, yaw, pitch, cull, NULL, NULL, 0, 0, fade);
rendermodel(mdl, ANIM_MAPMODEL|ANIM_LOOP, pos, yaw, pitch, 0, cull, NULL, NULL, 0, 0, fade);
}
}
}
@ -876,7 +876,7 @@ namespace game
yaw += 90;
v.mul(3);
v.add(pos);
rendermodel("projectiles/rocket", ANIM_MAPMODEL|ANIM_LOOP, v, yaw, pitch, MDL_CULL_VFC|MDL_CULL_OCCLUDED);
rendermodel("projectiles/rocket", ANIM_MAPMODEL|ANIM_LOOP, v, yaw, pitch, 0, MDL_CULL_VFC|MDL_CULL_OCCLUDED);
}
}

View File

@ -384,8 +384,8 @@ struct modelattach
modelattach(const char *tag, vec *pos) : tag(tag), name(NULL), anim(-1), basetime(0), pos(pos), m(NULL) {}
};
extern void rendermodel(const char *mdl, int anim, const vec &o, float yaw = 0, float pitch = 0, int cull = MDL_CULL_VFC | MDL_CULL_DIST | MDL_CULL_OCCLUDED, dynent *d = NULL, modelattach *a = NULL, int basetime = 0, int basetime2 = 0, float size = 1, float trans = 1);
extern int intersectmodel(const char *mdl, int anim, const vec &pos, float yaw, float pitch, const vec &o, const vec &ray, float &dist, int mode = 0, dynent *d = NULL, modelattach *a = NULL, int basetime = 0, int basetime2 = 0, float size = 1);
extern void rendermodel(const char *mdl, int anim, const vec &o, float yaw = 0, float pitch = 0, float roll = 0, int cull = MDL_CULL_VFC | MDL_CULL_DIST | MDL_CULL_OCCLUDED, dynent *d = NULL, modelattach *a = NULL, int basetime = 0, int basetime2 = 0, float size = 1, float trans = 1);
extern int intersectmodel(const char *mdl, int anim, const vec &pos, float yaw, float pitch, float roll, const vec &o, const vec &ray, float &dist, int mode = 0, dynent *d = NULL, modelattach *a = NULL, int basetime = 0, int basetime2 = 0, float size = 1);
extern void abovemodel(vec &o, const char *mdl);
extern void renderclient(dynent *d, const char *mdlname, modelattach *attachments, int hold, int attack, int attackdelay, int lastaction, int lastpain, float scale = 1, bool ragdoll = false, float trans = 1);
extern void interpolateorientation(dynent *d, float &interpyaw, float &interppitch);