12#ifndef CSCI441_MD5_CAMERA_HPP
13#define CSCI441_MD5_CAMERA_HPP
72 explicit MD5Camera(
const char* MD5CAMERA_FILE,
AdvancementStrategy advancementStrategy, GLuint firstCutToRun = 0, GLfloat aspectRatio = 1.0f, GLfloat fovy = 45.0f, GLfloat nearClipPlane = 0.001f, GLfloat farClipPlane = 1000.0f, GLboolean INFO =
true, GLboolean ERRORS =
true);
104 bool _loadMD5CameraFromFile(
const char * MD5CAMERA_FILE, GLboolean INFO =
true, GLboolean ERRORS =
true);
112 glm::vec3 cameraPosition;
113 glm::vec3 cameraQuaternion;
120 GLuint* _cutPositions;
122 GLuint _currentFrameIndex;
123 GLuint _currentCutIndex;
126 void _updateCameraAttributesForCurrentFrame();
130 GLfloat _aspectRatio;
131 GLfloat _nearClipPlane;
132 GLfloat _farClipPlane;
137 const char *
const MD5CAMERA_FILE,
139 const GLuint firstCutToRun,
140 const GLfloat aspectRatio,
142 const GLfloat nearClipPlane,
143 const GLfloat farClipPlane,
144 const GLboolean INFO,
145 const GLboolean ERRORS
146) : _isInitialized(false),
150 _cutPositions(nullptr),
152 _currentFrameIndex(0),
153 _currentCutIndex(firstCutToRun),
154 _advancementStrategy(advancementStrategy),
156 _aspectRatio(aspectRatio),
157 _nearClipPlane(nearClipPlane),
158 _farClipPlane(farClipPlane)
160 mProjectionMatrix = glm::perspective(_fovy, _aspectRatio, _nearClipPlane, _farClipPlane);
162 _isInitialized = _loadMD5CameraFromFile(MD5CAMERA_FILE, INFO, ERRORS);
169 _isInitialized(false),
173 _cutPositions(nullptr),
175 _currentFrameIndex(0),
180 _nearClipPlane(0.001f),
181 _farClipPlane(1000.0f)
188) noexcept :
Camera(std::move(src)),
189 _isInitialized(
false),
193 _cutPositions(
nullptr),
195 _currentFrameIndex(0),
197 _advancementStrategy(AdvancementStrategy::RUN_SINGLE_CUT),
200 _nearClipPlane(0.001f),
201 _farClipPlane(1000.0f)
203 this->_moveFromSource(src);
222 this->_moveFromSource(src);
236inline void CSCI441::MD5Camera::_copy(
const MD5Camera& OTHER) {
238 _aspectRatio = OTHER._aspectRatio;
239 _nearClipPlane = OTHER._nearClipPlane;
240 _farClipPlane = OTHER._farClipPlane;
241 _frameRate = OTHER._frameRate;
242 _currentFrameIndex = OTHER._currentFrameIndex;
243 _currentCutIndex = OTHER._currentCutIndex;
244 _advancementStrategy = OTHER._advancementStrategy;
246 _isInitialized = OTHER._isInitialized;
248 _numCuts = OTHER._numCuts;
249 _cutPositions =
new GLuint[_numCuts];
250 for(
unsigned int i = 0; i < _numCuts; i++) {
251 _cutPositions[i] = OTHER._cutPositions[i];
254 _numFrames = OTHER._numFrames;
255 _frames =
new Frame[_numFrames];
256 for(
unsigned int i = 0; i < _numFrames; i++) {
257 _frames[i] = OTHER._frames[i];
265 _aspectRatio = src._aspectRatio;
266 src._aspectRatio = 0.0f;
268 _nearClipPlane = src._nearClipPlane;
269 src._nearClipPlane = 0.0f;
271 _farClipPlane = src._farClipPlane;
272 src._farClipPlane = 0.0f;
274 _frameRate = src._frameRate;
277 _currentFrameIndex = src._currentFrameIndex;
278 src._currentFrameIndex = 0;
280 _currentCutIndex = src._currentCutIndex;
281 src._currentCutIndex = 0;
283 _advancementStrategy = src._advancementStrategy;
285 _isInitialized = src._isInitialized;
286 src._isInitialized =
false;
288 _numCuts = src._numCuts;
291 _cutPositions = src._cutPositions;
292 src._cutPositions =
nullptr;
294 _numFrames = src._numFrames;
297 _frames = src._frames;
298 src._frames =
nullptr;
301inline void CSCI441::MD5Camera::_free() {
305 delete[] _cutPositions;
306 _cutPositions =
nullptr;
310inline bool CSCI441::MD5Camera::_loadMD5CameraFromFile(
311 const char *
const MD5CAMERA_FILE,
312 const GLboolean INFO,
313 const GLboolean ERRORS
315 if ( INFO ) fprintf( stdout,
"[.md5camera]: -=-=-=-=-=-=-=- BEGIN %s Info -=-=-=-=-=-=-=- \n", MD5CAMERA_FILE );
320 std::ifstream md5CameraFile(MD5CAMERA_FILE);
321 if( !md5CameraFile.is_open() ) {
322 if (ERRORS) fprintf( stderr,
"[.md5camera]: [ERROR]: Could not open \"%s\"\n", MD5CAMERA_FILE );
323 if ( INFO ) fprintf( stdout,
"[.md5camera]: -=-=-=-=-=-=-=- END %s Info -=-=-=-=-=-=-=- \n", MD5CAMERA_FILE );
327 std::string sectionLabel, commandLineStr, brace;
329 Frame frame = { glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 0.0f, 0.0f), 45.0f };
332 md5CameraFile >> sectionLabel >> md5version;
333 if(sectionLabel !=
"MD5Version" || md5version != 10) {
334 if (ERRORS) fprintf (stderr,
"[.md5camera]: [ERROR]: improper MD5Camera version found \"%s %d\"\n", sectionLabel.c_str(), md5version );
335 if ( INFO ) fprintf( stdout,
"[.md5camera]: -=-=-=-=-=-=-=- END %s Info -=-=-=-=-=-=-=- \n", MD5CAMERA_FILE );
340 md5CameraFile >> sectionLabel;
341 getline(md5CameraFile, commandLineStr);
343 for(
unsigned short i = 0; i < 5; i++) {
344 md5CameraFile >> sectionLabel;
345 if(sectionLabel ==
"numFrames") {
347 md5CameraFile >> _numFrames;
348 _frames =
new Frame[_numFrames];
349 }
else if(sectionLabel ==
"frameRate") {
351 md5CameraFile >> _frameRate;
352 }
else if(sectionLabel ==
"numCuts") {
354 md5CameraFile >> _numCuts;
355 _cutPositions =
new GLuint[_numCuts];
356 }
else if(sectionLabel ==
"cuts") {
361 md5CameraFile >> brace;
362 if (_cutPositions ==
nullptr) {
363 if (ERRORS) fprintf( stderr,
"[.md5camera]: [ERROR]: malformed md5camera file. numCuts not previously defined in file\n" );
366 for(
unsigned int cutNumber = 0; cutNumber < _numCuts; cutNumber++) {
367 md5CameraFile >> _cutPositions[cutNumber];
369 md5CameraFile >> brace;
370 _currentFrameIndex = _cutPositions[_currentCutIndex];
371 }
else if(sectionLabel ==
"camera") {
375 md5CameraFile >> brace;
376 for(
unsigned int frameNumber = 0; frameNumber < _numFrames; frameNumber++) {
377 md5CameraFile >> brace >> frame.cameraPosition.x >> frame.cameraPosition.y >> frame.cameraPosition.z >> brace;
378 md5CameraFile >> brace >> frame.cameraQuaternion.x >> frame.cameraQuaternion.y >> frame.cameraQuaternion.z >> brace;
379 md5CameraFile >> frame.fieldOfView;
381 md5CameraFile >> brace;
383 if (ERRORS) fprintf( stderr,
"[.md5camera]: [ERROR]: unknown section label found \"%s\"\n", sectionLabel.c_str() );
384 if ( INFO ) fprintf( stdout,
"[.md5camera]: -=-=-=-=-=-=-=- END %s Info -=-=-=-=-=-=-=- \n", MD5CAMERA_FILE );
390 printf(
"[.md5camera]: Camera Stats:\n" );
391 printf(
"[.md5camera]: Num Frames:\t%u\tFrame Rate:\t%u\tNum Cuts: \t%u\n", _numFrames, _frameRate, _numCuts );
395 double seconds = difftime( end, start );
398 printf(
"[.md5camera]: Completed in %.3fs\n", seconds );
399 printf(
"[.md5camera]: -=-=-=-=-=-=-=- END %s Info -=-=-=-=-=-=-=- \n\n", MD5CAMERA_FILE );
407 if( !_isInitialized )
return;
412 if( _currentFrameIndex == _numFrames - 1) {
413 switch(_advancementStrategy) {
414 case AdvancementStrategy::LOOP_ALL_CUTS:
416 _currentCutIndex = 0;
417 case AdvancementStrategy::LOOP_SINGLE_CUT:
419 _currentFrameIndex = _cutPositions[ _currentCutIndex ];
422 case AdvancementStrategy::RUN_SINGLE_CUT:
423 case AdvancementStrategy::RUN_ALL_CUTS:
429 else if( _currentCutIndex == _numCuts - 1 ) {
431 _currentFrameIndex++;
436 if( _currentFrameIndex == _cutPositions[_currentCutIndex + 1] - 1 ) {
437 switch(_advancementStrategy) {
438 case AdvancementStrategy::RUN_ALL_CUTS:
439 case AdvancementStrategy::LOOP_ALL_CUTS:
442 case AdvancementStrategy::LOOP_SINGLE_CUT:
444 _currentFrameIndex = _cutPositions[ _currentCutIndex ];
447 case AdvancementStrategy::RUN_SINGLE_CUT:
453 _currentFrameIndex++;
456 _updateCameraAttributesForCurrentFrame();
461 if( !_isInitialized )
return;
466 if( _currentFrameIndex == 0) {
467 switch(_advancementStrategy) {
468 case AdvancementStrategy::LOOP_ALL_CUTS:
470 _currentCutIndex = _numFrames-1;
473 case AdvancementStrategy::LOOP_SINGLE_CUT:
474 if( _numCuts == 1 ) {
476 _currentCutIndex = _numFrames-1;
479 _currentFrameIndex = _cutPositions[ _currentCutIndex+1 ] - 1;
483 case AdvancementStrategy::RUN_SINGLE_CUT:
484 case AdvancementStrategy::RUN_ALL_CUTS:
490 else if( _currentCutIndex == 0 ) {
492 _currentFrameIndex--;
497 if( _currentFrameIndex == _cutPositions[_currentCutIndex] ) {
498 switch(_advancementStrategy) {
499 case AdvancementStrategy::RUN_ALL_CUTS:
500 case AdvancementStrategy::LOOP_ALL_CUTS:
503 case AdvancementStrategy::LOOP_SINGLE_CUT:
505 _currentFrameIndex = _cutPositions[ _currentCutIndex+1 ] - 1;
508 case AdvancementStrategy::RUN_SINGLE_CUT:
514 _currentFrameIndex--;
517 _updateCameraAttributesForCurrentFrame();
520inline void CSCI441::MD5Camera::_updateCameraAttributesForCurrentFrame() {
522 mCameraPosition = _frames[_currentFrameIndex].cameraPosition;
526 glm::vec4 q(_frames[_currentFrameIndex].cameraQuaternion, 0.0f);
527 GLfloat t = 1.0f - (q.x * q.x) - (q.y * q.y) - (q.z * q.z);
534 glm::vec3 defaultCameraDirection(0.0f, 0.0f, -1.0f);
535 glm::vec4 inverseQ(-q.x, -q.y, -q.z, q.w);
536 inverseQ = glm::normalize(inverseQ);
538 glm::vec4 tmp( (q.w * defaultCameraDirection.x) + (q.y * defaultCameraDirection.z) - (q.z * defaultCameraDirection.y),
539 (q.w * defaultCameraDirection.y) + (q.z * defaultCameraDirection.x) - (q.x * defaultCameraDirection.z),
540 (q.w * defaultCameraDirection.z) + (q.x * defaultCameraDirection.y) - (q.y * defaultCameraDirection.x),
541 -(q.w * defaultCameraDirection.x) - (q.y * defaultCameraDirection.y) - (q.z * defaultCameraDirection.z) );
542 glm::vec4 rotatedCameraDirection((tmp.x * inverseQ.w) + (tmp.w * inverseQ.x) + (tmp.y * inverseQ.z) - (tmp.z * inverseQ.y),
543 (tmp.y * inverseQ.w) + (tmp.w * inverseQ.y) + (tmp.z * inverseQ.x) - (tmp.x * inverseQ.z),
544 (tmp.z * inverseQ.w) + (tmp.w * inverseQ.z) + (tmp.x * inverseQ.y) - (tmp.y * inverseQ.x),
545 (tmp.w * inverseQ.w) - (tmp.x * inverseQ.x) - (tmp.y * inverseQ.y) - (tmp.z * inverseQ.z) );
546 mCameraDirection = glm::vec3( rotatedCameraDirection.x, rotatedCameraDirection.y, rotatedCameraDirection.z );
547 mCameraLookAtPoint = mCameraPosition + mCameraDirection;
550 glm::vec3 defaultCameraUpVector(0.0f, 1.0f, 0.0f);
551 glm::vec4 tmp2( (q.w * defaultCameraUpVector.x) + (q.y * defaultCameraUpVector.z) - (q.z * defaultCameraUpVector.y),
552 (q.w * defaultCameraUpVector.y) + (q.z * defaultCameraUpVector.x) - (q.x * defaultCameraUpVector.z),
553 (q.w * defaultCameraUpVector.z) + (q.x * defaultCameraUpVector.y) - (q.y * defaultCameraUpVector.x),
554 -(q.w * defaultCameraUpVector.x) - (q.y * defaultCameraUpVector.y) - (q.z * defaultCameraUpVector.z) );
555 glm::vec4 rotatedCameraUpVector((tmp2.x * inverseQ.w) + (tmp2.w * inverseQ.x) + (tmp2.y * inverseQ.z) - (tmp2.z * inverseQ.y),
556 (tmp2.y * inverseQ.w) + (tmp2.w * inverseQ.y) + (tmp2.z * inverseQ.x) - (tmp2.x * inverseQ.z),
557 (tmp2.z * inverseQ.w) + (tmp2.w * inverseQ.z) + (tmp2.x * inverseQ.y) - (tmp2.y * inverseQ.x),
558 (tmp2.w * inverseQ.w) - (tmp2.x * inverseQ.x) - (tmp2.y * inverseQ.y) - (tmp2.z * inverseQ.z) );
559 mCameraUpVector = glm::vec3(rotatedCameraUpVector.x, rotatedCameraUpVector.y, rotatedCameraUpVector.z);
565 _fovy = _frames[_currentFrameIndex].fieldOfView;
566 mProjectionMatrix = glm::perspective(_fovy, _aspectRatio, _nearClipPlane, _farClipPlane);
Abstract Camera class to be placed (position and orientation) within our scene.
Abstract Class to represent a synthetic camera. The following methods must be overridden:
Definition: Camera.hpp:37
glm::mat4 mProjectionMatrix
stores the Projection Matrix
Definition: Camera.hpp:184
Camera & operator=(const Camera &)=default
assign a copy of an existing camera
A camera that implements the MD5Camera specification.
Definition: MD5Camera.hpp:28
MD5Camera & operator=(const MD5Camera &)
deep copy another MD5Camera
Definition: MD5Camera.hpp:206
~MD5Camera() override
delete cuts and frames
Definition: MD5Camera.hpp:232
AdvancementStrategy
what to do when the end of a cut is reached
Definition: MD5Camera.hpp:33
@ LOOP_SINGLE_CUT
run through just the initial specified cut, looping back to the beginning when the end is reached
@ LOOP_ALL_CUTS
run through all cuts beginning at initial specified cut, advancing to next cut when the end of the cu...
@ RUN_ALL_CUTS
run through all cuts beginning at initial specified cut, advancing to next cut when the end of the cu...
@ RUN_SINGLE_CUT
run through just the initial specified cut, stop when end is reached
void moveBackward(GLfloat unused) override
steps backward along the camera's view
Definition: MD5Camera.hpp:459
void recomputeOrientation() override
Uses theta, phi, & radius to update the camera's view matrix parameters. The camera orientation is co...
Definition: MD5Camera.hpp:99
void moveForward(GLfloat unused) override
steps forward along the camera's view
Definition: MD5Camera.hpp:405
MD5Camera()=delete
must create camera object from parameterized constructor
CSCI441 Helper Functions for OpenGL.
Definition: ArcballCam.hpp:17