From: Charles McGarvey Date: Tue, 8 Dec 2009 07:48:59 +0000 (-0700) Subject: experimental shapes hierarchy and raycasting X-Git-Url: https://git.brokenzipper.com/gitweb?a=commitdiff_plain;h=2d77fb5fb3480f522658f30af6addd5146530517;p=chaz%2Fyoink experimental shapes hierarchy and raycasting --- diff --git a/Makefile.am b/Makefile.am index 009c2dc..bb29cd0 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3,7 +3,10 @@ ACLOCAL_AMFLAGS = -I m4 SUBDIRS = data doc src -EXTRA_DIST = extra +EXTRA_DIST = autogen.sh extra + + +.PHONY: run debug docs package run: all @cd src && $(MAKE) run @@ -11,9 +14,6 @@ run: all debug: all @cd src && $(MAKE) debug - -.PHONY: docs package - docs: $(DOXYGEN) diff --git a/data/scenes/Classic.lua b/data/scenes/Classic.lua index 963db84..68b7b66 100644 --- a/data/scenes/Classic.lua +++ b/data/scenes/Classic.lua @@ -751,8 +751,8 @@ DrawTilemap({ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ResetTransform() -Translate(-0.3, -0.17, -28) -Scale(100, 50, 1) +Translate(-0.32, -0.28, -24) +Scale(105, 52, 1) SetTexture("BackgroundFar") DrawTile() diff --git a/data/textures/BackgroundFar.png b/data/textures/BackgroundFar.png index 39c9c21..df10334 100644 Binary files a/data/textures/BackgroundFar.png and b/data/textures/BackgroundFar.png differ diff --git a/data/textures/BackgroundNear.png b/data/textures/BackgroundNear.png index 762f97d..fd30b7f 100644 Binary files a/data/textures/BackgroundNear.png and b/data/textures/BackgroundNear.png differ diff --git a/doc/yoink.6.in b/doc/yoink.6.in index 5b37c38..5822f29 100644 --- a/doc/yoink.6.in +++ b/doc/yoink.6.in @@ -33,7 +33,7 @@ Yoink \- An alien-smashing action game. .SH DESCRIPTION Leap tall buildings! Crush stupid robots beneath your feet! Wield your extra-terrestrial powers in the defence of humanity, and send those alien -invaders back from whence they came! This is Yoink. +invaders back from whence they came! You play the part of a flying alien heroine who must defend her home on Earth from other airborne alien invaders. The game draws inspiration from diff --git a/src/Character.cc b/src/Character.cc index 7110449..3022c31 100644 --- a/src/Character.cc +++ b/src/Character.cc @@ -138,14 +138,14 @@ void Character::draw(Mf::Scalar alpha) const Mf::Scalar s = 0.5; glBegin(GL_TRIANGLE_FAN); - glTexCoord2f(coords[0], coords[1]); - glVertex3(position[0]-s, position[1]-s, mZCoord); - glTexCoord2f(coords[2], coords[3]); - glVertex3(position[0]+s, position[1]-s, mZCoord); - glTexCoord2f(coords[4], coords[5]); - glVertex3(position[0]+s, position[1]+s, mZCoord); - glTexCoord2f(coords[6], coords[7]); - glVertex3(position[0]-s, position[1]+s, mZCoord); + glTexCoord(coords[0], coords[1]); + glVertex(position[0]-s, position[1]-s, mZCoord); + glTexCoord(coords[2], coords[3]); + glVertex(position[0]+s, position[1]-s, mZCoord); + glTexCoord(coords[4], coords[5]); + glVertex(position[0]+s, position[1]+s, mZCoord); + glTexCoord(coords[6], coords[7]); + glVertex(position[0]-s, position[1]+s, mZCoord); glEnd(); } @@ -155,7 +155,7 @@ void Character::setZCoord(Mf::Scalar z) } -int Character::getOctant(const Mf::Aabb& aabb) const +int Character::getOctant(const Mf::Aabb<3>& aabb) const { int octantNum = -1; diff --git a/src/Character.hh b/src/Character.hh index 28e588b..2173422 100644 --- a/src/Character.hh +++ b/src/Character.hh @@ -68,7 +68,7 @@ public: void addForce(Mf::Vector2 force); void setPosition(Mf::Vector2 position); - virtual int getOctant(const Mf::Aabb& aabb) const; + virtual int getOctant(const Mf::Aabb<3>& aabb) const; Tilemap tilemap; Animation animation; diff --git a/src/GameLayer.cc b/src/GameLayer.cc index f61ec3d..41000f3 100644 --- a/src/GameLayer.cc +++ b/src/GameLayer.cc @@ -121,6 +121,17 @@ GameLayer::GameLayer() : void GameLayer::pushed(Mf::Engine& engine) { engine.push(Hud::alloc(mState)); + + mRay.direction.set(1.0, 0.0); + + mLine.a.set(20, 10); + mLine.b.set(19, 14); + + mPlane.normal.set(-1.0, 0.0, 0.0); + mPlane.d = 0.0; + + mSphere.point.set(22, 5); + mSphere.radius = 2; } @@ -132,11 +143,37 @@ void GameLayer::update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt) mState.scene->checkForCollision(*mState.heroine); mState.camera.setPosition(Mf::Vector3(-mState.heroine->getState().position[0], - -mState.heroine->getState().position[1], -10)); + -mState.heroine->getState().position[1], -9)); //mState.camera.lookAt(Mf::promote(mState.heroine->getState().position)); //Mf::Vector3 heroinePosition = Mf::promote(mState.heroine->getState().position); //Mf::Sound::setListenerPosition(heroinePosition); + + mRay.point = mState.heroine->getState().position; + + Mf::Ray<2>::Intersection meh; + + Mf::Scalar d = mLine.intersectRay(mRay, meh); + if (d > 0.0) + { + Mf::logDebug("line: d = %f", d); + Mf::logDebug(" P = <%f,%f>", meh.point[0], meh.point[1]); + Mf::logDebug(" n = <%f,%f>", meh.normal[0], meh.normal[1]); + } + //d = mPlane.intersectRay(mRay, meh); + //if (d > 0.0) + //{ + //Mf::logDebug("plane: d = %f", d); + //Mf::logDebug(" P = <%f,%f>", meh.point[0], meh.point[1]); + //Mf::logDebug(" n = <%f,%f>", meh.normal[0], meh.normal[1]); + //} + d = mSphere.intersectRay(mRay, meh); + if (d > 0.0) + { + Mf::logDebug("sphere: d = %f", d); + Mf::logDebug(" P = <%f,%f>", meh.point[0], meh.point[1]); + Mf::logDebug(" n = <%f,%f>", meh.normal[0], meh.normal[1]); + } } @@ -154,6 +191,10 @@ void GameLayer::draw(Mf::Engine& engine, Mf::Scalar alpha) const mState.heroine->setZCoord(getZCoord(mState.heroine->getState().position)); mState.heroine->draw(alpha); + + mRay.draw(); + mLine.draw(); + mSphere.draw(); } bool GameLayer::handleEvent(Mf::Engine& engine, const Mf::Event& event) @@ -173,6 +214,16 @@ bool GameLayer::handleEvent(Mf::Engine& engine, const Mf::Event& event) mMusic.toggle(); return true; } + else if (event.key.keysym.sym == SDLK_PAGEUP) + { + mRay.direction = cml::rotate_vector_2D(mRay.direction, cml::rad(10.0)); + return true; + } + else if (event.key.keysym.sym == SDLK_PAGEDOWN) + { + mRay.direction = cml::rotate_vector_2D(mRay.direction, cml::rad(-10.0)); + return true; + } return mState.heroine->handleEvent(event); case SDL_KEYUP: diff --git a/src/GameLayer.hh b/src/GameLayer.hh index d75d9dc..f966c70 100644 --- a/src/GameLayer.hh +++ b/src/GameLayer.hh @@ -47,6 +47,11 @@ #include #include +#include +#include +#include +#include + #include "Character.hh" #include "Heroine.hh" #include "Scene.hh" @@ -58,6 +63,7 @@ typedef boost::shared_ptr GameLayerP; class GameLayer : public Mf::Layer { public: + GameLayer(); static GameLayerP alloc() @@ -99,6 +105,11 @@ private: State mState; Mf::Sound mMusic; Mf::Sound mPunchSound; + + Mf::Ray<2> mRay; + Mf::Line<2> mLine; + Mf::Plane mPlane; + Mf::Sphere<2> mSphere; }; diff --git a/src/Hud.cc b/src/Hud.cc index 90f5dd9..3a178f6 100644 --- a/src/Hud.cc +++ b/src/Hud.cc @@ -88,32 +88,32 @@ void ProgressBar::draw(Mf::Scalar alpha) const mTilemap.bind(); glBegin(GL_QUADS); - glTexCoord2(mTexCoords[0], mTexCoords[1]); - glVertex2v(mVertices[0].data()); - glTexCoord2(mMidCoords[0], mTexCoords[3]); - glVertex2v(mVertices[1].data()); - glTexCoord2(mMidCoords[0], mTexCoords[5]); - glVertex2v(mVertices[6].data()); - glTexCoord2(mTexCoords[6], mTexCoords[7]); - glVertex2v(mVertices[7].data()); - - glTexCoord2(mMidCoords[0], mTexCoords[1]); - glVertex2v(mVertices[1].data()); - glTexCoord2(mMidCoords[1], mTexCoords[3]); - glVertex2v(mVertices[2].data()); - glTexCoord2(mMidCoords[1], mTexCoords[5]); - glVertex2v(mVertices[5].data()); - glTexCoord2(mMidCoords[0], mTexCoords[7]); - glVertex2v(mVertices[6].data()); - - glTexCoord2(mMidCoords[1], mTexCoords[1]); - glVertex2v(mVertices[2].data()); - glTexCoord2(mTexCoords[2], mTexCoords[3]); - glVertex2v(mVertices[3].data()); - glTexCoord2(mTexCoords[4], mTexCoords[5]); - glVertex2v(mVertices[4].data()); - glTexCoord2(mMidCoords[1], mTexCoords[7]); - glVertex2v(mVertices[5].data()); + glTexCoord(mTexCoords[0], mTexCoords[1]); + glVertex(mVertices[0]); + glTexCoord(mMidCoords[0], mTexCoords[3]); + glVertex(mVertices[1]); + glTexCoord(mMidCoords[0], mTexCoords[5]); + glVertex(mVertices[6]); + glTexCoord(mTexCoords[6], mTexCoords[7]); + glVertex(mVertices[7]); + + glTexCoord(mMidCoords[0], mTexCoords[1]); + glVertex(mVertices[1]); + glTexCoord(mMidCoords[1], mTexCoords[3]); + glVertex(mVertices[2]); + glTexCoord(mMidCoords[1], mTexCoords[5]); + glVertex(mVertices[5]); + glTexCoord(mMidCoords[0], mTexCoords[7]); + glVertex(mVertices[6]); + + glTexCoord(mMidCoords[1], mTexCoords[1]); + glVertex(mVertices[2]); + glTexCoord(mTexCoords[2], mTexCoords[3]); + glVertex(mVertices[3]); + glTexCoord(mTexCoords[4], mTexCoords[5]); + glVertex(mVertices[4]); + glTexCoord(mMidCoords[1], mTexCoords[7]); + glVertex(mVertices[5]); glEnd(); } diff --git a/src/MainLayer.cc b/src/MainLayer.cc index 38c849e..faa4622 100644 --- a/src/MainLayer.cc +++ b/src/MainLayer.cc @@ -76,7 +76,7 @@ void MainLayer::update(Mf::Engine& engine, Mf::Scalar t, Mf::Scalar dt) if (engine.getSize() == 1) { // this is the only layer left on the stack - engine.push(TitleLayer::alloc()); + //engine.push(TitleLayer::alloc()); } } @@ -206,9 +206,7 @@ void printInfo(int argc, char* argv[]) std::cout << " Executable: " << argv[0] << std::endl << " Version: "VERSION << std::endl -#if defined(__DATE__) && defined(__TIME__) - << " Built: "__DATE__" "__TIME__ << std::endl -#endif + << " Built: " << COMPILE_TIME << std::endl << " Compiler: "COMPILER_STRING << std::endl << " Assets: " << assets << std::endl << "Build options: " diff --git a/src/Makefile.am b/src/Makefile.am index f100272..e2ea2fe 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -34,6 +34,7 @@ libmoof_a_SOURCES = \ Moof/Interpolator.hh \ Moof/Layer.hh \ Moof/Library.hh \ + Moof/Line.hh \ Moof/Log.cc \ Moof/Log.hh \ Moof/Math.hh \ @@ -42,6 +43,7 @@ libmoof_a_SOURCES = \ Moof/OpenGL.hh \ Moof/Plane.cc \ Moof/Plane.hh \ + Moof/Ray.hh \ Moof/Rectangle.cc \ Moof/Rectangle.hh \ Moof/Resource.cc \ @@ -50,9 +52,9 @@ libmoof_a_SOURCES = \ Moof/Script.hh \ Moof/Settings.cc \ Moof/Settings.hh \ + Moof/Shape.hh \ Moof/Sound.cc \ Moof/Sound.hh \ - Moof/Sphere.cc \ Moof/Sphere.hh \ Moof/StringTools.cc \ Moof/StringTools.hh \ @@ -104,6 +106,7 @@ yoink_SOURCES = \ TitleLayer.hh \ Typesetter.cc \ Typesetter.hh \ + version.c \ version.h \ $(ENDLIST) @@ -125,3 +128,6 @@ run: all debug: all $(YOINK_ENVIRONMENT) gdb ./yoink +all-local: # always rebuild version.c + @touch version.c + diff --git a/src/Moof/Aabb.cc b/src/Moof/Aabb.cc index 17ce663..692ec36 100644 --- a/src/Moof/Aabb.cc +++ b/src/Moof/Aabb.cc @@ -35,6 +35,7 @@ namespace Mf { + /* void Aabb::getOctant(Aabb& octant, int num) const { Vector3 mid = getCenter(); @@ -80,75 +81,9 @@ void Aabb::getOctant(Aabb& octant, int num) const break; } } +*/ -void Aabb::getCorners(Vector3 corners[8]) const -{ - corners[0][0] = min[0]; corners[0][1] = min[1]; corners[0][2] = max[2]; - corners[1][0] = max[0]; corners[1][1] = min[1]; corners[1][2] = max[2]; - corners[2][0] = max[0]; corners[2][1] = max[1]; corners[2][2] = max[2]; - corners[3][0] = min[0]; corners[3][1] = max[1]; corners[3][2] = max[2]; - corners[4][0] = min[0]; corners[4][1] = min[1]; corners[4][2] = min[2]; - corners[5][0] = max[0]; corners[5][1] = min[1]; corners[5][2] = min[2]; - corners[6][0] = max[0]; corners[6][1] = max[1]; corners[6][2] = min[2]; - corners[7][0] = min[0]; corners[7][1] = max[1]; corners[7][2] = min[2]; -} - - -void Aabb::encloseVertices(const Vector3 vertices[], unsigned count) -{ - min = vertices[0]; - max = vertices[0]; - - for (unsigned i = 1; i < count; ++i) - { - if (vertices[i][0] < min[0]) min[0] = vertices[i][0]; - if (vertices[i][0] > max[0]) max[0] = vertices[i][0]; - if (vertices[i][1] < min[1]) min[1] = vertices[i][1]; - if (vertices[i][1] > max[1]) max[1] = vertices[i][1]; - if (vertices[i][2] < min[2]) min[2] = vertices[i][2]; - if (vertices[i][2] > max[2]) max[2] = vertices[i][2]; - } -} - - -void Aabb::draw(Scalar alpha) const -{ - Scalar vertices[] = {min[0], min[1], min[2], - min[0], max[1], min[2], - max[0], max[1], min[2], - max[0], min[1], min[2], - min[0], max[1], max[2], - min[0], min[1], max[2], - max[0], min[1], max[2], - max[0], max[1], max[2]}; - - GLubyte indices[] = {0, 1, 2, 3, - 1, 2, 7, 4, - 3, 0, 5, 6, - 2, 3, 6, 7, - 5, 0, 1, 4, - 4, 5, 6, 7}; - - glEnableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glVertexPointer(3, GL_SCALAR, 0, vertices); - - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - Texture::resetBind(); - - glDrawElements(GL_QUADS, sizeof(indices), GL_UNSIGNED_BYTE, indices); - - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - //glDisableClientState(GL_VERTEX_ARRAY); - - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); -} - -bool Aabb::isVisible(const Frustum& frustum) const -{ - return frustum.contains(*this); -} } // namespace Mf diff --git a/src/Moof/Aabb.hh b/src/Moof/Aabb.hh index 6a7e064..83926b3 100644 --- a/src/Moof/Aabb.hh +++ b/src/Moof/Aabb.hh @@ -33,6 +33,11 @@ #include #include #include +#include + +#include +#include +#include namespace Mf { @@ -42,14 +47,17 @@ namespace Mf { * Axis-aligned Bounding Box */ -struct Aabb : public Cullable, public Drawable +template +struct Aabb : public Cullable, public Drawable, public Shape { - Vector3 min; - Vector3 max; + typedef cml::vector< Scalar, cml::fixed > Vector; + + Vector min; + Vector max; Aabb() {} - Aabb(const Vector3& a, const Vector3& b) + Aabb(const Vector& a, const Vector& b) { init(a, b); } @@ -57,13 +65,13 @@ struct Aabb : public Cullable, public Drawable Aabb(Scalar ax, Scalar ay, Scalar az, Scalar bx, Scalar by, Scalar bz) { - Vector3 a(ax, ay, az); - Vector3 b(bx, by, bz); + Vector a(ax, ay, az); + Vector b(bx, by, bz); init(a, b); } - void init(const Vector3& a, const Vector3& b) + void init(const Vector& a, const Vector& b) { if (a[0] < b[0]) { @@ -97,19 +105,19 @@ struct Aabb : public Cullable, public Drawable } } - Vector3 getCenter() const + Vector getCenter() const { - return Vector3((min[0] + max[0]) / 2.0, + return Vector((min[0] + max[0]) / 2.0, (min[1] + max[1]) / 2.0, (min[2] + max[2]) / 2.0); } - void getOctant(Aabb& octant, int num) const; + //void getOctant(Aabb& octant, int num) const; Plane getPlaneXY() const { Plane plane; - plane.normal = Vector3(0.0, 0.0, 1.0); + plane.normal = Vector(0.0, 0.0, 1.0); plane.d = cml::dot(-plane.normal, getCenter()); return plane; } @@ -117,7 +125,7 @@ struct Aabb : public Cullable, public Drawable Plane getPlaneXZ() const { Plane plane; - plane.normal = Vector3(0.0, 1.0, 0.0); + plane.normal = Vector(0.0, 1.0, 0.0); plane.d = cml::dot(-plane.normal, getCenter()); return plane; } @@ -125,17 +133,84 @@ struct Aabb : public Cullable, public Drawable Plane getPlaneYZ() const { Plane plane; - plane.normal = Vector3(1.0, 0.0, 0.0); + plane.normal = Vector(1.0, 0.0, 0.0); plane.d = cml::dot(-plane.normal, getCenter()); return plane; } + /* void getCorners(Vector3 corners[8]) const; void encloseVertices(const Vector3 vertices[], unsigned count); void draw(Scalar alpha = 0.0) const; bool isVisible(const Frustum& frustum) const; + */ + + +void getCorners(Vector corners[8]) const +{ + corners[0][0] = min[0]; corners[0][1] = min[1]; corners[0][2] = max[2]; + corners[1][0] = max[0]; corners[1][1] = min[1]; corners[1][2] = max[2]; + corners[2][0] = max[0]; corners[2][1] = max[1]; corners[2][2] = max[2]; + corners[3][0] = min[0]; corners[3][1] = max[1]; corners[3][2] = max[2]; + corners[4][0] = min[0]; corners[4][1] = min[1]; corners[4][2] = min[2]; + corners[5][0] = max[0]; corners[5][1] = min[1]; corners[5][2] = min[2]; + corners[6][0] = max[0]; corners[6][1] = max[1]; corners[6][2] = min[2]; + corners[7][0] = min[0]; corners[7][1] = max[1]; corners[7][2] = min[2]; +} + + +void encloseVertices(const Vector vertices[], unsigned count) +{ + min.zero(); + max.zero(); + + for (unsigned i = 1; i < count; ++i) + { + min.minimize(vertices[i]); + max.maximize(vertices[i]); + } +} + + +void draw(Scalar alpha = 0.0) const +{ + Scalar vertices[] = {min[0], min[1], min[2], + min[0], max[1], min[2], + max[0], max[1], min[2], + max[0], min[1], min[2], + min[0], max[1], max[2], + min[0], min[1], max[2], + max[0], min[1], max[2], + max[0], max[1], max[2]}; + + GLubyte indices[] = {0, 1, 2, 3, + 1, 2, 7, 4, + 3, 0, 5, 6, + 2, 3, 6, 7, + 5, 0, 1, 4, + 4, 5, 6, 7}; + + glEnableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_TEXTURE_COORD_ARRAY); + glVertexPointer(3, GL_SCALAR, 0, vertices); + + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + Texture::resetBind(); + + glDrawElements(GL_QUADS, sizeof(indices), GL_UNSIGNED_BYTE, indices); + + glEnableClientState(GL_TEXTURE_COORD_ARRAY); + //glDisableClientState(GL_VERTEX_ARRAY); + + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +} + +bool isVisible(const Frustum& frustum) const +{ + return frustum.contains(*this); +} }; diff --git a/src/Moof/Dispatch.cc b/src/Moof/Dispatch.cc index 17f8f17..8ad29fd 100644 --- a/src/Moof/Dispatch.cc +++ b/src/Moof/Dispatch.cc @@ -121,8 +121,6 @@ Dispatch::Handler::~Handler() Dispatch::Dispatch() : mImpl(new Dispatch::Impl) {} -Dispatch::~Dispatch() {} - Dispatch& Dispatch::getInstance() { diff --git a/src/Moof/Dispatch.hh b/src/Moof/Dispatch.hh index bbf37f3..4483f99 100644 --- a/src/Moof/Dispatch.hh +++ b/src/Moof/Dispatch.hh @@ -108,7 +108,6 @@ public: Dispatch(); - ~Dispatch(); // create and/or get a global instance static Dispatch& getInstance(); diff --git a/src/Moof/Engine.cc b/src/Moof/Engine.cc index 785cb4b..fca5e15 100644 --- a/src/Moof/Engine.cc +++ b/src/Moof/Engine.cc @@ -216,6 +216,8 @@ public: Timer::getNextFire()), Timer::ACTUAL); } while (!mStack.empty()); + + mDispatch.dispatch("engine.stopping"); } void dispatchEvents() diff --git a/src/Moof/Entity.hh b/src/Moof/Entity.hh index 52cb79d..ee0f860 100644 --- a/src/Moof/Entity.hh +++ b/src/Moof/Entity.hh @@ -55,8 +55,8 @@ class Entity : public Cullable, public Drawable { protected: - Aabb mAabb; - Sphere mSphere; + Aabb<3> mAabb; + Sphere<3> mSphere; public: @@ -72,12 +72,12 @@ public: return mSphere.isVisible(frustum) && mAabb.isVisible(frustum); } - const Aabb& getAabb() const + const Aabb<3>& getAabb() const { return mAabb; } - const Sphere& getSphere() const + const Sphere<3>& getSphere() const { return mSphere; } diff --git a/src/Moof/Frustum.cc b/src/Moof/Frustum.cc index 86e4d5b..1db6d25 100644 --- a/src/Moof/Frustum.cc +++ b/src/Moof/Frustum.cc @@ -60,7 +60,7 @@ void Frustum::init(const Matrix4& modelview, Scalar fovy, Scalar aspect, init(modelview, projection); } -Frustum::Collision Frustum::contains(const Aabb& aabb) const +Frustum::Collision Frustum::contains(const Aabb<3>& aabb) const { Vector3 corners[8]; int nTotalInside = 0; @@ -89,7 +89,7 @@ Frustum::Collision Frustum::contains(const Aabb& aabb) const } -Frustum::Collision Frustum::contains(const Sphere& sphere) const +Frustum::Collision Frustum::contains(const Sphere<3>& sphere) const { for (int i = 0; i < 6; ++i) { diff --git a/src/Moof/Frustum.hh b/src/Moof/Frustum.hh index c708c06..406e230 100644 --- a/src/Moof/Frustum.hh +++ b/src/Moof/Frustum.hh @@ -36,8 +36,8 @@ namespace Mf { -class Aabb; -class Sphere; +template class Aabb; +template class Sphere; class Frustum { @@ -66,8 +66,8 @@ public: void init(const Matrix4& modelview, Scalar fovy, Scalar aspect, Scalar abutting, Scalar distant); - Collision contains(const Aabb& aabb) const; - Collision contains(const Sphere& sphere) const; + Collision contains(const Aabb<3>& aabb) const; + Collision contains(const Sphere<3>& sphere) const; }; diff --git a/src/Moof/Line.hh b/src/Moof/Line.hh new file mode 100644 index 0000000..4a54e2d --- /dev/null +++ b/src/Moof/Line.hh @@ -0,0 +1,131 @@ + +/******************************************************************************* + + 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_LINE_HH_ +#define _MOOF_LINE_HH_ + +#include +#include +#include +#include +#include + +#include + + +namespace Mf { + + +template +struct Line : public Drawable, public Shape +{ + typedef cml::vector< Scalar, cml::fixed > Vector; + + Vector a; + Vector b; + + Scalar intersectRay(const Ray<2>& ray, Ray<2>::Intersection& intersection) + { + // solve: Cx + r*Dx = Ax + s(Bx - Ax) + // Cy + r*Dy = Ay + s(By - Ay) + // where: 0 <= s <= 1 if intersection + // given: A = a + // B = b + // C = ray.point + // D = ray.direction + + Scalar denom = ray.direction[0] * (b[1] - a[1]) + + ray.direction[1] * (a[0] - b[0]); + + // check if the ray and line are parallel + if (isEqual(denom, SCALAR(0.0))) + { + Scalar numer = a[0] * (ray.point[1] - b[1]) + + b[0] * (a[1] - ray.point[1]) + + ray.point[0] * (b[1] - a[1]); + + // check if they are collinear + if (isEqual(numer, SCALAR(0.0))) + { + intersection.point = ray.point; + intersection.normal.set(0.0, 0.0); + return SCALAR(0.0); + } + + return SCALAR(-1.0); + } + + Scalar s = (ray.direction[0] * (ray.point[1] - a[1]) + + ray.direction[1] * (a[0] - ray.point[0])) / denom; + + // check if the ray hits the segment + if (s < SCALAR(0.0) || s > SCALAR(1.0)) return SCALAR(-1.0); + + Scalar r = -(a[0] * (ray.point[1] - b[1]) + + b[0] * (a[1] - ray.point[1]) + + ray.point[0] * (b[1] - a[1])) / denom; + + // make sure we're dealing with the right side of the ray + if (r < SCALAR(0.0)) return SCALAR(-1.0); + + intersection.point = ray.point + r * ray.direction; + + // gotta use the correct normal + Vector n = cml::perp(a - b); + if (cml::dot(a - ray.point, n) < 0) intersection.normal = n; + else intersection.normal = -n; + + return r; + } + + void draw(Scalar alpha = 0.0) const + { + Mf::Texture::resetBind(); + glBegin(GL_LINES); + glVertex(a); + glVertex(b); + glEnd(); + } +}; + + +template +struct Polygon : public Shape +{ + typedef cml::vector< Scalar, cml::fixed > Vector; + + Vector points[N]; +}; + + +} // namespace Mf + +#endif // _MOOF_LINE_HH_ + +/** vim: set ts=4 sw=4 tw=80: *************************************************/ + diff --git a/src/Moof/Math.hh b/src/Moof/Math.hh index c63cfe7..ae747ec 100644 --- a/src/Moof/Math.hh +++ b/src/Moof/Math.hh @@ -37,7 +37,26 @@ #include #include -#include // GLscalar +#include + +#if HAVE_CONFIG_H +#include "config.h" +#endif + + +#if USE_DOUBLE_PRECISION + +typedef GLdouble GLscalar; +#define GL_SCALAR GL_DOUBLE +#define SCALAR(D) (D) + +#else + +typedef GLfloat GLscalar; +#define GL_SCALAR GL_FLOAT +#define SCALAR(F) (F##f) + +#endif namespace Mf { diff --git a/src/Moof/Octree.hh b/src/Moof/Octree.hh index ca464a5..13ece5b 100644 --- a/src/Moof/Octree.hh +++ b/src/Moof/Octree.hh @@ -52,7 +52,7 @@ struct OctreeInsertable { virtual ~OctreeInsertable() {} - virtual int getOctant(const Aabb& aabb) const = 0; + virtual int getOctant(const Aabb<3>& aabb) const = 0; }; @@ -65,7 +65,7 @@ class Octree : public Entity { std::list objects; - Node(const Aabb& aabb) + Node(const Aabb<3>& aabb) { mAabb = aabb; mSphere.point = mAabb.getCenter(); @@ -114,8 +114,8 @@ private: ASSERT(node.valid() && "invalid node passed"); ASSERT(entity && "null entity passed"); - Aabb entityAabb = entity->getAabb(); - Aabb nodeAabb = node->getAabb(); + Aabb<3> entityAabb = entity->getAabb(); + Aabb<3> nodeAabb = node->getAabb(); if (!(entityAabb.max[0] < nodeAabb.max[0] && entityAabb.min[0] > nodeAabb.min[0] && @@ -162,7 +162,7 @@ private: { ASSERT(node.valid() && "invalid node passed"); - Aabb octant; + Aabb<3> octant; for (int i = mTree.children(node); i <= index; ++i) { diff --git a/src/Moof/OpenGL.hh b/src/Moof/OpenGL.hh index e74f601..1e37b5e 100644 --- a/src/Moof/OpenGL.hh +++ b/src/Moof/OpenGL.hh @@ -31,126 +31,97 @@ #include +#include + #if HAVE_CONFIG_H #include "config.h" #endif +// generic function arguments + +#define ARGS_P const GLscalar* p +#define PASS_P p + +#define ARGS_M const Mf::Matrix4& m +#define PASS_M m.data() + +// ordinal function arguments + +#define ARGS_S2 GLscalar a, GLscalar b +#define PASS_S2 a, b +#define ARGS_S3 GLscalar a, GLscalar b, GLscalar c +#define PASS_S3 a, b, c +#define ARGS_S4 GLscalar a, GLscalar b, GLscalar c, GLscalar d +#define PASS_S4 a, b, c, d + +#define ARGS_P2 const Mf::Vector2& p +#define PASS_P2 p.data() +#define ARGS_P3 const Mf::Vector3& p +#define PASS_P3 p.data() +#define ARGS_P4 const Mf::Vector4& p +#define PASS_P4 p.data() + +#define ARGS_V2 const Mf::Vector2& v +#define PASS_V2 v[0], v[1] +#define ARGS_V3 const Mf::Vector3& v +#define PASS_V3 v[0], v[1], v[2] +#define ARGS_V4 const Mf::Vector4& v +#define PASS_V4 v[0], v[1], v[2], v[3] + + #if USE_DOUBLE_PRECISION -typedef GLdouble GLscalar; -#define GL_SCALAR GL_DOUBLE -#define SCALAR(D) (D) - -inline void glGetScalarv(GLenum a, GLscalar* b) -{ glGetDoublev(a, b); } - -inline void glLoadMatrix(const GLscalar* a) -{ glLoadMatrixd(a); } -inline void glMultMatrix(const GLscalar* a) -{ glMultMatrixd(a); } - -inline void glScale(GLscalar a, GLscalar b, GLscalar c) -{ glScaled(a, b, c); } -inline void glRotate(GLscalar a, GLscalar b, GLscalar c, GLscalar d) -{ glRotated(a, b, c, d); } -inline void glTranslate(GLscalar a, GLscalar b, GLscalar c) -{ glTranslated(a, b, c); } - -inline void glColor3(GLscalar a, GLscalar b, GLscalar c) -{ glColor3d(a, b, c); } -inline void glColor4(GLscalar a, GLscalar b, GLscalar c, GLscalar d) -{ glColor4d(a, b, c, d); } -inline void glColor3v(const GLscalar *a) -{ glColor3dv(a); } -inline void glColor4v(const GLscalar *a) -{ glColor4dv(a); } - -inline void glVertex2(GLscalar a, GLscalar b) -{ glVertex2d(a, b); } -inline void glVertex3(GLscalar a, GLscalar b, GLscalar c) -{ glVertex3d(a, b, c); } -inline void glVertex4(GLscalar a, GLscalar b, GLscalar c, GLscalar d) -{ glVertex4d(a, b, c, d); } -inline void glVertex2v(const GLscalar* a) -{ glVertex2dv(a); } -inline void glVertex3v(const GLscalar* a) -{ glVertex3dv(a); } -inline void glVertex4v(const GLscalar* a) -{ glVertex4dv(a); } - -inline void glTexCoord2(GLscalar a, GLscalar b) -{ glTexCoord2d(a, b); } -inline void glTexCoord3(GLscalar a, GLscalar b, GLscalar c) -{ glTexCoord3d(a, b, c); } -inline void glTexCoord4(GLscalar a, GLscalar b, GLscalar c, GLscalar d) -{ glTexCoord4d(a, b, c, d); } -inline void glTexCoord2v(const GLscalar* a) -{ glTexCoord2dv(a); } -inline void glTexCoord3v(const GLscalar* a) -{ glTexCoord3dv(a); } -inline void glTexCoord4v(const GLscalar* a) -{ glTexCoord4dv(a); } +#define OPENGL_GENERIC_FUNC(R, N, L) \ + inline R gl##N(ARGS_##L) { gl##N##d(PASS_##L); }// + +#define OPENGL_ORDINAL_FUNC(R, N, K) \ + inline R gl##N(ARGS_##S##K) { gl##N##K##d(PASS_##S##K); } \ + inline R gl##N(ARGS_##P##K) { gl##N##K##d##v(PASS_##P##K); }// #else -typedef GLfloat GLscalar; -#define GL_SCALAR GL_FLOAT -#define SCALAR(F) (F##f) - -inline void glGetScalarv(GLenum a, GLscalar* b) -{ glGetFloatv(a, b); } - -inline void glLoadMatrix(const GLscalar* a) -{ glLoadMatrixf(a); } -inline void glMultMatrix(const GLscalar* a) -{ glMultMatrixf(a); } - -inline void glScale(GLscalar a, GLscalar b, GLscalar c) -{ glScalef(a, b, c); } -inline void glRotate(GLscalar a, GLscalar b, GLscalar c, GLscalar d) -{ glRotatef(a, b, c, d); } -inline void glTranslate(GLscalar a, GLscalar b, GLscalar c) -{ glTranslatef(a, b, c); } - -inline void glColor3(GLscalar a, GLscalar b, GLscalar c) -{ glColor3f(a, b, c); } -inline void glColor4(GLscalar a, GLscalar b, GLscalar c, GLscalar d) -{ glColor4f(a, b, c, d); } -inline void glColor3v(const GLscalar *a) -{ glColor3fv(a); } -inline void glColor4v(const GLscalar *a) -{ glColor4fv(a); } - -inline void glVertex2(GLscalar a, GLscalar b) -{ glVertex2f(a, b); } -inline void glVertex3(GLscalar a, GLscalar b, GLscalar c) -{ glVertex3f(a, b, c); } -inline void glVertex4(GLscalar a, GLscalar b, GLscalar c, GLscalar d) -{ glVertex4f(a, b, c, d); } -inline void glVertex2v(const GLscalar* a) -{ glVertex2fv(a); } -inline void glVertex3v(const GLscalar* a) -{ glVertex3fv(a); } -inline void glVertex4v(const GLscalar* a) -{ glVertex4fv(a); } - -inline void glTexCoord2(GLscalar a, GLscalar b) -{ glTexCoord2f(a, b); } -inline void glTexCoord3(GLscalar a, GLscalar b, GLscalar c) -{ glTexCoord3f(a, b, c); } -inline void glTexCoord4(GLscalar a, GLscalar b, GLscalar c, GLscalar d) -{ glTexCoord4f(a, b, c, d); } -inline void glTexCoord2v(const GLscalar* a) -{ glTexCoord2fv(a); } -inline void glTexCoord3v(const GLscalar* a) -{ glTexCoord3fv(a); } -inline void glTexCoord4v(const GLscalar* a) -{ glTexCoord4fv(a); } +#define OPENGL_GENERIC_FUNC(R, N, L) \ + inline R gl##N(ARGS_##L) { gl##N##f(PASS_##L); }// + +#define OPENGL_ORDINAL_FUNC(R, N, K) \ + inline R gl##N(ARGS_##S##K) { gl##N##K##f(PASS_##S##K); } \ + inline R gl##N(ARGS_##P##K) { gl##N##K##f##v(PASS_##P##K); }// #endif +OPENGL_GENERIC_FUNC(void, LoadMatrix, P); +OPENGL_GENERIC_FUNC(void, LoadMatrix, M); +OPENGL_GENERIC_FUNC(void, MultMatrix, P); +OPENGL_GENERIC_FUNC(void, MultMatrix, M); + +OPENGL_GENERIC_FUNC(void, Scale, S3); +OPENGL_GENERIC_FUNC(void, Scale, V3); +OPENGL_GENERIC_FUNC(void, Rotate, S4); +OPENGL_GENERIC_FUNC(void, Rotate, V4); +OPENGL_GENERIC_FUNC(void, Translate, S3); +OPENGL_GENERIC_FUNC(void, Translate, V3); + +OPENGL_ORDINAL_FUNC(void, Color, 3); +OPENGL_ORDINAL_FUNC(void, Color, 4); + +OPENGL_ORDINAL_FUNC(void, Vertex, 2); +OPENGL_ORDINAL_FUNC(void, Vertex, 3); +OPENGL_ORDINAL_FUNC(void, Vertex, 4); + +OPENGL_ORDINAL_FUNC(void, TexCoord, 2); +OPENGL_ORDINAL_FUNC(void, TexCoord, 3); +OPENGL_ORDINAL_FUNC(void, TexCoord, 4); + + +#if USE_DOUBLE_PRECISION +inline void glGetScalar(GLenum a, GLscalar* b) { glGetDoublev(a, b); } +#else +inline void glGetScalar(GLenum a, GLscalar* b) { glGetFloatv(a, b); } +#endif + + #endif // _MOOF_OPENGL_HH_ /** vim: set ts=4 sw=4 tw=80: *************************************************/ diff --git a/src/Moof/Plane.cc b/src/Moof/Plane.cc index 5390934..71ea65e 100644 --- a/src/Moof/Plane.cc +++ b/src/Moof/Plane.cc @@ -34,7 +34,7 @@ namespace Mf { -Plane::Halfspace Plane::intersects(const Aabb& aabb) const +Plane::Halfspace Plane::intersects(const Aabb<3>& aabb) const { Vector3 corners[8]; int nPositive = 8; @@ -54,7 +54,7 @@ Plane::Halfspace Plane::intersects(const Aabb& aabb) const else return INTERSECT; } -Plane::Halfspace Plane::intersects(const Sphere& sphere) const +Plane::Halfspace Plane::intersects(const Sphere<3>& sphere) const { Scalar distance = getDistanceToPoint(sphere.point); diff --git a/src/Moof/Plane.hh b/src/Moof/Plane.hh index 06e4abd..5ec59ea 100644 --- a/src/Moof/Plane.hh +++ b/src/Moof/Plane.hh @@ -28,15 +28,16 @@ #ifndef _MOOF_PLANE_HH_ #define _MOOF_PLANE_HH_ - + #include +#include namespace Mf { -class Aabb; -class Sphere; +template class Aabb; +template class Sphere; /* @@ -44,7 +45,7 @@ class Sphere; * is normal to the plane. */ -struct Plane +struct Plane : public Shape<3> { Vector3 normal; Scalar d; @@ -65,8 +66,41 @@ struct Plane d(scalar) {} + Scalar intersectRay(const Ray<3>& ray, Ray<3>::Intersection& intersection) + { + // solve: [(ray.point + t*ray.direction) dot normal] + d = 0 + + Scalar denominator = cml::dot(ray.direction, normal); + + // check for parallel condition + if (denominator == SCALAR(0.0)) + { + if (isEqual(cml::dot(ray.point, normal), -d)) + { + // the ray lies on the plane + intersection.point = ray.point; + intersection.normal = normal; + return SCALAR(0.0); + } + + // no solution + return SCALAR(-1.0); + } + + Scalar t = (cml::dot(ray.point, normal) + d) / denominator; + if (t > SCALAR(0.0)) + { + ray.solve(intersection.point, t); + intersection.normal = normal; + } + + return t; + } + + /* Causes the normal of the plane to become normalized. The scalar may also - * be changed to keep the equation true. */ + * be changed to keep the equation true. Word to the wise: don't normalize + * a plane if the normal is the zero vector. */ void normalize() { Scalar mag = normal.length(); @@ -92,8 +126,8 @@ struct Plane else return POSITIVE; } - Halfspace intersects(const Aabb& aabb) const; - Halfspace intersects(const Sphere& sphere) const; + Halfspace intersects(const Aabb<3>& aabb) const; + Halfspace intersects(const Sphere<3>& sphere) const; }; diff --git a/src/Moof/Ray.hh b/src/Moof/Ray.hh new file mode 100644 index 0000000..15e1d9d --- /dev/null +++ b/src/Moof/Ray.hh @@ -0,0 +1,89 @@ + +/******************************************************************************* + + 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_RAY_HH_ +#define _MOOF_RAY_HH_ + +#include +#include +#include +#include + + +namespace Mf { + + +/** + * A line that goes to infinity. + */ + +template +struct Ray : public Drawable +{ + typedef cml::vector< Scalar, cml::fixed > Vector; + + // solution = point + t*direction + Vector point; + Vector direction; + + struct Intersection + { + Vector point; // nearest point of intersection + Vector normal; // surface normal at intersection point + }; + + void solve(Vector& p, Scalar t) const + { + p = point + t*direction; + } + + void draw(Scalar alpha = 0.0) const + { + Vector end = point + 1000.0 * direction; + + Mf::Texture::resetBind(); + glBegin(GL_LINES); + glVertex(point); + glVertex(end); + glEnd(); + } + + void normalize() + { + direction.normalize(); + } + +}; + + +} // namespace Mf + +#endif // _MOOF_RAY_HH_ + +/** vim: set ts=4 sw=4 tw=80: *************************************************/ + diff --git a/src/Moof/Shape.hh b/src/Moof/Shape.hh new file mode 100644 index 0000000..b78eaad --- /dev/null +++ b/src/Moof/Shape.hh @@ -0,0 +1,80 @@ + +/******************************************************************************* + + 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_SHAPE_HH_ +#define _MOOF_SHAPE_HH_ + +#include +#include +#include +#include + + +// Frustum +// Plane (can construct from Triangle<3>) +// Ray +// Shape<> +// +- Line<> +// +- Ball<> +// | Circle <- Ball<2> +// | Sphere <- Ball<3> +// +- Box<> +// | Rectangle <- Box<2> +// | Aabb <- Box<3> +// +- Polygon<> +// | Triangle <- Polygon<3> +// +- Cylinder +// +- Cone + + +namespace Mf { + + +template +class Shape +{ + /** + * Checks if this shape is intersected by a given ray. If so, returns the + * distance from the start of the ray to the shape and information about the + * intersection via the 2nd parameter. A negative value is returned if + * there is no intersection. + */ + virtual Scalar intersectRay(const Ray& ray, + typename Ray::Intersection& intersection) + { + return SCALAR(-1.0); + } +}; + + +} // namespace Mf + +#endif // _MOOF_SHAPE_HH_ + +/** vim: set ts=4 sw=4 tw=80: *************************************************/ + diff --git a/src/Moof/Sphere.cc b/src/Moof/Sphere.cc index 5e43e0d..aa2c139 100644 --- a/src/Moof/Sphere.cc +++ b/src/Moof/Sphere.cc @@ -46,7 +46,8 @@ void Sphere::draw(Scalar alpha) const glPushMatrix(); - glTranslate(point[0], point[1], point[2]); + //glTranslate(point[0], point[1], point[2]); + glTranslate(point); gluSphere(sphereObj, (GLdouble)radius, 16, 16); glPopMatrix(); diff --git a/src/Moof/Sphere.hh b/src/Moof/Sphere.hh index 319a3ae..f7b6a95 100644 --- a/src/Moof/Sphere.hh +++ b/src/Moof/Sphere.hh @@ -31,7 +31,10 @@ #include #include +#include #include +#include +#include namespace Mf { @@ -41,41 +44,134 @@ namespace Mf { * A round object. */ -struct Sphere : public Cullable, public Drawable +template +struct Sphere : public Cullable, public Drawable, public Shape { - Vector3 point; + typedef cml::vector< Scalar, cml::fixed > Vector; + + // (solution - point)^2 - radius^2 = 0 + Vector point; Scalar radius; Sphere() {} - Sphere(const Vector3& p, Scalar r) : + Sphere(const Vector& p, Scalar r) : point(p), radius(r) {} - Sphere(Scalar x, Scalar y, Scalar z, Scalar r) : - point(x, y, z), - radius(r) {} + //Sphere(Scalar x, Scalar y, Scalar z, Scalar r) : + //point(x, y, z), + //radius(r) {} - void init(const Vector3& p, Scalar r) + void init(const Vector& p, Scalar r) { point = p; radius = r; } - void init(const Vector3& p, const Vector3& o) + void init(const Vector& p, const Vector& o) { point = p; radius = (o - p).length(); } - void encloseVertices(const Vector3 vertices[], unsigned count); - void draw(Scalar alpha = 0.0) const; - bool isVisible(const Frustum& frustum) const; + // a ray inside the sphere will not intersect on its way out + Scalar intersectRay(const Ray& ray, + typename Ray::Intersection& intersection) + { + Vector b = point - ray.point; + Scalar z = cml::dot(b, ray.direction); + + // check if the ball is behind the ray + if (z < SCALAR(0.0)) return SCALAR(-1.0); + + Scalar d2 = cml::dot(b, b) - z*z; + Scalar r2 = radius * radius; + + // check for an intersection + if (d2 > r2) return SCALAR(-1.0); + + Scalar t = z - std::sqrt(r2 - d2); + ray.solve(intersection.point, t); + intersection.normal = intersection.point - point; + + return t; + } + + + //void encloseVertices(const Vector vertices[], unsigned count); + + //void draw(Scalar alpha = 0.0) const; + //bool isVisible(const Frustum& frustum) const; + +void encloseVertices(const Vector vertices[], unsigned count) +{ + // TODO +} + +void draw(Scalar alpha = 0.0) const; +//{ + //GLUquadricObj* sphereObj = gluNewQuadric(); + //gluQuadricDrawStyle(sphereObj, GLU_LINE); + + //glPushMatrix(); + + //glTranslate(point); + //gluSphere(sphereObj, GLdouble(radius), 16, 16); + + //glPopMatrix(); + + //gluDeleteQuadric(sphereObj); +//} + +bool isVisible(const Frustum& frustum) const +{ + return true; +} }; -inline bool checkCollision(const Sphere& a, const Sphere& b) +template <> +inline bool Sphere<3>::isVisible(const Frustum& frustum) const +{ + return frustum.contains(*this); +} + +template <> +inline void Sphere<2>::draw(Scalar alpha) const +{ + GLUquadricObj* sphereObj = gluNewQuadric(); + gluQuadricDrawStyle(sphereObj, GLU_LINE); + + glPushMatrix(); + + glTranslate(promote(point)); + gluSphere(sphereObj, GLdouble(radius), 16, 16); + + glPopMatrix(); + + gluDeleteQuadric(sphereObj); +} + +template <> +inline void Sphere<3>::draw(Scalar alpha) const +{ + GLUquadricObj* sphereObj = gluNewQuadric(); + gluQuadricDrawStyle(sphereObj, GLU_LINE); + + glPushMatrix(); + + glTranslate(point); + gluSphere(sphereObj, GLdouble(radius), 16, 16); + + glPopMatrix(); + + gluDeleteQuadric(sphereObj); +} + +template +inline bool checkCollision(const Sphere& a, const Sphere& b) { Scalar d = (a.point - b.point).length(); return d < (a.radius + b.radius); diff --git a/src/Moof/Transition.hh b/src/Moof/Transition.hh index ab09c02..310e8ea 100644 --- a/src/Moof/Transition.hh +++ b/src/Moof/Transition.hh @@ -97,15 +97,15 @@ public: glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); - glColor4(1.0, 1.0, 1.0, alpha); + glColor(1.0, 1.0, 1.0, alpha); Mf::Texture::resetBind(); //glRectf(-1.0f, -1.0f, 1.0f, 1.0f); glBegin(GL_QUADS); - glVertex3f(-1.0, -1.0, -0.1); - glVertex3f(1.0, -1.0, -0.1); - glVertex3f(1.0, 1.0, -0.1); - glVertex3f(-1.0, 1.0, -0.1); + glVertex(-1.0, -1.0, -0.1); + glVertex(1.0, -1.0, -0.1); + glVertex(1.0, 1.0, -0.1); + glVertex(-1.0, 1.0, -0.1); glEnd(); glDisable(GL_BLEND); diff --git a/src/Scene.cc b/src/Scene.cc index 9b4d1fd..452cc13 100644 --- a/src/Scene.cc +++ b/src/Scene.cc @@ -34,6 +34,7 @@ #include #include #include +#include #include #include //#include @@ -156,9 +157,10 @@ struct Scene::Impl : public Mf::Library std::string mTexture; //Mf::Octree::Ptr mOctree; - std::list< boost::shared_ptr > mObjects; + std::list< boost::shared_ptr > mObjects; + std::list< Mf::Line<2> > mLines; - Mf::Aabb mBounds; + Mf::Aabb<3> mBounds; enum AXIS @@ -219,7 +221,7 @@ struct Scene::Impl : public Mf::Library } - static int loadBox(Mf::Script& script, Mf::Aabb& aabb) + static int loadBox(Mf::Script& script, Mf::Aabb<3>& aabb) { Mf::Script::Value table[] = { @@ -413,6 +415,14 @@ struct Scene::Impl : public Mf::Library Quad* quad = new Quad(demotedVertices, mTexture, indices[h][w]); quad->setSurface(surface); + if (surface != Quad::NONE) + { + // need a 2d line for collisions + // assuming the camera always looks directly to -z when the + // scene is built, simply demoting the vector again should + // project the points to the xy-plane + } + boost::shared_ptr quadPtr(quad); //mOctree->insert(quadPtr); mObjects.push_back(quadPtr); @@ -545,7 +555,7 @@ bool Scene::checkForCollision(Character& character) std::list< boost::shared_ptr >::const_iterator it; int collisions = 0; - Mf::Sphere sphere = character.getSphere(); + Mf::Sphere<3> sphere = character.getSphere(); for (it = objects.begin(); it != objects.end(); ++it) { diff --git a/src/version.c b/src/version.c new file mode 100644 index 0000000..9e78b78 --- /dev/null +++ b/src/version.c @@ -0,0 +1,40 @@ + +/******************************************************************************* + + 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 "version.h" + + +#if defined(__DATE__) && defined(__TIME__) +const char* COMPILE_TIME = __DATE__" "__TIME__; +#else +const char* COMPILE_TIME = "Unknown"; +#endif + + +/** vim: set ts=4 sw=4 tw=80: *************************************************/ + diff --git a/src/version.h b/src/version.h index 3ea5cf2..a6e48d5 100644 --- a/src/version.h +++ b/src/version.h @@ -30,6 +30,10 @@ #define _VERSION_H_ +// the time and date of the compilation +extern const char* COMPILE_TIME; + + // yoinked from fluxbox #ifdef __VERSION__