]> Dogcows Code - chaz/yoink/commitdiff
fixed layer bugs; generalized octree
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Sat, 17 Oct 2009 07:15:47 +0000 (01:15 -0600)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Sat, 17 Oct 2009 07:15:47 +0000 (01:15 -0600)
32 files changed:
configure.ac
data/yoinkrc
doc/yoink.6.in
src/Character.cc
src/Character.hh
src/GameLayer.cc
src/GameLayer.hh
src/Heroine.cc [new file with mode: 0644]
src/Heroine.hh [new file with mode: 0644]
src/Hud.cc
src/MainLayer.cc
src/MainLayer.hh
src/Makefile.am
src/Moof/Camera.cc
src/Moof/Camera.hh
src/Moof/Engine.cc
src/Moof/Engine.hh
src/Moof/Entity.hh
src/Moof/Interpolator.hh
src/Moof/Math.hh
src/Moof/Octree.cc [deleted file]
src/Moof/Octree.hh
src/Moof/OpenGL.hh
src/Moof/Scene.cc [deleted file]
src/Moof/Scene.hh [deleted file]
src/Moof/Transition.hh [new file with mode: 0644]
src/Moof/Video.cc
src/Moof/Video.hh
src/Scene.cc [new file with mode: 0644]
src/Scene.hh [new file with mode: 0644]
src/TitleLayer.cc [new file with mode: 0644]
src/TitleLayer.hh [new file with mode: 0644]

index f7e75b0a2a7ea1295c77ac2e019da35ca36fc38b..245a183618a428ce02134779112260a10eca471d 100644 (file)
@@ -94,6 +94,11 @@ AC_ARG_WITH([log-level],
                        [log_level=$withval],
                        [log_level=3])
 
+AC_ARG_ENABLE([double],
+                         [  --enable-double         use double-precision numbers],
+                         [double=$enableval],
+                         [double=no])
+
 
 if test x$developer = xyes
 then
@@ -128,6 +133,13 @@ then
        CXXFLAGS="$CXXFLAGS -Wextra -Wno-unused-parameter"
 fi
 
+if test x$double = xyes
+then
+       AC_DEFINE([USE_DOUBLE_PRECISION], 1,
+                         [Define to 1 if you want to use double-precison numbers.])
+fi
+
+
 AC_DEFINE_UNQUOTED([YOINK_LOGLEVEL], [$log_level],
                                   [Define to detail level of logging.])
 
index bcb0f0645f040edee3631b1fc865e7c4a16c3427..86b333d51c56652f4ca16546b589859b8630389a 100644 (file)
@@ -12,12 +12,12 @@ print "loading yoinkrc..."
 detail = 3
 
 -- Set the amount of time in seconds between each update of the physics
--- state.  A value of 0.01 or lower is ideal for accurate physics
--- approximations.  Values that are much higher cause the CPU to do less
+-- state.  A value of 100 or higher is ideal for accurate physics
+-- approximations.  Values that are much lower cause the CPU to do less
 -- work, but accuracy will suffer.  Errors could be introduced in the game
--- with extremely high values.
+-- with extremely low values.
 
-timestep = 0.01
+timestep = 80
 
 -- Set the maximum number of frames that can be drawn per second.  A value
 -- of 50 is pretty good.  If your computer is really old, you can get away
@@ -30,7 +30,7 @@ timestep = 0.01
 -- not be able to update the physics on schedule which could actually
 -- significantly lower the quality of the animation.
 
-maxfps = 45
+maxfps = 40
 
 -- Set whether or not to print the current actual framerate to the console.
 
index 2432bd5de9d39abdcdaf847bd69e7759b89e2d6c..5742a5e51963b9dcc518380c0abbb358133ad101 100644 (file)
@@ -78,8 +78,8 @@ unlike that of other configuration files you are already familiar with.  The
 syntax used is lua.
 .B yoink
 looks for configuration files and loads them in this order, the options from
-each subsequent configuration files taking precedence over the same options from
-previous files.
+each subsequent configuration files taking precedence over the same options if
+they exist in previous files.
 .TP
 1. @DATADIR@/yoinkrc
 This is the base configuration file which should be considered read-only.  Look
@@ -96,8 +96,9 @@ This is an optional environment variable you can set to point to a configuration
 file.
 .PP
 Options that are passed as arguments take precedence over options loaded from
-the configuration file(s).  This mechanism is good for running the game with a
-temporary setting which you do not intend to retain.  Examples:
+the configuration file(s).  This mechanism can be used to play the game with
+temporary settings which you do not intend to retain.  Here are some examples of
+passing options on the command-line:
 .PP
 .TP
 yoink fullscreen=true
@@ -123,58 +124,60 @@ as the numbers 1024 and 768.  The video size will be 1024x768.
 Here is a list of some of the options available:
 .TP
 .B detail
-The level of detail.  Possible values are high, medium, and low.  This effects
-the number of objects drawn to the screen.  A high level of detail will draw
-everything but could cause poor frame rates if the graphics driver can't keep up
-with the load.  Lower levels will omit certain details which aren't crucial for
-playing the game with the benefit of higher frame rates.  See the Notes for more
-ways to get good performance.
+The level of detail.  Possible values are 1, 2, or 3, 1 meaning the least amount
+of detail and 3 meaning the most.  This effects the number of objects drawn to
+the screen.  A high level of detail will draw everything but could cause poor
+frame rates if the graphics driver can't keep up with the load.  Lower levels
+will omit certain details which aren't crucial for playing the game with the
+benefit of higher frame rates.  See the Notes for more ways to increase the
+game's performance.  The default value is 3.
 .TP
 .B doublebuffer
-If true, double-buffering will be used to render animations with minimal
-distortions.  Otherwise, a single buffer will be used.  The recommended value is
-true.
+If true, double-buffering will be used to help minimize distortion and artifacts
+caused by the animation of the game.  Otherwise, a single buffer will be used.
+The default value is true.
 .TP
 .B fullscreen
 If true, the window will capture the display and render the game in full screen
-splendor.  A value of false means the game will run in a window.
+splendor.  A value of false means the game will run in a window.  The default
+value is false.
 .TP
 .B maxfps
-The maximum number of frames to be drawn per second.  A value of 50 is pretty
-good.  If your computer is pretty old, can get away with decreasing this value
-and still have reasonably smooth animation.  You can set this to a very high
-number to effectively render as many frames as is possible, but the actual rate
-could be limited by vertical display synchronization, depending on the X11
-driver and settings used.  You should not set this option higher than the point
-where the vertical synchronization effectively limits the draw rate or else the
-game may not be able to update the physics on schedule which could actually
-significantly lower the quality of the animation.
+The maximum number of frames to be drawn per second.  If your computer is really
+old, you can get away with decreasing this value and still have reasonably
+smooth animation.  You can set this to a very high number to effectively render
+as many frames as is possible, but the actual rate could be limited by vertical
+display synchronization, depending on the X11 driver and settings used.  You
+should not set this option higher than the point where the vertical
+synchronization effectively limits the draw rate or else the game may not be
+able to update the physics on schedule which could actually significantly lower
+the quality of the animation.  The default value is 40.
 .TP
 .B printfps
-If true, the current number of frames being draw per second will be printed to
-the console.  This is usually off by default, but you can set this to true if
-you're interested in the draw rate you're actually getting.
+If true, the current number of frames being drawn per second will be printed to
+the console.  The default value is false.
 .TP
 .B resizable
 If true, the window will be resizable by the window manager.  This option is
-meaningless if the game is drawing to the full screen.
+meaningless if the game is drawing to the full screen.  The default option is
+true.
 .TP
 .B showcursor
 This option effects the visibility of the cursor while it is "hovering" over the
-window.  If the value is true, the cursor will be visible.  Otherwise, the
-cursor will be hidden.
+display.  If the value is true, the cursor will be visible.  Otherwise, the
+cursor will be hidden.  The default value is true.
 .TP
 .B timestep
-The amount of time in seconds between each update of the physics state.  A value
-of 0.01 or lower is ideal for accurate physics approximations.  Values that are
-much higher cause the CPU to do less work, but accuracy will suffer.  Errors
-could be introduced in the game with extremely high values.
+The number of times per second the simulation state will be updated.  A value
+of 100 or higher is ideal for a better physical simulation.  Values that are
+much lower cause the CPU to do less work, but accuracy will suffer.  Errors
+could be introduced in the game with extremely low values.  The default value
+is 80.
 .TP
 .B videomode
 The resolution or size of the window.  The value is an array with three number
 elements representing the width, height, and bits per pixel that make up the
-video mode.  A typical value is {800,600} for a size of 800x600 pixels with
-millions of colors (the third number is optional).
+video mode.  The third number is optional.  The default value is {800, 600}.
 .PP
 This is only a list of the more useful options.  You'll have to use the source
 to find out about the more esoteric options, but you probably won't need to.
@@ -189,10 +192,7 @@ If set to a path of a valid directory (presumably a user's home directory),
 .B yoink
 will look for a file at
 .I $HOME/.yoinkrc
-and load it as a configuration file.  Saving options within the game will cause
-this file to be over-written with the new options, unless the
-.I YOINKRC
-variable is set.
+and load it as a configuration file.
 .TP
 USER
 .B yoink
@@ -218,27 +218,34 @@ Yoink may or may not be playable with acceptable frame rates without a hardware
 accelerated OpenGL driver installed and working, depending on how fast your CPU
 is.  Yoink is really not all that heavy on graphics, but it doesn't take much to
 overload a software implementation.  If you're stuck without hardware
-acceleration, there are some things you can do to get better frame rates:
+acceleration, there are some things you can do to get better frame rates, in
+order of effectiveness:
 .TP
 1. Decrease the resolution.
 Use the
 .I videomode
-option.  This speeds up software renderers considerably.
+option or just resize the window if the
+.I fullscreen
+option is false and the
+.I resizable
+option is true.  This speeds up software renderers considerably.
 .TP
-2. Decrease the level of rendering detail.
+2. Decrease the timestep.
+Use the
+.I timestep
+option.  You can set the timestep to be as low as the your
+.I maxfps
+option, but it is not recommended to set this lower than the target frame rate.
+Remember the trade-off here is decreased simulation accuracy.  Try this to set
+your frame rate to 30Hz and your timestep to 60Hz:
+.PP
+yoink maxfps=30 timestep=maxfps\\*2
+.TP
+3. Decrease the level of rendering detail.
 Use the
 .I detail
 option.  The game world may look sparse or incomplete, but that may be better
 than choppy animation.
-.PP
-On the other hand, if you already get high frame rates, you may also want to cap
-the rate so that your computer doesn't do more work than it really needs to.
-You can get reasonably smooth animation at around 30fps, but you can probably
-tell a difference between that and a higher rate like 50fps.  The latter will
-look noticeably smoother and nice, while the former is just "okay."  See
-the
-.I maxfps
-option.
 .br
 .SH BUGS
 .PP
index c6ad2a049874d821befa4e90da831703ce2ec653..8e5a4c65e7437ca4f80a8614a8b17c5f1c087454 100644 (file)
@@ -49,7 +49,7 @@ Character::Character(const std::string& name) :
 
        previous = current;
 
-       updateContainers();
+       //updateContainers();
 }
 
 
@@ -72,85 +72,33 @@ void Character::update(Mf::Scalar t, Mf::Scalar dt)
 
        animation_.update(t, dt);
 
-       updateContainers();
+       //updateContainers();
 }
 
-void Character::updateContainers()
-{
-       aabb_.init(Mf::Vector3(current.position[0]-16.0, current.position[1]-16.0, z),
-                       Mf::Vector3(current.position[0]+16.0, current.position[1]+16.0, z));
-       sphere_.point = Mf::Vector3(current.position[0], current.position[1], z);
-       sphere_.radius = (aabb_.min - sphere_.point).length();
-}
-
-void Character::handleEvent(const Mf::Event& event)
-{
-       // really just for heroine...
-       
-       Mf::Scalar force = 4000.0;
-       
-       Mf::Vector2 left = Mf::Vector2(-force, 0.0);
-       Mf::Vector2 right = Mf::Vector2(force, 0.0);
-       Mf::Vector2 down = Mf::Vector2(0.0, -force);
-       Mf::Vector2 up = Mf::Vector2(0.0, force);
-
-       switch (event.type)
-       {
-               case SDL_KEYDOWN:
-                       if (event.key.keysym.sym == SDLK_a)
-                       {
-                               userForce += left;
-                       }
-                       else if (event.key.keysym.sym == SDLK_d)
-                       {
-                               userForce += right;
-                       }
-                       else if (event.key.keysym.sym == SDLK_s)
-                       {
-                               userForce += down;
-                       }
-                       else if (event.key.keysym.sym == SDLK_w)
-                       {
-                               userForce += up;
-                       }
-                       break;
-
-               case SDL_KEYUP:
-                       if (event.key.keysym.sym == SDLK_a)
-                       {
-                               userForce -= left;
-                       }
-                       else if (event.key.keysym.sym == SDLK_d)
-                       {
-                               userForce -= right;
-                       }
-                       else if (event.key.keysym.sym == SDLK_s)
-                       {
-                               userForce -= down;
-                       }
-                       else if (event.key.keysym.sym == SDLK_w)
-                       {
-                               userForce -= up;
-                       }
-                       break;
-       }
-
-       //Mf::logInfo("current force [%f %f]", current.force[0], current.force[1]);
-       //std::cerr << "current force: " << current.force << std::endl;
-}
+//void Character::updateContainers()
+//{
+       //aabb_.init(Mf::Vector3(current.position[0]-16.0, current.position[1]-16.0, z),
+                       //Mf::Vector3(current.position[0]+16.0, current.position[1]+16.0, z));
+       //sphere_.point = Mf::Vector3(current.position[0], current.position[1], z);
+       //sphere_.radius = (aabb_.min - sphere_.point).length();
+//}
 
 
 void Character::draw(Mf::Scalar alpha) const
 {
        State state = cml::lerp(previous, current, alpha);
 
-       glColor3f(1.0f, 1.0f, 1.0f);
+       //glColor3f(1.0f, 1.0f, 1.0f);
        tilemap_.bind();
 
        Mf::Tilemap::Index frame = animation_.getFrame();
 
+       Mf::Tilemap::Orientation orientation = Mf::Tilemap::NORMAL;
+
+       if (current.velocity[0] < 0.0) orientation = Mf::Tilemap::REVERSE;
+
        Mf::Scalar coords[8];
-       tilemap_.getTileCoords(frame, coords);
+       tilemap_.getTileCoords(frame, coords, orientation);
 
        Mf::Scalar s = 16.0;
 
@@ -165,7 +113,7 @@ void Character::draw(Mf::Scalar alpha) const
                glVertex3(state.position[0]-s, state.position[1]+s, z);
        glEnd();
 
-       glColor3f(0.0f, 0.0f, 0.0f);
+       //glColor3f(0.0f, 0.0f, 0.0f);
        Mf::Texture::resetBind();
 
        glBegin(GL_TRIANGLES);
@@ -174,7 +122,7 @@ void Character::draw(Mf::Scalar alpha) const
                glVertex3(500.0, 210.0, 64.0);
        glEnd();
 
-       glColor3f(1.0f, 1.0f, 1.0f);
+       //glColor3f(1.0f, 1.0f, 1.0f);
 }
 
 
