18, 18, 18})
-- Cheaty invisible platform
+-- This draws nothing but creates a platform on the roof for walking.
ResetTransform()
-Translate(10, 4, 3)
+Rotate(X, 90)
+Translate(10, 5, 0)
DrawTilemap({
width = 3,
surface = TOP,
function GetZCoord(x, y)
- return 3
+ return 3.00001
end
return "dumb"
end
+
+-- vim: tw=80 ts=4
+
#include <Moof/Log.hh>
#include <Moof/Math.hh>
#include <Moof/OpenGL.hh>
+#include <Moof/Settings.hh>
#include <Moof/Video.hh>
#include "GameLayer.hh"
{
mState.scene = Scene::alloc(mState.sceneList[0]);
mState.sceneList.erase(mState.sceneList.begin());
- mState.scene->load(mState.script);
+
+ Mf::Script::Status status = mState.scene->load(mState.script);
+ if (status != Mf::Script::SUCCESS)
+ {
+ std::string str;
+ mState.script[-1].get(str);
+
+ Mf::logScript("%s", str.c_str());
+ throw Mf::Exception(Mf::ErrorCode::SCRIPT_ERROR, str);
+ }
}
}
{
mMusic.setLooping(true);
mMusic.enqueue("NightFusionLoop");
- mMusic.stream();
+
+ bool isMute = false;
+ Mf::Settings::getInstance().get("nomusic", isMute);
+ if (!isMute) mMusic.play();
loadSceneLoader();
advanceScene(); // load the first scene
engine.push(Hud::alloc(mState));
mRay.direction.set(1.0, 0.0);
+ mRay3.direction.set(1.0, 0.0, 0.0);
mLine.a.set(20, 10);
mLine.b.set(19, 14);
//Mf::Sound::setListenerPosition(heroinePosition);
mRay.point = mState.heroine->getState().position;
+ mRay3.point = Mf::promote(mRay.point);
+ mRay3.direction = Mf::promote(mRay.direction);
Mf::Ray<2>::Intersection meh;
+ Mf::Ray<3>::Intersection meh3;
Mf::Scalar d = mLine.intersectRay(mRay, meh);
if (d > 0.0)
Mf::logDebug(" P = <%f,%f>", meh.point[0], meh.point[1]);
Mf::logDebug(" n = <%f,%f>", meh.normal[0], meh.normal[1]);
}
- //d = mPlane.intersectRay(mRay, meh);
+ //d = mPlane.intersectRay(mRay3, meh3);
//if (d > 0.0)
//{
//Mf::logDebug("plane: d = %f", d);
- //Mf::logDebug(" P = <%f,%f>", meh.point[0], meh.point[1]);
- //Mf::logDebug(" n = <%f,%f>", meh.normal[0], meh.normal[1]);
+ //Mf::logDebug(" P = <%f,%f>", meh3.point[0], meh3.point[1]);
+ //Mf::logDebug(" n = <%f,%f>", meh3.normal[0], meh3.normal[1]);
//}
d = mSphere.intersectRay(mRay, meh);
if (d > 0.0)
Mf::logDebug(" P = <%f,%f>", meh.point[0], meh.point[1]);
Mf::logDebug(" n = <%f,%f>", meh.normal[0], meh.normal[1]);
}
+
+ std::list<Mf::Ray<2>::Intersection> hits;
+ if (mState.scene->castRay(mRay, hits))
+ {
+ Mf::logDebug("scene: d = %f", d);
+ Mf::logDebug(" P = <%f,%f>", hits.front().point[0], hits.front().point[1]);
+ Mf::logDebug(" n = <%f,%f>", hits.front().normal[0], hits.front().normal[1]);
+ }
}
void setProjection();
void setProjection(Mf::Scalar width, Mf::Scalar height);
- State mState;
- Mf::Sound mMusic;
- Mf::Sound mPunchSound;
-
- Mf::Ray<2> mRay;
- Mf::Line<2> mLine;
- Mf::Plane mPlane;
+ State mState;
+ Mf::SoundStream mMusic;
+ Mf::Sound mPunchSound;
+
+ Mf::Ray<2> mRay;
+ Mf::Ray<3> mRay3;
+ Mf::Line<2> mLine;
+ Mf::Plane mPlane;
Mf::Sphere<2> mSphere;
};
Vector a;
Vector b;
- Scalar intersectRay(const Ray<2>& ray, Ray<2>::Intersection& intersection)
+
+ Line() {}
+
+ Line(const Vector& point1, const Vector& point2) :
+ a(point1),
+ b(point2) {}
+
+ Scalar intersectRay(const Ray<2>& ray,
+ Ray<2>::Intersection& intersection) const
{
// solve: Cx + r*Dx = Ax + s(Bx - Ax)
// Cy + r*Dy = Ay + s(By - Ay)
return Vector2(vec[0], vec[1]);
}
-inline Vector4 promote(const Vector3& vec, Scalar extra = 1.0)
+inline Vector4 promote(const Vector3& vec, Scalar extra = 0.0)
{
return Vector4(vec[0], vec[1], vec[2], extra);
}
-inline Vector3 promote(const Vector2& vec, Scalar extra = 1.0)
+inline Vector3 promote(const Vector2& vec, Scalar extra = 0.0)
{
return Vector3(vec[0], vec[1], extra);
}
{
// the ray lies on the plane
intersection.point = ray.point;
- intersection.normal = normal;
+ intersection.normal.set(0.0, 0.0, 0.0);
+ //intersection.normal = normal;
return SCALAR(0.0);
}
return SCALAR(-1.0);
}
- Scalar t = (cml::dot(ray.point, normal) + d) / denominator;
+ Scalar distance = cml::dot(ray.point, normal) + d;
+ Scalar t = -distance / denominator;
if (t > SCALAR(0.0))
{
ray.solve(intersection.point, t);
- intersection.normal = normal;
+
+ if (distance >= 0.0) intersection.normal = normal;
+ else intersection.normal = -normal;
}
return t;
*/
Value(lua_State* s = 0, int i = 0) :
index(i),
- state(s) {}
+ mState(s) {}
/**
* A copied value presently points to the same value, except the real
Value(const Value& copy) :
index(copy.getRealIndex()),
- state(copy.state) {}
+ mState(copy.mState) {}
// check the type of the value
- bool isBoolean() const { return (bool)lua_isboolean(state, index); }
- bool isFunction() const { return (bool)lua_isfunction(state, index); }
- bool isNil() const { return (bool)lua_isnil(state, index); }
- bool isNone() const { return (bool)lua_isnone(state, index); }
- bool isValid() const { return state != 0 && !isNone(); }
- bool isNoneOrNil() const { return (bool)lua_isnoneornil(state, index); }
- bool isNumber() const { return (bool)lua_isnumber(state, index); }
- bool isString() const { return (bool)lua_isstring(state, index); }
- bool isTable() const { return (bool)lua_istable(state, index); }
- bool isThread() const { return (bool)lua_isthread(state, index); }
- bool isData() const { return (bool)lua_isuserdata(state, index); }
- bool isLightData() const { return (bool)lua_islightuserdata(state, index); }
+ bool isBoolean() const { return (bool)lua_isboolean(mState, index); }
+ bool isFunction() const { return (bool)lua_isfunction(mState, index); }
+ bool isNil() const { return (bool)lua_isnil(mState, index); }
+ bool isNone() const { return (bool)lua_isnone(mState, index); }
+ bool isValid() const { return mState != 0 && !isNone(); }
+ bool isNoneOrNil() const { return (bool)lua_isnoneornil(mState, index); }
+ bool isNumber() const { return (bool)lua_isnumber(mState, index); }
+ bool isString() const { return (bool)lua_isstring(mState, index); }
+ bool isTable() const { return (bool)lua_istable(mState, index); }
+ bool isThread() const { return (bool)lua_isthread(mState, index); }
+ bool isData() const { return (bool)lua_isuserdata(mState, index); }
+ bool isLightData() const { return (bool)lua_islightuserdata(mState, index); }
/**
* Check the value and throw an error if its the wrong type. There's a
{
if (type != getType())
{
- luaL_typerror(state, index, lua_typename(state, type));
+ luaL_typerror(mState, index, lua_typename(mState, type));
}
}
void throwError(const char* error)
{
- luaL_argerror(state, index, error);
+ luaL_argerror(mState, index, error);
}
Value& requireBoolean()
{
- if (!isBoolean()) luaL_typerror(state, index, "boolean");
+ if (!isBoolean()) luaL_typerror(mState, index, "boolean");
return *this;
}
Value& requireNumber()
{
- if (!isNumber()) luaL_typerror(state, index, "number");
+ if (!isNumber()) luaL_typerror(mState, index, "number");
return *this;
}
Value& requireString()
{
- if (!isString()) luaL_typerror(state, index, "string");
+ if (!isString()) luaL_typerror(mState, index, "string");
return *this;
}
Value& requireTable()
{
- if (!isTable()) luaL_typerror(state, index, "table");
+ if (!isTable()) luaL_typerror(mState, index, "table");
return *this;
}
Value& requireFunction()
{
- if (!isFunction()) luaL_typerror(state, index, "function");
+ if (!isFunction()) luaL_typerror(mState, index, "function");
return *this;
}
Value& requireData()
{
- if (!isData()) luaL_typerror(state, index, "data");
+ if (!isData()) luaL_typerror(mState, index, "data");
return *this;
}
Value& requireNil()
{
- if (!isNil()) luaL_typerror(state, index, "nil");
+ if (!isNil()) luaL_typerror(mState, index, "nil");
return *this;
}
Value& requireThread()
{
- if (!isThread()) luaL_typerror(state, index, "thread");
+ if (!isThread()) luaL_typerror(mState, index, "thread");
return *this;
}
Type getType() const
{
- return (Type)lua_type(state, index);
+ return (Type)lua_type(mState, index);
}
/**
std::string getTypeName() const
{
- return std::string(luaL_typename(state, index));
+ return std::string(luaL_typename(mState, index));
}
size_t getLength() const
{
- return lua_objlen(state, index);
+ return lua_objlen(mState, index);
}
int getRealIndex() const
{
- if (index < 0) return lua_gettop(state) + 1 + index;
+ if (index < 0) return lua_gettop(mState) + 1 + index;
else return index;
}
const void* getIdentifier() const
{
- return lua_topointer(state, index);
+ return lua_topointer(mState, index);
}
bool operator == (const Value& rhs) const
{
- return (bool)lua_equal(state, index, rhs.index);
+ return (bool)lua_equal(mState, index, rhs.index);
}
bool operator != (const Value& rhs) const
{
}
bool operator < (const Value& rhs) const
{
- return (bool)lua_lessthan(state, index, rhs.index);
+ return (bool)lua_lessthan(mState, index, rhs.index);
}
bool operator <= (const Value& rhs) const
{
}
operator bool () const
{
- return (bool)lua_toboolean(state, index);
+ return (bool)lua_toboolean(mState, index);
}
Value& operator = (const Value& rhs)
{
if (isNumber())
{
- value = (T)lua_tointeger(state, index);
+ value = (T)lua_tointeger(mState, index);
return true;
}
return false;
{
if (isNumber())
{
- value = (float)lua_tonumber(state, index);
+ value = (float)lua_tonumber(mState, index);
return true;
}
return false;
{
if (isNumber())
{
- value = (double)lua_tonumber(state, index);
+ value = (double)lua_tonumber(mState, index);
return true;
}
return false;
{
if (isBoolean())
{
- value = (bool)lua_toboolean(state, index);
+ value = (bool)lua_toboolean(mState, index);
return true;
}
return false;
if (isString())
{
size_t size;
- const char* str = lua_tolstring(state, index, &size);
+ const char* str = lua_tolstring(mState, index, &size);
value.assign(str, size);
return true;
}
array.clear();
- Value value(state, -1);
+ Value value(mState, -1);
int realIndex = getRealIndex();
bool done = false;
for (int i = 1; !done; ++i)
{
- lua_rawgeti(state, realIndex, i);
+ lua_rawgeti(mState, realIndex, i);
T v;
if (value.get(v)) array.push_back(v);
else done = true;
- lua_pop(state, 1);
+ lua_pop(mState, 1);
}
return true;
dictionary.clear();
- Value key(state, -2);
- Value value(state, -1);
+ Value key(mState, -2);
+ Value value(mState, -1);
int realIndex = getRealIndex();
- lua_pushnil(state);
- while (lua_next(state, realIndex) != 0)
+ lua_pushnil(mState);
+ while (lua_next(mState, realIndex) != 0)
{
std::string k;
if (!key.isNumber() && key.get(k))
T v;
if (value.get(v)) dictionary[k] = v;
}
- lua_pop(state, 1);
+ lua_pop(mState, 1);
}
- lua_pop(state, 1);
+ lua_pop(mState, 1);
return true;
}
void pushCopy() const
{
- lua_pushvalue(state, index);
+ lua_pushvalue(mState, index);
}
/**
void replaceWithTop()
{
- lua_replace(state, index);
+ lua_replace(mState, index);
}
void remove()
{
- lua_remove(state, index);
+ lua_remove(mState, index);
}
/**
void insertTopHere()
{
- lua_insert(state, index);
+ lua_insert(mState, index);
}
void pushMetatable() const
{
- lua_getmetatable(state, index);
+ lua_getmetatable(mState, index);
}
void pushField() const
{
- lua_gettable(state, index);
+ lua_gettable(mState, index);
}
void pushField(const std::string& name) const
{
- lua_getfield(state, index, name.c_str());
+ lua_getfield(mState, index, name.c_str());
+ }
+
+ void pushField(size_t index) const
+ {
+ lua_pushinteger(mState, lua_Integer(index));
+ pushField();
}
private:
- lua_State* state;
+ lua_State* mState;
};
template <int D>
class Shape
{
+public:
+
+ virtual ~Shape() {}
/**
* Checks if this shape is intersected by a given ray. If so, returns the
* distance from the start of the ray to the shape and information about the
#include <cstdio>
#include <deque>
+#include <list>
#include <string>
-#include <vector>
#include <AL/al.h>
#include <vorbis/codec.h>
// make sure the engine is initialized
Engine::getInstance();
- ALfloat zero[] = {0.0f, 0.0f, 0.0f};
-
+ mIsLoaded = false;
+ mIsPlaying = false;
+ mIsLooping = false;
+
alGenSources(1, &mSource);
+ ALfloat zero[] = {0.0f, 0.0f, 0.0f};
alSourcef(mSource, AL_PITCH, 1.0f);
alSourcef(mSource, AL_GAIN, 1.0f);
alSourcefv(mSource, AL_POSITION, zero);
alSourcefv(mSource, AL_VELOCITY, zero);
- mIsPlaying = false;
- mIsLooping = false;
+ alSourcei(mSource, AL_LOOPING, mIsLooping);
}
~Impl()
alDeleteSources(1, &mSource);
- while (!mBufferObjects.empty())
+ while (!mBuffers.empty())
{
- alDeleteBuffers(1, &mBufferObjects.back());
- mBufferObjects.pop_back();
+ alDeleteBuffers(1, &mBuffers.back());
+ mBuffers.pop_back();
}
}
{
if (mQueue.empty()) return;
- ALenum type;
- alGetSourcei(mSource, AL_SOURCE_TYPE, &type);
-
- if (type != AL_STATIC)
- {
- mQueue.front()->loadAll(mSource);
- }
+ if (!mIsLoaded) mQueue.front()->loadAll(mSource);
- alSourcei(mSource, AL_LOOPING, mIsLooping);
alSourcePlay(mSource);
- mIsPlaying = true;
+ mIsLoaded = true;
}
- void stream()
+ void playStream()
{
- stop();
+ if (mQueue.empty()) return;
- alSourcei(mSource, AL_BUFFER, AL_NONE);
- mQueue.front()->rewind();
- beginStream();
+ if (!mIsPlaying)
+ {
+ alSourcei(mSource, AL_LOOPING, false);
+ bufferStream();
+ }
+
+ if (!mStreamTimer.isValid())
+ {
+ mStreamTimer.init(boost::bind(&Impl::streamUpdate, this, _1, _2),
+ 1.0, Timer::REPEAT);
+ }
- alSourcei(mSource, AL_LOOPING, AL_FALSE);
alSourcePlay(mSource);
mIsPlaying = true;
-
- mStreamTimer.init(boost::bind(&Impl::streamUpdate, this, _1, _2), 1.0,
- Timer::REPEAT);
}
- void beginStream()
+ void bufferStream()
{
ALuint buffer;
- for (int i = mBufferObjects.size(); i < 8; ++i)
+ for (int i = mBuffers.size(); i <= 8; ++i)
{
alGenBuffers(1, &buffer);
- mBufferObjects.push_back(buffer);
- }
- for (int i = 0; i < 8; ++i)
- {
- buffer = mBufferObjects[i];
- mQueue.front()->stream(buffer);
- alSourceQueueBuffers(mSource, 1, &buffer);
+
+ if (mQueue.front()->stream(buffer))
+ {
+ alSourceQueueBuffers(mSource, 1, &buffer);
+ mBuffers.push_back(buffer);
+ }
+ else
+ {
+ alDeleteBuffers(1, &buffer);
+ break;
+ }
}
}
mQueue.front()->stream(bufferObj);
alSourceQueueBuffers(mSource, 1, &bufferObj);
logInfo("loading new buffer");
+
+ // queue up any unused buffers
+ bufferStream();
}
else if (mIsLooping)
{
alSourceQueueBuffers(mSource, 1, &bufferObj);
logInfo("looping same buffer");
}
+ else
+ {
+ // nothing more to play, stopping...
+ mIsPlaying = false;
+ std::remove(mBuffers.begin(), mBuffers.end(), bufferObj);
+ }
}
}
mStreamTimer.invalidate();
}
- void resume()
- {
- alSourcePlay(mSource);
- mIsPlaying = true;
-
- ALenum type;
- alGetSourcei(mSource, AL_SOURCE_TYPE, &type);
-
- if (type == AL_STREAMING)
- {
- mStreamTimer.init(boost::bind(&Impl::streamUpdate, this, _1, _2),
- 1.0, Timer::REPEAT);
- }
- }
-
void setSample(const std::string& name)
{
- bool playing = isPlaying();
- ALenum type;
- alGetSourcei(mSource, AL_SOURCE_TYPE, &type);
-
stop();
+ alSourcei(mSource, AL_BUFFER, AL_NONE);
+
mQueue.clear();
+ mIsLoaded = false;
- //alSourcei(mSource, AL_BUFFER, AL_NONE);
enqueue(name);
- if (playing)
+ while (!mBuffers.empty())
{
- if (type == AL_STREAMING) stream();
- else play();
+ alDeleteBuffers(1, &mBuffers.back());
+ mBuffers.pop_back();
}
}
ALuint mSource;
- std::vector<ALuint> mBufferObjects;
+ std::list<ALuint> mBuffers;
+ bool mIsLoaded;
bool mIsPlaying;
bool mIsLooping;
mImpl(new Sound::Impl(name)) {}
-void Sound::play()
+void Sound::setSample(const std::string& name)
{
// pass through
- mImpl->play();
+ mImpl->setSample(name);
}
-void Sound::stream()
+
+void Sound::play()
{
// pass through
- mImpl->stream();
+ mImpl->play();
}
-
void Sound::stop()
{
// pass through
mImpl->pause();
}
-void Sound::resume()
-{
- // pass through
- mImpl->resume();
-}
void Sound::toggle()
{
- if (mImpl->mIsPlaying) pause();
- else resume();
+ if (isPlaying()) pause();
+ else play();
}
-
-void Sound::setSample(const std::string& name)
-{
- // pass through
- mImpl->setSample(name);
-}
-
-void Sound::enqueue(const std::string& name)
-{
- // pass through
- mImpl->enqueue(name);
-}
-
-
bool Sound::isPlaying() const
{
// pass through
return mImpl->isPlaying();
}
+
void Sound::setPosition(const Vector3& position)
{
- float p[3] = {position[0], position[1], position[2]};
- alSourcefv(mImpl->mSource, AL_POSITION, p);
+ float vec[3] = {position[0], position[1], position[2]};
+ alSourcefv(mImpl->mSource, AL_POSITION, vec);
}
void Sound::setVelocity(const Vector3& velocity)
{
- float v[3] = {velocity[0], velocity[1], velocity[2]};
- alSourcefv(mImpl->mSource, AL_VELOCITY, v);
+ float vec[3] = {velocity[0], velocity[1], velocity[2]};
+ alSourcefv(mImpl->mSource, AL_VELOCITY, vec);
}
void Sound::setGain(Scalar gain)
void Sound::setListenerPosition(const Vector3& position)
{
- alListener3f(AL_POSITION, float(position[0]), float(position[1]),
- float(position[2]));
+ //alListener3f(AL_POSITION, float(position[0]), float(position[1]),
+ //float(position[2]));
+ float vec[] = {position[0], position[1], position[2]};
+ alListenerfv(AL_POSITION, vec);
}
void Sound::setListenerVelocity(const Vector3& velocity)
{
- alListener3f(AL_VELOCITY, float(velocity[0]), float(velocity[1]),
- float(velocity[2]));
+ //alListener3f(AL_VELOCITY, float(velocity[0]), float(velocity[1]),
+ //float(velocity[2]));
+ float vec[] = {velocity[0], velocity[1], velocity[2]};
+ alListenerfv(AL_VELOCITY, vec);
}
void Sound::setListenerOrientation(const Vector3& forward, const Vector3& up)
}
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+void SoundStream::enqueue(const std::string& name)
+{
+ // pass through
+ mImpl->enqueue(name);
+}
+
+
+void SoundStream::play()
+{
+ // pass through
+ mImpl->playStream();
+}
+
+
} // namespace Mf
/** vim: set ts=4 sw=4 tw=80: *************************************************/
class Sound;
typedef boost::shared_ptr<Sound> SoundP;
+class SoundStream;
+typedef boost::shared_ptr<SoundStream> SoundStreamP;
+
class Sound : public Resource
{
Sound();
explicit Sound(const std::string& name);
+ virtual ~Sound() {}
- void play();
- void stream();
-
- // TODO this API sucks... refactor me!!
+ // this implicitly stops the sound if it is playing
+ void setSample(const std::string& name);
+ virtual void play();
void stop();
void pause();
- void resume();
- void toggle();
-
- void setSample(const std::string& name);
- void enqueue(const std::string& name);
+ void toggle();
bool isPlaying() const;
void setPosition(const Vector3& position);
static std::string getPath(const std::string& name);
-private:
+protected:
class Impl;
boost::shared_ptr<Impl> mImpl;
};
+class SoundStream : public Sound
+{
+public:
+
+ static SoundStreamP alloc(const std::string& name)
+ {
+ return SoundStreamP(new SoundStream(name));
+ }
+
+ SoundStream();
+ explicit SoundStream(const std::string& name) :
+ Sound(name) {}
+
+ void enqueue(const std::string& name);
+
+ void play();
+};
+
+
} // namespace Mf
#endif // _MOOF_SOUND_HH_
*******************************************************************************/
#include <map>
-#include <vector>
#include <Moof/Aabb.hh>
#include <Moof/Camera.hh>
{
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,
+ Quad(const Mf::Vector3* vertices[4], const std::string& texture,
Tilemap::Index 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))
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;
bool mBlending;
bool mFog;
- SURFACE mSurface;
+ Surface mSurface;
};
Mf::Script::Status 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);
Mf::Script::Value table = script[1].requireTable();
Mf::Script::Value 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();
-
+ nTiles = table.getLength();
if (nTiles % width != 0) table.throwError("invalid number of tiles");
- std::vector< std::vector<Tilemap::Index> > indices;
-
- int i, w, h;
-
+ if (width == 0) table.throwError("width field must not be zero");
height = nTiles / width;
- indices.resize(height);
+
+ Mf::Vector3 vertices[height+1][width+1];
// 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)
+ // do first row and first column of vertices
+
+ for (int w = 0; w <= width; ++w)
+ {
+ vertices[height][w] = Mf::demote(mTransform *
+ Mf::Vector4(w, height, 0.0, 1.0));
+ }
+ for (int h = 0; h < height; ++h)
{
- std::vector<Tilemap::Index> row;
+ 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;
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 == Tilemap::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;
+ Quad::Surface surface = Quad::NONE;
- Mf::Vector3 demotedVertices[4];
+ table.pushField("surface");
+ top.get(surface);
+ script.pop();
- 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]);
+ 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(demotedVertices, mTexture, indices[h][w]);
- quad->setSurface(surface);
+ //Mf::Vector2 tr = Mf::demote(vertices[height+1][width+1]);
+ //Mf::Vector2 bl = Mf::demote(vertices[0][0]);
- 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]);
+ //Mf::logInfo("pt1: %f, %f", bl[0], bl[1]);
+ //Mf::logInfo("pt2: %f, %f", tr[0], tr[1]);
- 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");
+
+ //if (tl == tr)
+ //{
+ //mLines.push_back(Mf::Line<2>(bl, tl));
+ //}
+ //else
+ //{
+ //mLines.push_back(Mf::Line<2>(bl, tl));
+ //}
}
return 0;
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);
}
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;
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>::Intersection>& 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>::Intersection hit;
+ Mf::Scalar d = (*it).intersectRay(ray, hit);
+ if (d > 0.0)
+ {
+ hits.push_back(hit);
+ return true;
+ }
+ }
+
+ 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()))
#ifndef _SCENE_HH_
#define _SCENE_HH_
+#include <list>
#include <string>
#include <boost/shared_ptr.hpp>
Mf::Scalar getZCoord(const Mf::Vector2& position) const;
+ bool castRay(const Mf::Ray<2>& ray,
+ std::list<Mf::Ray<2>::Intersection>& hits) const;
bool checkForCollision(Character& character);
static std::string getPath(const std::string& name);
-#!/bin/bash
+#!/bin/sh
#
# Yoink