model roll
parent
c4b8fa99bd
commit
1a21d747cf
|
@ -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();
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ¢er, vec &radius, int yaw, int pitch);
|
||||
extern void rotatebb(vec ¢er, 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();
|
||||
|
|
|
@ -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 ¢er, 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) {}
|
||||
|
|
|
@ -197,9 +197,10 @@ namespace mpr
|
|||
vec o, radius;
|
||||
quat orient;
|
||||
|
||||
ModelOBB(const vec &ent, const vec ¢er, const vec &radius, float yaw, float pitch) : o(ent), radius(radius), orient(vec(0, 0, 1), yaw*RAD)
|
||||
ModelOBB(const vec &ent, const vec ¢er, 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 ¢er, const vec &radius, float yaw, float pitch) : o(ent), radius(radius), orient(vec(0, 0, 1), yaw*RAD)
|
||||
ModelEllipse(const vec &ent, const vec ¢er, 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));
|
||||
}
|
||||
|
||||
|
|
|
@ -715,8 +715,18 @@ bool plcollide(physent *d, const vec &dir) // collide with player or monster
|
|||
return true;
|
||||
}
|
||||
|
||||
void rotatebb(vec ¢er, vec &radius, int yaw, int pitch)
|
||||
void rotatebb(vec ¢er, 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 ¢er, 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 ¢er, const vec &radius, float yaw, float pitch)
|
||||
static inline bool mmcollide(physent *d, const vec &dir, const extentity &e, const vec ¢er, 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;
|
||||
}
|
||||
|
|
|
@ -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 ¢er, 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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue