-/*******************************************************************************
-
- 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/Exception.hh>
-#include <Moof/Library.hh>
+#include <Moof/Manager.hh>
#include <Moof/Line.hh>
#include <Moof/Log.hh>
#include <Moof/Math.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::Library<Impl>
+struct Scene::Impl : public Mf::Manager<Impl>
{
struct Quad : public Mf::Entity
{
- enum SURFACE
+ enum Surface
{
NONE = 0,
LEFT = 1,
TOP = 3
};
- Quad(const Mf::Vector3 vertices[4], const std::string& texture,
- Tilemap::Index tileIndex) :
+ 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)
- {
- mVertices[num] = vertices[i][j];
- }
+ mVertices[i] = *vertices[i];
+ //for (int j = 0; j < 3; ++j, ++num)
+ //{
+ //mVertices[num] = (*vertices[i])[j];
+ //}
}
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;
mTexCoords[0] = mTexCoords[1] =
mTexCoords[3] = mTexCoords[6] = 0.0;
mTexCoords[5] = mTexCoords[7] = 1.0;
}
- mAabb.encloseVertices(vertices, 4);
+ mAabb.encloseVertices(mVertices, 4);
mSphere.point = mAabb.getCenter();
mSphere.radius = (mAabb.min - mSphere.point).length();
}
mFog = fog;
}
- void setSurface(SURFACE type)
+ void setSurface(Surface type)
{
mSurface = type;
}
- SURFACE getSurface() const
+ Surface getSurface() const
{
return mSurface;
}
//glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
mTilemap.bind();
- glVertexPointer(3, GL_SCALAR, 0, mVertices);
+ glVertexPointer(3, GL_SCALAR, 0, mVertices[0].data());
glTexCoordPointer(2, GL_SCALAR, 0, mTexCoords);
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
- Mf::Scalar mVertices[12];
+ Mf::Vector3 mVertices[4];
Mf::Scalar mTexCoords[8];
- Tilemap mTilemap;
+ Mf::Texture mTilemap;
bool mBlending;
bool mFog;
- SURFACE mSurface;
+ Surface mSurface;
};
};
- explicit Impl(const std::string& name) :
- Mf::Library<Impl>(name) {}
+ void init(const std::string& name) {}
+
void importSceneBindings(Mf::Script& script)
{
boost::bind(&Impl::drawTile, this, _1));
int detail = 3;
- Mf::Settings::getInstance().get("detail", detail);
+ Mf::settings.get("detail", detail);
script.push(detail); script.set("detail");
script.push(1); script.set("LOW");
}
- Mf::Script::Status load(Mf::Script& script)
+ Mf::Script::Result load(Mf::Script& script)
{
std::string filePath = Scene::getPath(getName());
- if (filePath == "") return Mf::Script::FILE_ERROR;
+ if (filePath == "")
+ {
+ script.push("the scene file could not be found");
+ return Mf::Script::FILE_ERROR;
+ }
importSceneBindings(script);
return script.doFile(filePath);
static int loadBox(Mf::Script& script, Mf::Aabb<3>& aabb)
{
- Mf::Script::Value table[] =
- {
- script[1].requireTable(),
- script[2].requireTable()
- };
+ script[1].requireTable();
+ script[2].requireTable();
+ script.setSize(2);
- for (int i = 0; i <= 1; ++i)
+ for (int i = 1; i <= 2; ++i)
{
for (int j = 1; j <= 3; ++j)
{
- script.push(j);
- table[i].pushField();
+ script[i].pushField(j);
}
}
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);
int rotate(Mf::Script& script)
{
- Mf::Script::Value axis = script[1].requireNumber();
- 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(mTransform, index, cml::rad(value));
+ cml::matrix_rotate_about_world_axis(mTransform,
+ index, cml::rad(value));
return 0;
}
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();
+ Mf::Script::Slot top = script[-1];
- Quad::SURFACE surface;
- table.pushField("surface");
- top.get(surface);
- script.pop();
-
- int width = 1;
- int height = 1;
+ int width = 1;
+ int height = 1;
+ int nTiles = 0;
table.pushField("width");
top.get(width);
script.pop();
- int nTiles = 0;
-
- //table.pushField("tiles");
- Mf::Script::Value tiles = script.getTop();
- nTiles = tiles.getLength();
-
- if (nTiles % width != 0) table.throwError("invalid number of tiles");
+ nTiles = table.getLength();
+ if (nTiles % width != 0)
+ {
+ table.throwError("invalid number of tiles");
+ }
- std::vector< std::vector<Tilemap::Index> > indices;
+ if (width == 0) table.throwError("width field must not be zero");
+ 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(i);
- tiles.pushField();
+ int wPlus1 = w + 1;
+ int hPlus1 = h + 1;
+
+ table.pushField(i);
- Tilemap::Index index;
+ Mf::Texture::TileIndex index;
top.get(index);
- row.push_back(index);
- }
+ script.pop();
- indices[h] = row;
- }
+ vertices[h][wPlus1] = Mf::demote(mTransform *
+ Mf::Vector4(wPlus1, h, 0.0, 1.0));
- Mf::Vector4 vertices[height+1][width+1];
+ if (index == Mf::Texture::NO_TILE) continue;
- Mf::Matrix4 transposedTransform = mTransform;
- transposedTransform.transpose();
+ const Mf::Vector3* corners[4] = {
+ &vertices[h][w],
+ &vertices[h][wPlus1],
+ &vertices[hPlus1][wPlus1],
+ &vertices[hPlus1][w]
+ };
- 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;
+ Quad* quad = new Quad(corners, mTexture, index);
+ //quad->setSurface(surface);
+
+ 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;
-
- Mf::Vector3 demotedVertices[4];
+ Quad::Surface surface = Quad::NONE;
- demotedVertices[0] = Mf::demote(vertices[h][w]);
- demotedVertices[1] = Mf::demote(vertices[h][w+1]);
- demotedVertices[2] = Mf::demote(vertices[h+1][w+1]);
- demotedVertices[3] = Mf::demote(vertices[h+1][w]);
+ table.pushField("surface");
+ top.get(surface);
+ script.pop();
- Quad* quad = new Quad(demotedVertices, mTexture, indices[h][w]);
- quad->setSurface(surface);
+ 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
- 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
- }
+ Mf::Vector2 bl = Mf::demote(vertices[0][0]);
+ Mf::Vector2 tr = Mf::demote(vertices[height][width]);
- boost::shared_ptr<Quad> quadPtr(quad);
- //mOctree->insert(quadPtr);
- mObjects.push_back(quadPtr);
- }
+ mLines.push_back(Mf::Line<2>(bl, tr));
+ Mf::logInfo("new line");
}
return 0;
int drawTile(Mf::Script& script)
{
- Mf::Script::Value param = script[1];
- Mf::Script::Value top = script[-1];
+ Mf::Script::Slot param = script[1];
+ Mf::Script::Slot top = script[-1];
- Tilemap::Index index = 0;
- int width = 1;
- bool blending = false;
- bool fog = false;
+ Mf::Texture::TileIndex index = 0;
+ int width = 1;
+ bool blending = false;
+ bool fog = false;
if (param.isTable())
{
param.get(index);
}
- Mf::Vector4 vertices[2][width+1];
-
- Mf::Matrix4 transposedTransform = mTransform;
- transposedTransform.transpose();
+ Mf::Vector3 vertices[2][width+1];
Mf::Scalar xf;
Mf::Scalar increment = 1.0 / Mf::Scalar(width);
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 demotedVertices[4];
+ int wPlus1 = w + 1;
- demotedVertices[0] = Mf::demote(vertices[0][w]);
- demotedVertices[1] = Mf::demote(vertices[0][w+1]);
- demotedVertices[2] = Mf::demote(vertices[1][w+1]);
- demotedVertices[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(demotedVertices, mTexture, index);
+ Quad* quad = new Quad(corners, mTexture, index);
quad->setBlending(blending);
quad->setFog(fog);
boost::shared_ptr<Quad> quadPtr(quad);
- //mOctree->insert(quadPtr);
mObjects.push_back(quadPtr);
}
mImpl(Scene::Impl::getInstance(name)) {}
-Mf::Script::Status Scene::load(Mf::Script& script)
+Mf::Script::Result Scene::load(Mf::Script& script)
{
// pass through
return mImpl->load(script);
void Scene::draw(Mf::Scalar alpha) const
{
- //mImpl->mOctree->draw(alpha);
std::list< boost::shared_ptr<Impl::Quad> >& objects = mImpl->mObjects;
std::list< boost::shared_ptr<Impl::Quad> >::const_iterator it;
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
{
- //mImpl->mOctree->drawIfVisible(alpha, frustum);
std::list< boost::shared_ptr<Impl::Quad> >& objects = mImpl->mObjects;
std::list< boost::shared_ptr<Impl::Quad> >::const_iterator 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();
}
+bool Scene::castRay(const Mf::Ray<2>& ray,
+ std::list<Mf::Ray<2>::Contact>& hits) const
+{
+ 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;
for (it = objects.begin(); it != objects.end(); ++it)
{
- Impl::Quad::SURFACE type = (*it)->getSurface();
+ Impl::Quad::Surface type = (*it)->getSurface();
if (type == Impl::Quad::NONE) continue;
if (Mf::checkCollision(sphere, (*it)->getSphere()))
if (collisions > 0)
{
- Mf::logInfo("collisions: %d", collisions);
+ Mf::logInfo << "collisions: " << collisions << std::endl;
}
return false;
return Mf::Resource::getPath("scenes/" + name + ".lua");
}
-
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
-