preliminary physics, sound, hud
authorCharles McGarvey <chazmcgarvey@brokenzipper.com>
Mon, 31 Aug 2009 05:59:27 +0000 (23:59 -0600)
committerCharles McGarvey <chazmcgarvey@brokenzipper.com>
Mon, 31 Aug 2009 05:59:27 +0000 (23:59 -0600)
38 files changed:
configure.ac
data/scenes/Test.json
data/sounds/NightFusion.xm [new file with mode: 0644]
extra/yoink.ebuild
src/Character.cc
src/Character.hh
src/Hud.cc [new file with mode: 0644]
src/Hud.hh [new file with mode: 0644]
src/Makefile.am
src/Moof/Aabb.cc
src/Moof/Animation.cc
src/Moof/Animation.hh
src/Moof/Camera.cc
src/Moof/Engine.cc
src/Moof/Engine.hh
src/Moof/Math.hh
src/Moof/Mippleton.hh
src/Moof/Octree.cc [new file with mode: 0644]
src/Moof/Octree.hh
src/Moof/OpenGL.cc
src/Moof/OpenGL.hh
src/Moof/Physics.hh [new file with mode: 0644]
src/Moof/Rectangle.cc [new file with mode: 0644]
src/Moof/Rectangle.hh [new file with mode: 0644]
src/Moof/Resource.cc
src/Moof/Resource.hh
src/Moof/RigidBody.hh [new file with mode: 0644]
src/Moof/Scene.cc
src/Moof/Scene.hh
src/Moof/Sound.cc [new file with mode: 0644]
src/Moof/Sound.hh [new file with mode: 0644]
src/Moof/State.hh [new file with mode: 0644]
src/Moof/Texture.cc
src/Moof/Texture.hh
src/Moof/Tilemap.cc
src/Moof/Tilemap.hh
src/YoinkApp.cc
src/YoinkApp.hh

index e8d8d9b090eddaa5ff27e84f0ee3ef205c81a86c..e8fd379c8091dcb2bbc7f704f3732d8446495641 100644 (file)
@@ -98,12 +98,21 @@ BOOST_FUNCTION
 AC_SEARCH_LIBS([IMG_Load], [SDL_image],,
                           [AC_MSG_ERROR([libSDL_image is required])])
 
+AC_SEARCH_LIBS([Sound_Init], [SDL_sound],,
+                          [AC_MSG_ERROR([libSDL_sound is required])])
+
 AC_SEARCH_LIBS([glBegin], [GL],,
                           [AC_MSG_ERROR([libGL is required])])
 
 AC_SEARCH_LIBS([gluPerspective], [GLU],,
                           [AC_MSG_ERROR([libGLU is required])])
 
+AC_SEARCH_LIBS([alGenBuffers], [openal],,
+                          [AC_MSG_ERROR([libopenal is required])])
+
+AC_SEARCH_LIBS([alutInit], [alut],,
+                          [AC_MSG_ERROR([libalut is required])])
+
 AC_SEARCH_LIBS([clock_gettime], [rt],
                           [AC_DEFINE([HAVE_CLOCK_GETTIME], 1,
                                                  [Define to 1 if you have the 'clock_gettime' function.])])
@@ -171,7 +180,7 @@ AC_OUTPUT
 # Print a friendly little message.
 #
 
-echo "====================================="
+echo "======================================"
 echo " Configuration complete!"
 echo ""
 
@@ -194,5 +203,5 @@ fi
 echo " To finish the installation, execute:"
 echo "  make"
 echo "  make install"
-echo "====================================="
+echo "======================================"
 
