CameraKeyFrame.h#

Parent directory (cameras)

Defines a simple mechanism for handling key frames (time based).

Includes#

  • PVRCore/glm.h

  • vector

Namespaces#

Classes#

Source Code#

#pragma once
#include <vector>
#include "PVRCore/glm.h"

namespace pvr {
struct CameraKeyFrame
{
    uint64_t frameMs;
    glm::vec3 position;
    glm::vec2 orientation;

    CameraKeyFrame(uint64_t frameMs, const glm::vec3& pos, const glm::vec2& orientation)
    {
        this->frameMs = frameMs;
        position = pos;
        this->orientation = orientation;
    }

    CameraKeyFrame() : frameMs(0), position(glm::vec3(0.0f)), orientation(glm::vec2(0.0f)) {}
};

struct CameraAnimationController
{
    CameraAnimationController()
    {
        restart();
        totalKeyFrameMs = 0;
    }

    void restart()
    {
        startKeyFrame = 0;
        endKeyFrame = 1;
        globalMs = 0;
        localMs = 0;
    }

    void setTotalTimeInMs(uint64_t totalMs) { totalKeyFrameMs = totalMs; }

    void advanceTime(uint64_t dt)
    {
        globalMs += dt;
        localMs += dt;
        if (localMs > totalKeyFrameMs)
        {
            localMs = localMs % totalKeyFrameMs; // wrap
            startKeyFrame = 0;
            endKeyFrame = 1;
        }
        while (localMs > keyframes[endKeyFrame].frameMs)
        {
            startKeyFrame = endKeyFrame;
            endKeyFrame += 1;
        }
    }

    glm::vec3 getPosition() const
    {
        const glm::vec3& pos0 = keyframes[startKeyFrame].position;
        const glm::vec3& pos1 = keyframes[endKeyFrame].position;

        float s = localMs - keyframes[startKeyFrame].frameMs;
        s /= (keyframes[endKeyFrame].frameMs - keyframes[startKeyFrame].frameMs);
        return pos0 + (s * (pos1 - pos0));
    }

    glm::vec2 getOrientation() const
    {
        const glm::vec2 rot0 = keyframes[startKeyFrame].orientation;
        const glm::vec2 rot1 = keyframes[endKeyFrame].orientation;

        float s = localMs - keyframes[startKeyFrame].frameMs;
        s /= (keyframes[endKeyFrame].frameMs - keyframes[startKeyFrame].frameMs);
        return glm::vec2(rot0.x + (s * (rot1.x - rot0.x)), rot0.y + (s * (rot1.y - rot0.y)));
    }

    uint32_t getCurrentBeginKeyFrame() const { return startKeyFrame; }

    uint32_t getCurrentEndKeyFrame() const { return endKeyFrame; }

    uint64_t getNumKeyFrames() const { return keyframes.size(); }

    void addKeyFrames(const CameraKeyFrame* keyFrames, uint32_t numKeyFrames)
    {
        this->keyframes.reserve(numKeyFrames + this->keyframes.size());
        for(uint32_t i = 0; i < numKeyFrames; ++i) { this->keyframes.emplace_back(keyFrames[i]); }

        totalKeyFrameMs = std::max(totalKeyFrameMs, this->keyframes.back().frameMs);
    }

    std::vector<CameraKeyFrame> keyframes;
    uint32_t startKeyFrame;
    uint32_t endKeyFrame;
    uint64_t globalMs;
    uint64_t localMs;
    uint64_t totalKeyFrameMs;
};
} // namespace pvr