+++ /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 <map>
-#include <vector>
-
-#include "Aabb.hh"
-#include "Camera.hh"
-#include "Entity.hh"
-#include "Log.hh"
-#include "Math.hh"
-#include "Scene.hh"
-#include "Script.hh"
-#include "Settings.hh"
-#include "Tilemap.hh"
-
-
-namespace Mf {
-
-
-static std::string getPath(const std::string& name)
-{
- return Resource::getPath("scenes/" + name + ".lua");
-}
-
-
-struct Meh
-{
- Matrix4 transform;
- std::string texture;
-
- OctreeP octree;
-
- enum AXIS
- {
- X = 0,
- Y = 1,
- Z = 2
- };
-
- Meh()
- {
- octree = Octree::alloc(Aabb());
- }
-
- static int loadBox(Script& script, Aabb& aabb)
- {
- Script::Value table[] = {script[1], script[2]};
-
- if (!table[0].isTable() || !table[1].isTable())
- {
- logWarning("wrong arguments to setPlayfieldBounds; ignoring...");
- return 0;
- }
-
- for (int i = 0; i <= 1; ++i)
- {
- for (int j = 1; j <= 3; ++j)
- {
- script.push((long)j);
- table[i].pushField();
- }
- }
-
- script[3].get(aabb.min[0]);
- script[4].get(aabb.min[1]);
- script[5].get(aabb.min[2]);
- script[6].get(aabb.max[0]);
- script[7].get(aabb.max[1]);
- script[8].get(aabb.max[2]);
-
- return 0;
- }
-
- int setPlayfieldBounds(Script& script)
- {
- Aabb bounds;
- return loadBox(script, bounds);
- }
-
- int setMaximumBounds(Script& script)
- {
- Aabb bounds;
- int ret = loadBox(script, bounds);
- octree = Octree::alloc(bounds);
- return ret;
- }
-
- int resetTransform(Script& script)
- {
- transform.identity();
- return 0;
- }
-
- int translate(Script& script)
- {
- Script::Value x = script[1].requireNumber();
- Script::Value y = script[2].requireNumber();
- Script::Value z = script[3].requireNumber();
-
- Vector3 vec;
- x.get(vec[0]);
- y.get(vec[1]);
- z.get(vec[2]);
-
- Matrix4 translation;
- cml::matrix_translation(translation, vec);
- transform = translation * transform;
-
- return 0;
- }
-
- int scale(Script& script)
- {
- if (script.getSize() == 3)
- {
- Vector3 vec;
- script[1].requireNumber().get(vec[0]);
- script[2].requireNumber().get(vec[1]);
- script[3].requireNumber().get(vec[2]);
-
- Matrix4 scaling;
- cml::matrix_scale(scaling, vec);
- transform = scaling * transform;
- }
- else if (script.getSize() == 1)
- {
- Scalar value = 1.0;
- script[1].requireNumber().get(value);
-
- Matrix4 scaling;
- cml::matrix_uniform_scale(scaling, value);
- transform = scaling * transform;
- }
- else
- {
- script.getTop().throwError("wrong number of arguments");
- }
-
- return 0;
- }
-
- int rotate(Script& script)
- {
- Script::Value axis = script[1].requireString();
- Script::Value angle = script[2].requireNumber();
-
- size_t index = 0;
- axis.get(index);
-
- Scalar value;
- angle.get(value);
-
- cml::matrix_rotate_about_world_axis(transform, index, cml::rad(value));
-
- return 0;
- }
-
- int setTexture(Script& script)
- {
- Script::Value name = script[1].requireString();
-
- name.get(texture);
-
- return 0;
- }
-
- int makeTilemap(Script& script)
- {
- Script::Value table = script[1].requireTable();
- Script::Value top = script[-1];
-
- long width = 1;
- long height = 1;
-
- table.pushField("width");
- top.get(width);
-
- long nTiles = 0;
-
- table.pushField("tiles");
- Script::Value tiles = script.getTop();
- nTiles = tiles.getLength();
-
- if (nTiles % width != 0) table.throwError("invalid number of tiles");
-
- std::vector< std::vector<Tilemap::Index> > indices;
-
- int i, w, h;
-
- height = nTiles / 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
-
- i = 1;
- for (h = height - 1; h >= 0; --h)
- {
- std::vector<Tilemap::Index> row;
-
- for (w = 0; w < width; ++w, ++i)
- {
- script.checkStack(2);
- script.push(long(i));
- tiles.pushField();
-
- long index;
- top.get(index);
-
- row.push_back(Tilemap::Index(index));
- }
-
- indices[h] = row;
- }
-
- 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<Quad> quadPtr(quad);
-
- octree->insert(quadPtr);
- }
- }
-
- return 0;
- }
-
- int makeBillboard(Script& script)
- {
- Script::Value table = script[1];
- Script::Value top = script[-1];
-
- long index = 0;
- long width = 1;
- bool blending = false;
- bool fog = false;
-
- if (table.isTable())
- {
- table.pushField("tile");
- top.get(index);
-
- table.pushField("u_scale");
- top.get(width);
-
- table.pushField("blend");
- top.get(blending);
-
- table.pushField("fog");
- top.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, Tilemap::Index(index));
- quad->setBlending(blending);
- quad->setFog(fog);
-
- boost::shared_ptr<Quad> quadPtr(quad);
-
- octree->insert(quadPtr);
- }
-
- return 0;
- }
-};
-
-
-static void importSceneBindings(Script& script, Meh& scene)
-{
- script.importFunction("SetPlayfieldBounds",
- boost::bind(&Meh::setPlayfieldBounds, &scene, _1));
- script.importFunction("SetMaximumBounds",
- boost::bind(&Meh::setMaximumBounds, &scene, _1));
- script.importFunction("ResetTransform",
- boost::bind(&Meh::resetTransform, &scene, _1));
- script.importFunction("Translate",
- boost::bind(&Meh::translate, &scene, _1));
- script.importFunction("Scale",
- boost::bind(&Meh::scale, &scene, _1));
- script.importFunction("Rotate",
- boost::bind(&Meh::rotate, &scene, _1));
- script.importFunction("SetTexture",
- boost::bind(&Meh::setTexture, &scene, _1));
- script.importFunction("MakeTilemap",
- boost::bind(&Meh::makeTilemap, &scene, _1));
- script.importFunction("MakeBillboard",
- boost::bind(&Meh::makeBillboard, &scene, _1));
-
- long detail = 3;
- Settings::getInstance().get("detail", detail);
- script.push(detail);
- script.set("detail");
-
- script.push(Quad::LEFT);
- script.set("LEFT");
- script.push(Quad::RIGHT);
- script.set("RIGHT");
- script.push(Quad::TOP);
- script.set("TOP");
-
- script.push(Meh::X);
- script.set("X");
- script.push(Meh::Y);
- script.set("Y");
- script.push(Meh::Z);
- script.set("Z");
-}
-
-
-OctreeP loadScene(const std::string& name)
-{
- std::string filePath = getPath(name);
-
- Meh cool;
-
- Script script;
- script.importStandardLibraries();
- importLogScript(script);
- importSceneBindings(script, cool);
-
- if (script.doFile(filePath) != Script::SUCCESS)
- {
- std::string str;
- script[-1].get(str);
- logScript("%s", str.c_str());
- }
-
- cool.octree->sort();
- return cool.octree;
-}
-
-
-} // namespace Mf
-
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
-