index 562a3befec0cb3224423f30392716e4c6b2c8c54..b6aac66f69a5b12238b2ff16c125cfede30b272b 100644 (file)
@@ -1,6 +1,6 @@
 {
        "playfield_bounds": [0, 0, -100, 1280, 500, 100],
-       "maximum_bounds": [-160, 0, -192, 1440, 512, 224],
+       "maximum_bounds": [-160, 0, -192, 1440, 480, 224],
        "instructions":
        [
 
                "translate", [-0.3, -0.17, -900],
                "scale", [3200, 1600, 1],
                "texture", "BackgroundFar",
-               "billboard",
-               {
-                       "fog": false
-               },
+               "billboard", null,
+
                "translate", [0, 0, 300],
                "texture", "BackgroundNear",
                "billboard",
                {
-                       "blend": true,
-                       "fog": false
+                       "blend": true
                },
 
        /* Trees */
diff --git a/data/sounds/NightFusion.xm b/data/sounds/NightFusion.xm
new file mode 100644 (file)
index 0000000..06120fc
Binary files /dev/null and b/data/sounds/NightFusion.xm differ
index 75a18082e13f0e9d822a68275726aeaf7a26e49f..52e26c7890864305409f4de5b5635cb0392d6ed9 100644 (file)
@@ -3,23 +3,30 @@
 # $Header: $
 
 EAPI=2
+
 inherit autotools eutils games
 
 DESCRIPTION="Alien-smashing action game"
 HOMEPAGE="http://www.dogcows.com/"
-SRC_URI="http://www.dogcows.com/yoink/${P}.tar.bz2"
+SRC_URI="http://www.dogcows.com/yoink/${P}.tar.bz2
+       http://eng.utah.edu/~mcgarvey/yoink/${P}.tar.bz2"
 
 LICENSE="BSD-2"
 SLOT="0"
-KEYWORDS="~amd64 ~ppc ~x86"
+KEYWORDS="amd64 ~ppc x86"
 IUSE="debug profile"
 
 RDEPEND="media-libs/libsdl[opengl]
        media-libs/sdl-image[png]
-       virtual/opengl"
+       virtual/opengl
+       media-libs/sdl-sound[mikmod, vorbis]
+       media-libs/openal"
 DEPEND="${RDEPEND}
+       dev-libs/boost
        dev-util/pkgconfig"
 
+RESTRICT="mirror"
+
 src_prepare() {
        sed -i \
                -e "s/-Werror//g" \
@@ -34,6 +41,7 @@ src_prepare() {
                -e "/man/d" \
                doc/Makefile.am \
                || die "sed failed"
+
        eautoreconf
 }
 
index f508682944d3a5db96ca210d9a710cd7ef2065d8..97a10b2553d27532cd2631f2a5447ae85ec7f1ca 100644 (file)
 
 #include "Character.hh"
 
+#include <iostream>
        
 Character::Character(const std::string& name) :
-       tilemap(name),
-       animation(name) {}
+       tilemap_(name),
+       animation_(name)
+{
+       current.mass = 1.0;
+       current.inverseMass = 1.0 / current.mass;
+
+       current.force = Mf::Vector2(0.0, -120.0);
+
+       current.position = Mf::Vector2(64.0, 64.0);
+       current.momentum = Mf::Vector2(0.0, 0.0);
+       current.recalculate();
+
+       previous = current;
+
+       updateContainers();
+}
 
 Character::~Character()
 {
@@ -40,16 +55,115 @@ Character::~Character()
 }
 
 
-void Character::draw(Mf::Scalar alpha) const {}
+void Character::update(Mf::Scalar t, Mf::Scalar dt)
+{
+       previous = current;
+       Mf::integrate<State,Derivative>(current, t, dt);
+
+       animation_.update(t, dt);
+
+       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 = 500.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)
+                       {
+                               current.force += left;
+                       }
+                       else if (event.key.keysym.sym == SDLK_d)
+                       {
+                               current.force += right;
+                       }
+                       else if (event.key.keysym.sym == SDLK_s)
+                       {
+                               current.force += down;
+                       }
+                       else if (event.key.keysym.sym == SDLK_w)
+                       {
+                               current.force += up;
+                       }
+                       break;
+
+               case SDL_KEYUP:
+                       if (event.key.keysym.sym == SDLK_a)
+                       {
+                               current.force -= left;
+                       }
+                       else if (event.key.keysym.sym == SDLK_d)
+                       {
+                               current.force -= right;
+                       }
+                       else if (event.key.keysym.sym == SDLK_s)
+                       {
+                               current.force -= down;
+                       }
+                       else if (event.key.keysym.sym == SDLK_w)
+                       {
+                               current.force -= up;
+                       }
+                       break;
+       }
+
+       std::cout << "current force: " << current.force << std::endl;
+}
+
+
+void Character::draw(Mf::Scalar alpha) const
+{
+       State state = cml::lerp(previous, current, alpha);
+
+       glColor3f(1.0f, 1.0f, 1.0f);
+       tilemap_.bind();
+
+       Mf::Tilemap::Index frame = animation_.getFrame();
+
+       Mf::Scalar coords[8];
+       tilemap_.getTileCoords(frame, coords);
+
+       Mf::Scalar s = 16.0;
+
+       glBegin(GL_QUADS);
+               glTexCoord2f(coords[0], coords[1]);
+               glVertex3(state.position[0]-s, state.position[1]-s, z);
+               glTexCoord2f(coords[2], coords[3]);
+               glVertex3(state.position[0]+s, state.position[1]-s, z);
+               glTexCoord2f(coords[4], coords[5]);
+               glVertex3(state.position[0]+s, state.position[1]+s, z);
+               glTexCoord2f(coords[6], coords[7]);
+               glVertex3(state.position[0]-s, state.position[1]+s, z);
+       glEnd();
+}
+
 
 Mf::Tilemap& Character::getTilemap()
 {
-       return tilemap;
+       return tilemap_;
 }
 
 Mf::Animation& Character::getAnimation()
 {
-       return animation;
+       return animation_;
 }
 
 
index e39e7ff93bb9ad3de3e66ef6e1ed163e6a97df11..a92992c6e3eca9fc4e6bb22581b8903f80bcdf58 100644 (file)
 #ifndef _CHARACTER_HH_
 #define _CHARACTER_HH_
 
+#include <boost/shared_ptr.hpp>
+
 #include <Moof/Animation.hh>
-#include <Moof/Drawable.hh>
-#include <Moof/Resource.hh>
+#include <Moof/Entity.hh>
+#include <Moof/Event.hh>
+#include <Moof/Math.hh>
+#include <Moof/Octree.hh>
+#include <Moof/Physics.hh>
 #include <Moof/Tilemap.hh>
 
 
 /**
- * Parent class of animate objects with "personalities."
+ * Parent class of animate objects with "personalities."  This basically
+ * includes the heroine herself and the bad guys.
  */
 
-class Character : public Mf::Drawable
+class Character : public Mf::Entity
 {
 public:
+
+       struct Derivative
+       {
+               Mf::Vector2 velocity;
+               Mf::Vector2 force;
+
+               Derivative operator*(Mf::Scalar dt) const
+               {
+                       Derivative derivative;
+                       derivative.velocity = dt * velocity;
+                       derivative.force = dt * force;
+                       return derivative;
+               }
+
+               Derivative operator+(const Derivative& other) const
+               {
+                       Derivative derivative;
+                       derivative.velocity = velocity + other.velocity;
+                       derivative.force = force + other.force;
+                       return derivative;
+               }
+       };
+
+       struct State
+       {
+               // primary
+               
+               Mf::Vector2 position;
+               Mf::Vector2 momentum;
+               Mf::Vector2 force;
+
+               // secondary
+
+               Mf::Vector2 velocity;
+
+               // constant
+               
+               Mf::Scalar      mass;
+               Mf::Scalar      inverseMass;
+
+
+               void getDerivative(Derivative& derivative, Mf::Scalar t) const
+               {
+                       //derivative.velocity = Mf::Vector2(0.0, 0.0);
+                       //derivative.force = Mf::Vector2(0.0, 0.0);
+                       derivative.velocity = velocity;
+                       derivative.force = force;
+               }
+
+               void recalculate()
+               {
+                       velocity = momentum * inverseMass;
+               }
+
+               void applyDerivative(const Derivative& derivative, Mf::Scalar dt)
+               {
+                       position += dt * derivative.velocity;
+                       momentum += dt * derivative.force;
+                       recalculate();
+               }
+
+               State operator*(Mf::Scalar scalar) const
+               {
+                       State state = *this;
+                       state.position *= scalar;
+                       state.momentum *= scalar;
+                       state.recalculate();
+                       return state;
+               }
+
+               State operator+(State state) const
+               {
+                       State newState = *this;
+                       newState.position +=  state.position;
+                       newState.momentum +=  state.momentum;
+                       newState.recalculate();
+                       return newState;
+               }
+       };
+
+
        Character(const std::string& name);
-       ~Character();
+       virtual ~Character();
 
+       void update(Mf::Scalar t, Mf::Scalar dt);
+       void handleEvent(const Mf::Event& event);
        void draw(Mf::Scalar alpha) const;
 
        Mf::Tilemap& getTilemap();
        Mf::Animation& getAnimation();
 
+       State                   previous;
+       State                   current;
+
+       stlplus::ntree<Mf::OctreeNode>::iterator treeNode;
+
 private:
-       Mf::Tilemap tilemap;
-       Mf::Animation animation;
+
+       void updateContainers();
+
+       static const Mf::Scalar z = 96.0;
+
+       Mf::Tilemap             tilemap_;
+       Mf::Animation   animation_;
 };
 
+typedef boost::shared_ptr<Character> CharacterPtr;
+
+
+inline Character::State operator*(Mf::Scalar scalar, const Character::State& state)
+{
+       Character::State newState = state;
+       newState.position *= scalar;
+       newState.momentum *= scalar;
+       newState.recalculate();
+       return newState;
+}
+
 
 #endif // _CHARACTER_HH_
 
diff --git a/src/Hud.cc b/src/Hud.cc
new file mode 100644 (file)
index 0000000..ea0dfea
--- /dev/null
@@ -0,0 +1,176 @@
+
+/*******************************************************************************
+
+ 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/OpenGL.hh>
+
+#include "Hud.hh"
+
+#include <iostream>
+
+
+ProgressBar::ProgressBar(const Mf::Tilemap& tilemap, Mf::Tilemap::Index index) :
+       progress_(0.0),
+       tilemap_(tilemap)
+{
+       tilemap.getTileCoords(index, texCoords_);
+
+       Mf::Scalar half = (texCoords_[2] - texCoords_[0]) / 2.0 + texCoords_[0];
+       midCoords_[0] = half - 0.01;
+       midCoords_[1] = half + 0.01;
+}
+
+void ProgressBar::resize(const Mf::Rectangle& rect)
+{
+       Mf::Scalar height = rect.max[1] - rect.min[1];
+       Mf::Scalar halfHeight = height / 2.0;
+
+       width_ = rect.max[0] - rect.min[0] - height;
+       // assert width > 0
+
+       vertices_[0] = rect.min;
+       vertices_[1] = Mf::Vector2(rect.min[0] + halfHeight, rect.min[1]);
+       vertices_[2] = vertices_[1];
+       vertices_[3] = Mf::Vector2(rect.min[0] + height,     rect.min[1]);
+       vertices_[4] = Mf::Vector2(rect.min[0] + height,     rect.max[1]);
+       vertices_[5] = Mf::Vector2(rect.min[0] + halfHeight, rect.max[1]);
+       vertices_[6] = vertices_[5];
+       vertices_[7] = Mf::Vector2(rect.min[0],              rect.max[1]);
+
+       setProgress(progress_);
+}
+
+void ProgressBar::setProgress(Mf::Scalar progress)
+{
+       Mf::Scalar halfHeight = (vertices_[7][1] - vertices_[0][1]) / 2.0;
+
+       vertices_[2][0] = vertices_[1][0] + progress * width_;
+       vertices_[3][0] = vertices_[1][0] + progress * width_ + halfHeight;
+       vertices_[4][0] = vertices_[1][0] + progress * width_ + halfHeight;
+       vertices_[5][0] = vertices_[1][0] + progress * width_;
+
+       progress_ = progress;
+}
+
+void ProgressBar::draw(Mf::Scalar alpha) const
+{
+       if (Mf::isEqual(progress_, 0.0))
+       {
+               // don't draw anything if the progress is 0%
+               return;
+       }
+
+       glColor4f(1.0f, 1.0f, 1.0f, 0.85f);
+       tilemap_.bind();
+
+       glBegin(GL_QUADS);
+               glTexCoord2(texCoords_[0], texCoords_[1]);
+               glVertex2v(vertices_[0].data());
+               glTexCoord2(midCoords_[0], texCoords_[3]);
+               glVertex2v(vertices_[1].data());
+               glTexCoord2(midCoords_[0], texCoords_[5]);
+               glVertex2v(vertices_[6].data());
+               glTexCoord2(texCoords_[6], texCoords_[7]);
+               glVertex2v(vertices_[7].data());
+
+               glTexCoord2(midCoords_[0], texCoords_[1]);
+               glVertex2v(vertices_[1].data());
+               glTexCoord2(midCoords_[1], texCoords_[3]);
+               glVertex2v(vertices_[2].data());
+               glTexCoord2(midCoords_[1], texCoords_[5]);
+               glVertex2v(vertices_[5].data());
+               glTexCoord2(midCoords_[0], texCoords_[7]);
+               glVertex2v(vertices_[6].data());
+
+               glTexCoord2(midCoords_[1], texCoords_[1]);
+               glVertex2v(vertices_[2].data());
+               glTexCoord2(texCoords_[2], texCoords_[3]);
+               glVertex2v(vertices_[3].data());
+               glTexCoord2(texCoords_[4], texCoords_[5]);
+               glVertex2v(vertices_[4].data());
+               glTexCoord2(midCoords_[1], texCoords_[7]);
+               glVertex2v(vertices_[5].data());
+       glEnd();
+}
+
+
+Hud::Hud() :
+       bar1_(Mf::Tilemap("StatusBars"), 0),
+       bar2_(Mf::Tilemap("StatusBars"), 2),
+       font_("Font")
+{
+       resize(800, 600);
+}
+
+
+void Hud::resize(int width, int height)
+{
+       cml::matrix_orthographic_RH( projection_, 
+                       0.0, 
+                       Mf::Scalar(width), 0.0, Mf::Scalar(height),
+                       1.0, -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,
+                               0.7 * width, height - 3));
+       bar2_.resize(Mf::Rectangle(20, height - 28,
+                               0.7 * width, height - 70));
+
+       setBar1Progress(0.05);
+       setBar2Progress(0.0);
+}
+
+
+void Hud::draw(Mf::Scalar alpha) const
+{
+       glMatrixMode(GL_PROJECTION);
+       glPushMatrix();
+       glLoadMatrix(projection_.data());
+
+       glMatrixMode(GL_MODELVIEW);
+       glPushMatrix();
+       glLoadIdentity();
+
+       glDisable(GL_DEPTH_TEST);
+       glEnable(GL_BLEND);
+
+       bar1_.draw();
+       bar2_.draw();
+
+       glDisable(GL_BLEND);
+       glEnable(GL_DEPTH_TEST);
+
+       glMatrixMode(GL_PROJECTION);
+       glPopMatrix();
+
+       glMatrixMode(GL_MODELVIEW);
+       glPopMatrix();
+}
+
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
diff --git a/src/Hud.hh b/src/Hud.hh
new file mode 100644 (file)
index 0000000..813e67f
--- /dev/null
@@ -0,0 +1,107 @@
+
+/*******************************************************************************
+
+ 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 _HUD_HH_
+#define _HUD_HH_
+
+/**
+ * @file Hud.hh
+ * Heads-up Display
+ */
+
+#include <Moof/Drawable.hh>
+#include <Moof/Math.hh>
+#include <Moof/Rectangle.hh>
+#include <Moof/Tilemap.hh>
+
+
+class ProgressBar : public Mf::Drawable
+{
+public:
+
+       ProgressBar(const Mf::Tilemap& tilemap, Mf::Tilemap::Index index);
+
+       void resize(const Mf::Rectangle& rect);
+
+       void setProgress(Mf::Scalar progress);
+
+       void draw(Mf::Scalar alpha = 0.0) const;
+
+private:
+
+       Mf::Scalar      progress_;
+
+       Mf::Vector2     vertices_[8];
+       Mf::Scalar      width_;
+
+       Mf::Tilemap     tilemap_;
+       Mf::Scalar      texCoords_[8];
+       Mf::Scalar      midCoords_[2];
+};
+
+
+class Hud : public Mf::Drawable
+{
+public:
+
+       Hud();
+
+       inline void setBar1Progress(Mf::Scalar progress)
+       {
+               // pass through
+               bar1_.setProgress(progress);
+       }
+
+       inline void setBar2Progress(Mf::Scalar progress)
+       {
+               // pass through
+               bar2_.setProgress(progress);
+       }
+
+       void setNumber(unsigned value);
+
+       void resize(int width, int height);
+
+       void draw(Mf::Scalar alpha = 0.0) const;
+
+private:
+
+       ProgressBar     bar1_;
+       ProgressBar     bar2_;
+
+       unsigned        number_;
+       Mf::Tilemap     font_;
+
+       Mf::Matrix4     projection_;
+};
+
+
+#endif // _HUD_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
index f4122dec4a3a6659d7531e510db69bb1535f8cf7..3273beaccf7ee7130e36436c4ace9bfad77b8871 100644 (file)
@@ -27,13 +27,17 @@ libmoof_la_SOURCES = \
                                   Moof/Interpolator.hh \
                                   Moof/Math.hh \
                                   Moof/Mippleton.hh \
+                                  Moof/Octree.cc \
                                   Moof/Octree.hh \
                                   Moof/OpenGL.cc \
                                   Moof/OpenGL.hh \
+                                  Moof/Physics.hh \
                                   Moof/Plane.cc \
                                   Moof/Plane.hh \
                                   Moof/Random.cc \
                                   Moof/Random.hh \
+                                  Moof/Rectangle.cc \
+                                  Moof/Rectangle.hh \
                                   Moof/Resource.cc \
                                   Moof/Resource.hh \
                                   Moof/Scene.cc \
@@ -45,6 +49,8 @@ libmoof_la_SOURCES = \
                                   Moof/Settings.cc \
                                   Moof/Settings.hh \
                                   Moof/Singleton.hh \
+                                  Moof/Sound.cc \
+                                  Moof/Sound.hh \
                                   Moof/Sphere.cc \
                                   Moof/Sphere.hh \
                                   Moof/StringTools.cc \
@@ -71,6 +77,8 @@ bin_PROGRAMS   = yoink
 yoink_SOURCES  = \
                                 Character.cc \
                                 Character.hh \
+                                Hud.cc \
+                                Hud.hh \
                                 TilemapFont.cc \
                                 TilemapFont.hh \
                                 Typesetter.cc \
index c844251b1d0551b2fcf9c94a8ddf2929c11baf6e..1fb382f7fab7069bd8e1b8378f5d42a4daa6ce78 100644 (file)
 
 *******************************************************************************/
 
-#include <Moof/Aabb.hh>
-#include <Moof/Camera.hh>
-#include <Moof/OpenGL.hh>
-#include <Moof/Texture.hh>
+#include "Aabb.hh"
+#include "Camera.hh"
+#include "OpenGL.hh"
+#include "Texture.hh"
 
 
 namespace Mf {
index 38ffa6c9c5e5c8ca9fdb83806e46f731d9bd274b..30e3fbbf4bcebb4d041d02d55b366b9b3e3a936e 100644 (file)
@@ -39,14 +39,14 @@ namespace Mf {
 
 /**
  * The collection of nested animation classes.  The animation implementation
- * consists of an AnimationImpl classes which is allocated and initialized with
- * the interface object.  This class contains the specific fields which are
- * required to run a single instance of an animation.  The sequence data is
- * loaded in a difference class which can be shared amongst multiple animation
- * implementation instances.
+ * consists of an Impl class which is allocated and initialized with the
+ * interface object.  This class contains the specific fields which are required
+ * to run a single instance of an animation.  The sequence data is loaded in a
+ * different class which can be shared amongst multiple animation implementation
+ * instances.
  */
 
-struct Animation::AnimationImpl
+struct Animation::Impl
 {
 
        /**
@@ -55,7 +55,7 @@ struct Animation::AnimationImpl
         * which wants to use these loaded sequences.
         */
 
-       struct AnimationData : public Mippleton<AnimationData>
+       struct GlobalData : public Mippleton<GlobalData>
        {
                /**
                 * A frame of an animation sequence.  A frame is merely an index which
@@ -182,7 +182,7 @@ struct Animation::AnimationImpl
 
                void loadFromFile()
                {
-                       std::string filePath = Animation::getPathToResource(getName());
+                       std::string filePath = Animation::getPath(getName());
 
                        Deserializer deserializer(filePath);
 
@@ -210,8 +210,8 @@ struct Animation::AnimationImpl
                 * registers itself as a mippleton and then loads the animation data.
                 */
 
-               explicit AnimationData(const std::string& name) :
-                       Mippleton<AnimationData>(name)
+               explicit GlobalData(const std::string& name) :
+                       Mippleton<GlobalData>(name)
                {
                        loadFromFile();
                }
@@ -224,8 +224,8 @@ struct Animation::AnimationImpl
         * Construction is intialization.
         */
 
-       AnimationImpl(const std::string& name) :
-               data(AnimationData::retain(name), &AnimationData::release),
+       Impl(const std::string& name) :
+               data(GlobalData::retain(name), &GlobalData::release),
                currentSequence(0),
                frameCounter(0),
                frameIndex(0),
@@ -241,7 +241,7 @@ struct Animation::AnimationImpl
 
        void startSequence(const std::string& name)
        {
-               std::map<std::string,AnimationData::Sequence>::iterator it;
+               std::map<std::string,GlobalData::Sequence>::iterator it;
 
                it = data->sequences.find(name);
 
@@ -299,9 +299,9 @@ struct Animation::AnimationImpl
                }
        }
 
-       boost::shared_ptr<AnimationData> data;                  ///< Internal data.
+       boost::shared_ptr<GlobalData> data;                     ///< Internal data.
 
-       AnimationData::Sequence*        currentSequence;        ///< Active sequence.
+       GlobalData::Sequence*   currentSequence;        ///< Active sequence.
        unsigned        frameCounter;                                           ///< Current frame.
        unsigned        frameIndex;                                                     ///< Index of current frame.
        Scalar          timeAccum;                                                      ///< Time accumulation.
@@ -311,7 +311,7 @@ struct Animation::AnimationImpl
 
 Animation::Animation(const std::string& name) :
        // pass through
-       impl_(new Animation::AnimationImpl(name)) {}
+       impl_(new Animation::Impl(name)) {}
 
 
 void Animation::startSequence(const std::string& name)
@@ -343,9 +343,9 @@ unsigned Animation::getFrame() const
  * "animations" subdirectory of any of the searched directories.
  */
 
-std::string Animation::getPathToResource(const std::string& name)
+std::string Animation::getPath(const std::string& name)
 {
-       return Resource::getPathToResource("animations/" + name + ".json");
+       return Resource::getPath("animations/" + name + ".json");
 }
 
 
index 57ce6a8ffe6f280b5a8396d77725bef07b8b86c2..cfda19beff3cd2b0de2686ea457d299d0fc15c79 100644 (file)
@@ -63,11 +63,11 @@ public:
        void update(Scalar t, Scalar dt);
        unsigned getFrame() const;
 
-       static std::string getPathToResource(const std::string& name);
+       static std::string getPath(const std::string& name);
 
 private:
-       class AnimationImpl;
-       boost::shared_ptr<AnimationImpl> impl_;
+       class Impl;
+       boost::shared_ptr<Impl> impl_;
 };
 
 
index cdebc7a7b735b7e681e3b28f041f576aa9166d7f..b38dd143cf04a51bc4dc30068a322ea77e073a42 100644 (file)
@@ -37,6 +37,7 @@ namespace Mf {
 void Camera::setPosition(const Vector3& point)
 {
        position_ = point;
+       calculateSecondary();
        //Vector3 coeff[2] = {position_, point};
        //pInterp_.init(coeff, 0.1);
 }
@@ -79,7 +80,8 @@ void Camera::update(Scalar t, Scalar dt)
 
 void Camera::lookAt(const Vector3& point)
 {
-       quaternion_rotation_aim_at(rotation_, position_, point);
+       cml::quaternion_rotation_aim_at(rotation_, position_, point, Vector3(0.0, -1.0, 0.0));
+       calculateSecondary();
 }
 
 void Camera::adjustFromInput(const Event& event)
@@ -87,29 +89,25 @@ void Camera::adjustFromInput(const Event& event)
        switch (event.type)
        {
                case SDL_KEYDOWN:
-                       if (event.key.keysym.sym == SDLK_RIGHT ||
-                                       event.key.keysym.sym == SDLK_d)
+                       if (event.key.keysym.sym == SDLK_RIGHT)
                        {
                                Vector3 vec = position_;
                                vec[0] -= 50.0;
                                setPosition(vec);
                        }
-                       else if (event.key.keysym.sym == SDLK_LEFT ||
-                                       event.key.keysym.sym == SDLK_a)
+                       else if (event.key.keysym.sym == SDLK_LEFT)
                        {
                                Vector3 vec = position_;
                                vec[0] += 50.0;
                                setPosition(vec);
                        }
-                       else if (event.key.keysym.sym == SDLK_UP ||
-                                       event.key.keysym.sym == SDLK_w)
+                       else if (event.key.keysym.sym == SDLK_UP)
                        {
                                Vector3 vec = position_;
                                vec[1] -= 50.0;
                                setPosition(vec);
                        }
-                       else if (event.key.keysym.sym == SDLK_DOWN ||
-                                       event.key.keysym.sym == SDLK_s)
+                       else if (event.key.keysym.sym == SDLK_DOWN)
                        {
                                Vector3 vec = position_;
                                vec[1] += 50.0;
@@ -123,7 +121,6 @@ void Camera::adjustFromInput(const Event& event)
                        }
                        else if (event.key.keysym.sym == SDLK_PAGEDOWN)
                        {
-                               //position_[2] -= 50.0;
                                Vector3 vec = position_;
                                vec[2] -= 50.0;
                                setPosition(vec);
@@ -137,9 +134,9 @@ void Camera::adjustFromInput(const Event& event)
 
                        Quaternion rotation = rotation_;
 
-                       quaternion_rotate_about_world_x(rotation, yrel);
+                       cml::quaternion_rotate_about_world_x(rotation, yrel);
                        //rotation_.normalize();
-                       quaternion_rotate_about_world_y(rotation, xrel);
+                       cml::quaternion_rotate_about_world_y(rotation, xrel);
                        rotation.normalize();
 
                        setRotation(rotation);
@@ -167,13 +164,14 @@ void Camera::adjustFromInput(const Event& event)
 
 void Camera::calculateSecondary()
 {
-       matrix_rotation_quaternion(modelview_, rotation_);
+       cml::matrix_rotation_quaternion(modelview_, rotation_);
 
        Matrix4 translate;
-       matrix_translation(translate, position_);
+       cml::matrix_translation(translate, position_);
 
-       //modelview_ = translate * modelview_;
+       //modelview_.transpose();
        modelview_ *= translate;
+       //modelview_ = translate * modelview_;
 
        frustum_.init(modelview_, projection_);
 }
index 53fca73e9e883cfab1d18aced70cd125391f26d1..78233688d60f69dba90c880a0c9e94b9518f0814 100644 (file)
@@ -32,6 +32,8 @@
 
 #include <SDL/SDL.h>
 #include "fastevents.h"
+#include <SDL/SDL_sound.h>
+#include <AL/alut.h>
 
 #include "Dispatcher.hh"
 #include "Engine.hh"
 namespace Mf {
 
 
-class Engine::EngineImpl
+class Engine::Impl
 {
 public:
-       EngineImpl(int argc, char* argv[], const std::string& configFile,
+       Impl(int argc, char* argv[], const std::string& configFile,
                        const std::string& name, const std::string& iconFile,
                        Engine* outer) :
                interface(outer),
@@ -61,18 +63,18 @@ public:
                {
                        throw Exception(FE_GetError());
                }
+               if (Sound_Init() != 0)
+               {
+                       //throw Exception(Sound_GetError());
+                       std::cerr << Sound_GetError() << std::endl;
+               }
+               alutInit(&argc, argv);
 
                settings.loadFromFile(configFile);
 
                long randomSeed;
-               if (settings.get("engine.rngseed", randomSeed))
-               {
-                       setSeed(randomSeed);
-               }
-               else
-               {
-                       setSeed();
-               }
+               if (settings.get("engine.rngseed", randomSeed)) setSeed(randomSeed);
+               else setSeed();
 
                double ts = 0.01;
                settings.get("engine.timestep", ts);
@@ -89,11 +91,13 @@ public:
                video->makeActive();
        }
 
-       ~EngineImpl()
+       ~Impl()
        {
                // the video object must be destroyed before we can shutdown SDL
                video.reset();
 
+               alutExit();
+               Sound_Quit();
                FE_Quit();
                SDL_Quit();
        }
@@ -232,8 +236,7 @@ public:
 
 Engine::Engine(int argc, char* argv[], const std::string& configFile,
                const std::string& name, const std::string& iconFile) :
-       impl_(new Engine::EngineImpl(argc, argv, configFile, name, iconFile, this))
-{}
+       impl_(new Engine::Impl(argc, argv, configFile, name, iconFile, this)) {}
 
 Engine::~Engine() {}
 
index 76120c49c890b45bba4beb618504f3ea76403df2..971d68fe1e28eb59e3536056dd19c4355ec0668c 100644 (file)
@@ -75,8 +75,8 @@ public:
        };
 
 private:
-       class EngineImpl;
-       boost::shared_ptr<EngineImpl> impl_;
+       class Impl;
+       boost::shared_ptr<Impl> impl_;
 };
 
 
index 26c4b5180dc61395c97752bd133b606de9285b10..a38af8b049dd77357c175aa79ecb2c5d5969c810 100644 (file)
@@ -68,12 +68,27 @@ inline Vector3& demoteVector(Vector3& left, const Vector4& right)
        return left;
 }
 
-inline Vector4& promoteVector(Vector4& left, const Vector3& right)
+inline Vector2& demoteVector(Vector2& left, const Vector3& right)
+{
+       left[0] = right[0];
+       left[1] = right[1];
+       return left;
+}
+
+inline Vector4& promoteVector(Vector4& left, const Vector3& right, Scalar extra = 1.0)
 {
        left[0] = right[0];
        left[1] = right[1];
        left[2] = right[2];
-       left[3] = 1.0;
+       left[3] = extra;
+       return left;
+}
+
+inline Vector3& promoteVector(Vector3& left, const Vector2& right, Scalar extra = 1.0)
+{
+       left[0] = right[0];
+       left[1] = right[1];
+       left[3] = extra;
        return left;
 }
 
index 7058eccf76214911933a61a7d3fca5a07de4fcf9..9ef960276b34a8d9384557d2b2a8d690c36d7488 100644 (file)
  * after the last interested code releases its hold on the object.
  */
 
-#include <Moof/Hash.hh>
 #include <string>
 
+#include <Moof/Hash.hh>
+
+
 namespace Mf {
 
 
diff --git a/src/Moof/Octree.cc b/src/Moof/Octree.cc
new file mode 100644 (file)
index 0000000..50b38ac
--- /dev/null
@@ -0,0 +1,320 @@
+
+/*******************************************************************************
+
+ 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 "Camera.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();
+       }
+}
+
+
+stlplus::ntree<OctreeNode>::iterator Octree::insert(stlplus::ntree<OctreeNode>::iterator node,
+               EntityPtr entity)
+{
+       Plane::Halfspace halfspace;
+       int octantNum = -1;
+
+       if (!node.valid())
+       {
+               std::cerr << "cannot insert into invalid node" << std::endl;
+               return stlplus::ntree<OctreeNode>::iterator();
+       }
+
+       Plane xy = node->getAabb().getPlaneXY();
+       halfspace = xy.intersectsSphere(entity->getSphere());
+       if (halfspace == Plane::INTERSECT)
+       {
+               halfspace = xy.intersectsAabb(entity->getAabb());
+       }
+
+       if (halfspace == Plane::POSITIVE)
+       {
+               Plane xz = node->getAabb().getPlaneXZ();
+               halfspace = xz.intersectsSphere(entity->getSphere());
+               if (halfspace == Plane::INTERSECT)
+               {
+                       halfspace = xz.intersectsAabb(entity->getAabb());
+               }
+
+               if (halfspace == Plane::POSITIVE)
+               {
+                       Plane yz = node->getAabb().getPlaneYZ();
+                       halfspace = yz.intersectsSphere(entity->getSphere());
+                       if (halfspace == Plane::INTERSECT)
+                       {
+                               halfspace = yz.intersectsAabb(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.intersectsSphere(entity->getSphere());
+                       if (halfspace == Plane::INTERSECT)
+                       {
+                               halfspace = yz.intersectsAabb(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.intersectsSphere(entity->getSphere());
+               if (halfspace == Plane::INTERSECT)
+               {
+                       halfspace = xz.intersectsAabb(entity->getAabb());
+               }
+
+               if (halfspace == Plane::POSITIVE)
+               {
+                       Plane yz = node->getAabb().getPlaneYZ();
+                       halfspace = yz.intersectsSphere(entity->getSphere());
+                       if (halfspace == Plane::INTERSECT)
+                       {
+                               halfspace = yz.intersectsAabb(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.intersectsSphere(entity->getSphere());
+                       if (halfspace == Plane::INTERSECT)
+                       {
+                               halfspace = yz.intersectsAabb(entity->getAabb());
+                       }
+
+                       if (halfspace == Plane::POSITIVE)
+                       {
+                               octantNum = 5;
+                       }
+                       else if (halfspace == Plane::NEGATIVE)
+                       {
+                               octantNum = 4;
+                       }
+               }
+       }
+
+       if (octantNum == -1)
+       {
+               node->objects.push_front(entity);
+               return node;
+       }
+       else
+       {
+               if ((int)tree_.children(node) <= octantNum)
+               {
+                       addChild(node, octantNum);
+               }
+
+               stlplus::ntree<OctreeNode>::iterator child = tree_.child(node, octantNum);
+
+               if (child.valid())
+               {
+                       return insert(child, entity);
+               }
+               else
+               {
+                       std::cerr << "expected but found no child at index " << octantNum << std::endl;
+                       return stlplus::ntree<OctreeNode>::iterator();
+               }
+       }
+}
+
+stlplus::ntree<OctreeNode>::iterator Octree::reinsert(EntityPtr entity,
+               stlplus::ntree<OctreeNode>::iterator node)
+{
+       if (!node.valid())
+       {
+               std::cerr << "cannot move entity from invalid node" << std::endl;
+               return stlplus::ntree<OctreeNode>::iterator();
+       }
+
+       std::list<EntityPtr>::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(stlplus::ntree<OctreeNode>::iterator node, int index)
+{
+       Aabb octant;
+
+       if (!node.valid())
+       {
+               std::cerr << "cannot add children to invalid node" << std::endl;
+               return;
+       }
+
+       for (int i = tree_.children(node); i <= index; ++i)
+       {
+               node->getAabb().getOctant(octant, i);
+               tree_.append(node, octant);
+       }
+}
+
+
+void Octree::draw(stlplus::ntree<OctreeNode>::iterator node, Scalar alpha)
+{
+       if (!node.valid())
+       {
+               std::cerr << "cannot draw null child node :-(" << std::endl;
+               return;
+       }
+
+       node->draw(alpha);
+
+       for (unsigned i = 0; i < tree_.children(node); ++i)
+       {
+               stlplus::ntree<OctreeNode>::iterator child = tree_.child(node, i);
+
+               if (child.valid())
+               {
+                       draw(child, alpha);
+               }
+               else
+               {
+                       std::cerr << "node is not a leaf, but has an invalid child" << std::endl;
+               }
+
+       }
+}
+
+void Octree::drawIfVisible(stlplus::ntree<OctreeNode>::iterator node,
+               Scalar alpha, const Camera& cam)
+{
+       //node.drawIfVisible(alpha, cam);
+       
+       if (!node.valid())
+       {
+               std::cerr << "invalid child while drawing :-(" << std::endl;
+               return;
+       }
+
+       Frustum::Collision collision =
+               cam.getFrustum().containsSphere(node->getSphere());
+       if (collision == Frustum::OUTSIDE) return;
+
+       collision = cam.getFrustum().containsAabb(node->getAabb());
+       if (collision == Frustum::OUTSIDE) return;
+
+
+       if (collision == Frustum::INSIDE)
+       {
+               node->draw(alpha);
+       }
+       else // collision == Frustum::INTERSECT
+       {
+               node->drawIfVisible(alpha, cam);
+       }
+
+       if (tree_.children(node) > 0)
+       {
+               if (collision == Frustum::INSIDE)
+               {
+                       for (unsigned i = 0; i < tree_.children(node); ++i)
+                       {
+                               stlplus::ntree<OctreeNode>::iterator child = tree_.child(node, i);
+
+                               if (child.valid())
+                               {
+                                       draw(child, alpha);
+                               }
+                               else
+                               {
+                                       std::cerr << "node is not a leaf, but has an invalid child" << std::endl;
+                               }
+
+                       }
+               }
+               else // collision == Frustum::INTERSECT
+               {
+                       for (unsigned i = 0; i < tree_.children(node); ++i)
+                       {
+                               stlplus::ntree<OctreeNode>::iterator child = tree_.child(node, i);
+
+                               if (child.valid())
+                               {
+                                       drawIfVisible(child, alpha, cam);
+                               }
+                               else
+                               {
+                                       std::cerr << "node is not a leaf, but has an invalid child" << std::endl;
+                               }
+                       }
+               }
+       }
+}
+
+
+} // namespace Mf
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
index 1c57ff2d3317fe83d10aa6972093683cb634556f..d896844f0379a4ab7ca1cebe32d52cb5a719a775 100644 (file)
@@ -29,6 +29,7 @@
 #ifndef _MOOF_OCTREE_HH_
 #define _MOOF_OCTREE_HH_
 
+#include <algorithm>
 #include <list>
 
 #include <boost/shared_ptr.hpp>
@@ -45,6 +46,9 @@
 namespace Mf {
 
 
+class Camera;
+
+
 struct OctreeNode : public Entity
 {
        std::list<EntityPtr> objects;
@@ -71,8 +75,9 @@ struct OctreeNode : public Entity
                {
                        (*it)->draw(alpha);
                }
-               if (!objects.empty())
-                       aabb_.draw(); // temporary
+
+               //if (!objects.empty())
+                       //aabb_.draw(); // temporary
        }
 
        void drawIfVisible(Scalar alpha, const Camera& cam) const
@@ -83,8 +88,9 @@ struct OctreeNode : public Entity
                {
                        (*it)->drawIfVisible(alpha, cam);
                }
-               if (!objects.empty())
-                       aabb_.draw();
+
+               //if (!objects.empty())
+                       //aabb_.draw();
        }
 
 
@@ -97,257 +103,58 @@ struct OctreeNode : public Entity
 
                return false;
        }
-};
 
 
-class Octree;
-typedef boost::shared_ptr<Octree> OctreePtr;
+       static bool compareZOrder(EntityPtr a, EntityPtr b)
+       {
+               return a->getSphere().point[2] < b->getSphere().point[2];
+       }
 
-class Octree
-{
+       void sort()
+       {
+               //std::sort(objects.begin(), objects.end(), compareZOrder);
+               objects.sort(compareZOrder);
+       }
+};
 
-       stlplus::ntree<OctreeNode> root_;
 
+class Octree
+{
 public:
 
        explicit Octree(const OctreeNode& rootNode)
        {
-               root_.insert(rootNode);
+               tree_.insert(rootNode);
        }
 
-       void insert(EntityPtr entity)
+       stlplus::ntree<OctreeNode>::iterator insert(EntityPtr entity)
        {
-               insert(root_.root(), entity);
+               return insert(tree_.root(), entity);
        }
 
-       void insert(stlplus::ntree<OctreeNode>::iterator node, EntityPtr entity)
-       {
-               Plane::Halfspace halfspace;
-               int octantNum = -1;
+       stlplus::ntree<OctreeNode>::iterator reinsert(EntityPtr entity,
+                       stlplus::ntree<OctreeNode>::iterator node);
 
-               if (!node.valid())
-               {
-                       std::cerr << "cannot insert into invalid node" << std::endl;
-                       return;
-               }
-
-               Plane xy = node->getAabb().getPlaneXY();
-               halfspace = xy.intersectsSphere(entity->getSphere());
-
-               if (halfspace == Plane::POSITIVE)
-               {
-                       Plane xz = node->getAabb().getPlaneXZ();
-                       halfspace = xz.intersectsSphere(entity->getSphere());
-
-                       if (halfspace == Plane::POSITIVE)
-                       {
-                               Plane yz = node->getAabb().getPlaneYZ();
-                               halfspace = yz.intersectsSphere(entity->getSphere());
-
-                               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.intersectsSphere(entity->getSphere());
-
-                               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.intersectsSphere(entity->getSphere());
-
-                       if (halfspace == Plane::POSITIVE)
-                       {
-                               Plane yz = node->getAabb().getPlaneYZ();
-                               halfspace = yz.intersectsSphere(entity->getSphere());
-
-                               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.intersectsSphere(entity->getSphere());
-
-                               if (halfspace == Plane::POSITIVE)
-                               {
-                                       octantNum = 5;
-                               }
-                               else if (halfspace == Plane::NEGATIVE)
-                               {
-                                       octantNum = 4;
-                               }
-                       }
-               }
-
-               if (octantNum == -1)
-               {
-                       node->objects.push_front(entity);
-                       //return node;
-               }
-               else
-               {
-                       if (root_.children(node) == 0)
-                       {
-                               addChildren(node);
-                       }
-
-                       stlplus::ntree<OctreeNode>::iterator child = root_.child(node, octantNum);
-
-                       if (child.valid())
-                       {
-                               return insert(child, entity);
-                       }
-                       else
-                       {
-                               std::cerr << "expected but found no child at index " << octantNum << std::endl;
-                               //return stlplus::ntree<OctreeNode>::iterator();
-                       }
-                       //return WeakPtr();
-               }
-       }
-
-       void addChildren(stlplus::ntree<OctreeNode>::iterator node)
+       void drawIfVisible(Scalar alpha, const Camera& cam)
        {
-               Aabb octant;
-
-               if (!node.valid())
-               {
-                       std::cerr << "cannot add children to invalid node" << std::endl;
-                       return;
-               }
-
-               for (int i = 0; i < 8; ++i)
-               {
-                       node->getAabb().getOctant(octant, i);
-                       //OctreeNode octantNode(octant);
-
-                       root_.append(node, octant);
-               }
+               drawIfVisible(tree_.root(), alpha, cam);
        }
 
-       void draw(stlplus::ntree<OctreeNode>::iterator node, Scalar alpha)
-       {
-               if (!node.valid())
-               {
-                       std::cerr << "cannot draw null child node :-(" << std::endl;
-                       return;
-               }
+       void sort();
 
-               node->draw(alpha);
-
-               for (unsigned i = 0; i < root_.children(node); ++i)
-               {
-                       stlplus::ntree<OctreeNode>::iterator child = root_.child(node, i);
-
-                       if (child.valid())
-                       {
-                               draw(child, alpha);
-                       }
-                       else
-                       {
-                               std::cerr << "node is not a leaf, but has an invalid child" << std::endl;
-                       }
-
-               }
-       }
+private:
+       stlplus::ntree<OctreeNode>::iterator insert(stlplus::ntree<OctreeNode>::iterator node, EntityPtr entity);
+       
+       void addChild(stlplus::ntree<OctreeNode>::iterator node, int index);
 
+       void draw(stlplus::ntree<OctreeNode>::iterator node, Scalar alpha);
        void drawIfVisible(stlplus::ntree<OctreeNode>::iterator node,
-                       Scalar alpha, const Camera& cam)
-       {
-               //node.drawIfVisible(alpha, cam);
-               
-               if (!node.valid())
-               {
-                       std::cerr << "invalid child while drawing :-(" << std::endl;
-                       return;
-               }
-
-               Frustum::Collision collision =
-                       cam.getFrustum().containsSphere(node->getSphere());
-               if (collision == Frustum::OUTSIDE) return;
-
-               collision = cam.getFrustum().containsAabb(node->getAabb());
-               if (collision == Frustum::OUTSIDE) return;
-
-
-               if (collision == Frustum::INSIDE)
-               {
-                       node->draw(alpha);
-               }
-               else // collision == Frustum::INTERSECT
-               {
-                       node->drawIfVisible(alpha, cam);
-               }
-
-               if (root_.children(node) > 0)
-               {
-                       if (collision == Frustum::INSIDE)
-                       {
-                               for (unsigned i = 0; i < root_.children(node); ++i)
-                               {
-                                       stlplus::ntree<OctreeNode>::iterator child = root_.child(node, i);
-
-                                       if (child.valid())
-                                       {
-                                               draw(child, alpha);
-                                       }
-                                       else
-                                       {
-                                               std::cerr << "node is not a leaf, but has an invalid child" << std::endl;
-                                       }
-
-                               }
-                       }
-                       else // collision == Frustum::INTERSECT
-                       {
-                               for (unsigned i = 0; i < root_.children(node); ++i)
-                               {
-                                       stlplus::ntree<OctreeNode>::iterator child = root_.child(node, i);
-
-                                       if (child.valid())
-                                       {
-                                               drawIfVisible(child, alpha, cam);
-                                       }
-                                       else
-                                       {
-                                               std::cerr << "node is not a leaf, but has an invalid child" << std::endl;
-                                       }
-                               }
-                       }
-               }
-       }
-
-       void drawIfVisible(Scalar alpha, const Camera& cam)
-       {
-               drawIfVisible(root_.root(), alpha, cam);
-       }
+                       Scalar alpha, const Camera& cam);
 
+       stlplus::ntree<OctreeNode> tree_;
 };
 
+typedef boost::shared_ptr<Octree> OctreePtr;
 
 
 } // namespace Mf
index e3e742b97c515d2a8ab2d58d1a1f57e12e3bc6d3..b286b35a0a5951f37b9e78561fa61cf934a08bc8 100644 (file)
@@ -52,6 +52,13 @@ void (*glVertex2v)(const GLscalar*)(glVertex2dv);
 void (*glVertex3v)(const GLscalar*)(glVertex3dv);
 void (*glVertex4v)(const GLscalar*)(glVertex4dv);
 
+void (*glTexCoord2)(GLscalar, GLscalar)(glTexCoord2d);
+void (*glTexCoord3)(GLscalar, GLscalar, GLscalar)(glTexCoord3d);
+void (*glTexCoord4)(GLscalar, GLscalar, GLscalar, GLscalar)(glTexCoord4d);
+void (*glTexCoord2v)(const GLscalar*)(glTexCoord2dv);
+void (*glTexCoord3v)(const GLscalar*)(glTexCoord3dv);
+void (*glTexCoord4v)(const GLscalar*)(glTexCoord4dv);
+
 #else
 
 void (*glGetScalarv(GLenum, GLscalar*)(glGetFloatv);
@@ -63,6 +70,11 @@ void (*glScale)(GLscalar, GLscalar, GLscalar)(glScalef);
 void (*glRotate)(GLscalar, GLscalar, GLscalar, GLscalar)(glRotatef);
 void (*glTranslate)(GLscalar, GLscalar, GLscalar)(glTranslatef);
 
+void (*glColor3)(GLscalar, GLscalar, GLscalar)(glColor3f);
+void (*glColor4)(GLscalar, GLscalar, GLscalar, GLscalar)(glColor4f);
+void (*glColor3v)(const GLscalar*)(glColor3fv);
+void (*glColor4v)(const GLscalar*)(glColor4fv);
+
 void (*glVertex2)(GLscalar, GLscalar)(glVertex2f);
 void (*glVertex3)(GLscalar, GLscalar, GLscalar)(glVertex3f);
 void (*glVertex4)(GLscalar, GLscalar, GLscalar, GLscalar)(glVertex4f);
@@ -70,10 +82,12 @@ void (*glVertex2v)(const GLscalar*)(glVertex2fv);
 void (*glVertex3v)(const GLscalar*)(glVertex3fv);
 void (*glVertex4v)(const GLscalar*)(glVertex4fv);
 
-void (*glColor3)(GLscalar, GLscalar, GLscalar)(glColor3f);
-void (*glColor4)(GLscalar, GLscalar, GLscalar, GLscalar)(glColor4f);
-void (*glColor3v)(const GLscalar*)(glColor3fv);
-void (*glColor4v)(const GLscalar*)(glColor4fv);
+void (*glTexCoord2)(GLscalar, GLscalar)(glTexCoord2f);
+void (*glTexCoord3)(GLscalar, GLscalar, GLscalar)(glTexCoord3f);
+void (*glTexCoord4)(GLscalar, GLscalar, GLscalar, GLscalar)(glTexCoord4f);
+void (*glTexCoord2v)(const GLscalar*)(glTexCoord2df);
+void (*glTexCoord3v)(const GLscalar*)(glTexCoord3df);
+void (*glTexCoord4v)(const GLscalar*)(glTexCoord4df);
 
 #endif
 
index 657f05f68fb22eb53ab7992e619604b6d69f085e..51c3e5f57cb3c639d3a033a6f154816fec3dfadb 100644 (file)
@@ -70,6 +70,14 @@ extern void (*glVertex2v)(const GLscalar*);
 extern void (*glVertex3v)(const GLscalar*);
 extern void (*glVertex4v)(const GLscalar*);
 
+extern void (*glTexCoord2)(GLscalar, GLscalar);
+extern void (*glTexCoord3)(GLscalar, GLscalar, GLscalar);
+extern void (*glTexCoord4)(GLscalar, GLscalar, GLscalar, GLscalar);
+extern void (*glTexCoord2v)(const GLscalar*);
+extern void (*glTexCoord3v)(const GLscalar*);
+extern void (*glTexCoord4v)(const GLscalar*);
+
+
 
 #endif // _MOOF_OPENGL_HH_
 
diff --git a/src/Moof/Physics.hh b/src/Moof/Physics.hh
new file mode 100644 (file)
index 0000000..a79a5c3
--- /dev/null
@@ -0,0 +1,75 @@
+
+/*******************************************************************************
+
+ 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_PHYSICS_HH_
+#define _MOOF_PHYSICS_HH_
+
+#include <Moof/Math.hh>
+
+
+namespace Mf {
+
+// Generic implementation of the RK4 integrator.  To use, you need one type
+// representing the state and another containing the derivatives of the state.
+
+template<typename S, typename D>
+inline D evaluate(const S& state, Scalar t)
+{
+       D derivative;
+       state.getDerivative(derivative, t);
+       return derivative;
+}
+
+template<typename S, typename D>
+inline D evaluate(const S& state,  Scalar t, Scalar dt, const D& derivative)
+{
+       S temp = state;
+       temp.applyDerivative(derivative, dt);
+       return evaluate<S,D>(temp, t + dt);
+}
+
+
+template<typename S, typename D>
+inline void integrate(S& state, Scalar t, Scalar dt)
+{
+       D a = evaluate<S,D>(state, t);
+       D b = evaluate<S,D>(state, t, dt * 0.5, a);
+       D c = evaluate<S,D>(state, t, dt * 0.5, b);
+       D d = evaluate<S,D>(state, t, dt, c);
+
+       //state += (a + (b + c) * 2.0 + d) * (1.0/6.0) * dt;
+       state.applyDerivative((a + (b + c) * 2.0 + d) * (1.0/6.0), dt);
+}
+
+
+} // namespace Mf
+
+#endif // _MOOF_PHYSICS_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
diff --git a/src/Moof/Rectangle.cc b/src/Moof/Rectangle.cc
new file mode 100644 (file)
index 0000000..fef6ac4
--- /dev/null
@@ -0,0 +1,51 @@
+
+/*******************************************************************************
+
+ 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 "Rectangle.hh"
+
+
+namespace Mf {
+
+
+void Rectangle::getCorners(Vector2 corners[4]) const
+{
+       corners[0][0] = min[0]; corners[0][1] = min[1];
+       corners[1][0] = max[0]; corners[1][1] = min[1];
+       corners[2][0] = max[0]; corners[2][1] = max[1];
+       corners[3][0] = min[0]; corners[3][1] = max[1];
+       corners[4][0] = min[0]; corners[4][1] = min[1];
+       corners[5][0] = max[0]; corners[5][1] = min[1];
+       corners[6][0] = max[0]; corners[6][1] = max[1];
+       corners[7][0] = min[0]; corners[7][1] = max[1];
+}
+
+
+} // namespace Mf
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
diff --git a/src/Moof/Rectangle.hh b/src/Moof/Rectangle.hh
new file mode 100644 (file)
index 0000000..97bb44a
--- /dev/null
@@ -0,0 +1,102 @@
+
+/*******************************************************************************
+
+ 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_RECTANGLE_HH_
+#define _MOOF_RECTANGLE_HH_
+
+#include <Moof/Math.hh>
+
+
+namespace Mf {
+
+
+/**
+ * Axis-aligned Bounding Box
+ */
+
+struct Rectangle
+{
+       Vector2 min;
+       Vector2 max;
+
+
+       Rectangle() {}
+
+       Rectangle(const Vector2& a, const Vector2& b)
+       {
+               init(a, b);
+       }
+
+       Rectangle(Scalar ax, Scalar ay, Scalar bx, Scalar by)
+       {
+               Vector2 a(ax, ay);
+               Vector2 b(bx, by);
+
+               init(a, b);
+       }
+
+       inline void init(const Vector2& a, const Vector2& b)
+       {
+               if (a[0] < b[0])
+               {
+                       min[0] = a[0];
+                       max[0] = b[0];
+               }
+               else
+               {
+                       min[0] = b[0];
+                       max[0] = a[0];
+               }
+               if (a[1] < b[1])
+               {
+                       min[1] = a[1];
+                       max[1] = b[1];
+               }
+               else
+               {
+                       min[1] = b[1];
+                       max[1] = a[1];
+               }
+       }
+
+       inline Vector2 getCenter() const
+       {
+               return Vector2((min[0] + max[0]) / 2.0,
+                                          (min[1] + max[1]) / 2.0);
+       }
+
+       void getCorners(Vector2 corners[4]) const;
+};
+
+
+} // namespace Mf
+
+#endif // _MOOF_RECTANGLE_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
index e21c834e869ce4bc78debe11c0c57d618ab7313e..d958c3aa9e551cc584d9fe14fe02cf3275846041 100644 (file)
@@ -54,7 +54,7 @@ void Resource::addSearchPath(const std::string& directory)
        }
 }
 
-std::string Resource::getPathToResource(const std::string& name)
+std::string Resource::getPath(const std::string& name)
 {
        std::vector<std::string>::iterator it;
 
index 716e906e03f4c1f53d1ae0b3ba44ace3b3f3ba0b..f7d17824dc2c6d162cd8ff4c3ddb2d3a1971950d 100644 (file)
@@ -72,7 +72,7 @@ public:
         * @return The first path found which resolves to a file.
         */
 
-       static std::string getPathToResource(const std::string& name);
+       static std::string getPath(const std::string& name);
 
 private:
        static std::vector<std::string> searchPaths_;
diff --git a/src/Moof/RigidBody.hh b/src/Moof/RigidBody.hh
new file mode 100644 (file)
index 0000000..11c6354
--- /dev/null
@@ -0,0 +1,72 @@
+
+/*******************************************************************************
+
+ 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_RIGIDBODY_HH_
+#define _MOOF_RIGIDBODY_HH_
+
+#include <Moof/Math.hh>
+#include <Moof/State.hh>
+
+
+namespace Mf {
+
+
+/**
+ * Interface for physical things with mass, momentum, yada yada yada.
+ */
+
+template <typename T>
+class RigidBody
+{
+public:
+       inline virtual ~RigidBody() {}
+
+       virtual void update(Scalar t, Scalar dt)
+       {
+               prevState_ = currentState_;
+               currentState_.integrate(t, dt);
+       }
+
+       inline T getInterpolatedState(Scalar alpha) const
+       {
+               return currentState_.interpolate(alpha, prevState_);
+       }
+
+protected:
+       T prevState_;
+       T currentState_;
+};
+
+
+} // namespace Mf
+
+#endif // _MOOF_RIGIDBODY_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
+
index 6c2b42715f70c767d0a74516dec05a8965692d2f..5e44221a93391a03afacb4b4059fe30ca47ffa37 100644 (file)
@@ -36,7 +36,6 @@
 #include "Entity.hh"
 #include "Math.hh"
 #include "Mippleton.hh"
-#include "Octree.hh"
 #include "OpenGL.hh"
 #include "Scene.hh"
 #include "Serializable.hh"
@@ -46,7 +45,7 @@
 namespace Mf {
 
 
-class Scene::SceneImpl : public Mippleton<SceneImpl>
+class Scene::Impl : public Mippleton<Impl>
 {
        class Quad : public Entity
        {
@@ -99,6 +98,12 @@ class Scene::SceneImpl : public Mippleton<SceneImpl>
                                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();
 
@@ -108,6 +113,7 @@ class Scene::SceneImpl : public Mippleton<SceneImpl>
                        glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
 
                        glDisable(GL_BLEND);
+                       glDisable(GL_FOG);
                }
 
                bool isVisible(const Camera& cam) const
@@ -145,8 +151,8 @@ class Scene::SceneImpl : public Mippleton<SceneImpl>
        }
 
 public:
-       SceneImpl(const std::string& name) :
-               Mippleton<SceneImpl>(name)
+       Impl(const std::string& name) :
+               Mippleton<Impl>(name)
        {
                loadFromFile();
        }
@@ -380,7 +386,6 @@ public:
                                Quad* quad = new Quad(quadVertices, texture, indices[h][w]);
                                boost::shared_ptr<Quad> quadPtr(quad);
 
-                               //objects.push_back(quadPtr);
                                octree->insert(quadPtr);
                        }
                }
@@ -392,39 +397,36 @@ public:
                std::map<std::string,SerializablePtr> rootObj;
                std::map<std::string,SerializablePtr>::iterator it;
 
-               if (!root->get(rootObj))
-               {
-                       std::cerr << "error loading scene billboard object" << std::endl;
-                       return;
-               }
-
                Tilemap::Index  index = 0;
                long                    width = 1;
                bool                    blending = false;
                bool                    fog = false;
 
-               if ((it = rootObj.find("tile")) != rootObj.end())
+               if (root->get(rootObj))
                {
-                       long value;
-                       if ((*it).second->get(value))
+                       if ((it = rootObj.find("tile")) != rootObj.end())
                        {
-                               index = Tilemap::Index(value);
+                               long value;
+                               if ((*it).second->get(value))
+                               {
+                                       index = Tilemap::Index(value);
+                               }
                        }
-               }
 
-               if ((it = rootObj.find("u_scale")) != rootObj.end())
-               {
-                       (*it).second->get(width);
-               }
+                       if ((it = rootObj.find("u_scale")) != rootObj.end())
+                       {
+                               (*it).second->get(width);
+                       }
 
-               if ((it = rootObj.find("blend")) != rootObj.end())
-               {
-                       (*it).second->get(blending);
-               }
+                       if ((it = rootObj.find("blend")) != rootObj.end())
+                       {
+                               (*it).second->get(blending);
+                       }
 
-               if ((it = rootObj.find("fog")) != rootObj.end())
-               {
-                       (*it).second->get(fog);
+                       if ((it = rootObj.find("fog")) != rootObj.end())
+                       {
+                               (*it).second->get(fog);
+                       }
                }
 
 
@@ -461,7 +463,6 @@ public:
 
                        boost::shared_ptr<Quad> quadPtr(quad);
 
-                       //objects.push_back(quad_Ptr);
                        octree->insert(quadPtr);
                }
        }
