Project::OSiRiON - Git repositories
Project::OSiRiON
News . About . Screenshots . Downloads . Forum . Wiki . Tracker . Git
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStijn Buys <ingar@osirion.org>2008-12-21 12:12:53 +0000
committerStijn Buys <ingar@osirion.org>2008-12-21 12:12:53 +0000
commitaad0913d91fc3b682deddb5a5f8380d1475174f5 (patch)
tree5b1489a36e7640805058d99db0a0c44447949f4a
parentda4b99de2cf290ccdd22587a8c50aeeadd5ac957 (diff)
improved func_rotate
-rw-r--r--doc/models.html30
-rw-r--r--src/model/fragment.h14
-rw-r--r--src/model/map.cc54
-rw-r--r--src/model/map.h10
-rw-r--r--src/model/model.h3
-rw-r--r--src/render/draw.cc13
-rw-r--r--src/render/particles.cc1
7 files changed, 99 insertions, 26 deletions
diff --git a/doc/models.html b/doc/models.html
index d2f6ca7..28ba9c7 100644
--- a/doc/models.html
+++ b/doc/models.html
@@ -49,6 +49,7 @@
<li><a href="#lights">Lights</a>
<li><a href="#flares">Flares</a>
<li><a href="#particles">Particles</a>
+ <li><a href="#groups">Function groups</a>
<li><a href="#other_entities">Other entities</a>
</ul>
@@ -56,9 +57,9 @@
Creating models with GtkRadiant
</h2>
<p>
- All the models for the game were created with GtkRadiant 1.5.0,
+ All the models for the game were created with GtkRadiant 1.5,
in theory any editor capable of exporting Quake 2 .map files could
- be used. Support for files for GtkRadiant 1.5.0 are included in the
+ be used. Support for files for GtkRadiant 1.5 are included in the
data distribution. Refer to the file INSTALL on where to find them
and how to install them. No map compiler is necessary, the engine
reads the .map files directly.
@@ -183,17 +184,17 @@
to the level but to add point lights to a model. Adding a light will
render a light flare texture in the corresponding location.
<p>
- The flare value indicates what texture will be used to draw the light.
+ The <i>flare</i> value indicates what texture will be used to draw the light.
The flare value is translated to a texture name, <i>bitmaps/fx/flare??</i>.
The default flare texture is <i>flare00</i>.
<p>
- The light value is used to determine the size of the flare. The engine
+ The <i>light</i> value is used to determine the size of the flare. The engine
default is 100, resulting in rather large flares.
<p>
- The default color is white, but the color can be set through radiant's
+ The default <i>_color</i> is white, but the color can be set through radiant's
color menu (K key). If the <i>entity</i> option (spawnflag 2) is set, the
color value will be ignored and the light will be rendered with the
- color of the entity it is attached to.
+ color of the entity it is attached to.
<p>
The <i>strobe</i> option (spawnflag 1) will create a blinking light. A number
of options can be set to manipulate the flashing behaviour. By default
@@ -241,6 +242,23 @@
</p><p>
Particles will only be rendered if the model is within detail range.
</p>
+<h2 id="groups">
+ Function groups
+</h2>
+<p>
+ Brushes can be grouped together into funcion groups. These groups can be used
+ to create moving parts in a model.
+</p>
+<p>
+ <i>func_door</i> will be used to create animated doors (not implemented)
+</p>
+<p>
+ <i>func_group</i> an editor utility to group brushes together.
+</p>
+<p>
+ <i>func_rotate</i> will create a rotating set of brushes. The center of the rotation
+ is automaticly calculated as the geometrical center of the group.
+</p>
<h2 id="other_entities">
Other entities
</h2>
diff --git a/src/model/fragment.h b/src/model/fragment.h
index fcdeca3..204a3c9 100644
--- a/src/model/fragment.h
+++ b/src/model/fragment.h
@@ -86,11 +86,16 @@ public:
inline const Type type() const { return group_type; }
+ inline const size_t size() const { return group_fragments.size(); }
+
+ inline const float angle() const { return group_angle; }
+
+ inline const float speed() const { return group_speed; }
+
inline iterator begin() { return group_fragments.begin(); }
inline iterator end() { return group_fragments.end(); }
- inline size_t size() const { return group_fragments.size(); }
inline void push_back(Fragment *fragment) { group_fragments.push_back(fragment); }
@@ -98,7 +103,12 @@ public:
inline void set_type(const Type type) { group_type = type; }
+ inline void set_angle(const float angle) { group_angle = angle; }
+
+ inline void set_speed(const float speed) { group_speed = speed; }
+
void clear();
+
private:
/// type definition for a list of model fragments
typedef std::list<Fragment *> Fragments;
@@ -108,6 +118,8 @@ private:
math::Vector3f group_forward;
Type group_type;
+ float group_angle;
+ float group_speed;
};
}
diff --git a/src/model/map.cc b/src/model/map.cc
index 71b0dda..c073a4d 100644
--- a/src/model/map.cc
+++ b/src/model/map.cc
@@ -242,14 +242,6 @@ bool Map::getline()
return true;
}
-void Map::clear_bbox()
-{
- for (int i=0; i < 3; i++) {
- class_minbbox[i] = MAX_BOUNDS;
- class_maxbbox[i] = -MAX_BOUNDS;
- }
-}
-
void Map::make_brushface(Plane *face)
{
using math::Vector3f;
@@ -678,6 +670,17 @@ void Map::close()
mapfile_ifs.close();
}
+void Map::clear_bbox()
+{
+ for (int i=0; i < 3; i++) {
+ class_minbbox[i] = MAX_BOUNDS;
+ class_maxbbox[i] = -MAX_BOUNDS;
+ }
+
+ class_angle = 0;
+ class_speed = 0;
+}
+
void Map::load_worldspawn(Model *model)
{
if (!map_materials.size())
@@ -694,7 +697,7 @@ void Map::load_worldspawn(Model *model)
load_fragmentgroup(model, FragmentGroup::None);
}
-void Map::load_fragmentgroup(Model *model, const FragmentGroup::Type type)
+void Map::load_fragmentgroup(Model *model, const FragmentGroup::Type class_type)
{
if (!VertexArray::instance() || VertexArray::instance()->overflow())
return;
@@ -702,9 +705,18 @@ void Map::load_fragmentgroup(Model *model, const FragmentGroup::Type type)
if (!map_materials.size())
return;
+ if (class_type == FragmentGroup::Rotate) {
+ if (class_speed == 0) {
+ // default rotation speed 45 degrees per second
+ class_speed = 45.0f;
+ }
+ }
+
FragmentGroup *group = new FragmentGroup();
- group->set_type(type);
+ group->set_type(class_type);
group->set_location((class_minbbox + class_maxbbox) / 2.0f - map_center);
+ group->set_angle(class_angle);
+ group->set_speed(class_speed);
for (Materials::iterator mit = map_materials.begin(); mit != map_materials.end(); mit++) {
// split the Primitives with this material into fragments
@@ -819,7 +831,7 @@ Model * Map::load(std::string const &name)
mapfile.load_worldspawn(model);
mapfile.clear_materials();
- } else if (mapfile.classname().compare("worldspawn") == 0) {
+ } else if (mapfile.in_class("worldspawn")) {
// worldspawn attributes
if (mapfile.got_key_int("enginesound", u)) {
@@ -832,14 +844,12 @@ Model * Map::load(std::string const &name)
} else if (mapfile.got_key_color("enginecolor", model->model_enginecolor)) {
continue;
-/*
- } else if (mapfile.got_key("name")) {
- continue;
-*/
+
} else if (mapfile.got_key()) {
con_warn "Unknown key " << mapfile.classname() << ":" << mapfile.key() << std::endl;
}
+
} else if (mapfile.got_classname("func_door")) {
mapfile.clear_bbox();
@@ -847,6 +857,8 @@ Model * Map::load(std::string const &name)
mapfile.load_fragmentgroup(model, FragmentGroup::Door);
mapfile.clear_materials();
+ } else if (mapfile.in_class("func_door")) {
+
} else if (mapfile.got_classname("func_group")) {
mapfile.clear_bbox();
@@ -861,6 +873,18 @@ Model * Map::load(std::string const &name)
mapfile.load_fragmentgroup(model, FragmentGroup::Rotate);
mapfile.clear_materials();
+ } else if (mapfile.in_class("func_rotate")) {
+
+ if (mapfile.got_key_float("angle", mapfile.class_angle)) {
+ continue;
+
+ } else if (mapfile.got_key_float("speed", mapfile.class_speed)) {
+ continue;
+
+ } else if (mapfile.got_key()) {
+ con_warn "Unknown key " << mapfile.classname() << ":" << mapfile.key() << std::endl;
+ }
+
} else if (mapfile.got_classend()) {
mapfile.clear_materials();
diff --git a/src/model/map.h b/src/model/map.h
index 9b75f7a..f9b036f 100644
--- a/src/model/map.h
+++ b/src/model/map.h
@@ -64,6 +64,11 @@ private:
/// true if the last read line contained a new classname
bool got_classname() const;
+ /// true if we are inside the requested class
+ bool in_class(const char *name) {
+ return (classname_current.compare(name) == 0);
+ }
+
/// true if the last read line contained a class closing bracket
inline bool got_classend() const
{
@@ -130,7 +135,7 @@ private:
void load_worldspawn(Model *model);
/// load parsed primitives into a FragmentGroup
- void load_fragmentgroup(Model *model, const FragmentGroup::Type type);
+ void load_fragmentgroup(Model *model, const FragmentGroup::Type class_type);
/// clear the current list of per-material geometry
void clear_materials();
@@ -160,9 +165,10 @@ private:
math::Vector3f class_maxbbox;
math::Vector3f class_minbbox;
+ float class_angle;
+ float class_speed;
math::Vector3f map_center;
-
Materials map_materials;
};
diff --git a/src/model/model.h b/src/model/model.h
index bdaa74a..6e9c5d8 100644
--- a/src/model/model.h
+++ b/src/model/model.h
@@ -23,6 +23,9 @@ namespace model
const float SCALE = 1.0f / 1024.0f;
const float LIGHTSCALE = 1.0f / 100.0f;
+const float ANGLEUP = -1.0f;
+const float ANGLEDOWN = -2.0f;
+
/// a 3D model contains a list of faces
class Model
{
diff --git a/src/render/draw.cc b/src/render/draw.cc
index afff831..e094a44 100644
--- a/src/render/draw.cc
+++ b/src/render/draw.cc
@@ -582,8 +582,17 @@ void draw_model_fragments(core::Entity *entity)
if (group->type() == model::FragmentGroup::Rotate) {
gl::push();
gl::translate(group->location());
- float angle = math::degrees360f(core::application()->time() * 90.0f);
- gl::rotate(angle, math::Vector3f::Xaxis());
+
+ float rotation_angle = math::degrees360f(core::application()->time() * group->speed());
+
+ if (group->angle() == model::ANGLEUP) {
+ gl::rotate(rotation_angle, math::Vector3f::Zaxis());
+ } else if (group->angle() == model::ANGLEDOWN) {
+ gl::rotate(-rotation_angle, math::Vector3f::Zaxis());
+ } else {
+ gl::rotate(rotation_angle, math::Vector3f::Xaxis());
+ }
+
gl::translate(group->location()* -1.0f);
}
diff --git a/src/render/particles.cc b/src/render/particles.cc
index 3a9521b..71ec26b 100644
--- a/src/render/particles.cc
+++ b/src/render/particles.cc
@@ -201,6 +201,7 @@ ParticleSystem::ParticleSystem(ParticleScript *script, core::Entity *entity, mod
if (modelclass->engine()) {
color.assign(entity->model()->enginecolor());
}
+ particlesystem_axis.assign(modelclass->axis());
}
}