#ifndef T_CLASS #define T_CLASS #include #include #include #include #include #include #include #include #include #include "Structures.h" class t { public: t() { pos = glm::vec3(0.0f); scale = glm::vec3(1.0f); orient = glm::quat(); } BoundingBox GetRotationlessAABB() { BoundingBox tr; tr.min = pos - scale/2.0f; tr.max = pos + scale/2.0f; return tr; } BoundingBox GetAABB() const { // Each world axis reaches as far as the rotated box's axes add up to, no need to visit the corners const glm::mat3 rotation = glm::mat3_cast(orient); const glm::vec3 half = scale * 0.5f; const glm::vec3 extent = glm::abs(rotation[0]) * half.x + glm::abs(rotation[1]) * half.y + glm::abs(rotation[2]) * half.z; BoundingBox tr; tr.min = pos - extent; tr.max = pos + extent; return tr; } float ScaleMagnitude2() { return scale.x* scale.x + scale.y* scale.y + scale.z* scale.z; } BoundingAxis GetBoundingAxis(int axis) { std::vector corners = { {0.5f,0.5f,0.5f}, {0.5f,-0.5f,0.5f}, {0.5f,-0.5f,-0.5f}, {0.5f,0.5f,-0.5f}, {-0.5f,0.5f,0.5f}, {-0.5f,-0.5f,0.5f}, {-0.5f,0.5f,-0.5f}, {-0.5f,-0.5f,-0.5f}, }; float min = FLT_MAX; float max = -FLT_MAX; bool init = false; for (glm::vec3& corner : corners) { corner *= scale; corner = orient * corner; corner += pos; min = std::min(min, corner[axis]); max = std::max(max, corner[axis]); } BoundingAxis tr; tr.min = min; tr.max = max; return tr; } void LookAt(glm::vec3 eye, glm::vec3 target) noexcept { TranslateTo(eye); orient = -orient * target; version++; } void TranslateBy(glm::vec3 e) noexcept { pos += e; version++; } void TranslateTo(glm::vec3 e) noexcept { pos = e; version++; } void ScaleBy(glm::vec3 e) noexcept { scale *= e; version++; } void ScaleBy(GLfloat e) noexcept { scale *= e; version++; } void ScaleTo(glm::vec3 e) noexcept { scale = e; version++; } void ScaleTo(GLfloat e) noexcept { scale = glm::vec3(e); version++; } void ScaleToX(GLfloat e) noexcept { scale.x = e; version++; } void ScaleToY(GLfloat e) noexcept { scale.y = e; version++; } void ScaleToZ(GLfloat e) noexcept { scale.z = e; version++; } void RotateToQuaternion(glm::quat q) noexcept { orient = q; version++; } void RotateByQuaternion(glm::quat q) noexcept { orient = q * orient; version++; } void NormalizeRotation() noexcept { orient = glm::normalize(orient); version++; } void RotateByQuaternionCumulate(glm::quat q) noexcept { orient = orient * q; version++; } void RotateByEulerAnglesCumulate(glm::vec3 e) noexcept { orient = orient * glm::quat(e); version++; } void RotateToEulerAngles(glm::vec3 e) noexcept { orient = glm::quat(e); version++; } void RotateByEulerAngles(glm::vec3 e) noexcept { RotateByQuaternion(glm::quat(e)); } glm::vec3 GetUpVector() const noexcept { glm::vec3 uppoint(0.0f, 1.0f,0.0f); return orient * uppoint; } glm::vec3 GetRightVector() const noexcept { glm::vec3 rightpoint(1.0f,0.0f, 0.0f); return orient * rightpoint; } glm::vec3 GetFrontVector() const noexcept { glm::vec3 frontpoint(0.0f,0.0f,1.0f); return orient * frontpoint; } glm::vec3 GetScale() const noexcept { return scale; } glm::vec3 GetTranslation() const noexcept { return pos; }; float GetTranslationX() const noexcept { return pos.x; } float GetTranslationY() const noexcept { return pos.y; } float GetTranslationZ() const noexcept { return pos.z; } void CopyMatrixTo(t& target) const noexcept { target.scale = scale; target.orient = orient; target.pos = pos; target.version++; } // Goes up every time it moves, turns or is resized, so other code can tell when something it worked out is stale unsigned int GetVersion() const noexcept { return version; } glm::mat4 GetScaleMatrix() const noexcept { return glm::scale(glm::mat4(1.0f), scale); } glm::mat4 GetTranslationMatrix() const noexcept { return glm::translate(glm::mat4(1.0f), pos); } glm::mat4 GetRotationMatrix() const noexcept { return glm::mat4_cast(orient); } // Kept until the transform changes. Physics asks for the same ones many times a step. glm::mat4 GetMatrix() const noexcept { if (cachedMatrixVersion != version) { // The rotation with each axis scaled and the translation dropped in, rather than three full matrices multiplied glm::mat4 matrix = glm::mat4_cast(orient); matrix[0] *= scale.x; matrix[1] *= scale.y; matrix[2] *= scale.z; matrix[3] = glm::vec4(pos, 1.0f); cachedMatrix = matrix; cachedMatrixVersion = version; } return cachedMatrix; } glm::mat4 GetMatrixRotationless() const noexcept { glm::mat4 scaleMat = glm::scale(glm::mat4(1.0f), scale); glm::mat4 translMat = glm::translate(glm::mat4(1.0f), pos); return translMat* scaleMat; } glm::quat GetRotationQuaternion() const noexcept { return orient; } glm::vec3 GetRotationEulerAngles() const noexcept { return glm::eulerAngles(orient); } private: glm::vec3 pos; glm::vec3 scale; glm::quat orient; unsigned int version = 1; mutable unsigned int cachedMatrixVersion = 0; mutable glm::mat4 cachedMatrix = glm::mat4(1.0f); }; class t_package { public: t t; }; #endif