@@ -469,7 +470,7 @@ public:
 
        void loadFromFile()
        {
-               std::string filePath = Scene::getPathToResource(getName());
+               std::string filePath = Scene::getPath(getName());
 
                Deserializer    deserializer(filePath, true);
                SerializablePtr root = deserializer.deserialize();
@@ -497,67 +498,50 @@ public:
                        return;
                }
 
-               //OctreeNode rootNode(maximumBounds);
+               // create the tree to store the quads
                octree = OctreePtr(new Octree(maximumBounds));
 
                if ((it = rootObj.find("instructions")) != rootObj.end())
                {
                        loadInstructions((*it).second);
                }
+
+               octree->sort();
        }
 
 
        void draw(Scalar alpha, const Camera& cam) const
        {
-               //QuadVector::const_iterator it;
-
                glEnableClientState(GL_VERTEX_ARRAY);
                glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
                octree->drawIfVisible(alpha, cam);
 
-               //int objectsDrawn = 0;
+               //glDisableClientState(GL_VERTEX_ARRAY);
+               //glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 
-               //for (it = objects.begin(); it != objects.end(); ++it)
-               //{
-                       //if ((*it)->isVisible(cam))
-                       //{
-                               ////std::cout << "draw object";
-                               //(*it)->draw();
+               //glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
-                               //objectsDrawn++;
-                       //}
-               //}
+               //Texture::resetBind();
+               //glColor3f(0.0f, 1.0f, 0.0f);
+               //playfieldBounds.draw();
+               //glColor3f(0.0f, 0.0f, 1.0f);
+               //maximumBounds.draw();
 
-               //std::cout << objectsDrawn << std::endl;
-
-               glDisableClientState(GL_VERTEX_ARRAY);
-               glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
-               glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
-
-               Texture::resetBind();
-               glColor3f(0.0f, 1.0f, 0.0f);
-               playfieldBounds.draw();
-               glColor3f(0.0f, 0.0f, 1.0f);
-               maximumBounds.draw();
-
-               glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+               //glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
        }
 
 
        Aabb playfieldBounds;
        Aabb maximumBounds;
 
