X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2Fscene.cc;h=04754ea1730e22fb24b53e19bcba976122124155;hp=7dd102b0af30c146d99e5b2d7af1bcb316517bee;hb=87bc17e55b0c1dc73ecc66df856d3f08fd7a7724;hpb=838bc00015eb7f583c7cf4b3b1007697bf047da1 diff --git a/src/scene.cc b/src/scene.cc index 7dd102b..04754ea 100644 --- a/src/scene.cc +++ b/src/scene.cc @@ -26,13 +26,20 @@ *******************************************************************************/ +#include #include #include -#include "mippleton.hh" +#include "aabb.hh" +#include "camera.hh" +#include "cullable.hh" #include "deserializer.hh" +#include "drawable.hh" +#include "math.hh" +#include "mippleton.hh" +#include "opengl.hh" #include "serializable.hh" -#include "aabb.hh" +#include "tilemap.hh" #include "scene.hh" @@ -42,6 +49,186 @@ namespace dc { class scene::scene_impl : public mippleton { + class scenery : public drawable, public cullable + { + 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 tiles : public scenery + { + public: + tiles(const matrix4& transform, const std::string& textureName, + serializable_ptr root) : + scenery(transform, textureName), + width(1), + height(1) + { + std::map rootObj; + + if (root->get(rootObj)) + { + std::map::iterator it; + + if ((it = rootObj.find("width")) != rootObj.end()) + { + (*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(unsigned(index)); + } + } + + indices[h] = row; + } + } + } + } + } + + void draw(scalar alpha) + { + glPushMatrix(); + //std::cout << "transforming..." << std::endl; + //std::cout << transformation << std::endl; + glMultMatrixf(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) + { + for (x = 0, xf = 0.0; x < width; x++, xf += 1.0) + { + scalar texCoords[8]; + + unsigned index = indices[y][x]; + + if (image.getTileCoords(index, texCoords)) + { + glBegin(GL_TRIANGLE_FAN); + glTexCoord2f(texCoords[0], texCoords[1]); + glVertex3f(xf, yf, 0.0f); + glTexCoord2f(texCoords[2], texCoords[3]); + glVertex3f(xf+1.0, yf, 0.0f); + glTexCoord2f(texCoords[4], texCoords[5]); + glVertex3f(xf+1.0, yf+1.0, 0.0f); + glTexCoord2f(texCoords[6], texCoords[7]); + glVertex3f(xf, yf+1.0, 0.0f); + glEnd(); + } + } + } + + glPopMatrix(); + } + + bool isVisible(const camera& cam) + { + return true; + } + + private: + long width, height; + std::vector > indices; + }; + + class billboard : public scenery + { + public: + billboard(const matrix4& transform, const std::string& textureName, + serializable_ptr root) : + scenery(transform, textureName), + index(0) + { + 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 = unsigned(value); + } + } + } + + image.getTileCoords(index, texCoords); + } + + void draw(scalar alpha) + { + glPushMatrix(); + glMultMatrixf(transformation.data()); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + image.bind(); + + glBegin(GL_TRIANGLE_FAN); + glTexCoord2f(texCoords[0], texCoords[1]); + glVertex2f(0.0f, 0.0f); + glTexCoord2f(texCoords[2], texCoords[3]); + glVertex2f(1.0f, 0.0f); + glTexCoord2f(texCoords[4], texCoords[5]); + glVertex2f(1.0f, 1.0f); + glTexCoord2f(texCoords[6], texCoords[7]); + glVertex2f(0.0f, 1.0f); + glEnd(); + + glPopMatrix(); + } + + bool isVisible(const camera& cam) + { + return false; + } + + private: + unsigned index; + scalar texCoords[8]; + }; + + static bool loadBox(aabb& theBox, serializable_ptr obj) { std::vector numbers; @@ -63,7 +250,6 @@ class scene::scene_impl : public mippleton } public: - scene_impl(const std::string& name) : mippleton(name) { @@ -71,6 +257,164 @@ public: } + void loadInstructions(serializable_ptr root) + { + std::vector rootObj; + + if (root->get(rootObj)) + { + std::vector::iterator it; + + matrix4 transform; + std::string texture; + + for (it = rootObj.begin(); it != rootObj.end(); it++) + { + std::string instruction; + + if ((*it)->get(instruction)) + { + if (instruction == "reset_transform") + { + transform.identity(); + //std::cout << "===================RESET=====================" << std::endl; + } + else if (instruction == "translate") + { + std::vector values; + + it++; + if ((*it)->get(values)) + { + vector3 vec; + + for (unsigned 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; + //std::cout << "TRANSLATE\t" << vec << std::endl + //<< transform << std::endl; + } + } + else if (instruction == "scale") + { + std::vector values; + + it++; + if ((*it)->get(values)) + { + if (values.size() == 1) + { + double value = 1.0; + + values[0]->getNumber(value); + + matrix4 scaling; + cml::matrix_uniform_scale(scaling, scalar(value)); + transform = scaling * transform; + //std::cout << "SCALE\t\t" << value << std::endl + //<< transform << std::endl; + } + else if (values.size() == 3) + { + vector3 vec; + + for (unsigned i = 0; i < values.size(); i++) + { + double value; + + if (values[i]->getNumber(value)) + { + vec[i] = value; + } + } + + matrix4 scaling; + cml::matrix_scale(scaling, vec); + transform = scaling * transform; + //std::cout << "SCALE\t\t" << vec << std::endl + //<< transform << std::endl; + } + } + } + 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; + + if (values[0]->get(axis)) + { + if (axis == "x") + { + axisIndex = 0; + } + else if (axis == "y") + { + axisIndex = 1; + } + else if (axis == "z") + { + axisIndex = 2; + } + values[1]->getNumber(value); + } + + cml::matrix_rotate_about_local_axis(transform, + axisIndex, scalar(value * cml::constantsd::rad_per_deg())); + //std::cout << "ROTATE\t" << axis << " " << value << std::endl + //<< transform << std::endl; + } + } + } + else if (instruction == "texture") + { + it++; + (*it)->get(texture); + } + else if (instruction == "tilemap") + { + //std::cout << "TILEMAP\t" << texture<< std::endl; + //std::cout << transform << std::endl; + + it++; + tiles* newTiles = new tiles(transform, texture, *it); + boost::shared_ptr sceneItem(newTiles); + objects.push_back(sceneItem); + } + else if (instruction == "billboard") + { + //std::cout << "BILLBOARD\t" << texture << std::endl; + //std::cout << transform << std::endl; + + it++; + billboard* newBB = new billboard(transform, texture, + *it); + boost::shared_ptr sceneItem(newBB); + objects.push_back(sceneItem); + } + } + } + } + } + + void loadFromFile() { std::string filePath = scene::getPathToResource(getName()); @@ -95,19 +439,32 @@ public: { loadBox(maximumBounds, (*it).second); } - - //for (i = rootObj.begin(); i != rootObj.end(); i++) - //{ - //sequences.insert(std::pair((*i).first, - //sequence((*i).second))); - //} + if ((it = rootObj.find("instructions")) != rootObj.end()) + { + loadInstructions((*it).second); + } } } } + + void draw(scalar alpha) + { + scenery_list::iterator it; + + for (it = objects.begin(); it != objects.end(); it++) + { + //std::cout << "draw object"; + (*it)->draw(alpha); + } + } + + aabb playfieldBounds; aabb maximumBounds; + typedef std::vector > scenery_list; + scenery_list objects; }; @@ -118,6 +475,8 @@ scene::scene(const std::string& name) : void scene::draw(scalar alpha) { + // pass through + impl->draw(alpha); }