12#ifndef CSCI441_MD5_MODEL_TYPES_HPP
13#define CSCI441_MD5_MODEL_TYPES_HPP
48#ifdef CSCI441_USE_GLEW
54#include <glm/ext/quaternion_float.hpp>
59namespace CSCI441_INTERNAL {
71 static constexpr GLshort MAX_NAME_LENGTH = 512;
79 char filename[MAX_NAME_LENGTH] =
"";
84 MD5Texture() =
default;
89 MD5Texture(
const MD5Texture &OTHER) {
97 MD5Texture& operator=(
const MD5Texture &OTHER) {
107 MD5Texture(MD5Texture&& src)
noexcept {
115 MD5Texture& operator=(MD5Texture&& src)
noexcept {
126 void _copyFromSrc(
const MD5Texture &src) {
127 this->texHandle = src.texHandle;
128 strncpy(this->filename, src.filename, MAX_NAME_LENGTH);
134 void _moveFromSrc(MD5Texture& src) {
138 strncpy(src.filename,
"", MAX_NAME_LENGTH);
143 struct MD5MaterialShader {
147 static constexpr GLshort MAX_NAME_LENGTH = 512;
151 static constexpr GLshort NUM_TEXTURES = 4;
155 char name[MAX_NAME_LENGTH] =
"";
159 MD5Texture textures[NUM_TEXTURES];
163 GLuint displacementScale = 1;
185 MD5MaterialShader() =
default;
186 MD5MaterialShader(
const MD5MaterialShader &OTHER) {
189 MD5MaterialShader& operator=(
const MD5MaterialShader &OTHER) {
190 if (
this != &OTHER) {
195 MD5MaterialShader(MD5MaterialShader&& src)
noexcept {
198 MD5MaterialShader& operator=(MD5MaterialShader&& src)
noexcept {
205 void _copyFromSrc(
const MD5MaterialShader &src) {
206 for (GLshort i = 0; i < NUM_TEXTURES; i++) {
207 this->textures[i] = src.textures[i];
209 strncpy(this->name, src.name, MAX_NAME_LENGTH);
211 void _moveFromSrc(MD5MaterialShader &src) {
212 for (GLshort i = 0; i < NUM_TEXTURES; i++) {
213 this->textures[i] = std::move( src.textures[i] );
215 strncpy(this->name, src.name, MAX_NAME_LENGTH);
216 strncpy(src.name,
"", MAX_NAME_LENGTH);
230 static constexpr GLint NULL_JOINT = -1;
234 static constexpr GLshort MAX_NAME_LENGTH = 256;
238 char name[MAX_NAME_LENGTH] =
"";
242 GLint parent = NULL_JOINT;
246 glm::vec3 position = {0.0f, 0.0f, 0.0f};
250 glm::quat orientation = {0.0f, 0.0f, 0.0f, 0.0f};
255 MD5Joint() =
default;
260 MD5Joint(
const MD5Joint &OTHER) {
268 MD5Joint& operator=(
const MD5Joint &OTHER) {
269 if (
this != &OTHER) {
278 MD5Joint(MD5Joint&& src)
noexcept {
286 MD5Joint& operator=(MD5Joint&& src)
noexcept {
297 void _copyFromSrc(
const MD5Joint& src) {
298 strncpy(this->name, src.name, MAX_NAME_LENGTH);
299 this->parent = src.parent;
300 this->position = src.position;
301 this->orientation = src.orientation;
308 void _moveFromSrc(MD5Joint& src) {
312 strncpy(src.name,
"", MAX_NAME_LENGTH);
313 src.parent = NULL_JOINT;
314 src.position = glm::vec3(0.0f, 0.0f, 0.0f);
315 src.orientation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
326 glm::vec2 texCoord = {0.0f, 0.0f};
339 MD5Vertex() =
default;
344 MD5Vertex(
const MD5Vertex &OTHER) {
352 MD5Vertex& operator=(
const MD5Vertex &OTHER) {
353 if (
this != &OTHER) {
362 MD5Vertex(MD5Vertex&& src)
noexcept {
370 MD5Vertex& operator=(MD5Vertex&& src)
noexcept {
381 void _copyFromSrc(
const MD5Vertex &src) {
382 this->texCoord = src.texCoord;
383 this->start = src.start;
384 this->count = src.count;
390 void _moveFromSrc(MD5Vertex& src) {
393 src.texCoord = glm::vec2(0.0f, 0.0f);
406 static constexpr GLshort NUM_VERTICES = 3;
410 GLint index[NUM_VERTICES] = {0};
415 MD5Triangle() =
default;
420 MD5Triangle(
const MD5Triangle &OTHER) {
428 MD5Triangle& operator=(
const MD5Triangle &OTHER) {
429 if (
this != &OTHER) {
438 MD5Triangle(MD5Triangle&& src)
noexcept {
446 MD5Triangle& operator=(MD5Triangle&& src)
noexcept {
457 void _copyFromSrc(
const MD5Triangle &src) {
458 for (GLshort i = 0; i < NUM_VERTICES; i++) {
459 this->index[i] = src.index[i];
466 void _moveFromSrc(MD5Triangle &src) {
469 for (GLint & i : src.index) {
482 GLint joint = MD5Joint::NULL_JOINT;
490 glm::vec3 position = {0.0f, 0.0f, 0.0f};
495 MD5Weight() =
default;
500 MD5Weight(
const MD5Weight &OTHER) {
508 MD5Weight& operator=(
const MD5Weight &OTHER) {
509 if (
this != &OTHER) {
518 MD5Weight(MD5Weight&& src)
noexcept {
526 MD5Weight& operator=(MD5Weight&& src)
noexcept {
537 void _copyFromSrc(
const MD5Weight &src) {
538 this->joint = src.joint;
539 this->bias = src.bias;
540 this->position = src.position;
546 void _moveFromSrc(MD5Weight &src) {
549 src.joint = MD5Joint::NULL_JOINT;
551 src.position = glm::vec3(0.0f, 0.0f, 0.0f);
563 MD5Vertex* vertices =
nullptr;
567 MD5Triangle* triangles =
nullptr;
571 MD5Weight* weights =
nullptr;
573 MD5MaterialShader* shader =
nullptr;
578 GLint numVertices = 0;
582 GLint numTriangles = 0;
586 GLint numWeights = 0;
608 MD5Mesh(
const MD5Mesh &OTHER) =
delete;
613 MD5Mesh& operator=(
const MD5Mesh &OTHER) =
delete;
619 MD5Mesh(MD5Mesh&& src)
noexcept {
627 MD5Mesh& operator=(MD5Mesh&& src)
noexcept {
638 void _moveFromSrc(MD5Mesh& src) {
639 this->vertices = src.vertices;
640 src.vertices =
nullptr;
642 this->triangles = src.triangles;
643 src.triangles =
nullptr;
645 this->weights = src.weights;
646 src.weights =
nullptr;
648 this->shader = src.shader;
649 src.shader =
nullptr;
651 this->numVertices = src.numVertices;
654 this->numTriangles = src.numTriangles;
655 src.numTriangles = 0;
657 this->numWeights = src.numWeights;
668 struct MD5JointInfo {
672 static constexpr GLshort MAX_NAME_LENGTH = 256;
676 char name[MAX_NAME_LENGTH] =
"";
680 GLint parent = MD5Joint::NULL_JOINT;
688 GLint startIndex = 0;
693 MD5JointInfo() =
default;
698 MD5JointInfo(
const MD5JointInfo& OTHER) {
706 MD5JointInfo& operator=(
const MD5JointInfo& OTHER) {
707 if (
this != &OTHER) {
716 MD5JointInfo(MD5JointInfo&& src)
noexcept {
724 MD5JointInfo& operator=(MD5JointInfo&& src)
noexcept {
735 void _copyFromSrc(
const MD5JointInfo &src) {
736 strncpy(this->name, src.name, MAX_NAME_LENGTH);
737 this->parent = src.parent;
738 this->flags = src.flags;
739 this->startIndex = src.startIndex;
745 void _moveFromSrc(MD5JointInfo &src) {
748 strncpy(src.name,
"", MAX_NAME_LENGTH);
749 src.parent = MD5Joint::NULL_JOINT;
758 struct MD5BaseFrameJoint {
762 glm::vec3 position = {0.0f, 0.0f, 0.0f};
766 glm::quat orientation = {0.0f, 0.0f, 0.0f, 0.0f};
771 MD5BaseFrameJoint() =
default;
776 MD5BaseFrameJoint(
const MD5BaseFrameJoint& OTHER) {
784 MD5BaseFrameJoint& operator=(
const MD5BaseFrameJoint &OTHER) {
785 if (
this != &OTHER) {
794 MD5BaseFrameJoint(MD5BaseFrameJoint&& src)
noexcept {
802 MD5BaseFrameJoint& operator=(MD5BaseFrameJoint&& src)
noexcept {
813 void _copyFromSrc(
const MD5BaseFrameJoint &src) {
814 this->position = src.position;
815 this->orientation = src.orientation;
821 void _moveFromSrc(MD5BaseFrameJoint &src) {
824 src.position = glm::vec3(0.0f, 0.0f, 0.0f);
825 src.orientation = glm::quat(0.0f, 0.0f, 0.0f, 0.0f);
833 struct MD5BoundingBox {
837 glm::vec3 min = {0.0f, 0.0f, 0.0f};
841 glm::vec3 max = {0.0f, 0.0f, 0.0f};
846 MD5BoundingBox() =
default;
851 MD5BoundingBox(
const MD5BoundingBox &OTHER) {
859 MD5BoundingBox& operator=(
const MD5BoundingBox &OTHER) {
860 if (
this != &OTHER) {
869 MD5BoundingBox(MD5BoundingBox&& src)
noexcept {
877 MD5BoundingBox& operator=(MD5BoundingBox&& src)
noexcept {
888 void _copyFromSrc(
const MD5BoundingBox& src) {
896 void _moveFromSrc(MD5BoundingBox& src) {
899 src.min = glm::vec3(0.0f, 0.0f, 0.0f);
900 src.max = glm::vec3(0.0f, 0.0f, 0.0f);
919 [[nodiscard]] GLint getNumberOfFrames()
const {
return _numFrames; }
926 void setNumberOfFrames(
const GLint numFrames) {
928 if(_skeletonFrames !=
nullptr) {
929 for (GLint i = 0; i < _numFrames; ++i) {
930 delete _skeletonFrames[i];
933 delete[] _skeletonFrames;
934 _skeletonFrames =
nullptr;
935 delete[] _boundingBoxes;
936 _boundingBoxes =
nullptr;
938 _numFrames = numFrames;
939 if ( _numFrames > 0 ) {
940 _skeletonFrames =
new MD5Joint*[_numFrames];
941 for (GLint i = 0; i < _numFrames; ++i) {
942 _skeletonFrames[i] =
nullptr;
944 _boundingBoxes =
new MD5BoundingBox[_numFrames];
952 [[nodiscard]] GLint getNumberOfJoints()
const {
return _numJoints; }
960 void setNumberOfJoints(
const GLint numJoints) {
962 if(_skeletonFrames !=
nullptr) {
963 for (GLint i = 0; i < _numFrames; ++i) {
964 delete _skeletonFrames[i];
965 _skeletonFrames[i] =
nullptr;
969 _numJoints = numJoints;
970 if (_numJoints > 0) {
971 if(_skeletonFrames !=
nullptr) {
972 for(GLint i = 0; i < _numFrames; ++i) {
974 _skeletonFrames[i] =
new MD5Joint[_numJoints];
987 [[nodiscard]]
const MD5Joint* getSkeletonFrame(
const GLint frameIndex)
const {
988 if ( frameIndex < 0 || frameIndex >= _numFrames ) {
989 throw std::out_of_range(
"frameIndex out of range");
991 if (_skeletonFrames ==
nullptr) {
992 throw std::out_of_range(
"skeleton frames are null, setNumberOfFrames() may not have been called");
994 return _skeletonFrames[frameIndex];
1005 [[nodiscard]] MD5Joint& getSkeletonFrameJoint(
const GLint frameIndex,
const GLint jointIndex)
const {
1006 if ( frameIndex < 0 || frameIndex >= _numFrames ) {
1007 throw std::out_of_range(
"frameIndex out of range");
1009 if ( jointIndex < 0 || jointIndex >= _numJoints ) {
1010 throw std::out_of_range(
"jointIndex out of range");
1012 if (_skeletonFrames ==
nullptr) {
1013 throw std::out_of_range(
"skeleton frames are null, setNumberOfFrames() may not have been called");
1015 if (_skeletonFrames[frameIndex] ==
nullptr) {
1016 throw std::out_of_range(
"skeleton joints are null, setNumberOfJoints() may not have been called");
1018 return _skeletonFrames[frameIndex][jointIndex];
1028 [[nodiscard]] MD5BoundingBox& getBoundingBox(
const GLint frameIndex)
const {
1029 if(frameIndex < 0 || frameIndex >= _numFrames) {
1030 throw std::out_of_range(
"frameIndex out of range");
1032 if (_boundingBoxes ==
nullptr) {
1033 throw std::out_of_range(
"bounding boxes are null, setNumberOfFrames() may not have been called");
1035 return _boundingBoxes[frameIndex];
1041 MD5Animation() =
default;
1046 if(_skeletonFrames !=
nullptr) {
1047 for (GLint i = 0; i < _numFrames; i++) {
1048 delete[] _skeletonFrames[i];
1049 _skeletonFrames[i] =
nullptr;
1052 delete[] _skeletonFrames;
1053 _skeletonFrames =
nullptr;
1055 delete[] _boundingBoxes;
1056 _boundingBoxes =
nullptr;
1063 MD5Animation(
const MD5Animation& OTHER) =
delete;
1068 MD5Animation& operator=(
const MD5Animation& OTHER) =
delete;
1074 MD5Animation(MD5Animation&& src)
noexcept {
1082 MD5Animation& operator=(MD5Animation&& src)
noexcept {
1093 GLint _numFrames = 0;
1098 GLint _numJoints = 0;
1103 MD5Joint** _skeletonFrames =
nullptr;
1108 MD5BoundingBox* _boundingBoxes =
nullptr;
1114 void _moveFromSrc(MD5Animation &src) {
1115 this->_numFrames = src._numFrames;
1118 this->_numJoints = src._numJoints;
1121 this->frameRate = src.frameRate;
1124 this->_skeletonFrames = src._skeletonFrames;
1125 src._skeletonFrames =
nullptr;
1127 this->_boundingBoxes = src._boundingBoxes;
1128 src._boundingBoxes =
nullptr;
1135 struct MD5AnimationState {
1139 GLint currFrame = 0;
1143 GLint nextFrame = 0;
1147 GLfloat lastTime = 0.0f;
1152 GLfloat maxTime = 0.0f;
1157 MD5AnimationState() =
default;
1162 MD5AnimationState(
const MD5AnimationState &OTHER) {
1163 _copyFromSrc(OTHER);
1170 MD5AnimationState& operator=(
const MD5AnimationState &OTHER) {
1171 if (
this != &OTHER) {
1172 _copyFromSrc(OTHER);
1180 MD5AnimationState(MD5AnimationState&& src)
noexcept {
1188 MD5AnimationState& operator=(MD5AnimationState&& src)
noexcept {
1199 void _copyFromSrc(
const MD5AnimationState &src) {
1200 this->currFrame = src.currFrame;
1201 this->nextFrame = src.nextFrame;
1202 this->lastTime = src.lastTime;
1203 this->maxTime = src.maxTime;
1209 void _moveFromSrc(MD5AnimationState &src) {
1214 src.lastTime = 0.0f;