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), float dist = 2.0f*max(radius.magnitude2(), 1.1f*radius.z),
yaw = fmod(lastmillis/10000.0f*360.0f, 360.0f); yaw = fmod(lastmillis/10000.0f*360.0f, 360.0f);
vec o(-center.x, dist - center.y, -0.1f*dist - center.z); 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(); modelpreview::end();
hudshader->set(); hudshader->set();

View File

@ -1044,25 +1044,31 @@ struct animmodel : model
static int intersectresult, intersectmode; static int intersectresult, intersectmode;
static float intersectdist, intersectscale; 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; if(!loaded) return -1;
yaw += spinyaw*lastmillis/1000.0f;
pitch += spinpitch*lastmillis/1000.0f;
vec axis(1, 0, 0), forward(0, 1, 0); vec axis(1, 0, 0), forward(0, 1, 0);
matrixpos = 0; matrixpos = 0;
matrixstack[0].identity(); matrixstack[0].identity();
if(!d || !d->ragdoll || anim&ANIM_RAGDOLL) 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].settranslation(pos);
matrixstack[0].rotate_around_z(yaw*RAD); 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(axis), axis);
matrixstack[0].transformnormal(vec(forward), forward); 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(offsetyaw) matrixstack[0].rotate_around_z(offsetyaw*RAD);
if(offsetpitch) matrixstack[0].rotate_around_x(offsetpitch*RAD); if(offsetpitch) matrixstack[0].rotate_around_x(offsetpitch*RAD);
if(offsetroll) matrixstack[0].rotate_around_y(-offsetroll*RAD);
} }
else 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; if(!loaded) return;
yaw += spinyaw*lastmillis/1000.0f;
pitch += spinpitch*lastmillis/1000.0f;
vec axis(1, 0, 0), forward(0, 1, 0); vec axis(1, 0, 0), forward(0, 1, 0);
matrixpos = 0; matrixpos = 0;
matrixstack[0].identity(); matrixstack[0].identity();
if(!d || !d->ragdoll || anim&ANIM_RAGDOLL) 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].settranslation(o);
matrixstack[0].rotate_around_z(yaw*RAD); 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(axis), axis);
matrixstack[0].transformnormal(vec(forward), forward); 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(offsetyaw) matrixstack[0].rotate_around_z(offsetyaw*RAD);
if(offsetpitch) matrixstack[0].rotate_around_x(offsetpitch*RAD); if(offsetpitch) matrixstack[0].rotate_around_x(offsetpitch*RAD);
if(offsetroll) matrixstack[0].rotate_around_y(-offsetroll*RAD);
} }
else else
{ {
@ -1249,6 +1261,7 @@ struct animmodel : model
m.identity(); m.identity();
if(offsetyaw) m.rotate_around_z(offsetyaw*RAD); if(offsetyaw) m.rotate_around_z(offsetyaw*RAD);
if(offsetpitch) m.rotate_around_x(offsetpitch*RAD); if(offsetpitch) m.rotate_around_x(offsetpitch*RAD);
if(offsetroll) m.rotate_around_y(-offsetroll*RAD);
m.translate(translate, scale); m.translate(translate, scale);
} }
@ -1307,11 +1320,16 @@ struct animmodel : model
bool animated() const bool animated() const
{ {
if(spinyaw || spinpitch) return true; if(spinyaw || spinpitch || spinroll) return true;
loopv(parts) if(parts[i]->animated()) return true; loopv(parts) if(parts[i]->animated()) return true;
return false; return false;
} }
bool pitched() const
{
return parts[0]->pitchscale != 0;
}
virtual bool loaddefaultparts() virtual bool loaddefaultparts()
{ {
return true; return true;

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) bool mmintersect(const extentity &e, const vec &o, const vec &ray, float maxdist, int mode, float &dist)
{ {
extern vector<mapmodelinfo> mapmodels; extern vector<mapmodelinfo> mapmodels;
if(!mapmodels.inrange(e.attr2)) return false; if(!mapmodels.inrange(e.attr1)) return false;
model *m = mapmodels[e.attr2].m; model *m = mapmodels[e.attr1].m;
if(!m) if(!m)
{ {
m = loadmodel(NULL, e.attr2); m = loadmodel(NULL, e.attr1);
if(!m) return false; if(!m) return false;
} }
if(mode&RAY_SHADOW) 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; else if((mode&RAY_ENTS)!=RAY_ENTS && (!m->collide || e.flags&extentity::F_NOCOLLIDE)) return false;
if(!m->bih && !m->setBIH()) return false; if(!m->bih && !m->setBIH()) return false;
vec mo = vec(o).sub(e.o), mray(ray); 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); if(scale > 0) mo.mul(100.0f/scale);
float v = mo.dot(mray), inside = m->bih->radius - mo.squaredlen(); float v = mo.dot(mray), inside = m->bih->radius - mo.squaredlen();
if((inside < 0 && v > 0) || inside + v*v < 0) return false; 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)
{ {
if(yaw < 0) yaw = 360 + yaw%360; 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); mo.rotate_around_x(rot.x, -rot.y);
mray.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(m->bih->traverse(mo, mray, maxdist ? maxdist : 1e16f, dist, mode))
{ {
if(scale > 0) dist *= scale/100.0f; 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 void mousemove(int dx, int dy);
extern bool pointincube(const clipplanes &p, const vec &v); extern bool pointincube(const clipplanes &p, const vec &v);
extern bool overlapsdynent(const vec &o, float radius); 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); extern float shadowray(const vec &o, const vec &ray, float radius, int mode, extentity *t = NULL);
struct ShadowRayCache; struct ShadowRayCache;
extern ShadowRayCache *newshadowraycache(); extern ShadowRayCache *newshadowraycache();
@ -646,7 +646,7 @@ extern void shadowmaskbatchedmodels(bool dynshadow = true);
extern void rendermapmodelbatches(); extern void rendermapmodelbatches();
extern void rendermodelbatches(); extern void rendermodelbatches();
extern void rendertransparentmodelbatches(); 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 clearbatchedmapmodels();
extern void preloadusedmapmodels(bool msg = false, bool bih = false); extern void preloadusedmapmodels(bool msg = false, bool bih = false);
extern int batcheddynamicmodels(); 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 struct model
{ {
float spinyaw, spinpitch, offsetyaw, offsetpitch; float spinyaw, spinpitch, spinroll, offsetyaw, offsetpitch, offsetroll;
bool collide, ellipsecollide, shadow, depthoffset; bool collide, ellipsecollide, shadow, depthoffset;
float scale; float scale;
vec translate; vec translate;
@ -11,11 +11,11 @@ struct model
float eyeheight, collideradius, collideheight; float eyeheight, collideradius, collideheight;
int batch; 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 ~model() { DELETEP(bih); }
virtual void calcbb(vec &center, vec &radius) = 0; 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 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, dynent *d, modelattach *a = NULL, float size = 1, float trans = 1) = 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 bool load() = 0;
virtual const char *name() const = 0; virtual const char *name() const = 0;
virtual int type() const = 0; virtual int type() const = 0;
@ -23,6 +23,7 @@ struct model
virtual bool envmapped() { return false; } virtual bool envmapped() { return false; }
virtual bool skeletal() const { return false; } virtual bool skeletal() const { return false; }
virtual bool animated() const { return false; } virtual bool animated() const { return false; }
virtual bool pitched() const { return true; }
virtual void setshader(Shader *shader) {} virtual void setshader(Shader *shader) {}
virtual void setenvmap(float envmapmin, float envmapmax, Texture *envmap) {} virtual void setenvmap(float envmapmin, float envmapmax, Texture *envmap) {}

View File

@ -197,9 +197,10 @@ namespace mpr
vec o, radius; vec o, radius;
quat orient; 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(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)); o.add(orient.rotate(center));
} }
@ -238,9 +239,10 @@ namespace mpr
vec o, radius; vec o, radius;
quat orient; 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(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)); 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; 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)
{ {
if(pitch < 0) pitch = 360 + pitch%360; 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> 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); E entvol(d);
M mdlvol(e.o, center, radius, yaw, pitch); M mdlvol(e.o, center, radius, yaw, pitch, roll);
vec cp; vec cp;
if(mpr::collide(entvol, mdlvol, NULL, NULL, &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]]; extentity &e = *ents[oc.mapmodels[i]];
if(e.flags&extentity::F_NOCOLLIDE) continue; if(e.flags&extentity::F_NOCOLLIDE) continue;
model *m = loadmodel(NULL, e.attr2); model *m = loadmodel(NULL, e.attr1);
if(!m || !m->collide) continue; if(!m || !m->collide) continue;
vec center, radius; vec center, radius;
m->collisionbox(center, radius); m->collisionbox(center, radius);
if(e.attr4 > 0) { float scale = e.attr4/100.f; center.mul(scale); radius.mul(scale); } if(e.attr5 > 0) { float scale = e.attr5/100.f; center.mul(scale); radius.mul(scale); }
int yaw = e.attr1, pitch = e.attr3; int yaw = e.attr2, pitch = e.attr3, roll = e.attr4;
switch(d->collidetype) switch(d->collidetype)
{ {
case COLLIDE_ELLIPSE: case COLLIDE_ELLIPSE:
if(pitch) rotatebb(center, radius, 0, pitch); if(pitch || roll) rotatebb(center, radius, 0, pitch, roll);
if(m->ellipsecollide) 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; 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; else if(!ellipserectcollide(d, dir, e.o, center, yaw, radius.x, radius.y, radius.z, radius.z)) return false;
break; break;
case COLLIDE_OBB: case COLLIDE_OBB:
if(m->ellipsecollide) 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; break;
case COLLIDE_AABB: case COLLIDE_AABB:
default: 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; if(!rectcollide(d, dir, center.add(e.o), radius.x, radius.y, radius.z, radius.z)) return false;
break; break;
} }

View File

@ -148,14 +148,15 @@ void mdlshader(char *shader)
COMMAND(mdlshader, "s"); COMMAND(mdlshader, "s");
void mdlspin(float *yaw, float *pitch) void mdlspin(float *yaw, float *pitch, float *roll)
{ {
checkmdl; checkmdl;
loadingmodel->spinyaw = *yaw; loadingmodel->spinyaw = *yaw;
loadingmodel->spinpitch = *pitch; loadingmodel->spinpitch = *pitch;
loadingmodel->spinroll = *roll;
} }
COMMAND(mdlspin, "ff"); COMMAND(mdlspin, "fff");
void mdlscale(int *percent) void mdlscale(int *percent)
{ {
@ -192,6 +193,14 @@ void mdlpitch(float *angle)
COMMAND(mdlpitch, "f"); COMMAND(mdlpitch, "f");
void mdlroll(float *angle)
{
checkmdl;
loadingmodel->offsetroll = *angle;
}
COMMAND(mdlroll, "f");
void mdlshadow(int *shadow) void mdlshadow(int *shadow)
{ {
checkmdl; checkmdl;
@ -454,7 +463,7 @@ bool modeloccluded(const vec &center, float radius)
struct batchedmodel struct batchedmodel
{ {
vec pos, center; vec pos, center;
float radius, yaw, pitch, sizescale, transparent; float radius, yaw, pitch, roll, sizescale, transparent;
int anim, basetime, basetime2, flags, attached; int anim, basetime, basetime2, flags, attached;
union union
{ {
@ -511,7 +520,7 @@ static inline void renderbatchedmodel(model *m, batchedmodel &b)
if(b.flags&MDL_FULLBRIGHT) anim |= ANIM_FULLBRIGHT; 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); VARP(maxmodelradiusdistance, 10, 200, 1000);
@ -872,7 +881,7 @@ void clearbatchedmapmodels()
batchedmodels.setsize(len); 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; if(!mapmodels.inrange(idx)) return;
mapmodelinfo &mmi = mapmodels[idx]; 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); m->boundbox(center, bbradius);
float radius = bbradius.magnitude(); float radius = bbradius.magnitude();
center.mul(size); 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.rotate_around_z(yaw*RAD);
center.add(o); center.add(o);
radius *= size; radius *= size;
@ -904,6 +915,7 @@ void rendermapmodel(int idx, int anim, const vec &o, float yaw, float pitch, int
b.anim = anim; b.anim = anim;
b.yaw = yaw; b.yaw = yaw;
b.pitch = pitch; b.pitch = pitch;
b.roll = roll;
b.basetime = basetime; b.basetime = basetime;
b.basetime2 = 0; b.basetime2 = 0;
b.sizescale = size; 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); 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); model *m = loadmodel(mdl);
if(!m) return; if(!m) return;
@ -931,6 +943,8 @@ void rendermodel(const char *mdl, int anim, const vec &o, float yaw, float pitch
else else
{ {
center.mul(size); 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.rotate_around_z(yaw*RAD);
center.add(o); center.add(o);
} }
@ -970,7 +984,7 @@ void rendermodel(const char *mdl, int anim, const vec &o, float yaw, float pitch
m->startrender(); m->startrender();
setaamask(true); setaamask(true);
if(flags&MDL_FULLBRIGHT) anim |= ANIM_FULLBRIGHT; 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(); m->endrender();
if(flags&MDL_CULL_QUERY && d->query) endquery(d->query); if(flags&MDL_CULL_QUERY && d->query) endquery(d->query);
return; return;
@ -984,6 +998,7 @@ void rendermodel(const char *mdl, int anim, const vec &o, float yaw, float pitch
b.anim = anim; b.anim = anim;
b.yaw = yaw; b.yaw = yaw;
b.pitch = pitch; b.pitch = pitch;
b.roll = roll;
b.basetime = basetime; b.basetime = basetime;
b.basetime2 = basetime2; b.basetime2 = basetime2;
b.sizescale = size; 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); 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); model *m = loadmodel(mdl);
if(!m) return -1; 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); 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) 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; 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(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); 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) 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; int anim = ANIM_MAPMODEL|ANIM_LOOP, basetime = 0;
if(e.flags&extentity::F_ANIM) entities::animatemapmodel(e, anim, basetime); 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() void rendermapmodels()

View File

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

View File

@ -350,7 +350,7 @@ struct captureclientmode : clientmode
baseinfo &b = bases[i]; baseinfo &b = bases[i];
if(!b.valid()) continue; if(!b.valid()) continue;
const char *basename = b.owner[0] ? (strcmp(b.owner, player1->team) ? "base/red" : "base/blue") : "base/neutral"; 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; 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_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); //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); abovemodel(height, ammoname);
vec ammopos(b.ammopos); vec ammopos(b.ammopos);
ammopos.z -= height.z/2 + sinf(lastmillis/100.0f)/20; 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) else loopj(b.ammo)
{ {
@ -373,7 +373,7 @@ struct captureclientmode : clientmode
ammopos.x += 10*cosf(angle); ammopos.x += 10*cosf(angle);
ammopos.y += 10*sinf(angle); ammopos.y += 10*sinf(angle);
ammopos.z += 4; 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; int tcolor = 0x1EC850, mtype = -1, mcolor = 0xFFFFFF, mcolor2 = 0;

View File

@ -511,13 +511,13 @@ struct collectclientmode : clientmode
{ {
base &b = bases[i]; base &b = bases[i];
const char *basename = b.team==team ? "base/blue" : "base/red"; 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; 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); 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); vec tokenpos(b.tokenpos);
tokenpos.z -= theight.z/2 + sinf(lastmillis/100.0f)/20; 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; 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)); formatstring(b.info)("%d", totalscore(b.team));
vec above(b.tokenpos); vec above(b.tokenpos);
above.z += TOKENHEIGHT; above.z += TOKENHEIGHT;
@ -528,7 +528,7 @@ struct collectclientmode : clientmode
token &t = tokens[i]; token &t = tokens[i];
vec p = t.o; vec p = t.o;
p.z += 1+sinf(lastmillis/100.0+t.o.x+t.o.y)/20; 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(); fpsent *exclude = isthirdperson() ? NULL : hudplayer();
loopv(players) loopv(players)
@ -539,7 +539,7 @@ struct collectclientmode : clientmode
int dteam = collectteambase(d->team); int dteam = collectteambase(d->team);
loopj(d->tokens) 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; pos.z += TOKENHEIGHT + 1;
} }
} }

