载入中...
搜索中...
未找到
SpriteClip.cpp
浏览该文件的文档.
2
4#include "common/Exception.h"
5
6#include <cmath>
7
8namespace eve::animation {
9
10SpriteClip::SpriteClip(const std::string &name) : name_(name) {}
11
12void SpriteClip::setName(const std::string &name) { name_ = name; }
13
14void SpriteClip::checkIndex(int index) const {
15 if (index < 0 || index >= getFrameCount())
16 throw Exception("SpriteClip: frame index %d out of range (count=%d)", index,
18}
19
20void SpriteClip::addFrame(int sheetFrameIndex, float duration) {
21 if (sheetFrameIndex < 0)
22 throw Exception("SpriteClip.addFrame: sheetFrameIndex must be >= 0");
23 if (duration < 0.f) throw Exception("SpriteClip.addFrame: duration must be >= 0");
24 frames_.push_back(Entry{sheetFrameIndex, duration});
25}
26
27void SpriteClip::addFrameByName(SpriteSheet *sheet, const std::string &frameName,
28 float duration) {
29 if (!sheet) throw Exception("SpriteClip.addFrameByName: sheet is null");
30 int idx = sheet->findFrame(frameName);
31 if (idx < 0)
32 throw Exception("SpriteClip.addFrameByName: unknown frame '%s'", frameName.c_str());
34}
35
36void SpriteClip::addRange(int firstSheetFrame, int lastSheetFrame, float fps) {
37 if (firstSheetFrame < 0 || lastSheetFrame < firstSheetFrame)
38 throw Exception("SpriteClip.addRange: expected 0 <= first <= last");
39 if (fps <= 0.f) throw Exception("SpriteClip.addRange: fps must be > 0");
40 const float duration = 1.f / fps;
41 for (int frame = firstSheetFrame; frame <= lastSheetFrame; ++frame)
42 addFrame(frame, duration);
43}
44
45void SpriteClip::setFPS(float fps) {
46 if (fps <= 0.f) throw Exception("SpriteClip.setFPS: fps must be > 0");
47 const float duration = 1.f / fps;
48 for (Entry &entry : frames_) entry.duration = duration;
49}
50
51float SpriteClip::getFPS() const {
52 if (frames_.empty()) return 0.f;
53 const float duration = frames_.front().duration;
54 if (duration <= 0.f) return 0.f;
55 for (const Entry &entry : frames_) {
56 if (std::fabs(entry.duration - duration) > 1e-6f) return 0.f;
57 }
58 return 1.f / duration;
59}
60
61void SpriteClip::addEvent(int clipFrame, const std::string &name) {
62 checkIndex(clipFrame);
63 events_[clipFrame] = name;
64}
65
66std::string SpriteClip::getEvent(int clipFrame) const {
67 auto it = events_.find(clipFrame);
68 return it == events_.end() ? std::string() : it->second;
69}
70
71void SpriteClip::clear() { frames_.clear(); }
72
74 checkIndex(index);
75 return frames_[static_cast<size_t>(index)].sheetFrame;
76}
77
79 checkIndex(index);
80 return frames_[static_cast<size_t>(index)].duration;
81}
82
84 float sum = 0.f;
85 for (const Entry &e : frames_) sum += e.duration;
86 return sum;
87}
88
89float SpriteClip::wrapTime(float timeSeconds) const {
90 if (timeSeconds < 0.f) timeSeconds = 0.f;
91 const float dur = getDuration();
92 if (dur <= 0.f) return 0.f;
93 if (loop_) {
94 float t = std::fmod(timeSeconds, dur);
95 if (t < 0.f) t += dur;
96 return t;
97 }
98 return timeSeconds > dur ? dur : timeSeconds;
99}
100
101int SpriteClip::frameAtTime(float timeSeconds) const {
102 if (frames_.empty()) return -1;
103 float t = wrapTime(timeSeconds);
104 const float dur = getDuration();
105 if (!loop_ && timeSeconds >= dur) return getFrameCount() - 1;
106
107 float acc = 0.f;
108 for (int i = 0; i < getFrameCount(); ++i) {
109 acc += frames_[static_cast<size_t>(i)].duration;
110 if (t < acc || i == getFrameCount() - 1) return i;
111 }
112 return getFrameCount() - 1;
113}
114
115} // namespace eve::animation
float duration
std::string name
int idx
float t
uint32_t index
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
SpriteClip(const std::string &name="")
Sprite clip.
int getSheetFrame(int index) const
Returns the sheet frame.
void addEvent(int clipFrame, const std::string &name)
Attach a named event to a clip-frame index.
float wrapTime(float timeSeconds) const
Local time wrapped or clamped according to loop flag.
float getFPS() const
Uniform FPS, or 0 when empty/variable-duration.
void addFrame(int sheetFrameIndex, float duration=0.1f)
Append one cell: sheetFrameIndex + display duration (seconds).
float getDuration() const
Returns the duration.
void setName(const std::string &name)
Sets the name.
void addFrameByName(SpriteSheet *sheet, const std::string &frameName, float duration=0.1f)
Resolve name via sheet and append.
void setFPS(float fps)
Replace every existing frame duration with 1/fps.
int frameAtTime(float timeSeconds) const
Map absolute time (seconds) into a clip frame index. When loop is false and t >= duration,...
int getFrameCount() const
Returns the frame count.
Definition SpriteClip.h:58
void addRange(int firstSheetFrame, int lastSheetFrame, float fps)
Append inclusive sheet-frame range at a uniform frame rate.
std::string getEvent(int clipFrame) const
Return event name for a frame, or empty when none.
float getFrameDuration(int index) const
Returns the frame duration.
Sprite-sheet / texture-atlas frame table (pixel rects).
Definition SpriteSheet.h:23
int findFrame(const std::string &name) const
Finds frame.