index 0a3f9f40d0724a26e2fdbaa1457ec8f1ab7f9932..c19206c416a022e1bcabce36c0a591facc35fc22 100644 (file)
@@ -35,7 +35,6 @@
 #include <Moof/Entity.hh>
 #include <Moof/Event.hh>
 #include <Moof/Math.hh>
-#include <Moof/Octree.hh>
 #include <Moof/RK4.hh>
 #include <Moof/Tilemap.hh>
 
@@ -136,33 +135,27 @@ struct Character : public Mf::Entity
        State                   previous;
        State                   current;
 
-       Mf::OctreeNodeP treeNode;
-
 
 private:
 
        static const Mf::Scalar z = 96.0;
 
-       Mf::Vector2 userForce;
-
        Mf::Tilemap             tilemap_;
        Mf::Animation   animation_;
 
-       void updateContainers();
+       //void updateContainers();
 
-public:
+protected:
 
-       static CharacterP alloc(const std::string& name)
-       {
-               return CharacterP(new Character(name));
-       }
+       Mf::Vector2 userForce;
+
+public:
 
        Character(const std::string& name);
        virtual ~Character() {}
 
-       void update(Mf::Scalar t, Mf::Scalar dt);
-       void handleEvent(const Mf::Event& event);
-       void draw(Mf::Scalar alpha) const;
+       virtual void update(Mf::Scalar t, Mf::Scalar dt);
+       virtual void draw(Mf::Scalar alpha) const;
 
        Mf::Tilemap& getTilemap();
        Mf::Animation& getAnimation();
index dfdadaa5f2c19fbe809193f9eebcc971569adfd6..33710696107bd5f0f8b4c91ef0867384e34c5b6e 100644 (file)
@@ -30,6 +30,7 @@
 #include <Moof/Log.hh>
 #include <Moof/Math.hh>
 #include <Moof/OpenGL.hh>
+#include <Moof/Video.hh>
 
 #include "GameLayer.hh"
 
 
 
 GameLayer::GameLayer() :
-       music("NightFusionIntro"),
+       music("BeatTheCube"),
        punchSound("Thump")
 {
        music.setLooping(true);
        music.enqueue("NightFusionLoop");
        music.stream();
 
-       heroine = Character::alloc("RobotTrooper");
-       heroine->getAnimation().startSequence("Run");
+       heroine = Heroine::alloc();
+       heroine->getAnimation().startSequence("FlyDiagonallyUp");
 
        Mf::Scalar a[6] = {0.0, 1.5, -0.5, 3.0, -2.0, 1.0};
        interp.init(a, 2.0, Mf::Interpolator::OSCILLATE);
 
-       Mf::Scalar b[2] = {1.0, 0.0};
-       fadeIn.init(b, 1.0);
+       scene = Scene::alloc("Classic");
 
-       octree = Mf::loadScene("Classic");
-       heroine->treeNode = octree->insert(heroine);
+       setProjection();
 
-       camera.setProjection(cml::rad(60.0), 1.33333, 32.0, 2500.0);
-       camera.uploadProjectionToGL();
+       hud = Hud::alloc();
 }
 
 
 void GameLayer::pushed(Mf::Engine& engine)
 {
-       hud = Hud::alloc();
-       engine.pushLayer(hud);
+       engine.push(hud);
 }
 
 
 void GameLayer::update(Mf::Scalar t, Mf::Scalar dt)
 {
-       //dt *= 0.7;
-
-       fadeIn.update(dt);
        camera.update(t, dt);
        heroine->update(t, dt);
 
-       // reinsert heroine
-       heroine->treeNode = octree->reinsert(heroine, heroine->treeNode);
-       octree->print(heroine->treeNode);
-       
        //camera.lookAt(heroine->getSphere().point);
        camera.setPosition(Mf::Vector3(-heroine->current.position[0],
                                -heroine->current.position[1], -256));
 
-       Mf::Vector3 heroinePosition;
-       Mf::promoteVector(heroinePosition, heroine->current.position);
-       Mf::Sound::setListenerPosition(heroinePosition);
-
-       interp.update(dt);
+       //Mf::Vector3 heroinePosition = Mf::promote(heroine->current.position);
+       //Mf::Sound::setListenerPosition(heroinePosition);
+       
+       interp.update(t, dt);
        hud->setBar1Progress(interp.getState(dt));
        hud->setBar2Progress(1.0 - interp.getState(dt));
 }
@@ -98,8 +87,7 @@ void GameLayer::update(Mf::Scalar t, Mf::Scalar dt)
 
 void GameLayer::draw(Mf::Scalar alpha) const
 {
-       glMatrixMode(GL_MODELVIEW);
-       glLoadMatrix(camera.getModelviewMatrix().data());
+       camera.uploadToGL();
 
        // DRAW THE SCENE
        Mf::Texture::resetBind();
@@ -107,36 +95,9 @@ void GameLayer::draw(Mf::Scalar alpha) const
        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
-       octree->drawIfVisible(alpha, camera.getFrustum());
-
-       //heroine->draw(alpha);
-       heroine->getAabb().draw();
-
-       // DRAW FADE
-       glEnable(GL_BLEND);
-       glMatrixMode(GL_PROJECTION);
-       glPushMatrix();
-       glLoadIdentity();
-       glMatrixMode(GL_MODELVIEW);
-       glPushMatrix();
-       glLoadIdentity();
-       glColor4f(0.0f, 0.0f, 0.0f, fadeIn.getState(alpha));
-       Mf::Texture::resetBind();
-
-       //glRectf(-1.0f, -1.0f, 1.0f, 1.0f);
-       glBegin(GL_QUADS);
-               glVertex3f(-1.0, -1.0, -0.1);
-               glVertex3f(1.0, -1.0, -0.1);
-               glVertex3f(1.0, 1.0, -0.1);
-               glVertex3f(-1.0, 1.0, -0.1);
-       glEnd();
-
-       glDisable(GL_BLEND);
+       scene->drawIfVisible(alpha, camera.getFrustum());
 
-       glMatrixMode(GL_PROJECTION);
-       glPopMatrix();
-       glMatrixMode(GL_MODELVIEW);
-       glPopMatrix();
+       heroine->draw(alpha);
 }
 
 bool GameLayer::handleEvent(const Mf::Event& event)
@@ -146,7 +107,7 @@ bool GameLayer::handleEvent(const Mf::Event& event)
                case SDL_KEYDOWN:
                        if (event.key.keysym.sym == SDLK_SPACE)
                        {
-                               heroine->getAnimation().startSequence("Punch");
+                               heroine->getAnimation().startSequence("Flattened");
                                Mf::logInfo("thump!");
                                punchSound.play();
                                return true;
@@ -158,7 +119,7 @@ bool GameLayer::handleEvent(const Mf::Event& event)
                        }
                        else if (event.key.keysym.sym == SDLK_y)
                        {
-                               Mf::Engine::getInstance().popLayer();
+                               Mf::Engine::getInstance().pop();
                                return true;
                        }
 
@@ -172,10 +133,7 @@ bool GameLayer::handleEvent(const Mf::Event& event)
                        return true;
 
                case SDL_VIDEORESIZE:
-                       glViewport(0, 0, event.resize.w, event.resize.h);
-                       camera.setProjection(cml::rad(60.0),
-                               double(event.resize.w) / double(event.resize.h), 32.0, 2500.0);
-                       camera.uploadProjectionToGL();
+                       setProjection(Mf::Scalar(event.resize.w), Mf::Scalar(event.resize.h));
                        break;
        }
 
@@ -183,5 +141,17 @@ bool GameLayer::handleEvent(const Mf::Event& event)
 }
 
 
+void GameLayer::setProjection()
+{
+       Mf::Video& video = Mf::Engine::getInstance().getVideo();
+       setProjection(video.getWidth(), video.getHeight());
+}
+
+void GameLayer::setProjection(Mf::Scalar width, Mf::Scalar height)
+{
+       camera.setProjection(cml::rad(60.0), width / height, 32.0, 2500.0);
+}
+
+
 /** vim: set ts=4 sw=4 tw=80: *************************************************/
 
index b2df7ef11f3aa3433612fc17ed0fec8b86400152..c4c5420888b63e5f7b7e7067fd5a9df9172f11da 100644 (file)
 #include <Moof/Interpolator.hh>
 #include <Moof/Layer.hh>
 #include <Moof/Math.hh>
-#include <Moof/Scene.hh>
 #include <Moof/Sound.hh>
 
 #include "Character.hh"
+#include "Heroine.hh"
 #include "Hud.hh"
+#include "Scene.hh"
 
 
 class GameLayer;
@@ -71,16 +72,18 @@ public:
 
 private:
 
+       void setProjection();
+       void setProjection(Mf::Scalar width, Mf::Scalar height);
+
        Mf::Sound music;
 
-       CharacterP heroine;
+       HeroineP        heroine;
+       SceneP          scene;
        Mf::Sound punchSound;
 
        Mf::PolynomialInterpolator<5> interp;
-       Mf::Lerp fadeIn;
 
        Mf::Camera camera;
-       Mf::OctreeP octree;
 
        HudP hud;
 };