-       //typedef std::vector< boost::shared_ptr<Quad> > QuadVector;
-       //QuadVector objects;
        OctreePtr octree;
 };
 
 
 Scene::Scene(const std::string& name) :
        // pass through
-       impl_(Scene::SceneImpl::retain(name), &Scene::SceneImpl::release) {}
+       impl_(Scene::Impl::retain(name), &Scene::Impl::release) {}
 
 
 void Scene::draw(Scalar alpha, const Camera& cam) const
@@ -573,14 +557,20 @@ void Scene::refresh()
 }
 
 
+OctreePtr Scene::getOctree() const
+{
+       // pass through
+       return impl_->octree;
+}
+
 /**
  * Specialized search location for scene files.  They can be found in the
  * "scenes" subdirectory of any of the searched directories.
  */
 
-std::string Scene::getPathToResource(const std::string& name)
+std::string Scene::getPath(const std::string& name)
 {
-       return Resource::getPathToResource("scenes/" + name + ".json");
+       return Resource::getPath("scenes/" + name + ".json");
 }
 
 
index 08ab6cc2441c7f58497fa01bffbe42853fb80e4c..4c4f29775b2ae21033fb69e8e9017b2ee542c5ff 100644 (file)
@@ -34,6 +34,7 @@
 #include <boost/shared_ptr.hpp>
 
 #include <Moof/Drawable.hh>
