+++ /dev/null
-
-/*******************************************************************************
-
- Copyright (c) 2009, Charles McGarvey
- All rights reserved.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
-
- * Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
- FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-*******************************************************************************/
-
-#include <iostream>
-#include <map>
-#include <vector>
-
-#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 "tilemap.hh"
-
-#include "scene.hh"
-
-
-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;
-
- if (obj->get(numbers))
- {
- if (numbers.size() == 6)
- {
- double num;
-
- if (numbers[0]->getNumber(num))
- {
-
- }
- }
- }
-
- return false;
- }
-
-public:
- scene_impl(const std::string& name) :
- mippleton<scene_impl>(name)
- {
- loadFromFile();
- }
-
-
- 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());
-
- deserializer in(filePath, true);
-
- serializable_ptr root = in.deserialize();
-
- if (root)
- {
- std::map<std::string,serializable_ptr> rootObj;
-
- if (root->get(rootObj))
- {
- std::map<std::string,serializable_ptr>::iterator it;
-
- 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)
- {
- 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;
-};
-
-
-scene::scene(const std::string& name) :
- // pass through
- impl(scene::scene_impl::retain(name), &scene::scene_impl::release) {}
-
-
-void scene::draw(scalar alpha)
-{
- // pass through
- impl->draw(alpha);
-}
-
-
-/**
- * Specialized search location for scene files. They can be found in the
- * "scenes" subdirectory of any of the searched directories.
- */
-
-std::string scene::getPathToResource(const std::string& name)
-{
- return resource::getPathToResource("scenes/" + name + ".json");
-}
-
-
-} // namespace dc
-
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
-