diff --git a/src/engine/Makefile b/src/engine/Makefile index 4164e49..78c621f 100644 --- a/src/engine/Makefile +++ b/src/engine/Makefile @@ -6,6 +6,7 @@ EE_OBJS = \ models/math/point.o \ models/math/vector3.o \ models/mesh_frame.o \ + models/bounding_box.o \ models/mesh_material.o \ models/mesh.o \ models/sprite.o \ diff --git a/src/engine/include/models/bounding_box.hpp b/src/engine/include/models/bounding_box.hpp new file mode 100644 index 0000000..cab4a9b --- /dev/null +++ b/src/engine/include/models/bounding_box.hpp @@ -0,0 +1,94 @@ +/* +# ______ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2020, tyra - https://github.com/h4570/tyra +# Licenced under Apache License 2.0 +# Michał Mostowik +*/ + +#ifndef _TYRA_BOUNDING_BOX_ +#define _TYRA_BOUNDING_BOX_ + +#include +#include +#include "math/point.hpp" +#include "math/vector3.hpp" + +/** + * Struct containing face data used in + * bounding box class. + */ +struct BoundingBoxFace +{ + BoundingBoxFace(){ + + }; + BoundingBoxFace(const Vector3 &t_minCorner, const Vector3 &t_maxCorner, float t_axisPos) + { + minCorner = t_minCorner; + maxCorner = t_maxCorner; + axisPosition = t_axisPos; + } + /** Position of the face on it's respective axis. */ + float axisPosition; + /** Corner of the face with lower coordinates */ + Vector3 minCorner; + /** Corner of the face with higher coordinates */ + Vector3 maxCorner; +}; + +/** + * Class containing bounding box data + * which can be used for collision detection. + */ +class BoundingBox +{ +public: + BoundingBox(Vector3 *t_vertices); + ~BoundingBox(); + const float &getHeight() { return _height; }; + const float &getDepth() { return _depth; }; + const float &getWidth() { return _width; }; + /** @returns the vector directly in middle of the bounding box. */ + const Vector3 &getCenter() { return _centerVector; }; + /** @returns the front face (further on z-axis) */ + const BoundingBoxFace &getFrontFace() { return _frontFace; }; + /** @returns the back face (nearer on z-axis) */ + const BoundingBoxFace &getBackFace() { return _backFace; }; + /** @returns the left face (further on x-axis) */ + const BoundingBoxFace &getLeftFace() { return _leftFace; }; + /** @returns the right face (nearer on x-axis) */ + const BoundingBoxFace &getRightFace() { return _rightFace; }; + /** @returns the top face (further on y-axis) */ + const BoundingBoxFace &getTopFace() { return _topFace; }; + /** @returns the bottom face (nearer on y-axis) */ + const BoundingBoxFace &getBottomFace() { return _bottomFace; }; + /** + * @returns bounding box raw vertices array. + * Total length: 8 + */ + const Vector3 &getVertex(const u8 &i) { return _vertices[i]; }; + /** @returns single vertex from raw vertices array.*/ + Vector3 *getVertices() { return _vertices; }; + +private: + Vector3 _vertices[8]; + float _height, _depth, _width; + Vector3 _centerVector; + /** Front face (further on z-axis) */ + BoundingBoxFace _frontFace; + /** Back face (nearer on z-axis) */ + BoundingBoxFace _backFace; + /** Left face (nearer on x-axis) */ + BoundingBoxFace _leftFace; + /** Right face (further on x-axis) */ + BoundingBoxFace _rightFace; + /** Top face (further on y-axis) */ + BoundingBoxFace _topFace; + /** Bottom face (nearer on y-axis) */ + BoundingBoxFace _bottomFace; +}; + +#endif \ No newline at end of file diff --git a/src/engine/include/models/mesh.hpp b/src/engine/include/models/mesh.hpp index aec1470..1f9e7ea 100644 --- a/src/engine/include/models/mesh.hpp +++ b/src/engine/include/models/mesh.hpp @@ -94,10 +94,13 @@ public: * Returns bounding vertex of current frame. * @param i 0-7. Because, bounding box have 8 corners */ - Vector3 &getCurrentBoundingBoxVertex(const u8 &i) { return frames[animState.currentFrame].getBoundingBoxVertex(i); }; + const Vector3 &getCurrentBoundingBoxVertex(const u8 &i) { return frames[animState.currentFrame].getBoundingBoxVertex(i); }; - /** Returns bounding box of current frame. Size: 8 */ - Vector3 *getCurrentBoundingBox() const { return frames[animState.currentFrame].getBoundingBox(); }; + /** @returns bounding box vertex array of current frame. Size: 8 */ + const Vector3 *getCurrentBoundingBoxVertices() const { return frames[animState.currentFrame].getBoundingBoxVertices(); }; + + /** @returns bounding box object of current frame. */ + const BoundingBox *getCurrentBoundingBox() const { return frames[animState.currentFrame].getBoundingBox(); }; // ---- // Setters diff --git a/src/engine/include/models/mesh_frame.hpp b/src/engine/include/models/mesh_frame.hpp index 99ec249..cd7c299 100644 --- a/src/engine/include/models/mesh_frame.hpp +++ b/src/engine/include/models/mesh_frame.hpp @@ -13,6 +13,7 @@ #include #include +#include "bounding_box.hpp" #include "math/point.hpp" #include "math/vector3.hpp" #include "./mesh_material.hpp" @@ -76,16 +77,21 @@ public: MeshMaterial *getMaterials() const { return materials; }; /** - * Returns bounding box (AABB). + * @returns bounding box (AABB). * Total length: 8 */ - Vector3 *getBoundingBox() { return boundingBox; }; + Vector3 *getBoundingBoxVertices() { return boundingBoxObj->getVertices(); }; /** - * Returns bounding box (AABB) vertex. + * @returns bounding box (AABB) vertex. * Total length: 8 */ - Vector3 &getBoundingBoxVertex(const u8 &i) { return boundingBox[i]; }; + const Vector3 &getBoundingBoxVertex(const u8 &i) { return boundingBoxObj->getVertex(i); }; + + /** + * @returns bounding box (AABB) object pointer. + */ + BoundingBox *getBoundingBox() { return boundingBoxObj; }; // ---- // Setters @@ -139,7 +145,7 @@ public: void calculateBoundingBoxes(); private: - Vector3 boundingBox[8]; + BoundingBox *boundingBoxObj; u8 _areSTsAllocated, _areVerticesAllocated, _areNormalsAllocated, diff --git a/src/engine/include/models/mesh_material.hpp b/src/engine/include/models/mesh_material.hpp index 0b5447e..3ba2621 100644 --- a/src/engine/include/models/mesh_material.hpp +++ b/src/engine/include/models/mesh_material.hpp @@ -12,6 +12,7 @@ #define _TYRA_MESH_MATERIAL_ #include +#include "bounding_box.hpp" #include "./math/vector3.hpp" #include "./math/plane.hpp" @@ -62,16 +63,21 @@ public: u32 *getNormalFaces() const { return normalFaces; }; /** - * Returns bounding box (AABB). + * @returns bounding box (AABB). * Total length: 8 */ - Vector3 *getBoundingBox() { return boundingBox; }; + Vector3 *getBoundingBoxVertices() { return boundingBoxObj->getVertices(); }; /** - * Returns bounding box (AABB) vertex. + * @returns bounding box (AABB) vertex. * Total length: 8 */ - Vector3 &getBoundingBoxVertex(const u8 &i) { return boundingBox[i]; }; + const Vector3 &getBoundingBoxVertex(const u8 &i) { return boundingBoxObj->getVertex(i); }; + + /** + * @returns bounding box (AABB) object pointer. + */ + BoundingBox *getBoundingBox() { return boundingBoxObj; }; // ---- // Setters @@ -119,7 +125,7 @@ public: u8 isInFrustum(Plane *t_frustumPlanes, const Vector3 &position); private: - Vector3 boundingBox[8]; + BoundingBox *boundingBoxObj; u32 facesCount, id; u32 *vertexFaces, *stFaces, *normalFaces; u8 _isNameSet, _areFacesAllocated, _isBoundingBoxCalculated; diff --git a/src/engine/models/bounding_box.cpp b/src/engine/models/bounding_box.cpp new file mode 100644 index 0000000..dc90364 --- /dev/null +++ b/src/engine/models/bounding_box.cpp @@ -0,0 +1,49 @@ +/* +# ______ ____ ___ +# | \/ ____| |___| +# | | | \ | | +#----------------------------------------------------------------------- +# Copyright 2020, tyra - https://github.com/h4570/tyra +# Licenced under Apache License 2.0 +# Michał Mostowik +*/ + +#include "../include/models/bounding_box.hpp" +#include "../include/utils/debug.hpp" +#include + +/** + * Construct a BoundingBox class + * Allows for user friendly access to bounding box data. + * @param t_vertices Array of 8 Vector3 elements. + */ +BoundingBox::BoundingBox(Vector3 *t_vertices) +{ + //Perform a deep copy of vertex array parameter + memcpy(_vertices, t_vertices, 8 * sizeof(Vector3)); + + //This might be shortened with Vector3 operator overloading, but current + //implementation is more human readable. + _height = _vertices[0].y - _vertices[2].y; + _width = _vertices[0].x - _vertices[4].x; + _depth = _vertices[0].z - _vertices[1].z; + + _centerVector = _vertices[0]; + _centerVector.x += (_width / 2); + _centerVector.y += (_height / 2); + _centerVector.z += (_depth / 2); + + //Z-Axis faces + _frontFace = BoundingBoxFace(_vertices[1], _vertices[7], _vertices[1].z); + _backFace = BoundingBoxFace(_vertices[0], _vertices[6], _vertices[0].z); + //X-Axis faces + _leftFace = BoundingBoxFace(_vertices[0], _vertices[3], _vertices[0].x); + _rightFace = BoundingBoxFace(_vertices[4], _vertices[7], _vertices[4].x); + //Y-Axis faces + _topFace = BoundingBoxFace(_vertices[2], _vertices[7], _vertices[2].y); + _bottomFace = BoundingBoxFace(_vertices[0], _vertices[5], _vertices[0].y); +} + +BoundingBox::~BoundingBox() +{ +} \ No newline at end of file diff --git a/src/engine/models/mesh.cpp b/src/engine/models/mesh.cpp index 84cddce..5a47159 100644 --- a/src/engine/models/mesh.cpp +++ b/src/engine/models/mesh.cpp @@ -347,7 +347,7 @@ u8 Mesh::isInFrustum(Plane *t_frustumPlanes) { Vector3 boxCalcTemp; u8 boxResult = 1, boxIn = 0, boxOut = 0; - Vector3 *currentBoundingBox = getCurrentBoundingBox(); + const Vector3 *currentBoundingBox = getCurrentBoundingBoxVertices(); for (int i = 0; i < 6; i++) { boxOut = 0; diff --git a/src/engine/models/mesh_frame.cpp b/src/engine/models/mesh_frame.cpp index ff9883d..0e224cd 100644 --- a/src/engine/models/mesh_frame.cpp +++ b/src/engine/models/mesh_frame.cpp @@ -37,6 +37,7 @@ MeshFrame::~MeshFrame() delete[] normals; if (_areMaterialsAllocated) delete[] materials; + delete boundingBoxObj; } // ---- @@ -93,6 +94,7 @@ void MeshFrame::allocateMaterials(const u32 &t_val) void MeshFrame::calculateBoundingBoxes() { + Vector3 boundingBox[8]; if (!_areVerticesAllocated) { PRINT_ERR("Can't calculate bounding box, because vertices were not allocated!"); @@ -121,6 +123,7 @@ void MeshFrame::calculateBoundingBoxes() if (hiZ < vertices[i].z) hiZ = vertices[i].z; } + boundingBox[0].set(lowX, lowY, lowZ); boundingBox[1].set(lowX, lowY, hiZ); boundingBox[2].set(lowX, hiY, lowZ); @@ -131,4 +134,8 @@ void MeshFrame::calculateBoundingBoxes() boundingBox[6].set(hiX, hiY, lowZ); boundingBox[7].set(hiX, hiY, hiZ); _isBoundingBoxCalculated = true; + + //BoundingBox is declared on the heap to prevent any ill-formed default + //constructor instantiated BoundingBox objects. + boundingBoxObj = new BoundingBox(boundingBox); } diff --git a/src/engine/models/mesh_material.cpp b/src/engine/models/mesh_material.cpp index f435ce6..d6108da 100644 --- a/src/engine/models/mesh_material.cpp +++ b/src/engine/models/mesh_material.cpp @@ -9,6 +9,7 @@ */ #include "../include/models/mesh_material.hpp" +#include "../include/models/bounding_box.hpp" #include "../include/utils/debug.hpp" #include "../include/utils/string.hpp" #include @@ -82,9 +83,9 @@ u8 MeshMaterial::isInFrustum(Plane *t_frustumPlanes, const Vector3 &position) for (u8 y = 0; y < 8 && (boxIn == 0 || boxOut == 0); y++) { boxCalcTemp.set( - boundingBox[y].x + position.x, - boundingBox[y].y + position.y, - boundingBox[y].z + position.z); + boundingBoxObj->getVertex(y).x + position.x, + boundingBoxObj->getVertex(y).y + position.y, + boundingBoxObj->getVertex(y).z + position.z); if (t_frustumPlanes[i].distanceTo(boxCalcTemp) < 0) boxOut++; else @@ -101,6 +102,7 @@ u8 MeshMaterial::isInFrustum(Plane *t_frustumPlanes, const Vector3 &position) void MeshMaterial::calculateBoundingBox(Vector3 *t_vertices, u32 t_vertCount) { + Vector3 boundingBox[8]; float lowX, lowY, lowZ, hiX, hiY, hiZ; lowX = hiX = t_vertices[vertexFaces[0]].x; lowY = hiY = t_vertices[vertexFaces[0]].y; @@ -132,4 +134,8 @@ void MeshMaterial::calculateBoundingBox(Vector3 *t_vertices, u32 t_vertCount) boundingBox[6].set(hiX, hiY, lowZ); boundingBox[7].set(hiX, hiY, hiZ); _isBoundingBoxCalculated = true; + + //BoundingBox is declared on the heap to prevent any ill-formed default + //constructor instantiated BoundingBox objects. + boundingBoxObj = new BoundingBox(boundingBox); } diff --git a/src/samples/floors/utils.cpp b/src/samples/floors/utils.cpp index 5195cf9..d8b1021 100644 --- a/src/samples/floors/utils.cpp +++ b/src/samples/floors/utils.cpp @@ -38,7 +38,7 @@ void Utils::getMinMax(const Mesh &t_mesh, Vector3 &t_min, Vector3 &t_max) { Vector3 calc = Vector3(); u8 isInitialized = 0; - Vector3 *boundingBox = t_mesh.getCurrentBoundingBox(); + const Vector3 *boundingBox = t_mesh.getCurrentBoundingBoxVertices(); for (u32 i = 0; i < 8; i++) { calc.set(