+#include <Moof/Octree.hh>
 #include <Moof/Resource.hh>
 
 
@@ -50,11 +51,13 @@ public:
        void draw(Scalar alpha, const Camera& cam) const;
        void refresh();
 
-       static std::string getPathToResource(const std::string& name);
+       OctreePtr getOctree() const;
+
+       static std::string getPath(const std::string& name);
 
 private:
-       class SceneImpl;
-       boost::shared_ptr<SceneImpl> impl_;
+       class Impl;
+       boost::shared_ptr<Impl> impl_;
 };
 
 
diff --git a/src/Moof/Sound.cc b/src/Moof/Sound.cc
new file mode 100644 (file)
index 0000000..9a632eb
--- /dev/null
@@ -0,0 +1,194 @@
+
+/*******************************************************************************
+
+ 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 <string>
+
+#include <SDL/SDL.h>
+#include <SDL/SDL_sound.h>
+#include <AL/al.h>
+
+#include "Mippleton.hh"
+#include "Sound.hh"
+
+
+namespace Mf {
+
+
+struct Sound::Impl
+{
+
+       static ALenum getAudioFormat(const Sound_AudioInfo& audioInfo)
+       {
+               if (audioInfo.format == AUDIO_U8 || audioInfo.format == AUDIO_S8)
+               {
+                       if (audioInfo.channels == 1) return AL_FORMAT_MONO8;
+                       else                         return AL_FORMAT_STEREO8;
+               }
+               else
+               {
+                       if (audioInfo.channels == 1) return AL_FORMAT_MONO16;
+                       else                         return AL_FORMAT_STEREO16;
+               }
+       }
+       
+       struct Buffer : public Mippleton<Buffer>
+       {
+               Buffer(const std::string& name) :
+                       Mippleton<Buffer>(name),
+                       object(0)
+               {}
+
+               ~Buffer()
+               {
+                       alDeleteBuffers(1, &object);
+               }
+               void loadFromFile(const std::string& filePath, bool stream)
+               {
+                       if (object != 0) return;
+
+                       Sound_Sample* sound = Sound_NewSampleFromFile(filePath.c_str(),
+                                       NULL, 8096);
+
+                       if (!sound)
+                       {
+                               std::cerr << "could not load sound from file" << std::endl;
+                               exit(1);
+                       }
+
+                       unsigned decoded = Sound_DecodeAll(sound);
+                       if (decoded == 0)
+                       {
+                               std::cout << "decoded no bytes" << std::endl;
+                               exit(1);
+                       }
+                       std::cerr << "buffer size: " << sound->buffer_size << std::endl;
+                       std::cerr << "channels: " << (int)sound->actual.channels << std::endl;
+                       std::cerr << "format: " << sound->actual.format << std::endl;
+                       std::cerr << "frequency: " << sound->actual.rate << std::endl;
+
+                       alGenBuffers(1, &object);
+                       alBufferData(object, getAudioFormat(sound->actual), sound->buffer,
+                                       sound->buffer_size, sound->actual.rate);
+
+                       Sound_FreeSample(sound);
+               }
+
+               ALuint object;
+
+       //ALfloat location[] = {0.0f, 0.0f, 0.0f};
+       //ALfloat location2[] = {0.0f, 0.0f, 0.0f};
+       //ALfloat orient[] = {0.0f, 0.0f, -1.0f, 0.0, 1.0, 0.0};
+
+
+       //alListenerfv(AL_POSITION, location);
+       //alListenerfv(AL_VELOCITY, location);
+       //alListenerfv(AL_VELOCITY, orient);
+       };
+
+       Impl(const std::string& name, bool stream = false) :
+               buffer_(Buffer::retain(name), Buffer::release)
+       {
+               if (!stream) buffer_->loadFromFile(Sound::getPath(name), stream);
+               else         buffer_->loadFromFile(SoundStream::getPath(name), stream);
+
+               ALfloat location[] = {0.0f, 0.0f, 0.0f};
+               
+               alGenSources(1, &source_);
+               alSourcei(source_,  AL_BUFFER, buffer_->object);
+               alSourcef(source_,  AL_PITCH, 1.0f);
+               alSourcef(source_,  AL_GAIN, 1.0f);
+               alSourcefv(source_, AL_POSITION, location);
+               alSourcefv(source_, AL_VELOCITY, location);
+               alSourcei(source_,  AL_LOOPING, AL_FALSE);
+       }
+
+       ~Impl()
+       {
+               alDeleteSources(1, &source_);
+       }
+
+
+       void update()
+       {
+       }
+
+
+       boost::shared_ptr<Buffer>       buffer_;
+       ALuint                                          source_;
+};
+
+
+Sound::Sound(const std::string& name) :
+       // pass through
+       impl_(new Sound::Impl(name)) {}
+
+
+void Sound::play()
+{
+       alSourceRewind(impl_->source_);
+       alSourcePlay(impl_->source_);
+}
+
+
+std::string Sound::getPath(const std::string& name)
+{
+       std::string path = Resource::getPath("sounds/" + name + ".ogg");
+       return path;
+}
+
+
+//##############################################################################
+
+
+SoundStream::SoundStream(const std::string& name)
+       // pass through
+       //impl_(name, true) {}
+{
+       impl_ = boost::shared_ptr<Sound::Impl>(new Sound::Impl(name, true));
+}
+
+
+void SoundStream::update(Scalar t, Scalar dt)
+{
+       // pass through
+       impl_->update();
+}
+
+
+std::string SoundStream::getPath(const std::string& name)
+{
+       std::string path = Resource::getPath("sounds/" + name + ".xm");
+       return path;
+}
+
+
+} // namespace Mf
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
diff --git a/src/Moof/Sound.hh b/src/Moof/Sound.hh
new file mode 100644 (file)
index 0000000..cca7dc7
--- /dev/null
@@ -0,0 +1,86 @@
+
+/*******************************************************************************
+
+ 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_SOUND_HH_
+#define _MOOF_SOUND_HH_
+
+/**
+ * @file Sound.hh
+ * Image-loading and OpenGL texture loading.
+ */
+
+#include <stdexcept>
+
+#include <boost/shared_ptr.hpp>
+
+#include <Moof/Math.hh>
+#include <Moof/Resource.hh>
+
+
+namespace Mf {
+
+
+class Sound : public Resource
+{
+public:
+       Sound(const std::string& name);
+
+       void play();
+
+       static std::string getPath(const std::string& name);
+
+       struct Exception : std::runtime_error
+       {
+               explicit Exception(const std::string& what_arg) :
+                       std::runtime_error(what_arg) {}
+       };
+
+protected:
+       Sound() {}
+       class Impl;
+       boost::shared_ptr<Impl> impl_;
+};
+
+
+class SoundStream : public Sound
+{
+public:
+       SoundStream(const std::string& name);
+
+       void update(Scalar t, Scalar dt);
+
+       static std::string getPath(const std::string& name);
+};
+
+
+} // namespace Mf
+
+#endif // _MOOF_SOUND_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
diff --git a/src/Moof/State.hh b/src/Moof/State.hh
new file mode 100644 (file)
index 0000000..8280edf
--- /dev/null
@@ -0,0 +1,100 @@
+
+/*******************************************************************************
+
+ 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_STATE_HH_
+#define _MOOF_STATE_HH_
+
+#include <Moof/Math.hh>
+
+
+namespace Mf {
+
+
+template <typename T>
+struct Derivative
+{
+       inline virtual ~Derivative() {}
+
+       virtual T operator*(Scalar dt) const = 0;
+       virtual T operator+(const T& other) const = 0;
+};
+
+
+/**
+ * Structure containing any information needed to place and orient an animate
+ * object in 3-space as well as predict future locations and orientations.
+ */
+
+template <typename T, typename D>
+struct State
+{
+       inline virtual ~State() {}
+
+       inline D evaluate(Scalar t)
+       {
+               D derivative;
+               calculateDerivatives(derivative, t);
+               return derivative;
+       }
+
+       inline D evaluate(Scalar t, Scalar dt, const D& derivative)
+       {
+               T state = *this;
+               state += derivative * dt;
+               state.recalculate();
+
+               D newDerivative;
+               calculateDerivatives(newDerivative, t);
+               return newDerivative;
+       }
+
+       inline void integrate(Scalar t, Scalar dt)
+       {
+               D a = evaluate(t);
+               D b = evaluate(t, dt * 0.5, a);
+               D c = evaluate(t, dt * 0.5, b);
+               D d = evaluate(t, dt, c);
+
+               *this += (a + (b + c) * 2.0 + d) * (1.0/6.0) * dt;
+       }
+
+       virtual void recalculate() {}
+
+       virtual void calculateDerivatives(D& derivative, Scalar t) = 0;
+       virtual T interpolate(Scalar alpha, const T& prevState) const = 0;
+
+       virtual T& operator+=(const D& derivative) = 0;
+};
+
+
+} // namespace Mf
+
+#endif // _MOOF_STATE_HH_
+
+/** vim: set ts=4 sw=4 tw=80: *************************************************/
+
index dc9407afc9da1af082ed577da1ab99a6b27bc1e6..e8f5d86d1f2e65fd85d413c5b93b26bfcedc6ac3 100644 (file)
@@ -51,7 +51,7 @@ namespace Mf {
  * objects and avoid having duplicate textures loaded to GL.
  */
 
-class Texture::TextureImpl : public Mippleton<TextureImpl>
+class Texture::Impl : public Mippleton<Impl>
 {
 
        /**
@@ -129,8 +129,8 @@ public:
         * Construction is initialization.
         */
 
-       explicit TextureImpl(const std::string& name) :
-               Mippleton<TextureImpl>(name),
+       explicit Impl(const std::string& name) :
+               Mippleton<Impl>(name),
                surface_(0),
                width_(0),
                height_(0),
@@ -145,10 +145,10 @@ public:
 
                // we want to know when the GL context is recreated
                Dispatcher::instance().addHandler("video.context_recreated",
-                               boost::bind(&TextureImpl::contextRecreated, this, _1), this);
+                               boost::bind(&Impl::contextRecreated, this, _1), this);
        }
 
