From 493ddb59a8620b49dfa0ff62ce93395ebfd02e86 Mon Sep 17 00:00:00 2001 From: Charles McGarvey Date: Sun, 16 Aug 2009 01:59:18 -0600 Subject: [PATCH] revamped scene drawing in preparation for octree --- data/scenes/Test.json | 2 +- src/Makefile.am | 2 +- src/Moof/Aabb.cc | 10 +- src/Moof/Aabb.hh | 6 +- src/Moof/Animation.cc | 8 +- src/Moof/Camera.hh | 8 +- src/Moof/Cullable.hh | 8 +- src/Moof/Dispatcher.cc | 20 +- src/Moof/Drawable.hh | 3 +- src/Moof/Entity.hh | 2 +- src/Moof/Frustum.hh | 25 +- src/Moof/Math.hh | 21 ++ src/Moof/Resource.cc | 2 +- src/Moof/Scene.cc | 694 ++++++++++++++++++++------------------- src/Moof/Serializable.hh | 14 +- src/Moof/Settings.cc | 4 +- src/Moof/Tilemap.hh | 1 + src/YoinkApp.cc | 6 - 18 files changed, 450 insertions(+), 386 deletions(-) diff --git a/data/scenes/Test.json b/data/scenes/Test.json index 7b0fd63..562a3be 100644 --- a/data/scenes/Test.json +++ b/data/scenes/Test.json @@ -1,6 +1,6 @@ { "playfield_bounds": [0, 0, -100, 1280, 500, 100], - "maximum_bounds": [-800, 0, -300, 2400, 1000, 600], + "maximum_bounds": [-160, 0, -192, 1440, 512, 224], "instructions": [ diff --git a/src/Makefile.am b/src/Makefile.am index ea68cde..62c10ca 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -85,7 +85,7 @@ EXTRA_DIST = Moof/cml YOINK_ENVIRONMENT = YOINK_DATADIR="$(top_srcdir)/data" run: all - $(YOINK_ENVIRONMENT) ./yoink + $(YOINK_ENVIRONMENT) ./yoink $(YOINK_OPTS) debug: all $(YOINK_ENVIRONMENT) gdb ./yoink diff --git a/src/Moof/Aabb.cc b/src/Moof/Aabb.cc index 7b2ada7..d81c971 100644 --- a/src/Moof/Aabb.cc +++ b/src/Moof/Aabb.cc @@ -27,6 +27,7 @@ *******************************************************************************/ #include +#include namespace Mf { @@ -43,7 +44,7 @@ void Aabb::draw(Scalar alpha) const max[0], min[1], max[2], max[0], max[1], max[2]}; - GLubyte indicis[] = {0, 1, 2, 3, + GLubyte indices[] = {0, 1, 2, 3, 1, 2, 7, 4, 3, 0, 5, 6, 2, 3, 6, 7, @@ -53,7 +54,12 @@ void Aabb::draw(Scalar alpha) const glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(3, GL_SCALAR, 0, vertices); - glDrawElements(GL_QUADS, sizeof(indicis), GL_UNSIGNED_BYTE, indicis); + glDrawElements(GL_QUADS, sizeof(indices), GL_UNSIGNED_BYTE, indices); +} + +bool Aabb::isVisible(const Camera& cam) const +{ + return cam.getFrustum().checkAabb(*this); } diff --git a/src/Moof/Aabb.hh b/src/Moof/Aabb.hh index b43e194..f51531a 100644 --- a/src/Moof/Aabb.hh +++ b/src/Moof/Aabb.hh @@ -29,6 +29,7 @@ #ifndef _MOOF_AABB_HH_ #define _MOOF_AABB_HH_ +#include #include #include @@ -40,7 +41,7 @@ namespace Mf { * Axis-aligned Bounding Box */ -struct Aabb : public Drawable +struct Aabb : public Cullable, public Drawable { Vector3 min; Vector3 max; @@ -103,7 +104,8 @@ struct Aabb : public Drawable (min[2] + max[2]) / 2.0); } - void draw(Scalar alpha) const; + void draw(Scalar alpha = 0.0) const; + bool isVisible(const Camera& cam) const; }; diff --git a/src/Moof/Animation.cc b/src/Moof/Animation.cc index 3c418f7..38ffa6c 100644 --- a/src/Moof/Animation.cc +++ b/src/Moof/Animation.cc @@ -83,7 +83,7 @@ struct Animation::AnimationImpl { std::map::iterator it; - for (it = rootObj.begin(); it != rootObj.end(); it++) + for (it = rootObj.begin(); it != rootObj.end(); ++it) { std::string key = (*it).first; if (key == "index") @@ -132,7 +132,7 @@ struct Animation::AnimationImpl if (root->get(rootObj)) { std::map::iterator it; - for (it = rootObj.begin(); it != rootObj.end(); it++) + for (it = rootObj.begin(); it != rootObj.end(); ++it) { std::string key = (*it).first; @@ -145,7 +145,7 @@ struct Animation::AnimationImpl std::vector::iterator jt; for (jt = framesObj.begin(); - jt != framesObj.end(); jt++) + jt != framesObj.end(); ++jt) { if (*jt) { @@ -196,7 +196,7 @@ struct Animation::AnimationImpl { std::map::iterator it; - for (it = rootObj.begin(); it != rootObj.end(); it++) + for (it = rootObj.begin(); it != rootObj.end(); ++it) { sequences.insert(std::pair((*it).first, Sequence((*it).second))); diff --git a/src/Moof/Camera.hh b/src/Moof/Camera.hh index 8b3b1da..0aa5dc9 100644 --- a/src/Moof/Camera.hh +++ b/src/Moof/Camera.hh @@ -30,6 +30,7 @@ #define _MOOF_CAMERA_HH_ #include +#include #include #include @@ -61,8 +62,12 @@ public: return transformation_; } - void adjustFromInput(const Event& event); + const Frustum& getFrustum() const + { + return frustum_; + } + void adjustFromInput(const Event& event); void update(Scalar t, Scalar dt); private: @@ -70,6 +75,7 @@ private: Quaternion rotation_; Matrix4 transformation_; + Frustum frustum_; Lerpv3 pInterp_; diff --git a/src/Moof/Cullable.hh b/src/Moof/Cullable.hh index 34a09b6..b25840e 100644 --- a/src/Moof/Cullable.hh +++ b/src/Moof/Cullable.hh @@ -29,12 +29,12 @@ #ifndef _MOOF_CULLABLE_HH_ #define _MOOF_CULLABLE_HH_ -#include - namespace Mf { +class Camera; + /** * Interface for anything that can be culled. */ @@ -42,7 +42,9 @@ namespace Mf { class Cullable { public: - virtual bool isVisible(const Camera& cam) const + inline virtual ~Cullable() {} + + inline virtual bool isVisible(const Camera& cam) const { return true; } diff --git a/src/Moof/Dispatcher.cc b/src/Moof/Dispatcher.cc index fa7b328..e0d3d21 100644 --- a/src/Moof/Dispatcher.cc +++ b/src/Moof/Dispatcher.cc @@ -94,18 +94,18 @@ void Dispatcher::removeHandler(Handler id) std::pair handlers(impl_->handlers.equal_range(id)); - Dispatcher::DispatcherImpl::HandlerIter i; - for (i = handlers.first; i != handlers.second; i++) + Dispatcher::DispatcherImpl::HandlerIter it; + for (it = handlers.first; it != handlers.second; ++it) { - Dispatcher::DispatcherImpl::CallbackIter it = impl_->callbacks.find((*i).second); + Dispatcher::DispatcherImpl::CallbackIter first = impl_->callbacks.find((*it).second); Dispatcher::DispatcherImpl::CallbackIter last = impl_->callbacks.end(); - Dispatcher::DispatcherImpl::CallbackIter j; - for (j = it; j != last; j++) + Dispatcher::DispatcherImpl::CallbackIter jt; + for (jt = first; jt != last; ++jt) { - if (((*j).second).first == id) + if (((*jt).second).first == id) { - impl_->callbacks.erase(j); + impl_->callbacks.erase(jt); break; } } @@ -125,10 +125,10 @@ void Dispatcher::dispatch(const std::string& message, const Notification& param) std::pair callbacks(impl_->callbacks.equal_range(message)); - Dispatcher::DispatcherImpl::CallbackIter i; - for (i = callbacks.first; i != callbacks.second; i++) + Dispatcher::DispatcherImpl::CallbackIter it; + for (it = callbacks.first; it != callbacks.second; ++it) { - Function callback = ((*i).second).second; + Function callback = ((*it).second).second; callback(param); } } diff --git a/src/Moof/Drawable.hh b/src/Moof/Drawable.hh index 1554b11..5cfd628 100644 --- a/src/Moof/Drawable.hh +++ b/src/Moof/Drawable.hh @@ -29,7 +29,6 @@ #ifndef _MOOF_DRAWABLE_HH_ #define _MOOF_DRAWABLE_HH_ -#include #include @@ -43,6 +42,8 @@ namespace Mf { class Drawable { public: + inline virtual ~Drawable() {} + virtual void draw(Scalar alpha) const = 0; }; diff --git a/src/Moof/Entity.hh b/src/Moof/Entity.hh index 738e137..7595054 100644 --- a/src/Moof/Entity.hh +++ b/src/Moof/Entity.hh @@ -32,8 +32,8 @@ #include #include -#include #include +#include namespace Mf { diff --git a/src/Moof/Frustum.hh b/src/Moof/Frustum.hh index 82eba17..ac2b353 100644 --- a/src/Moof/Frustum.hh +++ b/src/Moof/Frustum.hh @@ -35,16 +35,31 @@ namespace Mf { +class Aabb; + class Frustum { - Matrix4 projection; - //Plane left, right, bottom, top, near, far; + //Matrix4 projection; + Plane left, right, bottom, top, near, far; public: - Frustum(Scalar l, Scalar r, Scalar b, Scalar t, Scalar n, Scalar f); - Frustum(Scalar fovy, Scalar aspect, Scalar near, Scalar far); + typedef enum + { + OUTSIDE = 0, + INSIDE = 1, + INTERSECT = 2 + } Collision; + + //Frustum() {} + //Frustum(Scalar l, Scalar r, Scalar b, Scalar t, Scalar n, Scalar f); + //Frustum(Scalar fovy, Scalar aspect, Scalar near, Scalar far); + + inline Collision checkAabb(const Aabb& aabb) const + { + return INSIDE; + } - const Matrix4& getMatrix() const; + //const Matrix4& getMatrix() const; }; diff --git a/src/Moof/Math.hh b/src/Moof/Math.hh index c4e3484..4e1cda8 100644 --- a/src/Moof/Math.hh +++ b/src/Moof/Math.hh @@ -57,6 +57,27 @@ typedef cml::matrix< Scalar, cml::fixed<4,4>, typedef cml::quaternion< Scalar, cml::fixed<>, cml::vector_first, cml::positive_cross > Quaternion; +typedef cml::constants Constants; + + +inline Vector3& demoteVector(Vector3& left, const Vector4& right) +{ + left[0] = right[0]; + left[1] = right[1]; + left[2] = right[2]; + return left; +} + +inline Vector4& promoteVector(Vector4& left, const Vector3& right) +{ + left[0] = right[0]; + left[1] = right[1]; + left[2] = right[2]; + left[3] = 1.0; + return left; +} + + const Scalar EPSILON = 0.000001; diff --git a/src/Moof/Resource.cc b/src/Moof/Resource.cc index 5efe8f5..e21c834 100644 --- a/src/Moof/Resource.cc +++ b/src/Moof/Resource.cc @@ -58,7 +58,7 @@ std::string Resource::getPathToResource(const std::string& name) { std::vector::iterator it; - for (it = searchPaths_.begin(); it != searchPaths_.end(); it++) + for (it = searchPaths_.begin(); it != searchPaths_.end(); ++it) { std::string fullPath(*it); fullPath += name; diff --git a/src/Moof/Scene.cc b/src/Moof/Scene.cc index b8cb233..adec6ec 100644 --- a/src/Moof/Scene.cc +++ b/src/Moof/Scene.cc @@ -48,255 +48,113 @@ namespace Mf { class Scene::SceneImpl : public Mippleton { - class Scenery : public Entity + class Quad : public Entity { public: - Scenery(const Matrix4& transform, const std::string& textureName) : - transformation(transform), - image(textureName) {} - - protected: - Matrix4 transformation; - Tilemap image; - bool blending; - long detail; - bool fog; - }; - - class TilePanel : public Scenery - { - public: - TilePanel(const Matrix4& transform, const std::string& textureName, - SerializablePtr root) : - Scenery(transform, textureName), - width(1), - height(1) + Quad(const Vector3 vertices[4], const std::string& texture, + Tilemap::Index tileIndex) : + tilemap_(texture), + detail_(0), + blending_(false), + fog_(false) { - std::map rootObj; - - if (root->get(rootObj)) + for (int i = 0, num = 0; i < 4; ++i) { - std::map::iterator it; - - if ((it = rootObj.find("width")) != rootObj.end()) + for (int j = 0; j < 3; ++j, ++num) { - (*it).second->get(width); - } - if ((it = rootObj.find("tiles")) != rootObj.end()) - { - std::vector theTiles; - - if ((*it).second->get(theTiles)) - { - std::vector::iterator jt; - - height = theTiles.size() / width; - int w, h; - - indices.resize(height); - - for (h = height - 1, jt = theTiles.begin(); - jt != theTiles.end(); h--) - { - std::vector row; - - for (w = 0; w < width && jt != theTiles.end(); - w++, jt++) - { - long index; - - if ((*jt)->get(index)) - { - row.push_back(Tilemap::Index(index)); - } - } - - indices[h] = row; - } - } + vertices_[num] = vertices[i][j]; } } - } - - void draw(Scalar alpha) const - { - glPushMatrix(); - //std::cout << "transforming..." << std::endl; - //std::cout << transformation << std::endl; - glMultMatrix(transformation.data()); - - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - image.bind(); - - long x, y; - Scalar xf, yf; - for (y = 0, yf = 0.0; y < height; y++, yf += 1.0) + if (!tilemap_.getTileCoords(tileIndex, texCoords_)) { - for (x = 0, xf = 0.0; x < width; x++, xf += 1.0) - { - Scalar texCoords[8]; - - Tilemap::Index index = indices[y][x]; - - if (image.getTileCoords(index, texCoords)) - { - glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(texCoords[0], texCoords[1]); - glVertex2f(xf, yf); - glTexCoord2f(texCoords[2], texCoords[3]); - glVertex2f(xf+1.0, yf); - glTexCoord2f(texCoords[4], texCoords[5]); - glVertex2f(xf+1.0, yf+1.0); - glTexCoord2f(texCoords[6], texCoords[7]); - glVertex2f(xf, yf+1.0); - glEnd(); - } - } + std::cerr << "no coords for tile's texture" << std::endl; } - - glPopMatrix(); } - bool isVisible(const Camera& cam) + void setDetail(long detail) { - return true; + detail_ = detail; } - private: - long width, height; - std::vector > indices; - }; - - class Billboard : public Scenery - { - public: - Billboard(const Matrix4& transform, const std::string& textureName, - SerializablePtr root) : - Scenery(transform, textureName), - index(0), - uScale(1) + void setBlending(bool blending) { - std::map rootObj; - - if (root->get(rootObj)) - { - std::map::iterator it; - - if ((it = rootObj.find("tile")) != rootObj.end()) - { - long value; - if ((*it).second->get(value)) - { - index = Tilemap::Index(value); - } - } - if ((it = rootObj.find("u_scale")) != rootObj.end()) - { - (*it).second->get(uScale); - } - if ((it = rootObj.find("fog")) != rootObj.end()) - { - (*it).second->get(fog); - } - if ((it = rootObj.find("blend")) != rootObj.end()) - { - (*it).second->get(blending); - } - } - - image.getTileCoords(index, texCoords); + blending_ = blending; } - void draw(Scalar alpha) const + void setFog(bool fog) { - glPushMatrix(); - glMultMatrix(transformation.data()); + fog_ = fog; + } - if (blending) + void draw(Scalar alpha = 0.0) const + { + if (blending_) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - /*if (fog) glEnable(GL_FOG);*/ glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - image.bind(); + tilemap_.bind(); - float increment = 1.0f / float(uScale); - int x; - float xf; + //glEnableClientState(GL_VERTEX_ARRAY); + //glEnableClientState(GL_TEXTURE_COORD_ARRAY); + + //glVertexPointer(3, GL_SCALAR, 0, vertices_); + //glTexCoordPointer(2, GL_SCALAR, 0, texCoords_); + + //glDrawArrays(GL_TRIANGLE_FAN, 0, sizeof(vertices_)); + + //glDisableClientState(GL_VERTEX_ARRAY); + //glDisableClientState(GL_TEXTURE_COORD_ARRAY); - for (x = 0, xf = 0.0f; x < uScale; x++, xf += increment) - { glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(texCoords[0], texCoords[1]); - glVertex2f(xf, 0.0f); - glTexCoord2f(texCoords[2], texCoords[3]); - glVertex2f(xf+increment, 0.0f); - glTexCoord2f(texCoords[4], texCoords[5]); - glVertex2f(xf+increment, 1.0f); - glTexCoord2f(texCoords[6], texCoords[7]); - glVertex2f(xf, 1.0f); + glTexCoord2f(texCoords_[0], texCoords_[1]); + glVertex3v(vertices_); + glTexCoord2f(texCoords_[2], texCoords_[3]); + glVertex3v(vertices_+3); + glTexCoord2f(texCoords_[4], texCoords_[5]); + glVertex3v(vertices_+6); + glTexCoord2f(texCoords_[6], texCoords_[7]); + glVertex3v(vertices_+9); glEnd(); - } glDisable(GL_BLEND); - glDisable(GL_FOG); - - glPopMatrix(); } - bool isVisible(const Camera& cam) + bool isVisible(const Camera& cam) const { - return false; + return aabb_.isVisible(cam); } private: - Tilemap::Index index; - Scalar texCoords[8]; - long uScale; + Scalar vertices_[12]; + Scalar texCoords_[8]; + + Tilemap tilemap_; + + long detail_; + bool blending_; + bool fog_; }; - static bool loadBox(Aabb& theBox, SerializablePtr obj) + static void loadBox(Aabb& theBox, SerializablePtr obj) { std::vector numbers; - if (obj->get(numbers)) + if (obj->get(numbers) && numbers.size() == 6) { - if (numbers.size() == 6) - { - double num; - - if (numbers[0]->getNumber(num)) - { - theBox.min[0] = Scalar(num); - } - if (numbers[1]->getNumber(num)) - { - theBox.min[1] = Scalar(num); - } - if (numbers[2]->getNumber(num)) - { - theBox.min[2] = Scalar(num); - } - if (numbers[3]->getNumber(num)) - { - theBox.max[0] = Scalar(num); - } - if (numbers[4]->getNumber(num)) - { - theBox.max[1] = Scalar(num); - } - if (numbers[5]->getNumber(num)) - { - theBox.max[2] = Scalar(num); - } - } + double num; + + if (numbers[0]->getNumber(num)) theBox.min[0] = Scalar(num); + if (numbers[1]->getNumber(num)) theBox.min[1] = Scalar(num); + if (numbers[2]->getNumber(num)) theBox.min[2] = Scalar(num); + if (numbers[3]->getNumber(num)) theBox.max[0] = Scalar(num); + if (numbers[4]->getNumber(num)) theBox.max[1] = Scalar(num); + if (numbers[5]->getNumber(num)) theBox.max[2] = Scalar(num); } - - return false; } public: @@ -306,42 +164,78 @@ public: loadFromFile(); } - ~SceneImpl() - { - } - void loadInstructions(SerializablePtr root) { std::vector rootObj; + std::vector::iterator it; - if (root->get(rootObj)) + if (!root->get(rootObj)) { - std::vector::iterator it; + std::cerr << "error loading scene instructions" << std::endl; + return; + } - Matrix4 transform; - std::string texture; + Matrix4 transform; + std::string texture; - for (it = rootObj.begin(); it != rootObj.end(); it++) - { - std::string instruction; + for (it = rootObj.begin(); it != rootObj.end(); ++it) + { + std::string instruction; - if ((*it)->get(instruction)) + if ((*it)->get(instruction)) + { + if (instruction == "reset_transform") + { + transform.identity(); + } + else if (instruction == "translate") { - if (instruction == "reset_transform") + std::vector values; + + ++it; + if ((*it)->get(values)) { - transform.identity(); + Vector3 vec; + + for (size_t i = 0; i < values.size(); ++i) + { + double value; + + if (values[i]->getNumber(value)) + { + vec[i] = value; + } + } + + Matrix4 translation; + cml::matrix_translation(translation, vec); + transform = translation * transform; } - else if (instruction == "translate") + } + else if (instruction == "scale") + { + std::vector values; + + ++it; + if ((*it)->get(values)) { - std::vector values; + if (values.size() == 1) + { + double value = 1.0; + + values[0]->getNumber(value); - it++; - if ((*it)->get(values)) + Matrix4 scaling; + cml::matrix_uniform_scale(scaling, + Scalar(value)); + transform = scaling * transform; + } + else if (values.size() == 3) { Vector3 vec; - for (size_t i = 0; i < values.size(); i++) + for (size_t i = 0; i < values.size(); ++i) { double value; @@ -351,155 +245,275 @@ public: } } - Matrix4 translation; - cml::matrix_translation(translation, vec); - transform = translation * transform; + Matrix4 scaling; + cml::matrix_scale(scaling, vec); + transform = scaling * transform; } } - else if (instruction == "scale") - { - std::vector values; + } + else if (instruction == "rotate") + { + std::vector values; - it++; - if ((*it)->get(values)) + ++it; + if ((*it)->get(values)) + { + if (values.size() == 2) { - if (values.size() == 1) - { - double value = 1.0; - - values[0]->getNumber(value); + std::string axis; + size_t index = 0; + double value = 0.0; - Matrix4 scaling; - cml::matrix_uniform_scale(scaling, Scalar(value)); - transform = scaling * transform; - } - else if (values.size() == 3) + if (values[0]->get(axis)) { - Vector3 vec; - - for (size_t i = 0; i < values.size(); i++) - { - double value; - - if (values[i]->getNumber(value)) - { - vec[i] = value; - } - } + if (axis == "x") index = 0; + else if (axis == "y") index = 1; + else if (axis == "z") index = 2; - Matrix4 scaling; - cml::matrix_scale(scaling, vec); - transform = scaling * transform; + values[1]->getNumber(value); } - } - } - else if (instruction == "rotate") - { - std::vector values; - - it++; - if ((*it)->get(values)) - { - if (values.size() == 2) - { - std::string axis; - size_t axisIndex = 0; - double value = 0.0; - Vector3 vec(0.0, 0.0, 0.0); - if (values[0]->get(axis)) - { - if (axis == "x") - { - axisIndex = 0; - vec[0] = 1.0; - } - else if (axis == "y") - { - axisIndex = 1; - vec[1] = 1.0; - } - else if (axis == "z") - { - axisIndex = 2; - vec[2] = 1.0; - } - values[1]->getNumber(value); - } - - cml::matrix_rotate_about_world_axis(transform, - axisIndex, Scalar(value * cml::constantsd::rad_per_deg())); - } + cml::matrix_rotate_about_world_axis(transform, + index, cml::rad(Scalar(value))); } } - else if (instruction == "texture") - { - it++; - (*it)->get(texture); - } - else if (instruction == "tilemap") - { - it++; - TilePanel* tilePanel = new TilePanel(transform, texture, - *it); - boost::shared_ptr sceneItem(tilePanel); - objects.push_back(sceneItem); - } - else if (instruction == "billboard") - { - it++; - Billboard* billboard = new Billboard(transform, texture, - *it); - boost::shared_ptr sceneItem(billboard); - objects.push_back(sceneItem); - } + } + else if (instruction == "texture") + { + ++it; + (*it)->get(texture); + } + else if (instruction == "tilemap") + { + ++it; + loadTilemap(*it, transform, texture); + } + else if (instruction == "billboard") + { + ++it; + loadBillboard(*it, transform, texture); } } } } - void loadFromFile() + void loadTilemap(SerializablePtr root, const Matrix4& transform, + const std::string& texture) { - std::string filePath = Scene::getPathToResource(getName()); + std::map rootObj; + std::map::iterator it; - Deserializer deserializer(filePath, true); + if (!root->get(rootObj)) + { + std::cerr << "error loading scene tilemap object" << std::endl; + return; + } - SerializablePtr root = deserializer.deserialize(); + long width = 1; + long height = 1; + std::vector< std::vector > indices; - if (root) + if ((it = rootObj.find("width")) != rootObj.end()) { - std::map rootObj; + (*it).second->get(width); + } + else + { + std::cerr << "width is a required field of a tilemap" << std::endl; + return; + } - if (root->get(rootObj)) + std::vector tiles; + + if ((it = rootObj.find("tiles")) != rootObj.end() && + (*it).second->get(tiles) && + tiles.size() % width == 0) + { + std::vector::iterator jt; + int w, h; + + height = tiles.size() / width; + indices.resize(height); + + // the indices are stored upside-down in the scene file so that they + // are easier to edit as text, so we'll need to load them last row + // first + + for (h = height - 1, jt = tiles.begin(); jt != tiles.end(); --h) { - std::map::iterator it; + std::vector row; - if ((it = rootObj.find("playfield_bounds")) != rootObj.end()) - { - loadBox(playfieldBounds, (*it).second); - } - if ((it = rootObj.find("maximum_bounds")) != rootObj.end()) + for (w = 0; w < width && jt != tiles.end(); ++w, ++jt) { - loadBox(maximumBounds, (*it).second); - } - if ((it = rootObj.find("instructions")) != rootObj.end()) - { - loadInstructions((*it).second); + long index; + + if ((*jt)->get(index)) + { + row.push_back(Tilemap::Index(index)); + } } + + indices[h] = row; + } + } + else + { + std::cerr << "error loading tiles from tilemap object" << std::endl; + return; + } + + Vector4 vertices[height+1][width+1]; + + Matrix4 transposedTransform = transform; + transposedTransform.transpose(); + + for (int h = 0; h <= height; ++h) + { + for (int w = 0; w <= width; ++w) + { + vertices[h][w] = Vector4(Scalar(w), Scalar(h), 0.0, 1.0) * + transposedTransform; + } + } + + for (int h = 0; h < height; ++h) + { + for (int w = 0; w < width; ++w) + { + if (indices[h][w] == Tilemap::NO_TILE) continue; + + Vector3 quadVertices[4]; + + demoteVector(quadVertices[0], vertices[h][w]); + demoteVector(quadVertices[1], vertices[h][w+1]); + demoteVector(quadVertices[2], vertices[h+1][w+1]); + demoteVector(quadVertices[3], vertices[h+1][w]); + + Quad* quad = new Quad(quadVertices, texture, indices[h][w]); + boost::shared_ptr quadPtr(quad); + + objects.push_back(quadPtr); + } + } + } + + void loadBillboard(SerializablePtr root, const Matrix4& transform, + const std::string& texture) + { + std::map rootObj; + std::map::iterator it; + + if (!root->get(rootObj)) + { + std::cerr << "error loading scene billboard object" << std::endl; + return; + } + + Tilemap::Index index = 0; + long width = 1; + bool blending = false; + bool fog = false; + + if ((it = rootObj.find("tile")) != rootObj.end()) + { + long value; + if ((*it).second->get(value)) + { + index = Tilemap::Index(value); } } - std::cout << "playfield: " << playfieldBounds.min << " ... " << - playfieldBounds.max << std::endl; + if ((it = rootObj.find("u_scale")) != rootObj.end()) + { + (*it).second->get(width); + } + + if ((it = rootObj.find("blend")) != rootObj.end()) + { + (*it).second->get(blending); + } + + if ((it = rootObj.find("fog")) != rootObj.end()) + { + (*it).second->get(fog); + } + + + Vector4 vertices[2][width+1]; + + Matrix4 transposedTransform = transform; + transposedTransform.transpose(); + + Scalar xf; + Scalar increment = 1.0 / Scalar(width); + + for (int h = 0; h <= 1; ++h) + { + xf = 0.0; + for (int w = 0; w <= width; ++w, xf += increment) + { + vertices[h][w] = Vector4(xf, Scalar(h), 0.0, 1.0) * + transposedTransform; + } + } + + for (int w = 0; w < width; ++w) + { + Vector3 quadVertices[4]; + + demoteVector(quadVertices[0], vertices[0][w]); + demoteVector(quadVertices[1], vertices[0][w+1]); + demoteVector(quadVertices[2], vertices[1][w+1]); + demoteVector(quadVertices[3], vertices[1][w]); + + Quad* quad = new Quad(quadVertices, texture, index); + quad->setBlending(blending); + quad->setFog(fog); + + boost::shared_ptr quadPtr(quad); + + objects.push_back(quadPtr); + } + } + + + void loadFromFile() + { + std::string filePath = Scene::getPathToResource(getName()); + + Deserializer deserializer(filePath, true); + SerializablePtr root = deserializer.deserialize(); + + std::map rootObj; + std::map::iterator it; + + if (!root || !root->get(rootObj)) + { + std::cerr << "error loading scene file" << std::endl; + return; + } + + if ((it = rootObj.find("playfield_bounds")) != rootObj.end()) + { + loadBox(playfieldBounds, (*it).second); + } + if ((it = rootObj.find("maximum_bounds")) != rootObj.end()) + { + loadBox(maximumBounds, (*it).second); + } + if ((it = rootObj.find("instructions")) != rootObj.end()) + { + loadInstructions((*it).second); + } } void draw(Scalar alpha) { - SceneryVector::iterator it; + QuadVector::iterator it; - for (it = objects.begin(); it != objects.end(); it++) + for (it = objects.begin(); it != objects.end(); ++it) { //std::cout << "draw object"; (*it)->draw(alpha); @@ -508,8 +522,10 @@ public: glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBindTexture(GL_TEXTURE_2D, 0); - glColor4f(0.0f, 1.0f, 0.0f, 1.0f); - playfieldBounds.draw(0.0); + glColor3f(0.0f, 1.0f, 0.0f); + playfieldBounds.draw(); + glColor3f(0.0f, 0.0f, 1.0f); + maximumBounds.draw(); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } @@ -518,8 +534,8 @@ public: Aabb playfieldBounds; Aabb maximumBounds; - typedef std::vector > SceneryVector; - SceneryVector objects; + typedef std::vector< boost::shared_ptr > QuadVector; + QuadVector objects; }; diff --git a/src/Moof/Serializable.hh b/src/Moof/Serializable.hh index 458dbe8..f00fb94 100644 --- a/src/Moof/Serializable.hh +++ b/src/Moof/Serializable.hh @@ -129,10 +129,10 @@ SerializableBase >::serialize(Serializer& out) cons { out.pushArrayHead(); - std::vector::const_iterator i; - for (i = value_.begin(); i < value_.end(); i++) + std::vector::const_iterator it; + for (it = value_.begin(); it < value_.end(); ++it) { - (*i)->serialize(out); + (*it)->serialize(out); } out.pushArrayTail(); @@ -144,11 +144,11 @@ SerializableBase >::serialize(Serializer& { out.pushMapHead(); - std::map::const_iterator i; - for (i = value_.begin(); i != value_.end(); i++) + std::map::const_iterator it; + for (it = value_.begin(); it != value_.end(); ++it) { - out.push((*i).first); - (*i).second->serialize(out); + out.push((*it).first); + (*it).second->serialize(out); } out.pushMapTail(); diff --git a/src/Moof/Settings.cc b/src/Moof/Settings.cc index ccf690a..fe98f96 100644 --- a/src/Moof/Settings.cc +++ b/src/Moof/Settings.cc @@ -46,7 +46,7 @@ Settings::Settings(int argc, char* argv[]) void Settings::parseArgs(int argc, char* argv[]) { - for (int i = 1; i < argc; i++) + for (int i = 1; i < argc; ++i) { char* where = strchr(argv[i], (int)'='); @@ -91,7 +91,7 @@ void Settings::loadFromFiles(const std::vector& filePaths, char* home = getenv("HOME"); - for (it = filePaths.begin(); it != filePaths.end(); it++) + for (it = filePaths.begin(); it != filePaths.end(); ++it) { std::string path = *it; diff --git a/src/Moof/Tilemap.hh b/src/Moof/Tilemap.hh index f056886..80bede9 100644 --- a/src/Moof/Tilemap.hh +++ b/src/Moof/Tilemap.hh @@ -58,6 +58,7 @@ public: */ typedef unsigned Index; + static const Index NO_TILE = -1; typedef enum { diff --git a/src/YoinkApp.cc b/src/YoinkApp.cc index 023b3a3..1b9fa03 100644 --- a/src/YoinkApp.cc +++ b/src/YoinkApp.cc @@ -407,8 +407,6 @@ void YoinkApp::handleEvent(const Mf::Event& event) } -#include - int main(int argc, char* argv[]) { std::cout << PACKAGE_STRING << std::endl @@ -418,10 +416,6 @@ int main(int argc, char* argv[]) int status = 0; - //Mf::Tree myTree; - //Mf::Tree::Ptr prev = myTree.previousSibling(); - //myTree = *prev; - try { YoinkApp app(argc, argv); -- 2.43.0