diff --git a/src/Heroine.cc b/src/Heroine.cc
new file mode 100644 (file)
index 0000000..314f2c9
--- /dev/null
@@ -0,0 +1,97 @@
+
+/*******************************************************************************
+
+ 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.
+
+*******************************************************************************/
+
+#include <iostream>
+
+#include "Heroine.hh"
+#include "Log.hh"
+
+       
+Heroine::Heroine() :
+       Character("Heroine") {}
+
+
+void Heroine::handleEvent(const Mf::Event& event)
+{
+       // really just for heroine...
+       
+       Mf::Scalar force = 4000.0;
+       
+       Mf::Vector2 left = Mf::Vector2(-force, 0.0);
+       Mf::Vector2 right = Mf::Vector2(force, 0.0);
+       Mf::Vector2 down = Mf::Vector2(0.0, -force);
+       Mf::Vector2 up = Mf::Vector2(0.0, force);
+
+       switch (event.type)
+       {
+               case SDL_KEYDOWN:
+                       if (event.key.keysym.sym == SDLK_a)
+                       {
+                               userForce += left;
+                       }
+                       else if (event.key.keysym.sym == SDLK_d)
+                       {
+                               userForce += right;
+                       }
+                       else if (event.key.keysym.sym == SDLK_s)
+                       {
+                               userForce += down;
+                       }
+                       else if (event.key.keysym.sym == SDLK_w)
+                       {
+                               userForce += up;
+                       }
+                       break;
+
+               case SDL_KEYUP:
+                       if (event.key.keysym.sym == SDLK_a)
+                       {
+                               userForce -= left;
+                       }
+                       else if (event.key.keysym.sym == SDLK_d)
+                       {
+                               userForce -= right;
+                       }
+                       else if (event.key.keysym.sym == SDLK_s)
+                       {
+                               userForce -= down;
+                       }
+                       else if (event.key.keysym.sym == SDLK_w)
+                       {
+                               userForce -= up;
+                       }
+                       break;
+       }
+
+       //Mf::logInfo("current force [%f %f]", current.force[0], current.force[1]);
+       //std::cerr << "current force: " << current.force << std::endl;
+}
+
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
diff --git a/src/Heroine.hh b/src/Heroine.hh
new file mode 100644 (file)
index 0000000..9ee49d1
--- /dev/null
@@ -0,0 +1,70 @@
+
+/*******************************************************************************
+
+ 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.
+
+*******************************************************************************/
+
+#ifndef _HEROINE_HH_
+#define _HEROINE_HH_
+
+#include <boost/shared_ptr.hpp>
+
+#include <Moof/Animation.hh>
+#include <Moof/Entity.hh>
+#include <Moof/Event.hh>
+#include <Moof/Math.hh>
+#include <Moof/Octree.hh>
+#include <Moof/RK4.hh>
+#include <Moof/Tilemap.hh>
+
+#include "Character.hh"
+
+
+struct Heroine;
+typedef boost::shared_ptr<Heroine> HeroineP;
+
+
+/**
+ * Parent class of animate objects with "personalities."  This basically
+ * includes the heroine herself and the bad guys.
+ */
+
+struct Heroine : public Character
+{
+       Heroine();
+
+       static HeroineP alloc()
+       {
+               return HeroineP(new Heroine);
+       }
+
+       void handleEvent(const Mf::Event& event);
+};
+
+
+#endif // _HEROINE_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
index c535da5a5808d854899e270d243ecb8c8a7b1302..b336b28f14a67558698bdc52a55de092259d8998 100644 (file)
@@ -129,10 +129,10 @@ Hud::Hud() :
 
 void Hud::resize(int width, int height)
 {
-       cml::matrix_orthographic_RH( projection_, 
-                       0.0f
-                       Mf::Scalar(width), 0.0f, Mf::Scalar(height),
-                       1.0f, -1.0f, cml::z_clip_neg_one);
+       cml::matrix_orthographic_RH(projection_, 
+                       SCALAR(0.0)
+                       Mf::Scalar(width), SCALAR(0.0), Mf::Scalar(height),
+                       SCALAR(1.0), SCALAR(-1.0), cml::z_clip_neg_one);
 
        // position the two progress bars at the top-left of the screen
        bar1_.resize(Mf::Rectangle(20, height - 51,
index 51881a770d0e03d8f6d2846c96542c4a2e265d34..2266326402f89b475df8c1a57b3f4abd3dba9d37 100644 (file)
@@ -26,7 +26,7 @@
 
 *******************************************************************************/
 
-#include <cstdlib>             // getenv
+#include <cstdlib>             // atexit, getenv
 #include <cstring>
 #include <iostream>
 #include <string>
 #include <Moof/Log.hh>
 #include <Moof/OpenGL.hh>
 #include <Moof/Resource.hh>
+#include <Moof/Transition.hh>
 #include <Moof/Video.hh>
 
 #include "GameLayer.hh"
 #include "MainLayer.hh"
+#include "TitleLayer.hh"
 
 #if HAVE_CONFIG_H
 #include "config.h"
@@ -62,13 +64,28 @@ MainLayer::~MainLayer()
 void MainLayer::pushed(Mf::Engine& e)
 {
        engine = &e;
-       engine->pushLayer(GameLayer::alloc());
+
+       //Mf::Scalar coeff[] = {0.0, 1.0};
+       //Mf::Lerp interp(coeff, 0.25);
+
+       //Mf::LayerP gameLayer = GameLayer::alloc();
+       //Mf::Transition<Mf::Lerp>::Ptr transition =
+               //Mf::Transition<Mf::Lerp>::alloc(gameLayer, Mf::LayerP(), interp);
+       //engine->push(transition);
+       //engine->push(GameLayer::alloc());
+       engine->push(TitleLayer::alloc());
 }
 
 
 void MainLayer::draw(Mf::Scalar alpha) const
 {
-       glClear(GL_DEPTH_BUFFER_BIT);
+       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+
+       glMatrixMode(GL_MODELVIEW);
+       glLoadIdentity();
 }
 
 bool MainLayer::handleEvent(const Mf::Event& event)
@@ -78,7 +95,7 @@ bool MainLayer::handleEvent(const Mf::Event& event)
                case SDL_KEYDOWN:
                        if (event.key.keysym.sym == SDLK_ESCAPE)
                        {
-                               engine->clearLayers();
+                               quit();
                        }
                        else if (event.key.keysym.sym == SDLK_f)
                        {
@@ -92,47 +109,55 @@ bool MainLayer::handleEvent(const Mf::Event& event)
                        }
                        else if (event.key.keysym.sym == SDLK_y)
                        {
-                               engine->pushLayer(GameLayer::alloc());
+                               engine->push(GameLayer::alloc());
                        }
                        break;
 
+               case SDL_VIDEORESIZE:
+                       glViewport(0, 0, event.resize.w, event.resize.h);
+                       break;
+
                case SDL_QUIT:
-                       engine->clearLayers();
+                       quit();
                        break;
        }
 
        return false;
 }
 
+void MainLayer::quit()
+{
+#if NDEBUG
+       // we don't really need to unwind the stack and shut everything down because
+       // the operating system will take care of cleaning up
+       exit(0);
+#else
+       engine->clear();
+#endif
+}
+
 
 void MainLayer::setupGL()
 {
        glEnable(GL_TEXTURE_2D);
-
-       //glEnable(GL_CULL_FACE);
        glEnable(GL_DEPTH_TEST);
 
+       glEnable(GL_LINE_SMOOTH);
+       glEnable(GL_POLYGON_SMOOTH);
        glShadeModel(GL_SMOOTH);
-       //glEnable(GL_POLYGON_SMOOTH);
 
-       //int texSize;
-       //glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
-       //std::cout << "texture size: " << texSize << std::endl;
-       
        //glEnable(GL_BLEND);
        //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glEnable(GL_ALPHA_TEST);
        glAlphaFunc(GL_GREATER, 0.0);
 
-       glClearColor(1.0, 0.0, 0.0, 1.0);
+       glClearColor(0.0, 0.0, 0.0, 1.0);
 
-       //glMatrixMode(GL_PROJECTION);
-       //glLoadIdentity();
-       //gluPerspective(60.0, 1.33333, 1.0, 2500.0);
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
+       gluPerspective(60.0, 1.33333, 1.0, 2500.0);
 
-       //glMatrixMode(GL_MODELVIEW);
-       
-       //glLineWidth(10.0f);
+       glMatrixMode(GL_MODELVIEW);
 }
 
 void MainLayer::contextRecreated(const Mf::Notification* note)
@@ -162,6 +187,11 @@ void printUsage()
                          << "See documentation for more options." << std::endl;
 }
 
+void goodbye()
+{
+       std::cout << std::endl << "Goodbye..." << std::endl << std::endl;
+}
+
 int main(int argc, char* argv[])
 {
        if (argc > 1 &&
@@ -176,6 +206,8 @@ int main(int argc, char* argv[])
                          << "Send patches and bug reports to <"
                          PACKAGE_BUGREPORT << ">." << std::endl << std::endl;
 
+       atexit(goodbye);
+
 
 #if            YOINK_LOGLEVEL >= 4
        Mf::setLogLevel(Mf::LOG_DEBUG);
@@ -227,7 +259,7 @@ int main(int argc, char* argv[])
        try
        {
                Mf::Engine app(argc, argv, PACKAGE_STRING, iconFile, configFiles);
-               app.pushLayer(MainLayer::alloc());
+               app.push(MainLayer::alloc());
 
                app.run();
        }
@@ -238,7 +270,6 @@ int main(int argc, char* argv[])
                throw e;
        }
 
-       std::cout << std::endl << "Goodbye..." << std::endl << std::endl;
        return 0;
 }
 
index db529a12d5061b5b4b5e4ff04957c01514bd9416..44a0f23ddabc73553ec161937d7718cbe20f573b 100644 (file)
@@ -62,6 +62,8 @@ struct MainLayer : public Mf::Layer
        void draw(Mf::Scalar alpha) const;
        bool handleEvent(const Mf::Event& event);
 
