]> Dogcows Code - chaz/yoink/blobdiff - src/scene.cc
beginnings of scene rendering
[chaz/yoink] / src / scene.cc
index 7dd102b0af30c146d99e5b2d7af1bcb316517bee..04754ea1730e22fb24b53e19bcba976122124155 100644 (file)
 
 *******************************************************************************/
 
+#include <iostream>
 #include <map>
 #include <vector>
 
-#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<scene_impl>
 {
+       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<std::string,serializable_ptr> rootObj;
+
+                       if (root->get(rootObj))
+                       {
+                               std::map<std::string,serializable_ptr>::iterator it;
+
+                               if ((it = rootObj.find("width")) != rootObj.end())
+                               {
+                                       (*it).second->get(width);
+                               }
+                               if ((it = rootObj.find("tiles")) != rootObj.end())
+                               {
+                                       std::vector<serializable_ptr> theTiles;
+
+                                       if ((*it).second->get(theTiles))
+                                       {
+                                               std::vector<serializable_ptr>::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<unsigned> 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<std::vector<unsigned> > indices;
+       };
+
+       class billboard : public scenery
+       {
+       public:
+               billboard(const matrix4& transform, const std::string& textureName,
+                               serializable_ptr root) :
+                       scenery(transform, textureName),
+                       index(0)
+               {
+                       std::map<std::string,serializable_ptr> rootObj;
+
+                       if (root->get(rootObj))
+                       {
+                               std::map<std::string,serializable_ptr>::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<serializable_ptr> numbers;
@@ -63,7 +250,6 @@ class scene::scene_impl : public mippleton<scene_impl>
        }
 
 public:
-
        scene_impl(const std::string& name) :
                mippleton<scene_impl>(name)
        {
@@ -71,6 +257,164 @@ public:
        }
 
 
+       void loadInstructions(serializable_ptr root)
+       {
+               std::vector<serializable_ptr> rootObj;
+
+               if (root->get(rootObj))
+               {
+                       std::vector<serializable_ptr>::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<serializable_ptr> 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<serializable_ptr> 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<serializable_ptr> 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<scenery> 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<scenery> 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<std::string,sequence>((*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<boost::shared_ptr<scenery> > 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);
 }
 
 
This page took 0.026124 seconds and 4 git commands to generate.