Files
BlitzNext/Runtime/blitz3d/md2model.cpp
T

146 lines
3.1 KiB
C++
Raw Normal View History

2014-01-31 08:23:00 +13:00
2019-01-18 15:55:06 +01:00
#include "md2model.hpp"
2019-01-18 17:04:17 +01:00
#include "md2rep.hpp"
#include "std.hpp"
2014-01-31 08:23:00 +13:00
2019-01-18 17:04:17 +01:00
struct MD2Model::Rep : public MD2Rep {
2014-01-31 08:23:00 +13:00
int ref_cnt;
2019-01-18 17:04:17 +01:00
Rep(const string& f) : MD2Rep(f), ref_cnt(1) {}
2014-01-31 08:23:00 +13:00
};
2019-01-18 17:04:17 +01:00
MD2Model::MD2Model(const string& f)
: rep(new Rep(f)), anim_mode(0), anim_time(0), render_a(0), render_b(0), render_t(0), trans_verts(0)
{}
2014-01-31 08:23:00 +13:00
2019-01-18 17:04:17 +01:00
MD2Model::MD2Model(const MD2Model& t)
: Model(t), rep(t.rep), anim_mode(0), anim_time(0), render_a(0), render_b(0), render_t(0), trans_verts(0)
{
2014-01-31 08:23:00 +13:00
++rep->ref_cnt;
}
2019-01-18 17:04:17 +01:00
MD2Model::~MD2Model()
{
if (!--rep->ref_cnt)
delete rep;
if (trans_verts)
delete[] trans_verts;
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
void MD2Model::startMD2Anim(int first, int last, int mode, float speed, float trans)
{
if (last < first)
std::swap(first, last);
if (first < 0)
first = 0;
else if (first >= rep->numFrames())
first = rep->numFrames() - 1;
if (last < 0)
last = 0;
else if (last >= rep->numFrames())
last = rep->numFrames() - 1;
if (trans > 0) {
if (!trans_verts)
trans_verts = new MD2Rep::Vert[rep->numVertices()];
if (anim_mode & 0x8000)
rep->render(trans_verts, anim_time, trans_time);
else
rep->render(trans_verts, render_a, render_b, render_t);
trans_speed = 1.0f / trans;
trans_time = 0;
mode |= 0x8000;
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
anim_first = first;
anim_last = last;
anim_len = last - first;
anim_speed = speed;
anim_time = ((mode & 0x7fff) == Animator::ANIM_MODE_LOOP || anim_speed >= 0) ? anim_first : anim_last;
anim_mode = mode;
if (!anim_speed || !anim_len) {
render_a = render_b = anim_time;
render_t = 0;
anim_mode &= 0x8000;
2014-01-31 08:23:00 +13:00
}
}
2019-01-18 17:04:17 +01:00
void MD2Model::animate(float e)
{
Model::animate(e);
if (!anim_mode)
return;
if (anim_mode & 0x8000) {
trans_time += trans_speed;
if (trans_time < 1)
return;
anim_mode &= ~0x8000;
if (!anim_mode)
return;
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
anim_time = anim_time + anim_speed * e;
if (anim_time < anim_first) {
switch (anim_mode) {
2014-01-31 08:23:00 +13:00
case Animator::ANIM_MODE_LOOP:
2019-01-18 17:04:17 +01:00
anim_time += anim_len;
2014-01-31 08:23:00 +13:00
break;
case Animator::ANIM_MODE_PINGPONG:
2019-01-18 17:04:17 +01:00
anim_time = anim_first + (anim_first - anim_time);
anim_speed = -anim_speed;
2014-01-31 08:23:00 +13:00
break;
default:
2019-01-18 17:04:17 +01:00
anim_time = anim_first;
anim_mode = 0;
2014-01-31 08:23:00 +13:00
break;
}
2019-01-18 17:04:17 +01:00
} else if (anim_time >= anim_last) {
switch (anim_mode) {
2014-01-31 08:23:00 +13:00
case Animator::ANIM_MODE_LOOP:
2019-01-18 17:04:17 +01:00
anim_time -= anim_len;
2014-01-31 08:23:00 +13:00
break;
case Animator::ANIM_MODE_PINGPONG:
2019-01-18 17:04:17 +01:00
anim_time = anim_last - (anim_time - anim_last);
anim_speed = -anim_speed;
2014-01-31 08:23:00 +13:00
break;
default:
2019-01-18 17:04:17 +01:00
anim_time = anim_last;
anim_mode = 0;
2014-01-31 08:23:00 +13:00
break;
}
}
2019-01-18 17:04:17 +01:00
render_a = floor(anim_time);
render_b = render_a + 1;
if (anim_mode == Animator::ANIM_MODE_LOOP && render_b == anim_last)
render_b = anim_first;
render_t = anim_time - render_a;
2014-01-31 08:23:00 +13:00
}
2019-01-18 17:04:17 +01:00
bool MD2Model::render(const RenderContext& rc)
{
2014-01-31 08:23:00 +13:00
static Frustum f;
2019-01-18 17:04:17 +01:00
new (&f) Frustum(rc.getWorldFrustum(), -getRenderTform());
if (!f.cull(rep->getBox()))
return false;
if (anim_mode & 0x8000) {
rep->render(this, trans_verts, anim_time, trans_time);
} else {
rep->render(this, render_a, render_b, render_t);
2014-01-31 08:23:00 +13:00
}
return false;
}
2019-01-18 17:04:17 +01:00
int MD2Model::getMD2AnimLength() const
{
2014-01-31 08:23:00 +13:00
return rep->numFrames();
}
2019-01-18 17:04:17 +01:00
bool MD2Model::getValid() const
{
return rep->numFrames() > 0;
2014-01-31 08:23:00 +13:00
}