68 lines
1.8 KiB
C++
68 lines
1.8 KiB
C++
#pragma once
|
|
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
#include <glm/glm.hpp>
|
|
|
|
struct GcUvCell {
|
|
uint16_t x = 0;
|
|
uint16_t y = 0;
|
|
uint16_t width = 0;
|
|
uint16_t height = 0;
|
|
};
|
|
|
|
struct GcEffectSprite {
|
|
uint16_t uvRecord = 0;
|
|
int frame = 0;
|
|
glm::vec3 offsetPixels{0.0f};
|
|
glm::vec4 color{1.0f};
|
|
glm::vec2 scale{1.0f};
|
|
float rotationDegrees = 0.0f;
|
|
};
|
|
|
|
// Interpreter for the sprite subset of the original common effect format.
|
|
// It follows game471 FUN_005f2030/FUN_005f2250/FUN_005f23f0 and is enough to
|
|
// reproduce control-helper effects 61..69, including parent rotation nodes.
|
|
class GcTargetEffectBank {
|
|
public:
|
|
bool load(const std::string& efcPath, const std::string& uvPath, std::string* error = nullptr);
|
|
int lifetime(int effectId) const;
|
|
std::vector<GcEffectSprite> evaluate(int effectId, float tick, int uvRecordBase = 0) const;
|
|
const GcUvCell* uvCell(uint16_t record, int frame) const;
|
|
int uvTexture(uint16_t record) const;
|
|
|
|
private:
|
|
struct Key {
|
|
uint16_t time = 0;
|
|
uint8_t interpolation = 0;
|
|
std::vector<float> values;
|
|
};
|
|
struct Track {
|
|
uint16_t loopStart = 0;
|
|
uint16_t loopEnd = 0;
|
|
std::vector<Key> keys;
|
|
};
|
|
struct Child {
|
|
uint8_t type = 0;
|
|
uint16_t reference = 0xffff;
|
|
bool inheritParent = false;
|
|
std::array<Track, 5> tracks;
|
|
};
|
|
struct Effect {
|
|
uint16_t lifetime = 0;
|
|
std::vector<Child> children;
|
|
};
|
|
struct UvRecord {
|
|
int16_t textureIndex = -1;
|
|
std::vector<GcUvCell> cells;
|
|
};
|
|
|
|
static std::vector<float> sampleTrack(const Track& track, float tick, bool* started);
|
|
|
|
std::vector<Effect> effects_;
|
|
std::vector<UvRecord> uvRecords_;
|
|
};
|