ray-scene intersection
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Sun, 13 Dec 2009 18:24:55 +0000 (11:24 -0700)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Sun, 13 Dec 2009 18:24:55 +0000 (11:24 -0700)
13 files changed:
data/scenes/Classic.lua
src/GameLayer.cc
src/GameLayer.hh
src/Moof/Line.hh
src/Moof/Math.hh
src/Moof/Plane.hh
src/Moof/Script.hh
src/Moof/Shape.hh
src/Moof/Sound.cc
src/Moof/Sound.hh
src/Scene.cc
src/Scene.hh
win32/mkpackage.sh.in

index 68b7b660533b918db1db7aab4322c486768d8c1f..e8ba272faac8d7c8ad12808f8559d03440fc3aa1 100644 (file)
@@ -197,9 +197,11 @@ DrawTilemap({
        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,
@@ -811,7 +813,7 @@ end
 
 
 function GetZCoord(x, y)
-       return 3
+       return 3.00001
 end
 
 
@@ -892,3 +894,6 @@ function RandomSkillLevel()
        return "dumb"
 end
 
+
+-- vim: tw=80 ts=4
+
index 41000f395d645b8f13b4031e4f7db9e7a88bfcb6..1e607586d486169afa681b8cea57015b5353e2e9 100644 (file)
@@ -31,6 +31,7 @@
 #include <Moof/Log.hh>
 #include <Moof/Math.hh>
 #include <Moof/OpenGL.hh>
+#include <Moof/Settings.hh>
 #include <Moof/Video.hh>
 
 #include "GameLayer.hh"
@@ -92,7 +93,16 @@ void GameLayer::advanceScene()
        {
                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);
+               }
        }
 }
 
@@ -103,7 +113,10 @@ GameLayer::GameLayer() :
 {
        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
@@ -123,6 +136,7 @@ void GameLayer::pushed(Mf::Engine& engine)
        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);
@@ -150,8 +164,11 @@ void GameLayer::update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt)
        //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)
@@ -160,12 +177,12 @@ void GameLayer::update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt)
                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)
@@ -174,6 +191,14 @@ void GameLayer::update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt)
                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]);
+       }
 }
 
 
index f966c7092ca3703affa4dee90dc60172815a75dd..4692611789f7cfbc1829be8b67cf13677d94a87d 100644 (file)
@@ -102,13 +102,14 @@ private:
        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;
 };
 
index 4a54e2d5f008c5bcd62c21340b552ffeb0eb809a..33eecb9b3df6f91dec483b8022011eac8cdda2a4 100644 (file)
@@ -49,7 +49,15 @@ struct Line : public Drawable, public Shape<D>
        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)
index ae747ec37957417ca771fc0543a142d1adaf962d..05aa9ecf6504d55c0d33f1e3042612480d22df8f 100644 (file)
@@ -91,12 +91,12 @@ inline Vector2 demote(const Vector3& vec)
        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);
 }
index 5ec59eab28e1c6115f4923b92892de9fd5e9d572..11cd63ec23f2bf7f6517a8b2d5e937eb6f3832f3 100644 (file)
@@ -79,7 +79,8 @@ struct Plane : public Shape<3>
                        {
                                // 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);
                        }
 
@@ -87,11 +88,14 @@ struct Plane : public Shape<3>
                        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;
index 2f285cecc2bcdd740529783fcc8d4f7ea0fa581b..f67c62c20d27f67a09732650d4cdb4adb70b88c4 100644 (file)
@@ -125,7 +125,7 @@ public:
                 */
                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
@@ -136,22 +136,22 @@ public:
 
                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
@@ -170,54 +170,54 @@ public:
                {
                        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;
                }
 