+       void quit();
+
 private:
 
        /**
index ff318048071729560a868139f5663ef688b64c44..aeab798dfe4ce2260a775e77037d67749e2378bd 100644 (file)
@@ -41,7 +41,6 @@ libmoof_a_SOURCES = \
                                        Moof/Log.hh \
                                        Moof/Math.hh \
                                        Moof/Mippleton.hh \
-                                       Moof/Octree.cc \
                                        Moof/Octree.hh \
                                        Moof/OpenGL.hh \
                                        Moof/Plane.cc \
@@ -53,8 +52,6 @@ libmoof_a_SOURCES = \
                                        Moof/Resource.cc \
                                        Moof/Resource.hh \
                                        Moof/RK4.hh \
-                                       Moof/Scene.cc \
-                                       Moof/Scene.hh \
                                        Moof/Script.hh \
                                        Moof/Serializable.cc \
                                        Moof/Serializable.hh \
@@ -75,6 +72,7 @@ libmoof_a_SOURCES = \
                                        Moof/Tilemap.hh \
                                        Moof/Timer.cc \
                                        Moof/Timer.hh \
+                                       Moof/Transition.hh \
                                        Moof/Video.cc \
                                        Moof/Video.hh \
                                        Moof/fastevents.c \
@@ -113,12 +111,18 @@ yoink_SOURCES = \
                                Character.hh \
                                GameLayer.cc \
                                GameLayer.hh \
+                               Heroine.cc \
+                               Heroine.hh \
                                Hud.cc \
                                Hud.hh \
                                MainLayer.cc \
                                MainLayer.hh \
+                               Scene.cc \
+                               Scene.hh \
                                TilemapFont.cc \
                                TilemapFont.hh \
+                               TitleLayer.cc \
+                               TitleLayer.hh \
                                Typesetter.cc \
                                Typesetter.hh \
                                $(ENDLIST)
index 06261a1b41ba811b75a7746da669d6e5f6768531..6b6cfa1ac8572a26f6d8a558177813d9a342e434 100644 (file)
@@ -60,12 +60,13 @@ void Camera::setProjection(Scalar fovy, Scalar aspect, Scalar abutting,
 }
 
 
-void Camera::uploadProjectionToGL() const
+void Camera::uploadToGL() const
 {
        glMatrixMode(GL_PROJECTION);
-       glLoadMatrix(projection_.data());
+       glMultMatrix(projection_.data());
 
        glMatrixMode(GL_MODELVIEW);
+       glMultMatrix(modelview_.data());
 }
 
 void Camera::update(Scalar t, Scalar dt)
index b5927f438e0d3e27f376f8e5a559da6e5d9190f5..827c47f3384de021bcef0dfe0f5f1bf9cb90067d 100644 (file)
@@ -46,7 +46,7 @@ public:
        Camera() :
                position_(0.0, 0.0, 0.0)
        {
-               cml::quaternion_rotation_world_y(rotation_, 0.0f);
+               cml::quaternion_rotation_world_y(rotation_, SCALAR(0.0));
                calculateSecondary();
        }
 
@@ -56,7 +56,7 @@ public:
        void setProjection(const Matrix4& projection);
        void setProjection(Scalar fovy, Scalar aspect, Scalar near, Scalar far);
 
-       void uploadProjectionToGL() const;
+       void uploadToGL() const;
 
        void lookAt(const Vector3& point);
 
index 5bfaaf3cd8d715d0927c9a284a5199a6686e98a6..16da8d40620edd59199a02e46ef43302113f8984 100644 (file)
@@ -82,11 +82,13 @@ public:
                if (settings.get("rngseed", randomSeed)) setSeed(randomSeed);
                else setSeed();
 
-               settings.get("timestep", timestep);
+               Scalar timeStep = 80.0;
+               settings.get("timestep", timeStep);
+               timestep = 1.0 / timeStep;
 
-               long maxFps = 40;
+               Scalar maxFps = 40.0;
                settings.get("maxfps", maxFps);
-               drawRate = 1.0 / Scalar(maxFps);
+               drawRate = 1.0 / maxFps;
 
                settings.get("printfps", printFps);
 
@@ -246,55 +248,66 @@ public:
        }
 
 
-       void pushLayer(LayerP layer)
+       void push(LayerP layer)
        {
                ASSERT(layer && "cannot push null layer");
                stack.push_front(layer);
+               logInfo(" push: %d", stack.size());
                layer->pushed(interface);
        }
 
-       void popLayer()
+       LayerP pop()
        {
                bool fixIt = false;
                if (stack.begin() == stackIt) fixIt = true;
 
                LayerP popped = stack.front();
                stack.pop_front();
+               logInfo("  pop: %d", stack.size());
                popped->popped(interface);
 
                if (fixIt) stackIt = --stack.begin();
+
+               return popped;
        }
 
-       void popLayer(Layer* layer)
+       LayerP pop(Layer* layer)
        {
                bool fixIt = false;
 
+               std::list<LayerP> popped;
+
                std::list<LayerP>::iterator it;
                for (it = stack.begin(); it != stack.end(); ++it)
                {
+                       popped.push_back(*it);
+
                        if (it == stackIt) fixIt = true;
 
                        if ((*it).get() == layer)
                        {
                                ++it;
-                               do
+                               stack.erase(stack.begin(), it);
+
+                               for (it = popped.begin(); it != popped.end(); ++it)
                                {
-                                       LayerP popped = stack.front();
-                                       stack.pop_front();
-                                       popped->popped(interface);
+                                       (*it)->popped(interface);
                                }
-                               while (stack.begin() != it);
 
                                if (fixIt) stackIt = --stack.begin();
-                               return;
+
+                               return popped.back();
                        }
                }
+
+               return LayerP();
        }
 
-       void clearLayers()
+       void clear()
        {
                stack.clear();
                stackIt = stack.begin();
+               logInfo("clear: %d", stack.size());
        }
 
 
@@ -327,6 +340,8 @@ Engine& Engine::getInstance()
 {
        ASSERT(instance && "dereferencing null pointer");
        return *instance;
+       //static Engine engine;
+       //return engine;
 }
 
 
@@ -367,28 +382,28 @@ long Engine::getFrameRate() const
 }
 
 
-void Engine::pushLayer(LayerP layer)
+void Engine::push(LayerP layer)
 {
        // pass through
-       impl_->pushLayer(layer);
+       impl_->push(layer);
 }
 
-void Engine::popLayer()
+LayerP Engine::pop()
 {
        // pass through
-       impl_->popLayer();
+       return impl_->pop();
 }
 
-void Engine::popLayer(Layer* layer)
+LayerP Engine::pop(Layer* layer)
 {
        // pass through
-       impl_->popLayer(layer);
+       return impl_->pop(layer);
 }
 
-void Engine::clearLayers()
+void Engine::clear()
 {
        // pass through
-       impl_->clearLayers();
+       impl_->clear();
 }
 
 
index a0c23002080ff5ef65fa1a336cedd1294e101a35..e49f44db853cbf30ca59539a5ab6f04bac64a1be 100644 (file)
@@ -61,10 +61,11 @@ struct Engine
        Video& getVideo() const;
        long getFrameRate() const;
 
-       void pushLayer(LayerP layer);
-       void popLayer();
-       void popLayer(Layer* layer);
-       void clearLayers();
+       void push(LayerP layer);
+       LayerP pop();
+       // pops a specific layer and all layers above it
+       LayerP pop(Layer* layer);
+       void clear();
 
        struct Exception : public Mf::Exception
        {
index 310e0a128cbb52c0371ec742390d3d46144fcaeb..dc600103e54e890bcc2e0e5713f69619d3286a25 100644 (file)
@@ -56,24 +56,10 @@ class Entity : public Cullable, public Drawable
 public:
        virtual ~Entity() {}
 
-       const Aabb& getAabb() const
-       {
-               return aabb_;
-       }
-
-       const Sphere& getSphere() const
-       {
-               return sphere_;
-       }
-
-       void drawIfVisible(Scalar alpha, const Frustum& frustum) const
+       virtual void drawIfVisible(Scalar alpha, const Frustum& frustum) const
        {
                if (isVisible(frustum)) draw(alpha);
        }
-
-protected:
-       Aabb    aabb_;
-       Sphere  sphere_;
 };
 
 
index 7ded928d8c3109d78fa29a3ff3d4386272b94cc9..4de3f6974bd3a7ceeaf93945b9d7ca5323126c07 100644 (file)
@@ -29,6 +29,7 @@
 #ifndef _MOOF_INTERPOLATOR_HH_
 #define _MOOF_INTERPOLATOR_HH_
 
+#include <Moof/Log.hh>
 #include <Moof/Math.hh>
 
 
@@ -47,7 +48,7 @@ class Interpolator
                        {
                                case STOP:
                                        value = 1.0;
-                                       stopped_ = true;
+                                       done_ = true;
                                        break;
                                case REPEAT:
                                        value -= 1.0;
@@ -64,7 +65,7 @@ class Interpolator
                        {
                                case STOP:
                                        value = 0.0;
-                                       stopped_ = true;
+                                       done_ = true;
                                        break;
                                case REPEAT:
                                        value += 1.0;
@@ -96,13 +97,13 @@ public:
        void setMode(Mode mode)
        {
                mode_ = mode;
-               stopped_ = false;
+               done_ = false;
        }
 
 
-       void update(Scalar dt)
+       void update(Scalar t, Scalar dt)
        {
-               if (!stopped_)
+               if (!done_)
                {
                        alpha_ += dt * scale_;
                        clamp(alpha_);
@@ -110,13 +111,19 @@ public:
                }
        }
 
+       bool isDone() const
+       {
+               return done_;
+       }
+
        virtual void calculate(Scalar alpha) = 0;
 
 private:
+
        Scalar  alpha_;
        Mode    mode_;
        Scalar  scale_;
-       bool    stopped_;
+       bool    done_;
 };
 
 template <class T = Scalar>
index eb411e06d3299d90778117bafe81b08061c343ad..6665a195bc0341f0acb629d4e036bea95efd0c19 100644 (file)
@@ -62,36 +62,24 @@ typedef cml::quaternion< Scalar, cml::fixed<>, cml::vector_first,
 typedef cml::constants<Scalar>                                 Constants;
 
 
-inline Vector3& demoteVector(Vector3& left, const Vector4& right)
+inline Vector3 demote(const Vector4& vec)
 {
-       left[0] = right[0];
-       left[1] = right[1];
-       left[2] = right[2];
-       return left;
+       return Vector3(vec[0], vec[1], vec[2]);
 }
 
-inline Vector2& demoteVector(Vector2& left, const Vector3& right)
+inline Vector2 demote(const Vector3& vec)
 {
-       left[0] = right[0];
-       left[1] = right[1];
-       return left;
+       return Vector2(vec[0], vec[1]);
 }
 
-inline Vector4& promoteVector(Vector4& left, const Vector3& right, Scalar extra = 1.0)
+inline Vector4 promote(const Vector3& vec, Scalar extra = 1.0)
 {
-       left[0] = right[0];
-       left[1] = right[1];
-       left[2] = right[2];
-       left[3] = extra;
-       return left;
+       return Vector4(vec[0], vec[1], vec[2], extra);
 }
 
-inline Vector3& promoteVector(Vector3& left, const Vector2& right, Scalar extra = 1.0)
+inline Vector3 promote(const Vector2& vec, Scalar extra = 1.0)
 {
-       left[0] = right[0];
-       left[1] = right[1];
-       left[3] = extra;
-       return left;
+       return Vector3(vec[0], vec[1], extra);
 }
 
 
diff --git a/src/Moof/Octree.cc b/src/Moof/Octree.cc
deleted file mode 100644 (file)
index 062788d..0000000
+++ /dev/null
@@ -1,293 +0,0 @@
-
-/*******************************************************************************
-
- 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.
-
-*******************************************************************************/
-
-#include "Frustum.hh"
-#include "Log.hh"
-#include "Octree.hh"
-       
-
-namespace Mf {
-
-
-void Octree::sort()
-{
-       stlplus::ntree<OctreeNode>::prefix_iterator it;
-
-       for (it = tree_.prefix_begin(); it != tree_.prefix_end(); ++it)
-       {
-               it->sort();
-       }
-}
-
-
-OctreeNodeP Octree::insert(EntityP entity, OctreeNodeP node)
-{
-       ASSERT(node.valid() && "invalid node passed");
-       ASSERT(entity && "null entity passed");
-
-       int octantNum = -1;
-
-       Plane::Halfspace halfspace;
-
-       // TODO this method needs a lot of work
-       Plane xy = node->getAabb().getPlaneXY();
-
-
-       // make sure the entity is fully inside the volume
-       if (!(entity->getAabb().max[0] < node->getAabb().max[0] &&
-                       entity->getAabb().min[0] > node->getAabb().min[0] &&
-                       entity->getAabb().max[1] < node->getAabb().max[1] &&
-                       entity->getAabb().min[1] > node->getAabb().min[1] &&
-                       entity->getAabb().max[2] < node->getAabb().max[2] &&
-                       entity->getAabb().min[2] > node->getAabb().min[2]))
-       {
-               // TODO this check is only needed for the root node, if we're inside the
-               // volume of the root node, we'll be fully inside the child as
-               // determined by trying to insert the parent node
-               goto done;
-       }
-
-       halfspace = xy.intersects(entity->getSphere());
-       if (halfspace == Plane::INTERSECT)
-       {
-               halfspace = xy.intersects(entity->getAabb());
-       }
-
-       if (halfspace == Plane::POSITIVE)
-       {
-               Plane xz = node->getAabb().getPlaneXZ();
-               halfspace = xz.intersects(entity->getSphere());
-               if (halfspace == Plane::INTERSECT)
-               {
-                       halfspace = xz.intersects(entity->getAabb());
-               }
-
-               if (halfspace == Plane::POSITIVE)
-               {
-                       Plane yz = node->getAabb().getPlaneYZ();
-                       halfspace = yz.intersects(entity->getSphere());
-                       if (halfspace == Plane::INTERSECT)
-                       {
-                               halfspace = yz.intersects(entity->getAabb());
-                       }
-
-                       if (halfspace == Plane::POSITIVE)
-                       {
-                               octantNum = 2;
-                       }
-                       else if (halfspace == Plane::NEGATIVE)
-                       {
-                               octantNum = 3;
-                       }
-               }
-               else if (halfspace == Plane::NEGATIVE)
-               {
-                       Plane yz = node->getAabb().getPlaneYZ();
-                       halfspace = yz.intersects(entity->getSphere());
-                       if (halfspace == Plane::INTERSECT)
-                       {
-                               halfspace = yz.intersects(entity->getAabb());
-                       }
-
-                       if (halfspace == Plane::POSITIVE)
-                       {
-                               octantNum = 1;
-                       }
-                       else if (halfspace == Plane::NEGATIVE)
-                       {
-                               octantNum = 0;
-                       }
-               }
-       }
-       else if (halfspace == Plane::NEGATIVE)
-       {
-               Plane xz = node->getAabb().getPlaneXZ();
-               halfspace = xz.intersects(entity->getSphere());
-               if (halfspace == Plane::INTERSECT)
-               {
-                       halfspace = xz.intersects(entity->getAabb());
-               }
-
-               if (halfspace == Plane::POSITIVE)
-               {
-                       Plane yz = node->getAabb().getPlaneYZ();
-                       halfspace = yz.intersects(entity->getSphere());
-                       if (halfspace == Plane::INTERSECT)
-                       {
-                               halfspace = yz.intersects(entity->getAabb());
-                       }
-
-                       if (halfspace == Plane::POSITIVE)
-                       {
-                               octantNum = 6;
-                       }
-                       else if (halfspace == Plane::NEGATIVE)
-                       {
-                               octantNum = 7;
-                       }
-               }
-               else if (halfspace == Plane::NEGATIVE)
-               {
-                       Plane yz = node->getAabb().getPlaneYZ();
-                       halfspace = yz.intersects(entity->getSphere());
-                       if (halfspace == Plane::INTERSECT)
-                       {
-                               halfspace = yz.intersects(entity->getAabb());
-                       }
-
-                       if (halfspace == Plane::POSITIVE)
-                       {
-                               octantNum = 5;
-                       }
-                       else if (halfspace == Plane::NEGATIVE)
-                       {
-                               octantNum = 4;
-                       }
-               }
-       }
-
-done:
-
-       if (octantNum == -1)
-       {
-               node->objects.push_front(entity);
-               return node;
-       }
-       else
-       {
-               if ((int)tree_.children(node) <= octantNum)
-               {
-                       addChild(node, octantNum);
-               }
-
-               OctreeNodeP child = tree_.child(node, octantNum);
-               ASSERT(child.valid() && "expected valid child node");
-
-               return insert(entity, child);
-       }
-}
-
-OctreeNodeP Octree::reinsert(EntityP entity, OctreeNodeP node)
-{
-       ASSERT(entity && "null entity passed");
-       ASSERT(node.valid() && "invalid node passed");
-
-       std::list<EntityP>::iterator it;
-       it = std::find(node->objects.begin(), node->objects.end(), entity);
-
-       if (it != node->objects.end())
-       {
-               node->objects.erase(it);
-       }
-
-       return insert(entity);
-}
-
-
-void Octree::addChild(OctreeNodeP node, int index)
-{
-       ASSERT(node.valid() && "invalid node passed");
-
-       Aabb octant;
-
-       for (int i = tree_.children(node); i <= index; ++i)
-       {
-               node->getAabb().getOctant(octant, i);
-               tree_.append(node, octant);
-       }
-}
-
-
-void Octree::draw(Scalar alpha, OctreeNodeP node)
-{
-       ASSERT(node.valid() && "invalid node passed");
-
-       node->draw(alpha);
-
-       for (unsigned i = 0; i < tree_.children(node); ++i)
-       {
-               OctreeNodeP child = tree_.child(node, i);
-               ASSERT(child.valid() && "expected valid child node");
-
-               draw(alpha, child);
-       }
-}
-
-void Octree::drawIfVisible(Scalar alpha, const Frustum& frustum, OctreeNodeP node)
-{
-       ASSERT(node.valid() && "invalid node passed");
-
-       // try to cull by sphere
-       Frustum::Collision collision =
-               frustum.contains(node->getSphere());
-       if (collision == Frustum::OUTSIDE) return;
-
-       // try to cull by aabb
-       collision = frustum.contains(node->getAabb());
-       if (collision == Frustum::OUTSIDE) return;
-
-
-       if (collision == Frustum::INSIDE)
-       {
-               node->draw(alpha);
-       }
-       else // collision == Frustum::INTERSECT
-       {
-               node->drawIfVisible(alpha, frustum);
-       }
-
-       if (tree_.children(node) > 0)
-       {
-               if (collision == Frustum::INSIDE)
-               {
-                       for (unsigned i = 0; i < tree_.children(node); ++i)
-                       {
-                               OctreeNodeP child = tree_.child(node, i);
-                               ASSERT(child.valid() && "expected valid child node");
-
-                               draw(alpha, child);
-                       }
-               }
-               else // collision == Frustum::INTERSECT
-               {
-                       for (unsigned i = 0; i < tree_.children(node); ++i)
-                       {
-                               OctreeNodeP child = tree_.child(node, i);
-                               ASSERT(child.valid() && "expected valid child node");
-
-                               drawIfVisible(alpha, frustum, child);
-                       }
-               }
-       }
-}
-
-
-} // namespace Mf
-
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
-
index e3e2225f03299636137b21aa3a54aeb38fd25b38..cdac62a29071f4eeaeb51c48c055e84db1a029dc 100644 (file)
@@ -39,6 +39,7 @@
 #include <Moof/Aabb.hh>
 #include <Moof/Drawable.hh>
 #include <Moof/Entity.hh>
