#pragma once //======================================================================== // Geometry.h : Collection of code for 3D math and 3D shapes // // Part of the GameCode4 Application // // GameCode4 is the sample application that encapsulates much of the source code // discussed in "Game Coding Complete - 4th Edition" by Mike McShaffry and David // "Rez" Graham, published by Charles River Media. // ISBN-10: 1133776574 | ISBN-13: 978-1133776574 // // If this source code has found it's way to you, and you think it has helped you // in any way, do the authors a favor and buy a new copy of the book - there are // detailed explanations in it that compliment this code well. Buy a copy at Amazon.com // by clicking here: // http://www.amazon.com/gp/product/1133776574/ref=olp_product_details?ie=UTF8&me=&seller= // // There's a companion web site at http://www.mcshaffry.com/GameCode/ // // The source code is managed and maintained through Google Code: // http://code.google.com/p/gamecode4/ // // (c) Copyright 2012 Michael L. McShaffry and David Graham // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser GPL v3 // as published by the Free Software Foundation. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See // http://www.gnu.org/licenses/lgpl-3.0.txt for more details. // // You should have received a copy of the GNU Lesser GPL v3 // along with this program; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. // //======================================================================== //======================================================================== // Content References in Game Coding Complete 3rd Edition // // class glm::vec3 - Chapter 14, page 456 // class Vec4 - Chapter 14, page 457 // class Mat4x4 - Chapter 14, page 466 // class Quaternion - Chapter 14, page 471 // class Plane - Chapter 14, page 473 // class Frustum - Chapter 14, page 474 // #include #include #include #include #include const float GCC_PI = 3.14159265358979f; const float GCC_2PI = 2 * GCC_PI; extern glm::vec3 g_Up; extern glm::vec3 g_Right; extern glm::vec3 g_Forward; extern glm::vec4 g_Up4; extern glm::vec4 g_Right4; extern glm::vec4 g_Forward4; namespace geometry { inline glm::vec3 GetPosition(glm::mat4 matrix) { return glm::vec3(matrix[3]); } inline void SetPosition(glm::mat4 &matrix, glm::vec3 position) { matrix[3] = glm::vec4(position, matrix[3].w); } inline glm::vec3 GetDirection(glm::mat4 m) { // zero out position so we just have rotation component SetPosition(m, glm::vec3(0.0f)); glm::vec4 forward = m * g_Forward4; return glm::vec3(forward); } inline glm::mat4 BuildRotationX(float const radians) { return glm::rotate(glm::mat4(1.0f), radians, glm::vec3(1.0f, 0.0f, 0.0f)); } inline glm::mat4 BuildRotationY(float const radians) { return glm::rotate(glm::mat4(1.0f), radians, glm::vec3(0.0f, 1.0f, 0.0f)); } inline glm::mat4 BuildRotationZ(float const radians) { return glm::rotate(glm::mat4(1.0f), radians, glm::vec3(0.0f, 0.0f, 1.0f)); } inline glm::mat4 BuildTranslation(glm::vec3 const translation) { return glm::translate(glm::mat4(1.0f), translation); } inline glm::mat4 BuildYawPitchRoll(float const yawRadians, float const pitchRadians, float const rollRadians) { // [munnellg] taken from page 277 of 3d math primer for graphics and game development float cy = cos(yawRadians); float sy = sin(yawRadians); float cp = cos(pitchRadians); float sp = sin(pitchRadians); float cr = cos(rollRadians); float sr = sin(rollRadians); glm::mat4 rotation = glm::mat4( cy * cr + sy * sp * sr, sr * cp, -sy * cr + cy * sp * sr, 0.0f, -cy * sr + sy * sp * cr, cr * cp, sr * sy + cy * sp * cr, 0.0f, sy * cp, -sp, cy * cp, 0.0f, 0, 0, 0, 1.0f ); return rotation; } inline glm::vec3 GetYawPitchRoll(const glm::mat4 &orientation) { float yaw, pitch, roll; pitch = std::asin(-orientation[2][1]); double threshold = 0.001; // Hardcoded constant - burn him, he's a witch double test = std::cos(pitch); if (test > threshold) { roll = std::atan2(orientation[0][1], orientation[1][1]); yaw = std::atan2(orientation[2][0], orientation[2][2]); } else { roll = std::atan2(-orientation[1][0], orientation[0][0]); yaw = 0.0f; } return glm::vec3(yaw, pitch, roll); } }; //////////////////////////////////////////////////// // // D3D9 Vertex Type Definitions // // TRANSFORMED_VERTEX Description // UNTRANSFORMED_VERTEX Description // UNTRANSFORMED_LIT_VERTEX Description // D3D9Vertex_UnlitColored Description // D3D9Vertex_ColoredTextured Description // D3D9Vertex_Colored Description // // Note: There's been a slight change from the book in this code. // Instead of #define D3DFVF_BlahBlah they are static constants; // find them at the top of Geometry.cpp // // See Game Coding Complete, 3rd Edition, Chapter 13, page 440-444 //////////////////////////////////////////////////// struct SimpleVertex { glm::vec3 Pos; glm::vec3 Normal; }; struct VertexUnlitTextured { glm::vec3 Pos; glm::vec3 Normal; glm::vec2 Uv; }; struct VertexUnlitTexturedColored { glm::vec3 Pos; glm::vec3 Normal; glm::vec3 Diffuse; glm::vec2 Uv; }; struct VertexPositionColored { glm::vec3 Pos; glm::vec3 Diffuse; }; //////////////////////////////////////////////////// // // Plane Definition // //////////////////////////////////////////////////// class Plane { }; //////////////////////////////////////////////////// // // Frustum Definition // //////////////////////////////////////////////////// class Frustum { public: enum Side { Near, Far, Top, Right, Bottom, Left, NumPlanes }; Plane m_Planes[NumPlanes]; // planes of the frustum in camera space glm::vec3 m_NearClip[4]; // verts of the near clip planes in camera space glm::vec3 m_FarClip[4]; // verts of the far clip plane in camera space float m_Fov; // field of view in radians float m_Aspect; // aspect ratio - width divided by height float m_Near; // near clipping distance float m_Far; // far clipping distance public: Frustum(); bool Inside(const glm::vec3 &point) const; bool Inside(const glm::vec3 &point, const float radius) const; const Plane &Get(Side side) { return m_Planes[side]; } void SetFOV(float fov) { m_Fov=fov; Init(m_Fov, m_Aspect, m_Near, m_Far); } void SetAspect(float aspect) { m_Aspect=aspect; Init(m_Fov, m_Aspect, m_Near, m_Far); } void SetNear(float near) { m_Near=near; Init(m_Fov, m_Aspect, m_Near, m_Far); } void SetFar(float far) { m_Far=far; Init(m_Fov, m_Aspect, m_Near, m_Far); } void Init(const float fov, const float aspect, const float near, const float far); void Render(); };