-/*******************************************************************************
-
- 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.
-
-*******************************************************************************/
+/*] Copyright (c) 2009-2010, Charles McGarvey [**************************
+**] All rights reserved.
+*
+* vi:ts=4 sw=4 tw=75
+*
+* Distributable under the terms and conditions of the 2-clause BSD license;
+* see the file COPYING for a complete text of the license.
+*
+**************************************************************************/
#include <map>
-#include <vector>
#include <Moof/Aabb.hh>
#include <Moof/Camera.hh>
#include <Moof/Entity.hh>
+#include <Moof/Manager.hh>
+#include <Moof/Line.hh>
#include <Moof/Log.hh>
#include <Moof/Math.hh>
-#include <Moof/Mippleton.hh>
-#include <Moof/Octree.hh>
+//#include <Moof/Octree.hh>
#include <Moof/Script.hh>
#include <Moof/Settings.hh>
+#include <Moof/Texture.hh>
+#include "Character.hh"
#include "Scene.hh"
-#include "Tilemap.hh"
-struct Scene::Impl : public Mf::Mippleton<Impl>
+struct Scene::Impl : public Mf::Manager<Impl>
{
- class Quad : public Mf::Entity, public Mf::OctreeInsertable
+ struct Quad : public Mf::Entity
{
- Mf::Scalar vertices_[12];
- Mf::Scalar texCoords_[8];
-
- Tilemap tilemap_;
-
- bool blending_;
- bool fog_;
-
- Mf::Aabb aabb_;
- Mf::Sphere sphere_;
-
- public:
-
- enum SURFACE_TYPE
+ enum Surface
{
+ NONE = 0,
LEFT = 1,
RIGHT = 2,
TOP = 3
};
- Quad(const Mf::Vector3 vertices[4], const std::string& texture,
- Tilemap::Index tileIndex) :
- tilemap_(texture),
- blending_(false),
- fog_(false)
+ Quad(const Mf::Vector3* vertices[4], const std::string& texture,
+ Mf::Texture::TileIndex tileIndex) :
+ mTilemap(texture),
+ mBlending(false),
+ mFog(false),
+ mSurface(NONE)
{
- for (int i = 0, num = 0; i < 4; ++i)
+ for (int i = 0; i < 4; ++i)
{
- for (int j = 0; j < 3; ++j, ++num)
- {
- vertices_[num] = vertices[i][j];
- }
+ mVertices[i] = *vertices[i];
+ //for (int j = 0; j < 3; ++j, ++num)
+ //{
+ //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());
+ Mf::logWarning << "no index " << tileIndex <<
+ " in texture " << texture << std::endl;
- 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(mVertices, 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 setSurface(Surface 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[0].data());
+ glTexCoordPointer(2, GL_SCALAR, 0, mTexCoords);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
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;
+ return mSphere.isVisible(frustum);
}
- 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;
- }
- }
- }
+ Mf::Vector3 mVertices[4];
+ Mf::Scalar mTexCoords[8];
+
+ Mf::Texture mTilemap;
- return octantNum;
- }
+ bool mBlending;
+ bool mFog;
+ Surface mSurface;
};
- Mf::Matrix4 transform;
- std::string texture;
+ Mf::Matrix4 mTransform;
+ std::string mTexture;
+
+ //Mf::Octree<Quad>::Ptr mOctree;
+ std::list< boost::shared_ptr<Impl::Quad> > mObjects;
+ std::list<Mf::Line2> mLines;
- Mf::Octree<Quad>::Ptr octree;
+ Mf::Aabb<3> mBounds;
enum AXIS
};
+ void init(const std::string& name) {}
- explicit Impl(const std::string& name) :
- Mf::Mippleton<Impl>(name)
- {
- loadFromFile();
- }
- void importSceneBindings(Mf::Script& script)
+ void importSceneBindings(Mf::Settings& settings, 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",
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));
-
- long detail = 3;
- Mf::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(X); script.set("X");
- script.push(Y); script.set("Y");
- script.push(Z); script.set("Z");
+ script.importFunction("DrawTilemap",
+ boost::bind(&Impl::drawTilemap, this, _1));
+ script.importFunction("DrawTile",
+ boost::bind(&Impl::drawTile, this, _1));
+
+ int detail = 3;
+ settings.get("detail", detail);
+ script.globals().setField("detail", detail);
+
+ script.globals().setField("LOW", 1);
+ script.globals().setField("MEDIUM", 2);
+ script.globals().setField("HIGH", 3);
+
+ script.globals().setField("X", X);
+ script.globals().setField("Y", Y);
+ script.globals().setField("Z", Z);
+
+ script.globals().setField("LEFT", Quad::LEFT);
+ script.globals().setField("RIGHT", Quad::RIGHT);
+ script.globals().setField("TOP", Quad::TOP);
}
- void loadFromFile()
+ Mf::Script::Result load(Mf::Settings& settings, Mf::Script& script)
{
- Mf::Script script;
- std::string filePath = Scene::getPath(getName());
-
- script.importStandardLibraries();
- importLogScript(script);
- importSceneBindings(script);
-
- if (script.doFile(filePath) != Mf::Script::SUCCESS)
+ std::string path(getName());
+ if (!Scene::getPath(path))
{
- std::string str;
- script[-1].get(str);
- Mf::logScript("%s", str.c_str());
+ script.push("the scene file could not be found");
+ return Mf::Script::FILE_ERROR;
}
+
+ importSceneBindings(settings, script);
+ return script.doFile(path);
}
- static int loadBox(Mf::Script& script, Mf::Aabb& aabb)
+ static int loadBox(Mf::Script& script, Mf::Aabb3& aabb)
{
- Mf::Script::Value table[] =
- {
- script[1].requireTable(),
- script[2].requireTable()
- };
-
- if (!table[0].isTable() || !table[1].isTable())
- {
- Mf::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[1].requireTable();
+ script[2].requireTable();
- 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]);
+ script[1].pushField(1).get(aabb.min[0]);
+ script[1].pushField(2).get(aabb.min[1]);
+ script[1].pushField(3).get(aabb.min[2]);
+ script[2].pushField(1).get(aabb.max[0]);
+ script[2].pushField(2).get(aabb.max[1]);
+ script[2].pushField(3).get(aabb.max[2]);
return 0;
}
- int setPlayfieldBounds(Mf::Script& script)
+ int setBounds(Mf::Script& script)
{
- Mf::Aabb bounds;
- return loadBox(script, bounds);
- }
-
- int setMaximumBounds(Mf::Script& script)
- {
- Mf::Aabb bounds;
- int ret = loadBox(script, bounds);
- octree = Mf::Octree<Quad>::alloc(bounds);
+ int ret = loadBox(script, mBounds);
+ //mOctree = Mf::Octree<Quad>::alloc(mBounds);
return ret;
}
int resetTransform(Mf::Script& script)
{
- transform.identity();
+ mTransform.identity();
return 0;
}
int translate(Mf::Script& script)
{
- Mf::Script::Value x = script[1].requireNumber();
- Mf::Script::Value y = script[2].requireNumber();
- Mf::Script::Value z = script[3].requireNumber();
-
Mf::Vector3 vec;
- x.get(vec[0]);
- y.get(vec[1]);
- z.get(vec[2]);
+ script[1].requireNumber().get(vec[0]);
+ script[2].requireNumber().get(vec[1]);
+ script[3].requireNumber().get(vec[2]);
Mf::Matrix4 translation;
cml::matrix_translation(translation, vec);
- transform = translation * transform;
+ mTransform = translation * mTransform;
return 0;
}
int scale(Mf::Script& script)
{
- if (script.getSize() == 3)
+ int size = script.stackSize();
+
+ if (size == 1)
+ {
+ Mf::Scalar value = 1.0;
+ script[1].requireNumber().get(value);
+
+ Mf::Matrix4 scaling;
+ cml::matrix_uniform_scale(scaling, value);
+ mTransform = scaling * mTransform;
+ }
+ else if (size == 3)
{
Mf::Vector3 vec;
script[1].requireNumber().get(vec[0]);
Mf::Matrix4 scaling;
cml::matrix_scale(scaling, vec);
- transform = scaling * transform;
- }
- else if (script.getSize() == 1)
- {
- Mf::Scalar value = 1.0;
- script[1].requireNumber().get(value);
-
- Mf::Matrix4 scaling;
- cml::matrix_uniform_scale(scaling, value);
- transform = scaling * transform;
+ mTransform = scaling * mTransform;
}
else
{
- script.getTop().throwError("wrong number of arguments");
+ script.top().raise("wrong number of arguments");
}
return 0;
int rotate(Mf::Script& script)
{
- Mf::Script::Value axis = script[1].requireString();
- Mf::Script::Value angle = script[2].requireNumber();
-
size_t index = 0;
- axis.get(index);
+ script[1].requireNumber().get(index);
Mf::Scalar value;
- angle.get(value);
+ script[2].requireNumber().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)
{
- Mf::Script::Value name = script[1].requireString();
-
- name.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];
+ Mf::Script::Slot table = script[1].requireTable();
- long width = 1;
- long height = 1;
+ int width = 1;
+ table.get(width, "width");
- table.pushField("width");
- top.get(width);
-
- long nTiles = 0;
-
- table.pushField("tiles");
- Mf::Script::Value tiles = script.getTop();
- nTiles = tiles.getLength();
-
- if (nTiles % width != 0) table.throwError("invalid number of tiles");
+ int nTiles = table.length();
+ if (nTiles % width != 0)
+ {
+ table.raise("invalid number of tiles");
+ }
- std::vector< std::vector<Tilemap::Index> > indices;
+ if (width == 0) table.raise("width field must not be zero");
+ int height = nTiles / width;
- int i, w, h;
+ Mf::Vector3 vertices[height+1][width+1];
- 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
- // 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
+ // do first row and first column of vertices
- i = 1;
- for (h = height - 1; h >= 0; --h)
+ for (int w = 0; w <= width; ++w)
{
- std::vector<Tilemap::Index> row;
+ vertices[height][w] = Mf::demote(mTransform *
+ Mf::Vector4(w, height, 0.0, 1.0));
+ }
+ for (int h = 0; h < height; ++h)
+ {
+ vertices[h][0] = Mf::demote(mTransform *
+ Mf::Vector4(0.0, h, 0.0, 1.0));
+ }
- for (w = 0; w < width; ++w, ++i)
+ size_t i = 1;
+ for (int h = height - 1; h >= 0; --h)
+ {
+ for (int w = 0; w < width; ++w, ++i)
{
- script.checkStack(2);
- script.push(long(i));
- tiles.pushField();
+ int wPlus1 = w + 1;
+ int hPlus1 = h + 1;
- Tilemap::Index index;
- top.get(index);
+ Mf::Texture::TileIndex index;
+ table.get(index, i);
- row.push_back(index);
- }
+ vertices[h][wPlus1] = Mf::demote(mTransform *
+ Mf::Vector4(wPlus1, h, 0.0, 1.0));
- indices[h] = row;
- }
+ if (index == Mf::Texture::NO_TILE) continue;
- Mf::Vector4 vertices[height+1][width+1];
+ const Mf::Vector3* corners[4] = {
+ &vertices[h][w],
+ &vertices[h][wPlus1],
+ &vertices[hPlus1][wPlus1],
+ &vertices[hPlus1][w]
+ };
- Mf::Matrix4 transposedTransform = transform;
- transposedTransform.transpose();
+ Quad* quad = new Quad(corners, mTexture, index);
+ //quad->setSurface(surface);
- for (int h = 0; h <= height; ++h)
- {
- for (int w = 0; w <= width; ++w)
- {
- vertices[h][w] = Mf::Vector4(w, h, 0.0, 1.0) * transposedTransform;
+ boost::shared_ptr<Quad> quadPtr(quad);
+ mObjects.push_back(quadPtr);
}
}
- for (int h = 0; h < height; ++h)
- {
- for (int w = 0; w < width; ++w)
- {
- if (indices[h][w] == Tilemap::NO_TILE) continue;
+ Quad::Surface surface = Quad::NONE;
+ table.get(surface, "surface");
- Mf::Vector3 quadVertices[4];
-
- quadVertices[0] = Mf::demote(vertices[h][w]);
- quadVertices[1] = Mf::demote(vertices[h][w+1]);
- quadVertices[2] = Mf::demote(vertices[h+1][w+1]);
- quadVertices[3] = Mf::demote(vertices[h+1][w]);
+ if (surface != Quad::NONE)
+ {
+ // need a 2d line for collisions
+ // assuming the camera always looks directly to -z when the
+ // scene is built, simply demoting the vector again should
+ // project the points to the xy-plane
- Quad* quad = new Quad(quadVertices, texture, indices[h][w]);
- boost::shared_ptr<Quad> quadPtr(quad);
+ Mf::Vector2 bl = Mf::demote(vertices[0][0]);
+ Mf::Vector2 tr = Mf::demote(vertices[height][width]);
- octree->insert(quadPtr);
- }
+ mLines.push_back(Mf::Line<2>(bl, tr));
}
return 0;
}
- int makeBillboard(Mf::Script& script)
+ int drawTile(Mf::Script& script)
{
- Mf::Script::Value table = script[1];
- Mf::Script::Value top = script[-1];
+ Mf::Script::Slot param = script[1];
+ Mf::Script::Slot top = script[-1];
- long index = 0;
- long width = 1;
- bool blending = false;
- bool fog = false;
+ Mf::Texture::TileIndex index = 0;
+ int width = 1;
+ bool blending = false;
+ bool fog = false;
- if (table.isTable())
+ if (param.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);
+ param.get(index, 1);
+ param.get(width, "u_scale");
+ param.get(blending, "blend");
+ param.get(fog, "fog");
+ }
+ else if (param.isNumber())
+ {
+ param.get(index);
}
- Mf::Vector4 vertices[2][width+1];
-
- Mf::Matrix4 transposedTransform = transform;
- transposedTransform.transpose();
+ Mf::Vector3 vertices[2][width+1];
Mf::Scalar xf;
- Mf::Scalar increment = 1.0 / Mf::Scalar(width);
+ Mf::Scalar increment = SCALAR(1.0) / Mf::Scalar(width);
for (int h = 0; h <= 1; ++h)
{
xf = 0.0;
for (int w = 0; w <= width; ++w, xf += increment)
{
- vertices[h][w] = Mf::Vector4(xf, Mf::Scalar(h), 0.0, 1.0) *
- transposedTransform;
+ vertices[h][w] = Mf::demote(mTransform *
+ Mf::Vector4(xf, Mf::Scalar(h), 0.0, 1.0));
}
}
for (int w = 0; w < width; ++w)
{
- Mf::Vector3 quadVertices[4];
+ int wPlus1 = w + 1;
- quadVertices[0] = Mf::demote(vertices[0][w]);
- quadVertices[1] = Mf::demote(vertices[0][w+1]);
- quadVertices[2] = Mf::demote(vertices[1][w+1]);
- quadVertices[3] = Mf::demote(vertices[1][w]);
+ const Mf::Vector3* corners[4] = {
+ &vertices[0][w],
+ &vertices[0][wPlus1],
+ &vertices[1][wPlus1],
+ &vertices[1][w]
+ };
- Quad* quad = new Quad(quadVertices, texture, Tilemap::Index(index));
+ Quad* quad = new Quad(corners, mTexture, index);
quad->setBlending(blending);
quad->setFog(fog);
boost::shared_ptr<Quad> quadPtr(quad);
-
- octree->insert(quadPtr);
+ mObjects.push_back(quadPtr);
}
return 0;
Scene::Scene(const std::string& name) :
// pass through
- impl_(Scene::Impl::getInstance(name)) {}
+ mImpl(Scene::Impl::getInstance(name)) {}
+
+
+Mf::Script::Result Scene::load(Mf::Settings& settings, Mf::Script& script)
+{
+ // pass through
+ return mImpl->load(settings, script);
+}
void Scene::draw(Mf::Scalar alpha) const
{
- impl_->octree->draw(alpha);
+ std::list< boost::shared_ptr<Impl::Quad> >& objects = mImpl->mObjects;
+ std::list< boost::shared_ptr<Impl::Quad> >::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
+void Scene::drawIfVisible(Mf::Scalar alpha,
+ const Mf::Frustum& frustum) const
{
- impl_->octree->drawIfVisible(alpha, frustum);
+ std::list< boost::shared_ptr<Impl::Quad> >& objects = mImpl->mObjects;
+ std::list< boost::shared_ptr<Impl::Quad> >::const_iterator it;
+
+ for (it = objects.begin(); it != objects.end(); ++it)
+ {
+ (*it)->drawIfVisible(alpha, frustum);
+ }
+
+ std::list< Mf::Line<2> >& lines = mImpl->mLines;
+ std::list< Mf::Line<2> >::const_iterator lit;
+
+ for (lit = lines.begin(); lit != lines.end(); ++lit)
+ {
+ (*lit).draw(alpha);
+ }
+
+ mImpl->mBounds.draw();
}
-std::string Scene::getPath(const std::string& name)
+bool Scene::castRay(const Mf::Ray<2>& ray,
+ std::list<Mf::Ray<2>::Contact>& hits) const
{
- return Mf::Resource::getPath("scenes/" + name + ".lua");
+ std::list< Mf::Line<2> >& lines = mImpl->mLines;
+ std::list< Mf::Line<2> >::const_iterator it;
+
+ for (it = lines.begin(); it != lines.end(); ++it)
+ {
+ Mf::Ray<2>::Contact hit;
+ Mf::Scalar d = (*it).intersectRay(ray, hit);
+ if (d > 0.0)
+ {
+ hits.push_back(hit);
+ //return true;
+ }
+ }
+
+ hits.sort();
+ return !hits.empty();
+ //return false;
}
+bool Scene::checkForCollision(Character& character)
+{
+ return false;
+ //std::list< boost::shared_ptr<Impl::Quad> > objects;
+ //std::list<Mf::Octree<Impl::Quad>::InsertableP> objects;
+ //mImpl->mOctree->getNearbyObjects(objects, character);
+
+ std::list< boost::shared_ptr<Impl::Quad> >& objects = mImpl->mObjects;
+ std::list< boost::shared_ptr<Impl::Quad> >::const_iterator it;
+
+ int collisions = 0;
+ Mf::Sphere<3> sphere = character.getSphere();
+
+ for (it = objects.begin(); it != objects.end(); ++it)
+ {
+ Impl::Quad::Surface type = (*it)->getSurface();
+ if (type == Impl::Quad::NONE) continue;
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
+ 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: " << collisions << std::endl;
+ }
+
+ return false;
+}
+
+
+bool Scene::getPath(std::string& name)
+{
+ return Mf::Resource::getPath(name, "scenes/", "lua");
+}