+#include <Moof/Frustum.hh>
 #include <Moof/Log.hh>
 #include <Moof/Math.hh>
 #include <Moof/Sphere.hh>
 namespace Mf {
 
 
-class Frustum;
+//class Octree;
+//typedef boost::shared_ptr<Octree> OctreeP;
 
+//class Octree::Node;
+//typedef stlplus::ntree<Octree::Node>::iterator OctreeNodeP;
 
-struct OctreeNode;
-typedef stlplus::ntree<OctreeNode>::iterator OctreeNodeP;
 
-class Octree;
-typedef boost::shared_ptr<Octree> OctreeP;
+struct OctreeInsertable
+{
+       virtual ~OctreeInsertable() {}
+
+       virtual bool isInsideAabb(const Aabb& aabb) const = 0;
+       virtual int getOctant(const Aabb& aabb) const = 0;
+};
 
 
-struct OctreeNode : public Entity
+template <class T>
+class Octree : public Entity
 {
-       std::list<EntityP> objects;
+       typedef boost::shared_ptr<T> InsertableP;
 
-       OctreeNode()
+       struct Node : public Entity
        {
-               aabb_.min = Vector3(-1.0, -1.0, -1.0);
-               aabb_.max = Vector3(1.0, 1.0, 1.0);
-               sphere_.init(Vector3(0.0, 0.0, 0.0), 1.41421);
-       }
+               std::list<InsertableP> objects;
 
-       OctreeNode(const Aabb& aabb)
-       {
-               aabb_ = aabb;
-               sphere_.point = aabb.getCenter();
-               sphere_.radius = (aabb.min - sphere_.point).length();
-       }
+               Aabb aabb;
+               Sphere sphere;
 
-       void draw(Scalar alpha) const
-       {
-               std::list<EntityP>::const_iterator it;
+               Node(const Aabb& box) :
+                       aabb(box)
+               {
+                       sphere.point = aabb.getCenter();
+                       sphere.radius = (aabb.min - sphere.point).length();
+               }
 
-               for (it = objects.begin(); it != objects.end(); ++it)
+               void draw(Scalar alpha) const
                {
-                       (*it)->draw(alpha);
+                       typename std::list<InsertableP>::const_iterator it;
+
+                       for (it = objects.begin(); it != objects.end(); ++it)
+                       {
+                               (*it)->draw(alpha);
+                       }
+
+                       if (!objects.empty())
+                               aabb.draw(); // temporary
                }
 
-               if (!objects.empty())
-                       aabb_.draw(); // temporary
-       }
+               void drawIfVisible(Scalar alpha, const Frustum& frustum) const
+               {
+                       typename std::list<InsertableP>::const_iterator it;
+
+                       for (it = objects.begin(); it != objects.end(); ++it)
+                       {
+                               (*it)->drawIfVisible(alpha, frustum);
+                       }
+
+                       if (!objects.empty())
+                       {
+                               //aabb.draw();
+                               //sphere.draw();
+                       }
+               }
 
-       void drawIfVisible(Scalar alpha, const Frustum& frustum) const
-       {
-               std::list<EntityP>::const_iterator it;
 
-               for (it = objects.begin(); it != objects.end(); ++it)
+               bool isVisible(const Frustum& frustum) const
                {
-                       (*it)->drawIfVisible(alpha, frustum);
+                       if (sphere.isVisible(frustum))
+                       {
+                               return aabb.isVisible(frustum);
+                       }
+
+                       return false;
                }
+       };
 
-               if (!objects.empty())
+
+public:
+
+       typedef boost::shared_ptr<Octree> Ptr;
+       typedef typename stlplus::ntree<Node>::iterator NodeP;
+       
+private:
+
+
+       NodeP insert(InsertableP entity, NodeP node)
+       {
+               ASSERT(node.valid() && "invalid node passed");
+               ASSERT(entity && "null entity passed");
+
+               if (entity->isInsideAabb(node->aabb))
                {
-                       aabb_.draw();
-                       //sphere_.draw();
+                       return insert_recurse(entity, node);
+               }
+               else
+               {
+                       node->objects.push_back(entity);
+                       return node;
                }
        }
 
-
-       bool isVisible(const Frustum& frustum) const
+       NodeP insert_recurse(InsertableP entity, NodeP node)
        {
-               if (sphere_.isVisible(frustum))
+               ASSERT(node.valid() && "invalid node passed");
+               ASSERT(entity && "null entity passed");
+
+               int octantNum = entity->getOctant(node->aabb);
+               if (octantNum == -1)
                {
-                       return aabb_.isVisible(frustum);
+                       node->objects.push_back(entity);
+                       return node;
                }
+               else
+               {
+                       if ((int)tree_.children(node) <= octantNum)
+                       {
+                               addChild(node, octantNum);
+                       }
 
-               return false;
-       }
+                       NodeP child = tree_.child(node, octantNum);
+                       ASSERT(child.valid() && "expected valid child node");
 
+                       return insert(entity, child);
+               }
+       }
 
-       static bool compareZOrder(EntityP a, EntityP b)
+       void addChild(NodeP node, int index)
        {
-               return a->getSphere().point[2] < b->getSphere().point[2];
+               ASSERT(node.valid() && "invalid node passed");
+
+               Aabb octant;
+
+               for (int i = tree_.children(node); i <= index; ++i)
+               {
+                       node->aabb.getOctant(octant, i);
+                       tree_.append(node, octant);
+               }
        }
 
-       void sort()
+
+       void draw(Scalar alpha, NodeP node) const
        {
-               //std::sort(objects.begin(), objects.end(), compareZOrder);
-               objects.sort(compareZOrder);
+               ASSERT(node.valid() && "invalid node passed");
+
+               node->draw(alpha);
+
+               for (unsigned i = 0; i < tree_.children(node); ++i)
+               {
+                       NodeP child = tree_.child(node, i);
+                       ASSERT(child.valid() && "expected valid child node");
+
+                       draw(alpha, child);
+               }
        }
-};
 
+       void drawIfVisible(Scalar alpha, const Frustum& frustum, NodeP node) const
+       {
+               ASSERT(node.valid() && "invalid node passed");
 
-class Octree
-{
-       OctreeNodeP insert(EntityP entity, OctreeNodeP node);
-       
-       void addChild(OctreeNodeP node, int index);
+               // try to cull by sphere
+               Frustum::Collision collision = frustum.contains(node->sphere);
+               if (collision == Frustum::OUTSIDE) return;
+
+               // try to cull by aabb
+               collision = frustum.contains(node->aabb);
+               if (collision == Frustum::OUTSIDE) return;
+
+
+               if (collision == Frustum::INSIDE)
+               {
+                       node->draw(alpha);
+               }
+               else // collision == Frustum::INTERSECT
+               {
+                       node->drawIfVisible(alpha, frustum);
+               }
 
-       void draw(Scalar alpha, OctreeNodeP node);
-       void drawIfVisible(Scalar alpha, const Frustum& frustum, OctreeNodeP node);
+               if (tree_.children(node) > 0)
+               {
+                       if (collision == Frustum::INSIDE)
+                       {
+                               for (unsigned i = 0; i < tree_.children(node); ++i)
+                               {
+                                       NodeP child = tree_.child(node, i);
+                                       ASSERT(child.valid() && "expected valid child node");
+
+                                       draw(alpha, child);
+                               }
+                       }
+                       else // collision == Frustum::INTERSECT
+                       {
+                               for (unsigned i = 0; i < tree_.children(node); ++i)
+                               {
+                                       NodeP child = tree_.child(node, i);
+                                       ASSERT(child.valid() && "expected valid child node");
+
+                                       drawIfVisible(alpha, frustum, child);
+                               }
+                       }
+               }
+       }
+
+       mutable stlplus::ntree<Node> tree_;
 
-       stlplus::ntree<OctreeNode> tree_;
 
 public:
 
-       void print(OctreeNodeP node)
+       void print(NodeP node)
        {
                //logDebug("-----");
                //logDebug("depth to node: %d", tree_.depth(node));
                //logDebug("size of node: %d", tree_.size(node));
        }
 
-       static OctreeP alloc(const OctreeNode& rootNode)
+       static Ptr alloc(const Node& rootNode)
        {
-               return OctreeP(new Octree(rootNode));
+               return Ptr(new Octree(rootNode));
        }
 
-       explicit Octree(const OctreeNode& rootNode)
+       explicit Octree(const Node& rootNode)
        {
                tree_.insert(rootNode);
        }
 
-       OctreeNodeP insert(EntityP entity)
+       NodeP insert(InsertableP entity)
        {
                return insert(entity, tree_.root());
        }
 
-       OctreeNodeP reinsert(EntityP entity, OctreeNodeP node);
+       NodeP reinsert(InsertableP entity, NodeP node)
+       {
+               ASSERT(entity && "null entity passed");
+               ASSERT(node.valid() && "invalid node passed");
+
+               typename std::list<InsertableP>::iterator it;
+               it = std::find(node->objects.begin(), node->objects.end(), entity);
 
-       void draw(Scalar alpha)
+               if (it != node->objects.end())
+               {
+                       node->objects.erase(it);
+               }
+
+               return insert(entity);
+       }
+
+       void draw(Scalar alpha) const
        {
                draw(alpha, tree_.root());
        }
 
-       void drawIfVisible(Scalar alpha, const Frustum& frustum)
+       void drawIfVisible(Scalar alpha, const Frustum& frustum) const
        {
                drawIfVisible(alpha, frustum, tree_.root());
        }
-
-       void sort();
 };
 
 
index a5ae3a043f75100208d026fa386ab47d2fdd9878..c16d701d9afc391aa17da399e14cbf16efa70592 100644 (file)
 
 #include <SDL/SDL_opengl.h>
 
-
-/* Define to 1 if you want to use double precision floating-point numbers. */
-//#define USE_DOUBLE_PRECISION 1 
+#if HAVE_CONFIG_H
+#include "config.h"
+#endif
 
 
 #if USE_DOUBLE_PRECISION
 
 typedef GLdouble       GLscalar;
 #define GL_SCALAR      GL_DOUBLE
-
-inline void glGetScalarv(GLenum a, GLscalar* b) { glGetDoublev(a, b); }
-
-inline void glLoadMatrix(const GLscalar* a) { glLoadMatrixd(a); }
-inline void glMultMatrix(const GLscalar* a) { glMultMatrixd(a); }
-
-inline void glScale(GLscalar a, GLscalar b, GLscalar c) { glScaled(a, b, c); }
-inline void glRotate(GLscalar a, GLscalar b, GLscalar c, GLscalar d) { glRotated(a, b, c, d); }
-inline void glTranslate(GLscalar a, GLscalar b, GLscalar c) { glTranslated(a, b, c); }
-
-inline void glColor3(GLscalar a, GLscalar b, GLscalar c) { glColor3d(a, b, c); }
-inline void glColor4(GLscalar a, GLscalar b, GLscalar c, GLscalar d) { glColor4d(a, b, c, d); }
-inline void glColor3v(const GLscalar *a) { glColor3dv(a); }
-inline void glColor4v(const GLscalar *a) { glColor4dv(a); }
-
-inline void glVertex2(GLscalar a, GLscalar b) { glVertex2d(a, b); }
-inline void glVertex3(GLscalar a, GLscalar b, GLscalar c) { glVertex3d(a, b, c); }
-inline void glVertex4(GLscalar a, GLscalar b, GLscalar c, GLscalar d) { glVertex4d(a, b, c, d); }
-inline void glVertex2v(const GLscalar* a) { glVertex2dv(a); }
-inline void glVertex3v(const GLscalar* a) { glVertex3dv(a); }
-inline void glVertex4v(const GLscalar* a) { glVertex4dv(a); }
-
-inline void glTexCoord2(GLscalar a, GLscalar b) { glTexCoord2d(a, b); } 
-inline void glTexCoord3(GLscalar a, GLscalar b, GLscalar c) { glTexCoord3d(a, b, c); }
-inline void glTexCoord4(GLscalar a, GLscalar b, GLscalar c, GLscalar d) { glTexCoord4d(a, b, c, d); }
-inline void glTexCoord2v(const GLscalar* a) { glTexCoord2dv(a); }
-inline void glTexCoord3v(const GLscalar* a) { glTexCoord3dv(a); }
-inline void glTexCoord4v(const GLscalar* a) { glTexCoord4dv(a); }
+#define SCALAR(D)      D
+
+inline void glGetScalarv(GLenum a, GLscalar* b)
+{ glGetDoublev(a, b); }
+
+inline void glLoadMatrix(const GLscalar* a)
+{ glLoadMatrixd(a); }
+inline void glMultMatrix(const GLscalar* a)
+{ glMultMatrixd(a); }
+
+inline void glScale(GLscalar a, GLscalar b, GLscalar c)
+{ glScaled(a, b, c); }
+inline void glRotate(GLscalar a, GLscalar b, GLscalar c, GLscalar d)
+{ glRotated(a, b, c, d); }
+inline void glTranslate(GLscalar a, GLscalar b, GLscalar c)
+{ glTranslated(a, b, c); }
+
+inline void glColor3(GLscalar a, GLscalar b, GLscalar c)
+{ glColor3d(a, b, c); }
+inline void glColor4(GLscalar a, GLscalar b, GLscalar c, GLscalar d)
+{ glColor4d(a, b, c, d); }
+inline void glColor3v(const GLscalar *a)
+{ glColor3dv(a); }
+inline void glColor4v(const GLscalar *a)
+{ glColor4dv(a); }
+
+inline void glVertex2(GLscalar a, GLscalar b)
+{ glVertex2d(a, b); }
+inline void glVertex3(GLscalar a, GLscalar b, GLscalar c)
+{ glVertex3d(a, b, c); }
+inline void glVertex4(GLscalar a, GLscalar b, GLscalar c, GLscalar d)
+{ glVertex4d(a, b, c, d); }
+inline void glVertex2v(const GLscalar* a)
+{ glVertex2dv(a); }
+inline void glVertex3v(const GLscalar* a)
+{ glVertex3dv(a); }
+inline void glVertex4v(const GLscalar* a)
+{ glVertex4dv(a); }
+
+inline void glTexCoord2(GLscalar a, GLscalar b)
+{ glTexCoord2d(a, b); } 
+inline void glTexCoord3(GLscalar a, GLscalar b, GLscalar c)
+{ glTexCoord3d(a, b, c); }
+inline void glTexCoord4(GLscalar a, GLscalar b, GLscalar c, GLscalar d)
+{ glTexCoord4d(a, b, c, d); }
+inline void glTexCoord2v(const GLscalar* a)
+{ glTexCoord2dv(a); }
+inline void glTexCoord3v(const GLscalar* a)
+{ glTexCoord3dv(a); }
+inline void glTexCoord4v(const GLscalar* a)
+{ glTexCoord4dv(a); }
 
 #else
 
 typedef GLfloat                GLscalar;
 #define GL_SCALAR      GL_FLOAT
