134 lines
2.9 KiB
C++
134 lines
2.9 KiB
C++
// timeline.cpp
|
|
//
|
|
// Object timelines.
|
|
//
|
|
// Copyright (C) 2008, the Celestia Development Team
|
|
// Initial version by Chris Laurel, claurel@gmail.com
|
|
//
|
|
// This program is free software; you can redistribute it and/or
|
|
// modify it under the terms of the GNU General Public License
|
|
// as published by the Free Software Foundation; either version 2
|
|
// of the License, or (at your option) any later version.
|
|
|
|
#include "celengine/timeline.h"
|
|
#include "celengine/timelinephase.h"
|
|
#include "celengine/frametree.h"
|
|
#include "celengine/frame.h"
|
|
|
|
using namespace std;
|
|
|
|
|
|
/*! A Timeline is a list of TimelinePhases that covers a continuous
|
|
* interval of time.
|
|
*/
|
|
|
|
Timeline::~Timeline()
|
|
{
|
|
for (auto phase : phases)
|
|
{
|
|
// Remove the phase from whatever phase tree contains it.
|
|
phase->getFrameTree()->removeChild(phase);
|
|
}
|
|
}
|
|
|
|
|
|
bool
|
|
Timeline::appendPhase(TimelinePhase::SharedConstPtr &phase)
|
|
{
|
|
// Validate start and end times. If there are existing phases in the timeline,
|
|
// startTime must be equal to endTime of the previous phases so that there are
|
|
// no gaps and no overlaps.
|
|
if (!phases.empty())
|
|
{
|
|
if (phase->startTime() != phases.back()->endTime())
|
|
return false;
|
|
}
|
|
|
|
phases.push_back(phase);
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
const TimelinePhase::SharedConstPtr&
|
|
Timeline::findPhase(double t) const
|
|
{
|
|
// Find the phase containing time t. The overwhelming common case is
|
|
// nPhases = 1, so we special case that. Otherwise, we do a simple linear search,
|
|
// as the number of phases in a timeline should always be quite small.
|
|
if (phases.size() == 1)
|
|
{
|
|
return phases[0];
|
|
}
|
|
else
|
|
{
|
|
for (const auto& phase : phases)
|
|
{
|
|
if (t < phase->endTime())
|
|
return phase;
|
|
}
|
|
|
|
// Time is greater than the end time of the final phase. Just return the final phase.
|
|
return phases.back();
|
|
}
|
|
}
|
|
|
|
|
|
/*! Get the phase at the specified index.
|
|
*/
|
|
const TimelinePhase::SharedConstPtr&
|
|
Timeline::getPhase(unsigned int n) const
|
|
{
|
|
return phases.at(n);
|
|
}
|
|
|
|
|
|
/*! Get the number of phases in this timeline.
|
|
*/
|
|
unsigned int
|
|
Timeline::phaseCount() const
|
|
{
|
|
return phases.size();
|
|
}
|
|
|
|
|
|
double
|
|
Timeline::startTime() const
|
|
{
|
|
return phases.front()->startTime();
|
|
}
|
|
|
|
|
|
double
|
|
Timeline::endTime() const
|
|
{
|
|
return phases.back()->endTime();
|
|
}
|
|
|
|
|
|
/*! Check whether the timeline covers the specified time t. True if
|
|
* startTime <= t <= endTime. Note that this is deliberately different
|
|
* than the TimelinePhase::includes function, which is only true if
|
|
* t is strictly less than the end time.
|
|
*/
|
|
bool
|
|
Timeline::includes(double t) const
|
|
{
|
|
return phases.front()->startTime() <= t && t <= phases.back()->endTime();
|
|
}
|
|
|
|
|
|
void
|
|
Timeline::markChanged()
|
|
{
|
|
if (phases.size() == 1)
|
|
{
|
|
phases[0]->getFrameTree()->markChanged();
|
|
}
|
|
else
|
|
{
|
|
for (const auto phase : phases)
|
|
phase->getFrameTree()->markChanged();
|
|
}
|
|
}
|