@@ -228,7 +228,7 @@ public:
 
                Type getType() const
                {
-                       return (Type)lua_type(state, index);
+                       return (Type)lua_type(mState, index);
                }
 
                /**
@@ -237,7 +237,7 @@ public:
 
                std::string getTypeName() const
                {
-                       return std::string(luaL_typename(state, index));
+                       return std::string(luaL_typename(mState, index));
                }
 
 
@@ -247,12 +247,12 @@ public:
 
                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;
                }
 
@@ -263,13 +263,13 @@ public:
 
                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
                {
@@ -277,7 +277,7 @@ public:
                }
                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
                {
@@ -293,7 +293,7 @@ public:
                }
                operator bool () const
                {
-                       return (bool)lua_toboolean(state, index);
+                       return (bool)lua_toboolean(mState, index);
                }
 
                Value& operator = (const Value& rhs)
@@ -313,7 +313,7 @@ public:
                {
                        if (isNumber())
                        {
-                               value = (T)lua_tointeger(state, index);
+                               value = (T)lua_tointeger(mState, index);
                                return true;
                        }
                        return false;
@@ -323,7 +323,7 @@ public:
                {
                        if (isNumber())
                        {
-                               value = (float)lua_tonumber(state, index);
+                               value = (float)lua_tonumber(mState, index);
                                return true;
                        }
                        return false;
@@ -332,7 +332,7 @@ public:
                {
                        if (isNumber())
                        {
-                               value = (double)lua_tonumber(state, index);
+                               value = (double)lua_tonumber(mState, index);
                                return true;
                        }
                        return false;
@@ -342,7 +342,7 @@ public:
                {
                        if (isBoolean())
                        {
-                               value = (bool)lua_toboolean(state, index);
+                               value = (bool)lua_toboolean(mState, index);
                                return true;
                        }
                        return false;
@@ -353,7 +353,7 @@ public:
                        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;
                        }
@@ -367,19 +367,19 @@ public:
 
                        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;
@@ -392,12 +392,12 @@ public:
 
                        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))
@@ -405,9 +405,9 @@ public:
                                        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;
                }
@@ -420,7 +420,7 @@ public:
 
                void pushCopy() const
                {
-                       lua_pushvalue(state, index);
+                       lua_pushvalue(mState, index);
                }
 
                /**
@@ -429,12 +429,12 @@ public:
 
                void replaceWithTop()
                {
-                       lua_replace(state, index);
+                       lua_replace(mState, index);
                }
 
                void remove()
                {
-                       lua_remove(state, index);
+                       lua_remove(mState, index);
                }
 
                /**
@@ -444,29 +444,35 @@ public:
 
                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;
        };
 
 
index b78eaade7179cd9e5a2a9274509984dabaf89c10..c67a7798772e78b5e4992ba39b59e3c75b3428c9 100644 (file)
@@ -58,6 +58,9 @@ namespace Mf {
 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
index 4275ea4485900c67e147aeb04165b5f6c2496b30..3aec3f6aa90aa85f4c0f40936508a6ae01a2fff7 100644 (file)
@@ -28,8 +28,8 @@
 
 #include <cstdio>
 #include <deque>
+#include <list>
 #include <string>
-#include <vector>
 
 #include <AL/al.h>
 #include <vorbis/codec.h>
@@ -209,17 +209,19 @@ public:
                // 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()
@@ -228,10 +230,10 @@ public:
 
                alDeleteSources(1, &mSource);
 
-               while (!mBufferObjects.empty())
+               while (!mBuffers.empty())
                {
-                       alDeleteBuffers(1, &mBufferObjects.back());
-                       mBufferObjects.pop_back();
+                       alDeleteBuffers(1, &mBuffers.back());
+                       mBuffers.pop_back();
                }
        }
 
@@ -240,49 +242,50 @@ public:
        {
                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;
+                       }
                }
        }
 
@@ -317,6 +320,9 @@ public:
                                        mQueue.front()->stream(bufferObj);
                                        alSourceQueueBuffers(mSource, 1, &bufferObj);
                                        logInfo("loading new buffer");
+
+                                       // queue up any unused buffers
+                                       bufferStream();
                                }
                                else if (mIsLooping)
                                {
@@ -327,6 +333,12 @@ public:
                                        alSourceQueueBuffers(mSource, 1, &bufferObj);
                                        logInfo("looping same buffer");
                                }
+                               else
+                               {
+                                       // nothing more to play, stopping...
+                                       mIsPlaying = false;
+                                       std::remove(mBuffers.begin(), mBuffers.end(), bufferObj);
+                               }
                        }
                }
 
@@ -358,38 +370,21 @@ public:
                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();
                }
        }
 
@@ -435,8 +430,9 @@ public:
 
 
        ALuint                                  mSource;
-       std::vector<ALuint>             mBufferObjects;
+       std::list<ALuint>               mBuffers;
 
+       bool                                    mIsLoaded;
        bool                                    mIsPlaying;
        bool                                    mIsLooping;
 
@@ -455,19 +451,19 @@ Sound::Sound(const std::string& name) :
        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
@@ -480,48 +476,30 @@ void Sound::pause()
        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)
@@ -543,14 +521,18 @@ void Sound::setLooping(bool looping)
 
 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)
@@ -573,6 +555,23 @@ std::string Sound::getPath(const std::string& name)
 }
 
 
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+
+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: *************************************************/
index 982e9b4065eeca659601fd9015846407a2936fab..6e5f78a23fc4311e736000aecd922f534a003a3a 100644 (file)
@@ -47,6 +47,9 @@ namespace Mf {
 class Sound;
 typedef boost::shared_ptr<Sound> SoundP;
 
+class SoundStream;
+typedef boost::shared_ptr<SoundStream> SoundStreamP;
+
 
 class Sound : public Resource
 {
@@ -60,20 +63,16 @@ public:
        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);
@@ -89,13 +88,32 @@ public:
 
        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_
index 452cc134cc85359894bac9877649806424f54938..fce451799db5e4d56a9649e79f7d9ce7fd38453a 100644 (file)
@@ -27,7 +27,6 @@
 *******************************************************************************/
 
 #include <map>
-#include <vector>
 
 #include <Moof/Aabb.hh>
 #include <Moof/Camera.hh>
@@ -50,7 +49,7 @@ struct Scene::Impl : public Mf::Library<Impl>
 {
        struct Quad : public Mf::Entity
        {
-               enum SURFACE
+               enum Surface
                {
                        NONE    = 0,
                        LEFT    = 1,
@@ -58,19 +57,20 @@ struct Scene::Impl : public Mf::Library<Impl>
                        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))
@@ -84,7 +84,7 @@ struct Scene::Impl : public Mf::Library<Impl>
                                        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();
                }
@@ -99,12 +99,12 @@ struct Scene::Impl : public Mf::Library<Impl>
                        mFog = fog;
                }
 