-
-inline void glGetScalarv(GLenum a, GLscalar* b) { glGetFloatv(a, b); }
-
-inline void glLoadMatrix(const GLscalar* a) { glLoadMatrixf(a); }
-inline void glMultMatrix(const GLscalar* a) { glMultMatrixf(a); }
-
-inline void glScale(GLscalar a, GLscalar b, GLscalar c) { glScalef(a, b, c); }
-inline void glRotate(GLscalar a, GLscalar b, GLscalar c, GLscalar d) { glRotatef(a, b, c, d); }
-inline void glTranslate(GLscalar a, GLscalar b, GLscalar c) { glTranslatef(a, b, c); }
-
-inline void glColor3(GLscalar a, GLscalar b, GLscalar c) { glColor3f(a, b, c); }
-inline void glColor4(GLscalar a, GLscalar b, GLscalar c, GLscalar d) { glColor4f(a, b, c, d); }
-inline void glColor3v(const GLscalar *a) { glColor3fv(a); }
-inline void glColor4v(const GLscalar *a) { glColor4fv(a); }
-
-inline void glVertex2(GLscalar a, GLscalar b) { glVertex2f(a, b); }
-inline void glVertex3(GLscalar a, GLscalar b, GLscalar c) { glVertex3f(a, b, c); }
-inline void glVertex4(GLscalar a, GLscalar b, GLscalar c, GLscalar d) { glVertex4f(a, b, c, d); }
-inline void glVertex2v(const GLscalar* a) { glVertex2fv(a); }
-inline void glVertex3v(const GLscalar* a) { glVertex3fv(a); }
-inline void glVertex4v(const GLscalar* a) { glVertex4fv(a); }
-
-inline void glTexCoord2(GLscalar a, GLscalar b) { glTexCoord2f(a, b); } 
-inline void glTexCoord3(GLscalar a, GLscalar b, GLscalar c) { glTexCoord3f(a, b, c); }
-inline void glTexCoord4(GLscalar a, GLscalar b, GLscalar c, GLscalar d) { glTexCoord4f(a, b, c, d); }
-inline void glTexCoord2v(const GLscalar* a) { glTexCoord2fv(a); }
-inline void glTexCoord3v(const GLscalar* a) { glTexCoord3fv(a); }
-inline void glTexCoord4v(const GLscalar* a) { glTexCoord4fv(a); }
+#define SCALAR(F)      F##f
+
+inline void glGetScalarv(GLenum a, GLscalar* b)
+{ glGetFloatv(a, b); }
+
+inline void glLoadMatrix(const GLscalar* a)
+{ glLoadMatrixf(a); }
+inline void glMultMatrix(const GLscalar* a)
+{ glMultMatrixf(a); }
+
+inline void glScale(GLscalar a, GLscalar b, GLscalar c)
+{ glScalef(a, b, c); }
+inline void glRotate(GLscalar a, GLscalar b, GLscalar c, GLscalar d)
+{ glRotatef(a, b, c, d); }
+inline void glTranslate(GLscalar a, GLscalar b, GLscalar c)
+{ glTranslatef(a, b, c); }
+
+inline void glColor3(GLscalar a, GLscalar b, GLscalar c)
+{ glColor3f(a, b, c); }
+inline void glColor4(GLscalar a, GLscalar b, GLscalar c, GLscalar d)
+{ glColor4f(a, b, c, d); }
+inline void glColor3v(const GLscalar *a)
+{ glColor3fv(a); }
+inline void glColor4v(const GLscalar *a)
+{ glColor4fv(a); }
+
+inline void glVertex2(GLscalar a, GLscalar b)
+{ glVertex2f(a, b); }
+inline void glVertex3(GLscalar a, GLscalar b, GLscalar c)
+{ glVertex3f(a, b, c); }
+inline void glVertex4(GLscalar a, GLscalar b, GLscalar c, GLscalar d)
+{ glVertex4f(a, b, c, d); }
+inline void glVertex2v(const GLscalar* a)
+{ glVertex2fv(a); }
+inline void glVertex3v(const GLscalar* a)
+{ glVertex3fv(a); }
+inline void glVertex4v(const GLscalar* a)
+{ glVertex4fv(a); }
+
+inline void glTexCoord2(GLscalar a, GLscalar b)
+{ glTexCoord2f(a, b); } 
+inline void glTexCoord3(GLscalar a, GLscalar b, GLscalar c)
+{ glTexCoord3f(a, b, c); }
+inline void glTexCoord4(GLscalar a, GLscalar b, GLscalar c, GLscalar d)
+{ glTexCoord4f(a, b, c, d); }
+inline void glTexCoord2v(const GLscalar* a)
+{ glTexCoord2fv(a); }
+inline void glTexCoord3v(const GLscalar* a)
+{ glTexCoord3fv(a); }
+inline void glTexCoord4v(const GLscalar* a)
+{ glTexCoord4fv(a); }
 
 #endif
 
