X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Fyoink;a=blobdiff_plain;f=src%2FScene.cc;h=9b4d1fdf65ee3544cd29bc176a08bc3bdc3e9787;hp=bad59bfd79c0c0103e117324f895f003720ceb66;hb=8a1acac01b444dccf8b57cedf08392ada2e473c1;hpb=bffc879fc8ee8167bb123310d39fad4e2f426ffd diff --git a/src/Scene.cc b/src/Scene.cc index bad59bf..9b4d1fd 100644 --- a/src/Scene.cc +++ b/src/Scene.cc @@ -32,10 +32,11 @@ #include #include #include +#include +#include #include #include -#include -#include +//#include #include #include @@ -44,11 +45,11 @@ #include "Tilemap.hh" -struct Scene::Impl : public Mf::Mippleton +struct Scene::Impl : public Mf::Library { - struct Quad : public Mf::Entity, public Mf::OctreeInsertable + struct Quad : public Mf::Entity { - enum SURFACE_TYPE + enum SURFACE { NONE = 0, LEFT = 1, @@ -58,69 +59,74 @@ struct Scene::Impl : public Mf::Mippleton Quad(const Mf::Vector3 vertices[4], const std::string& texture, Tilemap::Index tileIndex) : - tilemap_(texture), - blending_(false), - fog_(false), - surfaceType_(NONE) + mTilemap(texture), + mBlending(false), + mFog(false), + mSurface(NONE) { for (int i = 0, num = 0; i < 4; ++i) { for (int j = 0; j < 3; ++j, ++num) { - vertices_[num] = vertices[i][j]; + mVertices[num] = vertices[i][j]; } } - if (!tilemap_.getTileCoords(tileIndex, texCoords_)) + if (!mTilemap.getTileCoords(tileIndex, mTexCoords)) { Mf::logWarning("no index %d in texture %s", tileIndex, texture.c_str()); - texCoords_[0] = texCoords_[1] = - texCoords_[3] = texCoords_[6] = 0.0; - texCoords_[2] = texCoords_[4] = - texCoords_[5] = texCoords_[7] = 1.0; + mTexCoords[0] = mTexCoords[1] = + mTexCoords[3] = mTexCoords[6] = 0.0; + mTexCoords[2] = mTexCoords[4] = + mTexCoords[5] = mTexCoords[7] = 1.0; } - aabb_.encloseVertices(vertices, 4); - sphere_.point = aabb_.getCenter(); - sphere_.radius = (aabb_.min - sphere_.point).length(); + mAabb.encloseVertices(vertices, 4); + mSphere.point = mAabb.getCenter(); + mSphere.radius = (mAabb.min - mSphere.point).length(); } void setBlending(bool blending) { - blending_ = blending; + mBlending = blending; } void setFog(bool fog) { - fog_ = fog; + mFog = fog; } - void setSurfaceType(SURFACE_TYPE type) + void setSurface(SURFACE type) { - surfaceType_ = type; + mSurface = type; + } + + SURFACE getSurface() const + { + return mSurface; } void draw(Mf::Scalar alpha = 0.0) const { - if (blending_) + if (mBlending) { glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } - if (fog_) + if (mFog) { glEnable(GL_FOG); glFogi(GL_FOG_MODE, GL_LINEAR); } //glColor4f(1.0f, 1.0f, 1.0f, 1.0f); - tilemap_.bind(); + mTilemap.bind(); - glVertexPointer(3, GL_SCALAR, 0, vertices_); - glTexCoordPointer(2, GL_SCALAR, 0, texCoords_); + glVertexPointer(3, GL_SCALAR, 0, mVertices); + glTexCoordPointer(2, GL_SCALAR, 0, mTexCoords); glDrawArrays(GL_TRIANGLE_FAN, 0, 4); @@ -130,158 +136,29 @@ struct Scene::Impl : public Mf::Mippleton bool isVisible(const Mf::Frustum& frustum) const { - return sphere_.isVisible(frustum); - } - - - bool isInsideAabb(const Mf::Aabb& aabb) const - { - // make sure the entity is fully inside the volume - if (!(aabb_.max[0] < aabb.max[0] && - aabb_.min[0] > aabb.min[0] && - aabb_.max[1] < aabb.max[1] && - aabb_.min[1] > aabb.min[1] && - aabb_.max[2] < aabb.max[2] && - aabb_.min[2] > aabb.min[2])) - { - return false; - } - - return true; - } - - int getOctant(const Mf::Aabb& aabb) const - { - int octantNum = -1; - - Mf::Plane::Halfspace halfspace; - - Mf::Plane xy = aabb.getPlaneXY(); - halfspace = xy.intersects(sphere_); - if (halfspace == Mf::Plane::INTERSECT) - { - halfspace = xy.intersects(aabb_); - } - - if (halfspace == Mf::Plane::POSITIVE) - { - Mf::Plane xz = aabb.getPlaneXZ(); - halfspace = xz.intersects(sphere_); - if (halfspace == Mf::Plane::INTERSECT) - { - halfspace = xz.intersects(aabb_); - } - - if (halfspace == Mf::Plane::POSITIVE) - { - Mf::Plane yz = aabb.getPlaneYZ(); - halfspace = yz.intersects(sphere_); - if (halfspace == Mf::Plane::INTERSECT) - { - halfspace = yz.intersects(aabb_); - } - - if (halfspace == Mf::Plane::POSITIVE) - { - octantNum = 2; - } - else if (halfspace == Mf::Plane::NEGATIVE) - { - octantNum = 3; - } - } - else if (halfspace == Mf::Plane::NEGATIVE) - { - Mf::Plane yz = aabb.getPlaneYZ(); - halfspace = yz.intersects(sphere_); - if (halfspace == Mf::Plane::INTERSECT) - { - halfspace = yz.intersects(aabb_); - } - - if (halfspace == Mf::Plane::POSITIVE) - { - octantNum = 1; - } - else if (halfspace == Mf::Plane::NEGATIVE) - { - octantNum = 0; - } - } - } - else if (halfspace == Mf::Plane::NEGATIVE) - { - Mf::Plane xz = aabb.getPlaneXZ(); - halfspace = xz.intersects(sphere_); - if (halfspace == Mf::Plane::INTERSECT) - { - halfspace = xz.intersects(aabb_); - } - - if (halfspace == Mf::Plane::POSITIVE) - { - Mf::Plane yz = aabb.getPlaneYZ(); - halfspace = yz.intersects(sphere_); - if (halfspace == Mf::Plane::INTERSECT) - { - halfspace = yz.intersects(aabb_); - } - - if (halfspace == Mf::Plane::POSITIVE) - { - octantNum = 6; - } - else if (halfspace == Mf::Plane::NEGATIVE) - { - octantNum = 7; - } - } - else if (halfspace == Mf::Plane::NEGATIVE) - { - Mf::Plane yz = aabb.getPlaneYZ(); - halfspace = yz.intersects(sphere_); - if (halfspace == Mf::Plane::INTERSECT) - { - halfspace = yz.intersects(aabb_); - } - - if (halfspace == Mf::Plane::POSITIVE) - { - octantNum = 5; - } - else if (halfspace == Mf::Plane::NEGATIVE) - { - octantNum = 4; - } - } - } - - return octantNum; + return mSphere.isVisible(frustum); } - Mf::Scalar vertices_[12]; - Mf::Scalar texCoords_[8]; + Mf::Scalar mVertices[12]; + Mf::Scalar mTexCoords[8]; - Tilemap tilemap_; - - bool blending_; - bool fog_; - SURFACE_TYPE surfaceType_; + Tilemap mTilemap; - Mf::Aabb aabb_; - Mf::Sphere sphere_; + bool mBlending; + bool mFog; + SURFACE mSurface; }; - Mf::Matrix4 transform; - std::string texture; + Mf::Matrix4 mTransform; + std::string mTexture; - Mf::Octree::Ptr octree; + //Mf::Octree::Ptr mOctree; + std::list< boost::shared_ptr > mObjects; - Mf::Aabb playfieldBounds; - Mf::Aabb maximumBounds; + Mf::Aabb mBounds; enum AXIS @@ -292,19 +169,13 @@ struct Scene::Impl : public Mf::Mippleton }; - explicit Impl(const std::string& name) : - Mf::Mippleton(name) - { - loadFromFile(); - } + Mf::Library(name) {} void importSceneBindings(Mf::Script& script) { - script.importFunction("SetPlayfieldBounds", - boost::bind(&Impl::setPlayfieldBounds, this, _1)); - script.importFunction("SetMaximumBounds", - boost::bind(&Impl::setMaximumBounds, this, _1)); + script.importFunction("SetBounds", + boost::bind(&Impl::setBounds, this, _1)); script.importFunction("ResetTransform", boost::bind(&Impl::resetTransform, this, _1)); script.importFunction("Translate", @@ -315,15 +186,19 @@ struct Scene::Impl : public Mf::Mippleton boost::bind(&Impl::rotate, this, _1)); script.importFunction("SetTexture", boost::bind(&Impl::setTexture, this, _1)); - script.importFunction("MakeTilemap", - boost::bind(&Impl::makeTilemap, this, _1)); - script.importFunction("MakeBillboard", - boost::bind(&Impl::makeBillboard, this, _1)); + script.importFunction("DrawTilemap", + boost::bind(&Impl::drawTilemap, this, _1)); + script.importFunction("DrawTile", + boost::bind(&Impl::drawTile, this, _1)); int detail = 3; Mf::Settings::getInstance().get("detail", detail); script.push(detail); script.set("detail"); + script.push(1); script.set("LOW"); + script.push(2); script.set("MEDIUM"); + script.push(3); script.set("HIGH"); + script.push(X); script.set("X"); script.push(Y); script.set("Y"); script.push(Z); script.set("Z"); @@ -334,21 +209,13 @@ struct Scene::Impl : public Mf::Mippleton } - void loadFromFile() + Mf::Script::Status load(Mf::Script& script) { - Mf::Script script; std::string filePath = Scene::getPath(getName()); + if (filePath == "") return Mf::Script::FILE_ERROR; - script.importStandardLibraries(); - importLogScript(script); importSceneBindings(script); - - if (script.doFile(filePath) != Mf::Script::SUCCESS) - { - std::string str; - script[-1].get(str); - Mf::logScript("%s", str.c_str()); - } + return script.doFile(filePath); } @@ -379,21 +246,16 @@ struct Scene::Impl : public Mf::Mippleton return 0; } - int setPlayfieldBounds(Mf::Script& script) + int setBounds(Mf::Script& script) { - return loadBox(script, playfieldBounds); - } - - int setMaximumBounds(Mf::Script& script) - { - int ret = loadBox(script, maximumBounds); - octree = Mf::Octree::alloc(maximumBounds); + int ret = loadBox(script, mBounds); + //mOctree = Mf::Octree::alloc(mBounds); return ret; } int resetTransform(Mf::Script& script) { - transform.identity(); + mTransform.identity(); return 0; } @@ -410,7 +272,7 @@ struct Scene::Impl : public Mf::Mippleton Mf::Matrix4 translation; cml::matrix_translation(translation, vec); - transform = translation * transform; + mTransform = translation * mTransform; return 0; } @@ -426,7 +288,7 @@ struct Scene::Impl : public Mf::Mippleton Mf::Matrix4 scaling; cml::matrix_scale(scaling, vec); - transform = scaling * transform; + mTransform = scaling * mTransform; } else if (script.getSize() == 1) { @@ -435,7 +297,7 @@ struct Scene::Impl : public Mf::Mippleton Mf::Matrix4 scaling; cml::matrix_uniform_scale(scaling, value); - transform = scaling * transform; + mTransform = scaling * mTransform; } else { @@ -456,35 +318,37 @@ struct Scene::Impl : public Mf::Mippleton Mf::Scalar value; angle.get(value); - cml::matrix_rotate_about_world_axis(transform, index, cml::rad(value)); + cml::matrix_rotate_about_world_axis(mTransform, index, cml::rad(value)); return 0; } int setTexture(Mf::Script& script) { - script[1].requireString().get(texture); + script[1].requireString().get(mTexture); return 0; } - int makeTilemap(Mf::Script& script) + int drawTilemap(Mf::Script& script) { Mf::Script::Value table = script[1].requireTable(); Mf::Script::Value top = script[-1]; - Quad::SURFACE_TYPE surfaceType; - table.pushField("surface_type"); - top.get(surfaceType); + Quad::SURFACE surface; + table.pushField("surface"); + top.get(surface); + script.pop(); int width = 1; int height = 1; table.pushField("width"); top.get(width); + script.pop(); int nTiles = 0; - table.pushField("tiles"); + //table.pushField("tiles"); Mf::Script::Value tiles = script.getTop(); nTiles = tiles.getLength(); @@ -522,7 +386,7 @@ struct Scene::Impl : public Mf::Mippleton Mf::Vector4 vertices[height+1][width+1]; - Mf::Matrix4 transposedTransform = transform; + Mf::Matrix4 transposedTransform = mTransform; transposedTransform.transpose(); for (int h = 0; h <= height; ++h) @@ -546,20 +410,21 @@ struct Scene::Impl : public Mf::Mippleton demotedVertices[2] = Mf::demote(vertices[h+1][w+1]); demotedVertices[3] = Mf::demote(vertices[h+1][w]); - Quad* quad = new Quad(demotedVertices, texture, indices[h][w]); - quad->setSurfaceType(surfaceType); + Quad* quad = new Quad(demotedVertices, mTexture, indices[h][w]); + quad->setSurface(surface); boost::shared_ptr quadPtr(quad); - octree->insert(quadPtr); + //mOctree->insert(quadPtr); + mObjects.push_back(quadPtr); } } return 0; } - int makeBillboard(Mf::Script& script) + int drawTile(Mf::Script& script) { - Mf::Script::Value table = script[1]; + Mf::Script::Value param = script[1]; Mf::Script::Value top = script[-1]; Tilemap::Index index = 0; @@ -567,24 +432,29 @@ struct Scene::Impl : public Mf::Mippleton bool blending = false; bool fog = false; - if (table.isTable()) + if (param.isTable()) { - table.pushField("tile"); + script.push(1); + param.pushField(); top.get(index); - table.pushField("u_scale"); + param.pushField("u_scale"); top.get(width); - table.pushField("blend"); + param.pushField("blend"); top.get(blending); - table.pushField("fog"); + param.pushField("fog"); top.get(fog); } + else if (param.isNumber()) + { + param.get(index); + } Mf::Vector4 vertices[2][width+1]; - Mf::Matrix4 transposedTransform = transform; + Mf::Matrix4 transposedTransform = mTransform; transposedTransform.transpose(); Mf::Scalar xf; @@ -609,12 +479,13 @@ struct Scene::Impl : public Mf::Mippleton demotedVertices[2] = Mf::demote(vertices[1][w+1]); demotedVertices[3] = Mf::demote(vertices[1][w]); - Quad* quad = new Quad(demotedVertices, texture, index); + Quad* quad = new Quad(demotedVertices, mTexture, index); quad->setBlending(blending); quad->setFog(fog); boost::shared_ptr quadPtr(quad); - octree->insert(quadPtr); + //mOctree->insert(quadPtr); + mObjects.push_back(quadPtr); } return 0; @@ -627,25 +498,100 @@ Scene::Scene(const std::string& name) : mImpl(Scene::Impl::getInstance(name)) {} +Mf::Script::Status Scene::load(Mf::Script& script) +{ + // pass through + return mImpl->load(script); +} + + void Scene::draw(Mf::Scalar alpha) const { - mImpl->octree->draw(alpha); + //mImpl->mOctree->draw(alpha); + std::list< boost::shared_ptr >& objects = mImpl->mObjects; + std::list< boost::shared_ptr >::const_iterator it; + + for (it = objects.begin(); it != objects.end(); ++it) + { + (*it)->draw(alpha); + } + + mImpl->mBounds.draw(); } void Scene::drawIfVisible(Mf::Scalar alpha, const Mf::Frustum& frustum) const { - mImpl->octree->drawIfVisible(alpha, frustum); + //mImpl->mOctree->drawIfVisible(alpha, frustum); + std::list< boost::shared_ptr >& objects = mImpl->mObjects; + std::list< boost::shared_ptr >::const_iterator it; + + for (it = objects.begin(); it != objects.end(); ++it) + { + (*it)->drawIfVisible(alpha, frustum); + } + + mImpl->mBounds.draw(); } bool Scene::checkForCollision(Character& character) { - std::list< boost::shared_ptr > objects; + return false; + //std::list< boost::shared_ptr > objects; //std::list::InsertableP> objects; - mImpl->octree->getNearbyObjects(objects, character); - mImpl->maximumBounds.draw(); + //mImpl->mOctree->getNearbyObjects(objects, character); + + std::list< boost::shared_ptr >& objects = mImpl->mObjects; + std::list< boost::shared_ptr >::const_iterator it; + + int collisions = 0; + Mf::Sphere sphere = character.getSphere(); + + for (it = objects.begin(); it != objects.end(); ++it) + { + Impl::Quad::SURFACE type = (*it)->getSurface(); + if (type == Impl::Quad::NONE) continue; + + if (Mf::checkCollision(sphere, (*it)->getSphere())) + { + ++collisions; + + Mf::Vector2 impulse(0.0, 0.0); + Mf::Vector2 p = character.getState().momentum; + + Mf::State2 state = character.getState(1.0); + sphere = character.getSphere(); + Mf::Scalar alpha = 1.0; + while (Mf::checkCollision(sphere, (*it)->getSphere())) + { + alpha -= 0.05; + state = character.getState(alpha); + } + + character.setPosition(state.position); + + //switch (type) + //{ + //case Impl::Quad::TOP: + //if (p[1] < 0.0) impulse[1] = -p[1]; + //break; + //case Impl::Quad::LEFT: + //if (p[0] > 0.0) impulse[0] = 1.5*-p[0]; + //break; + //case Impl::Quad::RIGHT: + //if (p[0] < 0.0) impulse[0] = 1.5*-p[0]; + //break; + //} + + //character.addImpulse(impulse); + } + } + + if (collisions > 0) + { + Mf::logInfo("collisions: %d", collisions); + } - Mf::logDebug("nearby objects: %d", objects.size()); return false; }