-               void setSurface(SURFACE type)
+               void setSurface(Surface type)
                {
                        mSurface = type;
                }
 
-               SURFACE getSurface() const
+               Surface getSurface() const
                {
                        return mSurface;
                }
@@ -126,7 +126,7 @@ struct Scene::Impl : public Mf::Library<Impl>
                        //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);
@@ -141,14 +141,14 @@ struct Scene::Impl : public Mf::Library<Impl>
                }
 
 
-               Mf::Scalar              mVertices[12];
+               Mf::Vector3             mVertices[4];
                Mf::Scalar              mTexCoords[8];
                
                Tilemap                 mTilemap;
 
                bool                    mBlending;
                bool                    mFog;
-               SURFACE                 mSurface;
+               Surface                 mSurface;
        };
 
 
@@ -214,7 +214,11 @@ struct Scene::Impl : public Mf::Library<Impl>
        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);
@@ -336,97 +340,105 @@ struct Scene::Impl : public Mf::Library<Impl>
                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;
@@ -462,10 +474,7 @@ struct Scene::Impl : public Mf::Library<Impl>
                        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);
@@ -475,26 +484,27 @@ struct Scene::Impl : public Mf::Library<Impl>
                        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);
                }
 
@@ -517,7 +527,6 @@ Mf::Script::Status Scene::load(Mf::Script& 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;
 
@@ -531,7 +540,6 @@ void Scene::draw(Mf::Scalar alpha) 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;
 
@@ -540,10 +548,38 @@ void Scene::drawIfVisible(Mf::Scalar alpha, const Mf::Frustum& frustum) const
                (*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;
@@ -559,7 +595,7 @@ bool Scene::checkForCollision(Character& character)
 
        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()))
index f9963e85dd0ea1e7567a5fd7e63f08daec01e47f..316f25b14d76d7f380586b815a025776f21caaf8 100644 (file)
@@ -29,6 +29,7 @@
 #ifndef _SCENE_HH_
 #define _SCENE_HH_
 
+#include <list>
 #include <string>
 
 #include <boost/shared_ptr.hpp>
@@ -66,6 +67,8 @@ public:
 
        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);
index 2051a22c1218491f2b6129f846301e3abda4425f..e6dffa2122d138d3fe18c34ad6ba7d991fa5af6f 100644 (file)
@@ -1,4 +1,4 @@
-#!/bin/bash
+#!/bin/sh
 
 #
 # Yoink
This page took 0.065243 seconds and 4 git commands to generate.