diff --git a/src/Moof/Scene.cc b/src/Moof/Scene.cc
deleted file mode 100644 (file)
index b331312..0000000
+++ /dev/null
@@ -1,414 +0,0 @@
-
-/*******************************************************************************
-
- 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.
-
-*******************************************************************************/
-
-#include <map>
-#include <vector>
-
-#include "Aabb.hh"
-#include "Camera.hh"
-#include "Entity.hh"
-#include "Log.hh"
-#include "Math.hh"
-#include "Scene.hh"
-#include "Script.hh"
-#include "Settings.hh"
-#include "Tilemap.hh"
-
-
-namespace Mf {
-
-
-static std::string getPath(const std::string& name)
-{
-       return Resource::getPath("scenes/" + name + ".lua");
-}
-
-
-struct Meh
-{
-       Matrix4         transform;
-       std::string     texture;
-
-       OctreeP         octree;
-
-       enum AXIS
-       {
-               X = 0,
-               Y = 1,
-               Z = 2
-       };
-
-       Meh()
-       {
-               octree = Octree::alloc(Aabb());
-       }
-
-       static int loadBox(Script& script, Aabb& aabb)
-       {
-               Script::Value table[] = {script[1], script[2]};
-
-               if (!table[0].isTable() || !table[1].isTable())
-               {
-                       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[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]);
-
-               return 0;
-       }
-
-       int setPlayfieldBounds(Script& script)
-       {
-               Aabb bounds;
-               return loadBox(script, bounds);
-       }
-
-       int setMaximumBounds(Script& script)
-       {
-               Aabb bounds;
-               int ret = loadBox(script, bounds);
-               octree = Octree::alloc(bounds);
-               return ret;
-       }
-
-       int resetTransform(Script& script)
-       {
-               transform.identity();
-               return 0;
-       }
-
-       int translate(Script& script)
-       {
-               Script::Value x = script[1].requireNumber();
-               Script::Value y = script[2].requireNumber();
-               Script::Value z = script[3].requireNumber();
-
-               Vector3 vec;
-               x.get(vec[0]);
-               y.get(vec[1]);
-               z.get(vec[2]);
-
-               Matrix4 translation;
-               cml::matrix_translation(translation, vec);
-               transform = translation * transform;
-
-               return 0;
-       }
-
-       int scale(Script& script)
-       {
-               if (script.getSize() == 3)
-               {
-                       Vector3 vec;
-                       script[1].requireNumber().get(vec[0]);
-                       script[2].requireNumber().get(vec[1]);
-                       script[3].requireNumber().get(vec[2]);
-
-                       Matrix4 scaling;
-                       cml::matrix_scale(scaling, vec);
-                       transform = scaling * transform;
-               }
-               else if (script.getSize() == 1)
-               {
-                       Scalar value = 1.0;
-                       script[1].requireNumber().get(value);
-
-                       Matrix4 scaling;
-                       cml::matrix_uniform_scale(scaling, value);
-                       transform = scaling * transform;
-               }
-               else
-               {
-                       script.getTop().throwError("wrong number of arguments");
-               }
-
-               return 0;
-       }
-
-       int rotate(Script& script)
-       {
-               Script::Value axis = script[1].requireString();
-               Script::Value angle = script[2].requireNumber();
-
-               size_t index = 0;
-               axis.get(index);
-
-               Scalar value;
-               angle.get(value);
-
-               cml::matrix_rotate_about_world_axis(transform, index, cml::rad(value));
-
-               return 0;
-       }
-
-       int setTexture(Script& script)
-       {
-               Script::Value name = script[1].requireString();
-
-               name.get(texture);
-
-               return 0;
-       }
-
-       int makeTilemap(Script& script)
-       {
-               Script::Value table = script[1].requireTable();
-               Script::Value top = script[-1];
-
-               long width = 1;
-               long height = 1;
-
-               table.pushField("width");
-               top.get(width);
-
-               long nTiles = 0;
-
-               table.pushField("tiles");
-               Script::Value tiles = script.getTop();
-               nTiles = tiles.getLength();
-
-               if (nTiles % width != 0) table.throwError("invalid number of tiles");
-
-               std::vector< std::vector<Tilemap::Index> > indices;
-
-               int i, w, h;
-
-               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
-
-               i = 1;
-               for (h = height - 1; h >= 0; --h)
-               {
-                       std::vector<Tilemap::Index> row;
-
-                       for (w = 0; w < width; ++w, ++i)
-                       {
-                               script.checkStack(2);
-                               script.push(long(i));
-                               tiles.pushField();
-
-                               long index;
-                               top.get(index);
-
-                               row.push_back(Tilemap::Index(index));
-                       }
-
-                       indices[h] = row;
-               }
-
-               Vector4 vertices[height+1][width+1];
-
-               Matrix4 transposedTransform = transform;
-               transposedTransform.transpose();
-
-               for (int h = 0; h <= height; ++h)
-               {
-                       for (int w = 0; w <= width; ++w)
-                       {
-                               vertices[h][w] = Vector4(Scalar(w), Scalar(h), 0.0, 1.0) *
-                                       transposedTransform;
-                       }
-               }
-
-               for (int h = 0; h < height; ++h)
-               {
-                       for (int w = 0; w < width; ++w)
-                       {
-                               if (indices[h][w] == Tilemap::NO_TILE) continue;
-
-                               Vector3 quadVertices[4];
-
-                               demoteVector(quadVertices[0], vertices[h][w]);
-                               demoteVector(quadVertices[1], vertices[h][w+1]);
-                               demoteVector(quadVertices[2], vertices[h+1][w+1]);
-                               demoteVector(quadVertices[3], vertices[h+1][w]);
-
-                               Quad* quad = new Quad(quadVertices, texture, indices[h][w]);
-                               boost::shared_ptr<Quad> quadPtr(quad);
-
-                               octree->insert(quadPtr);
-                       }
-               }
-
-               return 0;
-       }
-
-       int makeBillboard(Script& script)
-       {
-               Script::Value table = script[1];
-               Script::Value top = script[-1];
-
-               long    index = 0;
-               long    width = 1;
-               bool    blending = false;
-               bool    fog = false;
-
-               if (table.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);
-               }
-
-               Vector4 vertices[2][width+1];
-
-               Matrix4 transposedTransform = transform;
-               transposedTransform.transpose();
-
-               Scalar xf;
-               Scalar increment = 1.0 / Scalar(width);
-
-               for (int h = 0; h <= 1; ++h)
-               {
-                       xf = 0.0;
-                       for (int w = 0; w <= width; ++w, xf += increment)
-                       {
-                               vertices[h][w] = Vector4(xf, Scalar(h), 0.0, 1.0) *
-                                       transposedTransform;
-                       }
-               }
-
-               for (int w = 0; w < width; ++w)
-               {
-                       Vector3 quadVertices[4];
-
-                       demoteVector(quadVertices[0], vertices[0][w]);
-                       demoteVector(quadVertices[1], vertices[0][w+1]);
-                       demoteVector(quadVertices[2], vertices[1][w+1]);
-                       demoteVector(quadVertices[3], vertices[1][w]);
-
-                       Quad* quad = new Quad(quadVertices, texture, Tilemap::Index(index));
-                       quad->setBlending(blending);
-                       quad->setFog(fog);
-
-                       boost::shared_ptr<Quad> quadPtr(quad);
-
-                       octree->insert(quadPtr);
-               }
-
-               return 0;
-       }
-};
-
-
-static void importSceneBindings(Script& script, Meh& scene)
-{
-       script.importFunction("SetPlayfieldBounds",
-                       boost::bind(&Meh::setPlayfieldBounds, &scene, _1));
-       script.importFunction("SetMaximumBounds",
-                       boost::bind(&Meh::setMaximumBounds, &scene, _1));
-       script.importFunction("ResetTransform",
-                       boost::bind(&Meh::resetTransform, &scene, _1));
-       script.importFunction("Translate",
-                       boost::bind(&Meh::translate, &scene, _1));
-       script.importFunction("Scale",
-                       boost::bind(&Meh::scale, &scene, _1));
-       script.importFunction("Rotate",
-                       boost::bind(&Meh::rotate, &scene, _1));
-       script.importFunction("SetTexture",
-                       boost::bind(&Meh::setTexture, &scene, _1));
-       script.importFunction("MakeTilemap",
-                       boost::bind(&Meh::makeTilemap, &scene, _1));
-       script.importFunction("MakeBillboard",
-                       boost::bind(&Meh::makeBillboard, &scene, _1));
-
-       long detail = 3;
-       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(Meh::X);
-       script.set("X");
-       script.push(Meh::Y);
-       script.set("Y");
-       script.push(Meh::Z);
-       script.set("Z");
-}
-
-
-OctreeP loadScene(const std::string& name)
-{
-       std::string filePath = getPath(name);
-
-       Meh cool;
-
-       Script script;
-       script.importStandardLibraries();
-       importLogScript(script);
-       importSceneBindings(script, cool);
-
-       if (script.doFile(filePath) != Script::SUCCESS)
-       {
-               std::string str;
-               script[-1].get(str);
-               logScript("%s", str.c_str());
-       }
-
-       cool.octree->sort();
-       return cool.octree;
-}
-
-
-} // namespace Mf
-
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
-
diff --git a/src/Moof/Scene.hh b/src/Moof/Scene.hh
deleted file mode 100644 (file)
index ce57bcd..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-
-/*******************************************************************************
-
- 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.
-
-*******************************************************************************/
-
-#ifndef _MOOF_SCENE_HH_
-#define _MOOF_SCENE_HH_
-
-#include <string>
-
-#include <boost/shared_ptr.hpp>
-
-#include <Moof/Drawable.hh>
-#include <Moof/Entity.hh>
-#include <Moof/Octree.hh>
-#include <Moof/Resource.hh>
-#include <Moof/Tilemap.hh>
-
-
-namespace Mf {
-
-
-OctreeP loadScene(const std::string& name);
-
-
-class Quad : public Entity
-{
-       Scalar          vertices_[12];
-       Scalar          texCoords_[8];
-       
-       Tilemap         tilemap_;
-
-       bool            blending_;
-       bool            fog_;
-
-public:
-
-       enum SURFACE_TYPE
-       {
-               LEFT    = 1,
-               RIGHT   = 2,
-               TOP             = 3
-       };
-
-       Quad(const Vector3 vertices[4], const std::string& texture,
-                       Tilemap::Index tileIndex) :
-               tilemap_(texture),
-               blending_(false),
-               fog_(false)
-       {
-               for (int i = 0, num = 0; i < 4; ++i)
-               {
-                       for (int j = 0; j < 3; ++j, ++num)
-                       {
-                               vertices_[num] = vertices[i][j];
-                       }
-               }
-
-               if (!tilemap_.getTileCoords(tileIndex, texCoords_))
-               {
-                       logWarning("no index %d in texture %s", tileIndex,
-                                       texture.c_str());
-
-                       texCoords_[0] = texCoords_[1] =
-                               texCoords_[3] = texCoords_[6] = 0.0;
-                       texCoords_[2] = texCoords_[4] =
-                               texCoords_[5] = texCoords_[7] = 1.0;
-               }
-
-               aabb_.encloseVertices(vertices, 4);
-               sphere_.point = aabb_.getCenter();
-               sphere_.radius = (aabb_.min - sphere_.point).length();
-       }
-
-       void setBlending(bool blending)
-       {
-               blending_ = blending;
-       }
-
-       void setFog(bool fog)
-       {
-               fog_ = fog;
-       }
-
-       void draw(Scalar alpha = 0.0) const
-       {
-               if (blending_)
-               {
-                       glEnable(GL_BLEND);
-                       glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
-               }
-
-               if (fog_)
-               {
-                       glEnable(GL_FOG);
-                       glFogi(GL_FOG_MODE, GL_LINEAR);
-               }
-
-               glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
-               tilemap_.bind();
-
-               glVertexPointer(3, GL_SCALAR, 0, vertices_);
-               glTexCoordPointer(2, GL_SCALAR, 0, texCoords_);
-
-               glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
-
-               glDisable(GL_BLEND);
-               glDisable(GL_FOG);
-       }
-
-       bool isVisible(const Frustum& frustum) const
-       {
-               return sphere_.isVisible(frustum);
-       }
-};
-
-
-} // namespace Mf
-
-#endif // _MOOF_SCENE_HH_
-
-/** vim: set ts=4 sw=4 tw=80: *************************************************/
-
diff --git a/src/Moof/Transition.hh b/src/Moof/Transition.hh
new file mode 100644 (file)
index 0000000..cf1595c
--- /dev/null
@@ -0,0 +1,177 @@
+
+/*******************************************************************************
+
+ 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.
+
+*******************************************************************************/
+
+#ifndef _MOOF_TRANSITION_HH_
+#define _MOOF_TRANSITION_HH_
+
+#include <boost/shared_ptr.hpp>
+
+#include <Moof/Engine.hh>
+#include <Moof/Interpolator.hh>
+#include <Moof/Layer.hh>
+#include <Moof/Log.hh>
+#include <Moof/Math.hh>
+#include <Moof/OpenGL.hh>
+#include <Moof/Texture.hh>
+
+
+namespace Mf {
+
+
+template <typename T>
+class Transition : public Layer
+{
+       LayerP  to;
+       LayerP  from;
+
+       T               interpolator;
+
+       Engine* engine;
+
+public:
+
+       Transition(LayerP t, LayerP f, const T& interp) :
+               to(t),
+               from(f),
+               interpolator(interp),
+               engine(0) {}
+
+       typedef boost::shared_ptr<Transition> Ptr;
+
+       static Ptr alloc(LayerP t, LayerP f, const T& interp)
+       {
+               return Ptr(new Transition(t, f, interp));
+       }
+
+
+       void pushed(Engine& e)
+       {
+               engine = &e;
+       }
+
+       void popped(Engine& e)
+       {
+               if (to) e.push(to);
+       }
+
+       void update(Scalar t, Scalar dt)
+       {
+               interpolator.update(t, dt);
+
+               if (from) from->update(t, dt);
+               if (to) to->update(t, dt);
+
+               if (interpolator.isDone())
+               {
+                       // to should /replace/ this
+                       engine->pop(this);
+               }
+       }
+
+       void drawFade(Scalar alpha) const
+       {
+               // DRAW FADE
+               glDisable(GL_DEPTH_TEST);
+               glDisable(GL_ALPHA_TEST);
+               glEnable(GL_BLEND);
+               glMatrixMode(GL_PROJECTION);
+               glPushMatrix();
+               glLoadIdentity();
+               glMatrixMode(GL_MODELVIEW);
+               glPushMatrix();
+               glLoadIdentity();
+               glColor4(1.0, 1.0, 1.0, alpha);
+               Mf::Texture::resetBind();
+
+               //glRectf(-1.0f, -1.0f, 1.0f, 1.0f);
+               glBegin(GL_QUADS);
+                       glVertex3f(-1.0, -1.0, -0.1);
+                       glVertex3f(1.0, -1.0, -0.1);
+                       glVertex3f(1.0, 1.0, -0.1);
+                       glVertex3f(-1.0, 1.0, -0.1);
+               glEnd();
+
+               glDisable(GL_BLEND);
+               glEnable(GL_DEPTH_TEST);
+               glEnable(GL_ALPHA_TEST);
+
+               glMatrixMode(GL_PROJECTION);
+               glPopMatrix();
+               glMatrixMode(GL_MODELVIEW);
+               glPopMatrix();
+       }
+
+       void draw(Scalar alpha) const
+       {
+               Scalar a = interpolator.getState(alpha);
+               logInfo("draw state: %f", a);
+
+               //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+
+               if (from)
+               {
+                       glPushMatrix();
+                       glLoadIdentity();
+                       glRotate(180.0 * a, 0.0, 1.0, 0.0);
+                       from->draw(alpha);
+                       glPopMatrix();
+               }
+                       //drawFade(a);
+
+               if (to)
+               {
+                       glPushMatrix();
+                       glLoadIdentity();
+                       glRotate(180.0 * (1.0 - a), 0.0, 1.0, 0.0);
+                       to->draw(alpha);
+                       glPopMatrix();
+               }
+                       //drawFade(1.0 - a);
+       }
+
+       bool handleEvent(const Event& event)
+       {
+               if (to)
+               {
+                       return to->handleEvent(event);
+               }
+               else if (from)
+               {
+                       return from->handleEvent(event);
+               }
+               return false;
+       }
+};
+
+
+} // namespace Mf
+
+#endif // _MOOF_TRANSITION_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
index ef966c7996e91fc2f33ca6aa6a5604d31ca2504d..8de161aa085daca5f087500869eb4067f329b34d 100644 (file)
@@ -288,6 +288,17 @@ void Video::swap()
 }
 
 