-       ~TextureImpl()
+       ~Impl()
        {
                if (surface_)
                {
@@ -239,7 +239,7 @@ public:
        {
                SDL_Surface* surface;
 
-               surface = IMG_Load(Texture::getPathToResource(getName()).c_str());
+               surface = IMG_Load(Texture::getPath(getName()).c_str());
 
                if (!surface)
                {
@@ -383,13 +383,12 @@ public:
        static GLuint   globalObject_;  ///< Global GL texture handle.
 };
 
-GLuint Texture::TextureImpl::globalObject_ = 0;
+GLuint Texture::Impl::globalObject_ = 0;
 
 
 Texture::Texture(const std::string& name) :
        // pass through
-       impl_(Texture::TextureImpl::retain(name), &Texture::TextureImpl::release)
-{}
+       impl_(Texture::Impl::retain(name), &Texture::Impl::release) {}
 
 
 /**
@@ -417,7 +416,7 @@ GLuint Texture::getObject() const
 void Texture::resetBind()
 {
        glBindTexture(GL_TEXTURE_2D, 0);
-       TextureImpl::globalObject_ = 0;
+       Impl::globalObject_ = 0;
 }
 
 
@@ -459,10 +458,10 @@ void Texture::setWrapT(GLuint wrap)
 }
 
 
-std::string Texture::getPathToResource(const std::string& name)
+std::string Texture::getPath(const std::string& name)
 {
-       // TODO named texture resources must be png for now
-       return Resource::getPathToResource("textures/" + name + ".png");
+       std::string path = Resource::getPath("textures/" + name + ".png");
+       return path;
 }
 
 
index 9d17eb8f66254dee136d41647eb76263c0d4ed40..cdb6059ceff00d039a41a8b68f6bae45a543f84c 100644 (file)
@@ -63,7 +63,7 @@ public:
        void setWrapS(GLuint wrap);
        void setWrapT(GLuint wrap);
 
-       static std::string getPathToResource(const std::string& name);
+       static std::string getPath(const std::string& name);
 
        struct Exception : std::runtime_error
        {
@@ -72,8 +72,8 @@ public:
        };
 
 private:
-       class TextureImpl;
-       boost::shared_ptr<TextureImpl> impl_;
+       class Impl;
+       boost::shared_ptr<Impl> impl_;
 };
 
 
index 9f24b1bce91547a200bf7de7090f9ce6a8110ca8..17642c723c9fccda03ee36325b14ff917f8b9218 100644 (file)
@@ -36,7 +36,7 @@
 namespace Mf {
 
 
-class Tilemap::TilemapImpl : public Mippleton<TilemapImpl>
+class Tilemap::Impl : public Mippleton<Impl>
 {
        static GLint filterFromString(const std::string& filter)
        {
@@ -75,8 +75,8 @@ class Tilemap::TilemapImpl : public Mippleton<TilemapImpl>
        }
 
 public:
-       TilemapImpl(const std::string& name) :
-               Mippleton<TilemapImpl>(name),
+       Impl(const std::string& name) :
+               Mippleton<Impl>(name),
                magFilter_(GL_NEAREST),
                minFilter_(GL_NEAREST),
                nTilesS_(1),
@@ -89,7 +89,7 @@ public:
 
        void loadFromFile()
        {
-               Deserializer deserializer(Tilemap::getPathToResource(getName()));
+               Deserializer deserializer(Tilemap::getPath(getName()));
 
                SerializablePtr root = deserializer.deserialize();
 
@@ -164,10 +164,8 @@ public:
 
 Tilemap::Tilemap(const std::string& name) :
        Texture(name),
-       impl_(Tilemap::TilemapImpl::retain(name), &Tilemap::TilemapImpl::release)
+       impl_(Tilemap::Impl::retain(name), &Tilemap::Impl::release)
 {
-       bind();
-
        setMinFilter(impl_->minFilter_);
        setMagFilter(impl_->magFilter_);
        setWrapS(impl_->wrapS_);
@@ -225,9 +223,9 @@ bool Tilemap::getTileCoords(unsigned index, Scalar coords[8],
 }
 
 
-std::string Tilemap::getPathToResource(const std::string& name)
+std::string Tilemap::getPath(const std::string& name)
 {
-       return Resource::getPathToResource("tilemaps/" + name + ".json");
+       return Resource::getPath("tilemaps/" + name + ".json");
 }
 
 
index 80bede9a10967d0ca38e79cdfb2739e537f57a67..942a5e9c899d42ef6152a9fc7df8402ded3050d2 100644 (file)
@@ -97,11 +97,11 @@ public:
        bool getTileCoords(Index index, Scalar coords[8], Orientation what) const;
 
 
-       static std::string getPathToResource(const std::string& name);
+       static std::string getPath(const std::string& name);
 
 private:
-       class TilemapImpl;
-       boost::shared_ptr<TilemapImpl> impl_;
+       class Impl;
+       boost::shared_ptr<Impl> impl_;
 };
 
 
index 493e6157cad7bdc2347f820cb26a1c1d406bbc39..a1c2dbbf8133f273e2aca98efdf2dc3f8db133ef 100644 (file)
 
 #include "YoinkApp.hh"
 
+#include <SDL/SDL_sound.h>
+#include <AL/al.h>
+#include <AL/alut.h>
+
 #if HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -94,42 +98,45 @@ static std::string iconFile()
        // then look in the configured data directory
        Mf::Resource::addSearchPath(YOINK_DATADIR);
 
-       return Mf::Resource::getPathToResource("yoink.png");
+       return Mf::Resource::getPath("yoink.png");
 }
 
 
 YoinkApp::YoinkApp(int argc, char* argv[]) :
-       Mf::Engine(argc, argv, configFiles(), PACKAGE_STRING, iconFile())
+       Mf::Engine(argc, argv, configFiles(), PACKAGE_STRING, iconFile()),
+       music("NightFusion"),
+       punchSound("RobotPunch")
 {
        Mf::Dispatcher::instance().addHandler("video.context_recreated",
                        boost::bind(&YoinkApp::contextRecreated, this, _1), this);
        setupGL();
 
+       music.play();
+
        state = 0.0;
 
-       someChar = new Character("RobotTrooper");
-       someChar->getAnimation().startSequence("Run");
+       heroine = CharacterPtr(new Character("RobotTrooper"));
+       heroine->getAnimation().startSequence("Run");
 
        font = new TilemapFont;
 
-       Mf::Vector2 coeffs[4];
-       coeffs[0] = Mf::Vector2(0.0, 0.0);
-       coeffs[1] = Mf::Vector2(0.5, 0.0);
-       coeffs[2] = Mf::Vector2(0.5, 0.0);
-       coeffs[3] = Mf::Vector2(1.0, 0.0);
+       Mf::Scalar coeffs[4];
+       coeffs[0] = 0.0;
+       coeffs[1] = 1.5;
+       coeffs[2] = -0.5;
+       coeffs[3] = 1.0;
        interp.init(coeffs, 1.0, Mf::Interpolator::OSCILLATE);
 
        Mf::Scalar coeff[2] = {1.0, 0.0};
-       fadeIn.init(coeff, 0.5f);
+       fadeIn.init(coeff, 0.1);
 
        testScene = new Mf::Scene("Test");
-
-       x = y = z = 0.0;
+       heroine->treeNode = testScene->getOctree()->insert(heroine);
 }
 
 YoinkApp::~YoinkApp()
 {
-       delete someChar;
+       //delete heroine;
        delete font;
        delete testScene;
 
@@ -185,8 +192,15 @@ void YoinkApp::update(Mf::Scalar t, Mf::Scalar dt)
 
        camera.update(t, dt);
 
-       someChar->getAnimation().update(t, dt);
+       heroine->update(t, dt);
+       heroine->treeNode = testScene->getOctree()->reinsert(heroine, heroine->treeNode);
+       
+       //camera.lookAt(heroine->getSphere().point);
+       camera.setPosition(Mf::Vector3(-heroine->current.position[0], -heroine->current.position[1], -256));
+
        interp.update(dt);
+       hud.setBar1Progress(interp.getValue());
+       hud.setBar2Progress(1.0 - interp.getValue());
 
        prevstate = state;
        state += dt;
@@ -206,19 +220,50 @@ void YoinkApp::draw(Mf::Scalar alpha)
        //Mf::Scalar cosstate = std::cos(drawstate);
        
 
-
        glMatrixMode(GL_MODELVIEW);
        //glLoadIdentity();
 
-       glBindTexture(GL_TEXTURE_2D, 0);
        //glRotatef(drawstate*15.0f, 0.0, 1.0, 0.0);
        //glTranslatef(x, y, z);
        glLoadMatrix(camera.getModelviewMatrix().data());
 
        // DRAW THE SCENE
+       Mf::Texture::resetBind();
        testScene->draw(alpha, camera);
 
 
+
+       //heroine->draw(alpha);
+
+
+       hud.draw();
+
+
+       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);
+
+       glMatrixMode(GL_PROJECTION);
+       glPopMatrix();
+       glMatrixMode(GL_MODELVIEW);
+       glPopMatrix();
+
        /*
        glLoadIdentity();
        
@@ -350,9 +395,10 @@ void YoinkApp::handleEvent(const Mf::Event& event)
                        {
                                getVideo().toggleFull();
                        }
-                       else if (event.key.keysym.sym == SDLK_a)
+                       else if (event.key.keysym.sym == SDLK_SPACE)
                        {
-                               someChar->getAnimation().startSequence("Punch");
+                               heroine->getAnimation().startSequence("Punch");
+                               punchSound.play();
                        }
                        else if (event.key.keysym.sym == SDLK_r)
                        {
@@ -363,30 +409,9 @@ void YoinkApp::handleEvent(const Mf::Event& event)
                                getVideo().toggleCursorGrab();
                                getVideo().toggleCursorVisible();
                        }
-                       //else if (event.key.keysym.sym == SDLK_RIGHT)
-                       //{
-                               //x -= 50.0;
-                       //}
-                       //else if (event.key.keysym.sym == SDLK_LEFT)
-                       //{
-                               //x += 50.0;
-                       //}
-                       //else if (event.key.keysym.sym == SDLK_UP)
-                       //{
-                               //y -= 50.0;
-                       //}
-                       //else if (event.key.keysym.sym == SDLK_DOWN)
-                       //{
-                               //y += 50.0;
-                       //}
-                       //else if (event.key.keysym.sym == SDLK_PAGEUP)
-                       //{
-                               //z += 50.0;
-                       //}
-                       //else if (event.key.keysym.sym == SDLK_PAGEDOWN)
-                       //{
-                               //z -= 50.0;
-                       //}
+
+               case SDL_KEYUP:
+                       heroine->handleEvent(event);
 
                case SDL_MOUSEMOTION:
                case SDL_MOUSEBUTTONDOWN:
@@ -399,6 +424,7 @@ void YoinkApp::handleEvent(const Mf::Event& event)
 
                case SDL_VIDEORESIZE:
                        glViewport(0, 0, event.resize.w, event.resize.h);
+                       hud.resize(event.resize.w, event.resize.h);
                        camera.setProjection(cml::rad(60.0), double(event.resize.w / event.resize.h), 32.0, 2500.0);
                        camera.uploadProjectionToGL();
                        break;
@@ -411,7 +437,7 @@ int main(int argc, char* argv[])
 {
        std::cout << PACKAGE_STRING << std::endl
                          << "Compiled " << __TIME__ " " __DATE__ << std::endl
-                         << "Send requests, patches, and bug reports to <"
+                         << "Send patches and bug reports to <"
                          PACKAGE_BUGREPORT << ">." << std::endl << std::endl;
 
        int status = 0;
index 66406d2d4447c0979ddb0ef94f1bced85da45569..1613707730ea0d6a3efc7d499556d73d162e65a5 100644 (file)
 #include "Character.hh"
 #include "TilemapFont.hh"
 
+#include <Moof/Sound.hh>
+
+#include "Hud.hh"
+
 
 class YoinkApp : public Mf::Engine
 {
@@ -65,19 +69,22 @@ private:
        void setupGL();
        void contextRecreated(const Mf::Notification& note);
 
-       Character* someChar;
+       Mf::SoundStream music;
+
+       CharacterPtr heroine;
+       Mf::Sound punchSound;
        TilemapFont *font;
 
-       Mf::Cerpv2 interp;
+       Mf::Cerps interp;
        Mf::Lerps fadeIn;
 
        Mf::Camera camera;
        Mf::Scene* testScene;
 
-       Mf::Scalar x, y, z;
-
        Mf::Scalar state;
        Mf::Scalar prevstate;
+
+       Hud hud;
 };
 
 
This page took 0.117331 seconds and 4 git commands to generate.