X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FMoof%2FScene.cc;h=fe49ed276d8706edc8626b566db7db51dd108dd8;hp=6c2b42715f70c767d0a74516dec05a8965692d2f;hb=ca0f7bdfba63140dca0bd20586d31980f3938eb2;hpb=329a48e4c4c2f5f2904b913938fc53154c48b825 diff --git a/src/Moof/Scene.cc b/src/Moof/Scene.cc index 6c2b427..fe49ed2 100644 --- a/src/Moof/Scene.cc +++ b/src/Moof/Scene.cc @@ -26,319 +26,234 @@ *******************************************************************************/ -#include #include #include #include "Aabb.hh" #include "Camera.hh" -#include "Deserializer.hh" #include "Entity.hh" +#include "Log.hh" #include "Math.hh" -#include "Mippleton.hh" -#include "Octree.hh" -#include "OpenGL.hh" #include "Scene.hh" -#include "Serializable.hh" +#include "Script.hh" +#include "Settings.hh" #include "Tilemap.hh" namespace Mf { -class Scene::SceneImpl : public Mippleton +static std::string getPath(const std::string& name) { - class Quad : public Entity - { - public: - Quad(const Vector3 vertices[4], const std::string& texture, - Tilemap::Index tileIndex) : - tilemap_(texture), - detail_(0), - blending_(false), - fog_(false) - { - for (int i = 0, num = 0; i < 4; ++i) - { - for (int j = 0; j < 3; ++j, ++num) - { - vertices_[num] = vertices[i][j]; - } - } + return Resource::getPath("scenes/" + name + ".lua"); +} - if (!tilemap_.getTileCoords(tileIndex, texCoords_)) - { - std::cerr << "no coords for tile's texture" << std::endl; - } - aabb_.encloseVertices(vertices, 4); - sphere_.point = aabb_.getCenter(); - sphere_.radius = (aabb_.min - sphere_.point).length(); - } +struct Meh +{ + Matrix4 transform; + std::string texture; - void setDetail(long detail) - { - detail_ = detail; - } + OctreeP octree; - void setBlending(bool blending) - { - blending_ = blending; - } + Meh() + { + octree = Octree::alloc(Aabb()); + } - void setFog(bool fog) + static int loadBox(Script& script, Aabb& aabb) + { + Script::Value table[] = {script[1], script[2]}; + + if (!table[0].isTable() || !table[1].isTable()) { - fog_ = fog; + logWarning("wrong arguments to setPlayfieldBounds; ignoring..."); + return 0; } - void draw(Scalar alpha = 0.0) const + for (int i = 0; i <= 1; ++i) { - if (blending_) + for (int j = 1; j <= 3; ++j) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + script.push((long)j); + table[i].pushField(); } + } - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - tilemap_.bind(); + 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]); - glVertexPointer(3, GL_SCALAR, 0, vertices_); - glTexCoordPointer(2, GL_SCALAR, 0, texCoords_); + return 0; + } - glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + int setPlayfieldBounds(Script& script) + { + Aabb bounds; + return loadBox(script, bounds); + } - glDisable(GL_BLEND); - } + 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; + } - bool isVisible(const Camera& cam) const + int translate(Script& script) + { + Script::Value x = script[1]; + Script::Value y = script[2]; + Script::Value z = script[3]; + + if (!x.isNumber() || !y.isNumber() || !z.isNumber()) { - return sphere_.isVisible(cam); + logWarning("wrong arguments to translate; ignoring..."); + return 0; } - private: - Scalar vertices_[12]; - Scalar texCoords_[8]; - - Tilemap tilemap_; + Vector3 vec; + x.get(vec[0]); + y.get(vec[1]); + z.get(vec[2]); - long detail_; - bool blending_; - bool fog_; - }; + Matrix4 translation; + cml::matrix_translation(translation, vec); + transform = translation * transform; + return 0; + } - static void loadBox(Aabb& theBox, SerializablePtr obj) + int scale(Script& script) { - std::vector numbers; + if (script.getSize() == 3) + { + Vector3 vec; + script[1].get(vec[0]); + script[2].get(vec[1]); + script[3].get(vec[2]); + + Matrix4 scaling; + cml::matrix_scale(scaling, vec); + transform = scaling * transform; + } + else if (script.getSize() == 1) + { + Scalar value = 1.0; + script[1].get(value); - if (obj->get(numbers) && numbers.size() == 6) + Matrix4 scaling; + cml::matrix_uniform_scale(scaling, + Scalar(value)); + transform = scaling * transform; + } + else { - 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); + logWarning("wrong arguments to scale; ignoring..."); } - } -public: - SceneImpl(const std::string& name) : - Mippleton(name) - { - loadFromFile(); + return 0; } - - void loadInstructions(SerializablePtr root) + int rotate(Script& script) { - std::vector rootObj; - std::vector::iterator it; + Script::Value a = script[1]; + Script::Value d = script[2]; - if (!root->get(rootObj)) + if (!a.isString() || !d.isNumber()) { - std::cerr << "error loading scene instructions" << std::endl; - return; + logWarning("wrong arguments to rotate; ignoring..."); + return 0; } - Matrix4 transform; - std::string texture; + std::string axis; + a.get(axis); - for (it = rootObj.begin(); it != rootObj.end(); ++it) - { - std::string instruction; + size_t index = 0; + if (axis == "x") index = 0; + else if (axis == "y") index = 1; + else if (axis == "z") index = 2; - if ((*it)->get(instruction)) - { - if (instruction == "reset_transform") - { - transform.identity(); - } - else if (instruction == "translate") - { - std::vector values; - - ++it; - if ((*it)->get(values)) - { - 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 == "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; - } - else if (values.size() == 3) - { - Vector3 vec; - - for (size_t 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; - } - } - } - else if (instruction == "rotate") - { - std::vector values; - - ++it; - if ((*it)->get(values)) - { - if (values.size() == 2) - { - std::string axis; - size_t index = 0; - double value = 0.0; - - if (values[0]->get(axis)) - { - if (axis == "x") index = 0; - else if (axis == "y") index = 1; - else if (axis == "z") index = 2; - - values[1]->getNumber(value); - } - - 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; - loadTilemap(*it, transform, texture); - } - else if (instruction == "billboard") - { - ++it; - loadBillboard(*it, transform, texture); - } - } - } + Scalar value; + d.get(value); + + cml::matrix_rotate_about_world_axis(transform, + index, cml::rad(Scalar(value))); + + return 0; } + int setTexture(Script& script) + { + Script::Value t = script[1]; + + if (t.isString()) t.get(texture); + else logWarning("wrong arguments to setTexture; ignoring..."); - void loadTilemap(SerializablePtr root, const Matrix4& transform, - const std::string& texture) + return 0; + } + + int makeTilemap(Script& script) { - std::map rootObj; - std::map::iterator it; + Script::Value table = script[1]; + Script::Value top = script[-1]; - if (!root->get(rootObj)) + if (!table.isTable()) { - std::cerr << "error loading scene tilemap object" << std::endl; - return; + logWarning("wrong arguments to makeTilemap; ignoring..."); + return 0; } long width = 1; long height = 1; - std::vector< std::vector > indices; - if ((it = rootObj.find("width")) != rootObj.end()) - { - (*it).second->get(width); - } - else - { - std::cerr << "width is a required field of a tilemap" << std::endl; - return; - } + table.pushField("width"); + top.get(width); + + long nTiles = 0; - std::vector tiles; + table.pushField("tiles"); + Script::Value tiles = script.getTop(); + nTiles = tiles.getLength(); - if ((it = rootObj.find("tiles")) != rootObj.end() && - (*it).second->get(tiles) && - tiles.size() % width == 0) + std::vector< std::vector > indices; + + if (nTiles % width == 0) { - std::vector::iterator jt; - int w, h; + int i, w, h; - height = tiles.size() / width; + 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 - for (h = height - 1, jt = tiles.begin(); jt != tiles.end(); --h) + i = 1; + for (h = height - 1; h >= 0; --h) { std::vector row; - for (w = 0; w < width && jt != tiles.end(); ++w, ++jt) + for (w = 0; w < width; ++w, ++i) { + script.checkStack(2); + script.push(long(i)); + tiles.pushField(); + long index; + top.get(index); - if ((*jt)->get(index)) - { - row.push_back(Tilemap::Index(index)); - } + row.push_back(Tilemap::Index(index)); } indices[h] = row; @@ -346,8 +261,8 @@ public: } else { - std::cerr << "error loading tiles from tilemap object" << std::endl; - return; + logError("invalid tiles in tilemap instruction"); + return 0; } Vector4 vertices[height+1][width+1]; @@ -380,54 +295,38 @@ public: Quad* quad = new Quad(quadVertices, texture, indices[h][w]); boost::shared_ptr quadPtr(quad); - //objects.push_back(quadPtr); octree->insert(quadPtr); } } + + return 0; } - void loadBillboard(SerializablePtr root, const Matrix4& transform, - const std::string& texture) + int makeBillboard(Script& script) { - std::map rootObj; - std::map::iterator it; + Script::Value table = script[1]; + Script::Value top = script[-1]; - if (!root->get(rootObj)) - { - std::cerr << "error loading scene billboard object" << std::endl; - return; - } + long index = 0; + long width = 1; + bool blending = false; + bool fog = false; - Tilemap::Index index = 0; - long width = 1; - bool blending = false; - bool fog = false; - - if ((it = rootObj.find("tile")) != rootObj.end()) + if (table.isTable()) { - long value; - if ((*it).second->get(value)) - { - index = Tilemap::Index(value); - } - } + table.pushField("tile"); + if (top.isNumber()) top.get(index); - if ((it = rootObj.find("u_scale")) != rootObj.end()) - { - (*it).second->get(width); - } + table.pushField("u_scale"); + if (top.isNumber()) top.get(width); - if ((it = rootObj.find("blend")) != rootObj.end()) - { - (*it).second->get(blending); - } + table.pushField("blend"); + if (top.isBoolean()) top.get(blending); - if ((it = rootObj.find("fog")) != rootObj.end()) - { - (*it).second->get(fog); + table.pushField("fog"); + if (top.isBoolean()) top.get(fog); } - Vector4 vertices[2][width+1]; Matrix4 transposedTransform = transform; @@ -455,132 +354,71 @@ public: demoteVector(quadVertices[2], vertices[1][w+1]); demoteVector(quadVertices[3], vertices[1][w]); - Quad* quad = new Quad(quadVertices, texture, index); + Quad* quad = new Quad(quadVertices, texture, Tilemap::Index(index)); quad->setBlending(blending); quad->setFog(fog); boost::shared_ptr quadPtr(quad); - //objects.push_back(quad_Ptr); octree->insert(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); - } - else - { - std::cerr << "maximum bounds required in scene" << std::endl; - return; - } - //OctreeNode rootNode(maximumBounds); - octree = OctreePtr(new Octree(maximumBounds)); - - if ((it = rootObj.find("instructions")) != rootObj.end()) - { - loadInstructions((*it).second); - } + return 0; } +}; - void draw(Scalar alpha, const Camera& cam) const - { - //QuadVector::const_iterator it; - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - - octree->drawIfVisible(alpha, cam); - - //int objectsDrawn = 0; +static void importScriptBindings(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)); +} - //for (it = objects.begin(); it != objects.end(); ++it) - //{ - //if ((*it)->isVisible(cam)) - //{ - ////std::cout << "draw object"; - //(*it)->draw(); - //objectsDrawn++; - //} - //} +OctreeP loadScene(const std::string& name) +{ + std::string filePath = getPath(name); - //std::cout << objectsDrawn << std::endl; + Meh cool; - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); + Script script; + script.importStandardLibraries(); + importLogScript(script); + importScriptBindings(script, cool); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + long detail = 3; + Settings::getInstance().get("detail", detail); - Texture::resetBind(); - glColor3f(0.0f, 1.0f, 0.0f); - playfieldBounds.draw(); - glColor3f(0.0f, 0.0f, 1.0f); - maximumBounds.draw(); + script.push(detail); + script.set("detail"); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + logInfo("doing file..."); + if (script.doFile(filePath) != 0) + { + std::string str; + script[-1].get(str); + logError("lua error: %s", str.c_str()); } + logInfo("done"); - - Aabb playfieldBounds; - Aabb maximumBounds; - - //typedef std::vector< boost::shared_ptr > QuadVector; - //QuadVector objects; - OctreePtr octree; -}; - - -Scene::Scene(const std::string& name) : - // pass through - impl_(Scene::SceneImpl::retain(name), &Scene::SceneImpl::release) {} - - -void Scene::draw(Scalar alpha, const Camera& cam) const -{ - // pass through - impl_->draw(alpha, cam); -} - -void Scene::refresh() -{ - //impl_->objects.clear(); - impl_->loadFromFile(); -} - - -/** - * 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"); + cool.octree->sort(); + return cool.octree; }