+int Video::getWidth() const
+{
+       return context_->w;
+}
+
+int Video::getHeight() const
+{
+       return context_->h;
+}
+
+
 Video::Attributes::Attributes()
 {
        // Set some sane GL and window defaults (see SDL_video.c:217)
index d640ad2386ce7a4fefa4bdda725fb35485302297..5f56f9e1d33e103ac0bf912b7f6584d0e45b516d 100644 (file)
@@ -128,6 +128,9 @@ public:
        void makeActive();
        void swap();
 
+       int getWidth() const;
+       int getHeight() const;
+
 
        struct Exception : public Mf::Exception
        {
diff --git a/src/Scene.cc b/src/Scene.cc
new file mode 100644 (file)
index 0000000..bd9c034
--- /dev/null
@@ -0,0 +1,647 @@
+
+/*******************************************************************************
+
+ 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.
+
+*******************************************************************************/
+
+#include <map>
+#include <vector>
+
+#include <Moof/Aabb.hh>
+#include <Moof/Camera.hh>
+#include <Moof/Entity.hh>
+#include <Moof/Log.hh>
+#include <Moof/Math.hh>
+#include <Moof/Mippleton.hh>
+#include <Moof/Octree.hh>
+#include <Moof/Script.hh>
+#include <Moof/Settings.hh>
+#include <Moof/Tilemap.hh>
+
+#include "Scene.hh"
+
+
+struct Scene::Impl : public Mf::Mippleton<Impl>
+{
+       class Quad : public Mf::Entity, public Mf::OctreeInsertable
+       {
+               Mf::Scalar              vertices_[12];
+               Mf::Scalar              texCoords_[8];
+               
+               Mf::Tilemap             tilemap_;
+
+               bool                    blending_;
+               bool                    fog_;
+
+               Mf::Aabb                aabb_;
+               Mf::Sphere              sphere_;
+
+       public:
+
+               enum SURFACE_TYPE
+               {
+                       LEFT    = 1,
+                       RIGHT   = 2,
+                       TOP             = 3
+               };
+
+               Quad(const Mf::Vector3 vertices[4], const std::string& texture,
+                               Mf::Tilemap::Index tileIndex) :
+                       tilemap_(texture),
+                       blending_(false),
+                       fog_(false)
+               {
+                       for (int i = 0, num = 0; i < 4; ++i)
+                       {
+                               for (int j = 0; j < 3; ++j, ++num)
+                               {
+                                       vertices_[num] = vertices[i][j];
+                               }
+                       }
+
+                       if (!tilemap_.getTileCoords(tileIndex, texCoords_))
+                       {
+                               Mf::logWarning("no index %d in texture %s", tileIndex,
+                                               texture.c_str());
+
+                               texCoords_[0] = texCoords_[1] =
+                                       texCoords_[3] = texCoords_[6] = 0.0;
+                               texCoords_[2] = texCoords_[4] =
+                                       texCoords_[5] = texCoords_[7] = 1.0;
+                       }
+
+                       aabb_.encloseVertices(vertices, 4);
+                       sphere_.point = aabb_.getCenter();
+                       sphere_.radius = (aabb_.min - sphere_.point).length();
+               }
+
+               void setBlending(bool blending)
+               {
+                       blending_ = blending;
+               }
+
+               void setFog(bool fog)
+               {
+                       fog_ = fog;
+               }
+
+               void draw(Mf::Scalar alpha = 0.0) const
+               {
+                       if (blending_)
+                       {
+                               glEnable(GL_BLEND);
+                               glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+                       }
+
+                       if (fog_)
+                       {
+                               glEnable(GL_FOG);
+                               glFogi(GL_FOG_MODE, GL_LINEAR);
+                       }
+
+                       //glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+                       tilemap_.bind();
+
+                       glVertexPointer(3, GL_SCALAR, 0, vertices_);
+                       glTexCoordPointer(2, GL_SCALAR, 0, texCoords_);
+
+                       glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
+
+                       glDisable(GL_BLEND);
+                       glDisable(GL_FOG);
+               }
+
+               bool isVisible(const Mf::Frustum& frustum) const
+               {
+                       return sphere_.isVisible(frustum);
+               }
+
+
+               bool isInsideAabb(const Mf::Aabb& aabb) const
+               {
+                       // make sure the entity is fully inside the volume
+                       if (!(aabb_.max[0] < aabb.max[0] &&
+                                 aabb_.min[0] > aabb.min[0] &&
+                                 aabb_.max[1] < aabb.max[1] &&
+                                 aabb_.min[1] > aabb.min[1] &&
+                                 aabb_.max[2] < aabb.max[2] &&
+                                 aabb_.min[2] > aabb.min[2]))
+                       {
+                               return false;
+                       }
+
+                       return true;
+               }
+
+               int getOctant(const Mf::Aabb& aabb) const
+               {
+                       int octantNum = -1;
+
+                       Mf::Plane::Halfspace halfspace;
+
+                       Mf::Plane xy = aabb.getPlaneXY();
+                       halfspace = xy.intersects(sphere_);
+                       if (halfspace == Mf::Plane::INTERSECT)
+                       {
+                               halfspace = xy.intersects(aabb_);
+                       }
+
+                       if (halfspace == Mf::Plane::POSITIVE)
+                       {
+                               Mf::Plane xz = aabb.getPlaneXZ();
+                               halfspace = xz.intersects(sphere_);
+                               if (halfspace == Mf::Plane::INTERSECT)
+                               {
+                                       halfspace = xz.intersects(aabb_);
+                               }
+
+                               if (halfspace == Mf::Plane::POSITIVE)
+                               {
+                                       Mf::Plane yz = aabb.getPlaneYZ();
+                                       halfspace = yz.intersects(sphere_);
+                                       if (halfspace == Mf::Plane::INTERSECT)
+                                       {
+                                               halfspace = yz.intersects(aabb_);
+                                       }
+
+                                       if (halfspace == Mf::Plane::POSITIVE)
+                                       {
+                                               octantNum = 2;
+                                       }
+                                       else if (halfspace == Mf::Plane::NEGATIVE)
+                                       {
+                                               octantNum = 3;
+                                       }
+                               }
+                               else if (halfspace == Mf::Plane::NEGATIVE)
+                               {
+                                       Mf::Plane yz = aabb.getPlaneYZ();
+                                       halfspace = yz.intersects(sphere_);
+                                       if (halfspace == Mf::Plane::INTERSECT)
+                                       {
+                                               halfspace = yz.intersects(aabb_);
+                                       }
+
+                                       if (halfspace == Mf::Plane::POSITIVE)
+                                       {
+                                               octantNum = 1;
+                                       }
+                                       else if (halfspace == Mf::Plane::NEGATIVE)
+                                       {
+                                               octantNum = 0;
+                                       }
+                               }
+                       }
+                       else if (halfspace == Mf::Plane::NEGATIVE)
+                       {
+                               Mf::Plane xz = aabb.getPlaneXZ();
+                               halfspace = xz.intersects(sphere_);
+                               if (halfspace == Mf::Plane::INTERSECT)
+                               {
+                                       halfspace = xz.intersects(aabb_);
+                               }
+
+                               if (halfspace == Mf::Plane::POSITIVE)
+                               {
+                                       Mf::Plane yz = aabb.getPlaneYZ();
+                                       halfspace = yz.intersects(sphere_);
+                                       if (halfspace == Mf::Plane::INTERSECT)
+                                       {
+                                               halfspace = yz.intersects(aabb_);
+                                       }
+
+                                       if (halfspace == Mf::Plane::POSITIVE)
+                                       {
+                                               octantNum = 6;
+                                       }
+                                       else if (halfspace == Mf::Plane::NEGATIVE)
+                                       {
+                                               octantNum = 7;
+                                       }
+                               }
+                               else if (halfspace == Mf::Plane::NEGATIVE)
+                               {
+                                       Mf::Plane yz = aabb.getPlaneYZ();
+                                       halfspace = yz.intersects(sphere_);
+                                       if (halfspace == Mf::Plane::INTERSECT)
+                                       {
+                                               halfspace = yz.intersects(aabb_);
+                                       }
+
+                                       if (halfspace == Mf::Plane::POSITIVE)
+                                       {
+                                               octantNum = 5;
+                                       }
+                                       else if (halfspace == Mf::Plane::NEGATIVE)
+                                       {
+                                               octantNum = 4;
+                                       }
+                               }
+                       }
+
+                       return octantNum;
+               }
+       };
+
+
+
+       Mf::Script                              script;
+
+       Mf::Matrix4                             transform;
+       std::string                             texture;
+
+       Mf::Octree<Quad>::Ptr   octree;
+
+
+       enum AXIS
+       {
+               X = 0,
+               Y = 1,
+               Z = 2
+       };
+
+
+
+       explicit Impl(const std::string& name) :
+               Mf::Mippleton<Impl>(name)
+       {
+               script.importStandardLibraries();
+               importLogScript(script);
+
+               importSceneBindings(script);
+               loadFromFile();
+       }
+
+       void importSceneBindings(Mf::Script& script)
+       {
+               script.importFunction("SetPlayfieldBounds",
+                               boost::bind(&Impl::setPlayfieldBounds, this, _1));
+               script.importFunction("SetMaximumBounds",
+                               boost::bind(&Impl::setMaximumBounds, this, _1));
+               script.importFunction("ResetTransform",
+                               boost::bind(&Impl::resetTransform, this, _1));
+               script.importFunction("Translate",
+                               boost::bind(&Impl::translate, this, _1));
+               script.importFunction("Scale",
+                               boost::bind(&Impl::scale, this, _1));
+               script.importFunction("Rotate",
+                               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");
+       }
+
+
+       void loadFromFile()
+       {
+               std::string filePath = Scene::getPath(getName());
+
+               if (script.doFile(filePath) != Mf::Script::SUCCESS)
+               {
+                       std::string str;
+                       script[-1].get(str);
+                       Mf::logScript("%s", str.c_str());
+               }
+       }
+
+
+       static int loadBox(Mf::Script& script, Mf::Aabb& 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[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]);
+
+               return 0;
+       }
+
+       int setPlayfieldBounds(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);
+               return ret;
+       }
+
+       int resetTransform(Mf::Script& script)
+       {
+               transform.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]);
+
+               Mf::Matrix4 translation;
+               cml::matrix_translation(translation, vec);
+               transform = translation * transform;
+
+               return 0;
+       }
+
+       int scale(Mf::Script& script)
+       {
+               if (script.getSize() == 3)
+               {
+                       Mf::Vector3 vec;
+                       script[1].requireNumber().get(vec[0]);
+                       script[2].requireNumber().get(vec[1]);
+                       script[3].requireNumber().get(vec[2]);
+
+                       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;
+               }
+               else
+               {
+                       script.getTop().throwError("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);
+
+               Mf::Scalar value;
+               angle.get(value);
+
+               cml::matrix_rotate_about_world_axis(transform, index, cml::rad(value));
+
+               return 0;
+       }
+
+       int setTexture(Mf::Script& script)
+       {
+               Mf::Script::Value name = script[1].requireString();
+
+               name.get(texture);
+
+               return 0;
+       }
+
+       int makeTilemap(Mf::Script& script)
+       {
+               Mf::Script::Value table = script[1].requireTable();
+               Mf::Script::Value top = script[-1];
+
+               long width = 1;
+               long height = 1;
+
+               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");
+
+               std::vector< std::vector<Mf::Tilemap::Index> > indices;
+
+               int i, w, h;
+
+               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
+
+               i = 1;
+               for (h = height - 1; h >= 0; --h)
+               {
+                       std::vector<Mf::Tilemap::Index> row;
+
+                       for (w = 0; w < width; ++w, ++i)
+                       {
+                               script.checkStack(2);
+                               script.push(long(i));
+                               tiles.pushField();
+
+                               long index;
+                               top.get(index);
+
+                               row.push_back(Mf::Tilemap::Index(index));
+                       }
+
+                       indices[h] = row;
+               }
+
+               Mf::Vector4 vertices[height+1][width+1];
+
+               Mf::Matrix4 transposedTransform = transform;
+               transposedTransform.transpose();
+
+               for (int h = 0; h <= height; ++h)
+               {
+                       for (int w = 0; w <= width; ++w)
+                       {
+                               vertices[h][w] = Mf::Vector4(Mf::Scalar(w), Mf::Scalar(h), 0.0, 1.0) *
+                                       transposedTransform;
+                       }
+               }
+
+               for (int h = 0; h < height; ++h)
+               {
+                       for (int w = 0; w < width; ++w)
+                       {
+                               if (indices[h][w] == Mf::Tilemap::NO_TILE) continue;
+
+                               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]);
+
+                               Quad* quad = new Quad(quadVertices, texture, indices[h][w]);
+                               boost::shared_ptr<Quad> quadPtr(quad);
+
+                               octree->insert(quadPtr);
+                       }
+               }
+
+               return 0;
+       }
+
+       int makeBillboard(Mf::Script& script)
+       {
+               Mf::Script::Value table = script[1];
+               Mf::Script::Value top = script[-1];
+
+               long    index = 0;
+               long    width = 1;
+               bool    blending = false;
+               bool    fog = false;
+
+               if (table.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);
+               }
+
+               Mf::Vector4 vertices[2][width+1];
+
+               Mf::Matrix4 transposedTransform = transform;
+               transposedTransform.transpose();
+
+               Mf::Scalar xf;
+               Mf::Scalar increment = 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;
+                       }
+               }
+
+               for (int w = 0; w < width; ++w)
+               {
+                       Mf::Vector3 quadVertices[4];
+
+                       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]);
+
+                       Quad* quad = new Quad(quadVertices, texture, Mf::Tilemap::Index(index));
+                       quad->setBlending(blending);
+                       quad->setFog(fog);
+
+                       boost::shared_ptr<Quad> quadPtr(quad);
+
+                       octree->insert(quadPtr);
+               }
+
+               return 0;
+       }
+};
+
+
+Scene::Scene(const std::string& name) :
+       // pass through
+       impl_(Scene::Impl::getInstance(name)) {}
+
+
+void Scene::draw(Mf::Scalar alpha) const
+{
+       impl_->octree->draw(alpha);
+}
+
+void Scene::drawIfVisible(Mf::Scalar alpha, const Mf::Frustum& frustum) const
+{
+       impl_->octree->drawIfVisible(alpha, frustum);
+}
+
+
+std::string Scene::getPath(const std::string& name)
+{
+       return Mf::Resource::getPath("scenes/" + name + ".lua");
+}
+
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
diff --git a/src/Scene.hh b/src/Scene.hh
new file mode 100644 (file)
index 0000000..ca96aea
--- /dev/null
@@ -0,0 +1,68 @@
+
+/*******************************************************************************
+
+ 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.
+
+*******************************************************************************/
+
+#ifndef _SCENE_HH_
+#define _SCENE_HH_
+
+#include <string>
+
+#include <boost/shared_ptr.hpp>
+
+#include <Moof/Cullable.hh>
+#include <Moof/Drawable.hh>
+#include <Moof/Resource.hh>
+
+
+class Scene;
+typedef boost::shared_ptr<Scene> SceneP;
+
+class Scene : public Mf::Cullable, public Mf::Drawable, public Mf::Resource
+{
+       class Impl;
+       boost::shared_ptr<Impl> impl_;
+
+public:
+
+       Scene(const std::string& name);
+
+       static SceneP alloc(const std::string& name)
+       {
+               return SceneP(new Scene(name));
+       }
+
+       void draw(Mf::Scalar alpha) const;
+       void drawIfVisible(Mf::Scalar alpha, const Mf::Frustum& frustum) const;
+
+       static std::string getPath(const std::string& name);
+};
+
+
+#endif // _SCENE_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
diff --git a/src/TitleLayer.cc b/src/TitleLayer.cc
new file mode 100644 (file)
index 0000000..a12168a
--- /dev/null
@@ -0,0 +1,81 @@
+
+/*******************************************************************************
+
+ 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.
+
+*******************************************************************************/
+
+#include <Moof/Engine.hh>
+#include <Moof/OpenGL.hh>
+#include <Moof/Transition.hh>
+
+#include "GameLayer.hh"
+#include "TitleLayer.hh"
+
+
+void TitleLayer::pushed(Mf::Engine& e)
+{
+       engine = &e;
+
+       Mf::Scalar coeff[] = {0.0, 1.0};
+       fadeIn.init(coeff, 0.1);
+
+       gameLayer = GameLayer::alloc();
+}
+
+void TitleLayer::update(Mf::Scalar t, Mf::Scalar dt)
+{
+       if (!fadeIn.isDone()) fadeIn.update(t, dt);
+}
+
+void TitleLayer::draw(Mf::Scalar alpha) const
+{
+       glClearColor(0.0, 0.0, fadeIn.getState(alpha), 1.0);
+       glClear(GL_COLOR_BUFFER_BIT);
+}
+
+bool TitleLayer::handleEvent(const Mf::Event& event)
+{
+       switch (event.type)
+       {
+               case SDL_KEYUP:
+                       Mf::LayerP titleLayer = engine->pop(this);
+                       //engine->pushLayer(GameLayer::alloc());
+
+                       Mf::Scalar coeff[] = {0.0, 1.0};
+                       Mf::Lerp interp(coeff, 0.2);
+
+                       //Mf::LayerP gameLayer = GameLayer::alloc();
+                       Mf::Transition<Mf::Lerp>::Ptr transition =
+                               Mf::Transition<Mf::Lerp>::alloc(gameLayer, titleLayer, interp);
+                       engine->push(transition);
+                       return true;
+       }
+
+       return false;
+}
+
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
diff --git a/src/TitleLayer.hh b/src/TitleLayer.hh
new file mode 100644 (file)
index 0000000..da4b4c5
--- /dev/null
@@ -0,0 +1,67 @@
+
+/*******************************************************************************
+
+ 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.
+
+*******************************************************************************/
+
+#ifndef _TITLELAYER_HH_
+#define _TITLELAYER_HH_
+
+#include <boost/shared_ptr.hpp>
+
+#include <Moof/Interpolator.hh>
+#include <Moof/Layer.hh>
+#include <Moof/Math.hh>
+
+
+class TitleLayer;
+typedef boost::shared_ptr<TitleLayer> TitleLayerP;
+
+struct TitleLayer : public Mf::Layer
+{
+       static TitleLayerP alloc()
+       {
+               return TitleLayerP(new TitleLayer);
+       }
+
+       void pushed(Mf::Engine& engine);
+
+       void update(Mf::Scalar t, Mf::Scalar dt);
+       void draw(Mf::Scalar alpha) const;
+       bool handleEvent(const Mf::Event& event);
+
+private:
+
+       Mf::Lerp fadeIn;
+       Mf::Engine* engine;
+
+       Mf::LayerP gameLayer;
+};
+
+
+#endif // _TITLELAYER_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
This page took 0.120099 seconds and 4 git commands to generate.