View File

@ -610,12 +610,12 @@ struct ctfclientmode : clientmode
#if 0 #if 0
if(m_hold) if(m_hold)
rendermodel(flagname, ANIM_MAPMODEL|ANIM_LOOP, rendermodel(flagname, ANIM_MAPMODEL|ANIM_LOOP,
pos, angle, 0, pos, angle, 0, 0,
MDL_GHOST | MDL_CULL_VFC, MDL_GHOST | MDL_CULL_VFC,
NULL, NULL, 0, 0, 0.5f + 0.5f*(2*fabs(fmod(lastmillis/1000.0f, 1.0f) - 0.5f))); NULL, NULL, 0, 0, 0.5f + 0.5f*(2*fabs(fmod(lastmillis/1000.0f, 1.0f) - 0.5f)));
#endif #endif
rendermodel(flagname, ANIM_MAPMODEL|ANIM_LOOP, rendermodel(flagname, ANIM_MAPMODEL|ANIM_LOOP,
pos, angle, 0, pos, angle, 0, 0,
MDL_CULL_VFC | MDL_CULL_OCCLUDED, 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)); 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; vec p = e.o;
p.z += 1+sinf(lastmillis/100.0+e.o.x+e.o.y)/20; 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 NOTUSED = ET_EMPTY, // entity slot not in use in map
LIGHT = ET_LIGHT, // lightsource, attr1 = radius, attr2 = intensity 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 PLAYERSTART, // attr1 = angle, attr2 = team
ENVMAP = ET_ENVMAP, // attr1 = radius ENVMAP = ET_ENVMAP, // attr1 = radius
PARTICLES = ET_PARTICLES, PARTICLES = ET_PARTICLES,

View File

@ -177,12 +177,6 @@ namespace game
case 2: mdlname = mdl.redteam; break; 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); 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); VARP(teamskins, 0, 0, 1);
@ -310,7 +304,7 @@ namespace game
base = 0; base = 0;
interp = &guninterp; 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); if(d->muzzle.x >= 0) d->muzzle = calcavatarpos(d->muzzle, 12);
} }

View File

@ -842,7 +842,7 @@ namespace game
} }
pitch = -bnc.roll; pitch = -bnc.roll;
if(bnc.bouncetype==BNC_GRENADE) 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 else
{ {
const char *mdl = NULL; const char *mdl = NULL;
@ -856,7 +856,7 @@ namespace game
case BNC_BARRELDEBRIS: mdl = barreldebrisnames[bnc.variant]; break; case BNC_BARRELDEBRIS: mdl = barreldebrisnames[bnc.variant]; break;
default: continue; 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; yaw += 90;
v.mul(3); v.mul(3);
v.add(pos); 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) {} 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 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, 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 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 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 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); extern void interpolateorientation(dynent *d, float &interpyaw, float &interppitch);