diff options
-rw-r--r-- | src/model/fragment.h | 22 | ||||
-rw-r--r-- | src/model/mapfile.cc | 35 | ||||
-rw-r--r-- | src/model/mapfile.h | 1 | ||||
-rw-r--r-- | src/render/draw.cc | 10 |
4 files changed, 65 insertions, 3 deletions
diff --git a/src/model/fragment.h b/src/model/fragment.h index 31b7b96..58ff4bb 100644 --- a/src/model/fragment.h +++ b/src/model/fragment.h @@ -79,7 +79,7 @@ private: class FragmentGroup { public: - enum Type {None = 0, Rotate = 1, Door = 2 }; + enum Type {None = 0, Rotate = 1, Move = 3, Door = 2 }; /// type definition for a list of model fragments typedef std::list<Fragment *> Fragments; @@ -105,6 +105,10 @@ public: inline const float speed() const { return group_speed; } + + inline const float distance() const { + return group_distance; + } inline const float scale() const { return group_scale; @@ -140,13 +144,28 @@ public: group_location.assign(location); } + /** + * @brief rotation axis + * For normal groups, this is the transformation matrix + * For rotating groups axis->forward() is the axis of the rotation. + * For movers, axis->forward() is the axis of movement. + */ inline void set_axis(const math::Axis &axis) { group_axis.assign(axis); } + /** + * @brief movement speed + * For rotating groups this is the number of degrees per second + * For movers, this is the speed in units per second + */ inline void set_speed(const float speed) { group_speed = speed; } + + inline void set_distance(const float distance) { + group_distance = distance; + } inline void set_scale(const float scale) { group_scale = scale; @@ -170,6 +189,7 @@ private: Type group_type; float group_speed; float group_scale; + float group_distance; bool group_transform; bool group_engine; diff --git a/src/model/mapfile.cc b/src/model/mapfile.cc index 09bb3af..f21484a 100644 --- a/src/model/mapfile.cc +++ b/src/model/mapfile.cc @@ -152,6 +152,7 @@ MapFile::MapFile() warning_q2brush = false; class_engine = false; class_speed = 0; + class_distance = 0; // the initial bounding box value is invalid: max and min are switched class_box.assign(MAX_BOUNDS, -MAX_BOUNDS); @@ -1123,6 +1124,7 @@ void MapFile::clear_bbox() class_box.assign(MAX_BOUNDS, -MAX_BOUNDS); class_axis.clear(); class_speed = 0; + class_distance = 0; class_engine = false; } @@ -1143,6 +1145,11 @@ void MapFile::load_fragmentgroup(Model *model, const FragmentGroup::Type class_t } group->set_speed(class_speed); group->set_engine(class_engine); + + } else if (class_type == FragmentGroup::Move) { + group->set_speed(class_speed); + group->set_distance(class_distance); + group->set_engine(class_engine); } // expand bounding box @@ -1351,6 +1358,34 @@ Model * MapFile::load(std::string const &name) mapfile.load_fragmentgroup(model, FragmentGroup::None); mapfile.clear_materials(); + } else if (mapfile.got_classname("func_move")) { + mapfile.clear_bbox(); + + } else if (mapfile.got_classend("func_move")) { + mapfile.load_fragmentgroup(model, FragmentGroup::Move); + mapfile.clear_materials(); + + } else if (mapfile.in_class("func_move")) { + + if (mapfile.got_key_axis(mapfile.class_axis)) { + continue; + + } else if (mapfile.got_key_int("spawnflags", u)) { + mapfile.class_engine = spawnflag_isset(u, 4); + continue; + + } else if (mapfile.got_key_float("speed", s)) { + mapfile.class_speed = s * SCALE; + continue; + + } else if (mapfile.got_key_float("distance", s)) { + mapfile.class_distance = s * SCALE; + continue; + + } else if (mapfile.got_key()) { + mapfile.unknown_key(); + } + } else if (mapfile.got_classname("func_rotate")) { mapfile.clear_bbox(); diff --git a/src/model/mapfile.h b/src/model/mapfile.h index c78b56c..5e4bfd8 100644 --- a/src/model/mapfile.h +++ b/src/model/mapfile.h @@ -196,6 +196,7 @@ private: math::BoundingBox3f class_box; math::Axis class_axis; float class_speed; + float class_distance; bool class_engine; Materials map_materials; diff --git a/src/render/draw.cc b/src/render/draw.cc index 30271f5..1e166b3 100644 --- a/src/render/draw.cc +++ b/src/render/draw.cc @@ -608,10 +608,16 @@ void draw_model_fragments(model::Model *model, if (group->type() == model::FragmentGroup::Rotate) { const float rotation_angle = math::degrees360f((group->engine() ? enginetime : core::application()->time()) * group->speed()); gl::rotate(-rotation_angle, group->axis().forward()); - } else { + + } else if (group->type() == model::FragmentGroup::Move ) { + const float speed = group->distance() / group->speed(); // units per second + math::Vector3f translation(group->axis().forward() * group->distance()); + translation *= sinf((group->engine() ? enginetime : core::application()->time()) * M_PI * speed) * 0.5f + 0.5f; + gl::translate(translation); + } else { gl::multmatrix(group->axis()); } - + const float s = group->scale(); if (s) gl::scale(s, s, s); |