5namespace Kinoko::Abstract::g3d {
8ChrAnmResult ResAnmChr::getAnmResult(f32 frame,
size_t idx)
const {
9 s32 offset = parse<s32>(m_rawData->toChrDataDic);
10 ResDic dic = ResDic(
reinterpret_cast<void *
>(
reinterpret_cast<uintptr_t
>(m_rawData) + offset));
11 const NodeData *data =
reinterpret_cast<const NodeData *
>(dic[idx]);
13 u32 flags = parse<u32>(data->flags);
16 result.flags = flags &
17 (ChrAnmResult::Flag::FLAG_ANM_EXISTS | ChrAnmResult::Flag::FLAG_MTX_IDENT |
18 ChrAnmResult::Flag::FLAG_ROT_TRANS_ZERO | ChrAnmResult::Flag::FLAG_SCALE_ONE |
19 ChrAnmResult::Flag::FLAG_SCALE_UNIFORM | ChrAnmResult::Flag::FLAG_ROT_ZERO |
20 ChrAnmResult::Flag::FLAG_TRANS_ZERO | ChrAnmResult::Flag::FLAG_PATCH_SCALE |
21 ChrAnmResult::Flag::FLAG_PATCH_ROT | ChrAnmResult::Flag::FLAG_PATCH_TRANS |
22 ChrAnmResult::Flag::FLAG_SSC_APPLY | ChrAnmResult::Flag::FLAG_SSC_PARENT |
23 ChrAnmResult::Flag::FLAG_XSI_SCALING);
25 u32 index = (flags & NodeData::Flag::FLAG_HAS_SRT_MASK) >> 22;
27 ASSERT(index < s_getAnmResultTable.size());
29 (*s_getAnmResultTable[index])(frame, result, m_infoData, data);
35template <
typename TData,
typename TDerived>
40 void operator++(
int) {
43 void operator--(
int) {
47 [[nodiscard]] TDerived operator+(
int n) {
48 return TDerived(mPtr + n);
60 :
public CResAnmChrFrmBase<ResAnmChr::Frm48Data, CResAnmChrFrm<ResAnmChr::Frm48Data>> {
64 [[nodiscard]] s16 GetFrame()
const {
65 return parse<s16>(mPtr->frame);
68 [[nodiscard]] f32 GetFrameF32()
const {
69 return static_cast<f32
>(parse<s16>(mPtr->frame)) * (1.0f / 32.0f);
73 f32 x = parse<f32>(pFVSData->fvs48.scale);
74 f32 y =
static_cast<f32
>(parse<u16>(mPtr->value));
75 f32 z = parse<f32>(pFVSData->fvs48.offset);
80 [[nodiscard]] f32 GetSlope()
const {
81 return static_cast<f32
>(parse<s16>(mPtr->slope)) * (1.0f / 256.0f);
87 :
public CResAnmChrFrmBase<ResAnmChr::Frm96Data, CResAnmChrFrm<ResAnmChr::Frm96Data>> {
91 [[nodiscard]] f32 GetFrame()
const {
92 return parse<f32>(mPtr->frame);
95 [[nodiscard]] f32 GetFrameF32()
const {
96 return parse<f32>(mPtr->frame);
100 return parse<f32>(mPtr->value);
103 [[nodiscard]] f32 GetSlope()
const {
104 return parse<f32>(mPtr->slope);
123 [[nodiscard]]
static TFrame QuantizeFrame(f32 frame) {
124 return static_cast<TFrame
>(frame * 32.0f);
139 [[nodiscard]]
static TFrame QuantizeFrame(f32 frame) {
149 return parse<f32>(anmData->constValue);
152 const ResAnmChr::AnmData *pFVSAnmData =
reinterpret_cast<const ResAnmChr::AnmData *
>(
153 reinterpret_cast<uintptr_t
>(nodeData) + parse<s32>(anmData->toResAnmChrAnmData));
155 return CalcAnimationFVS<CAnmFmtTraits<T>>(frame, &pFVSAnmData->fvs);
158[[nodiscard]]
inline f32 CalcResult48(f32 frame,
const ResAnmChr::NodeData *nodeData,
159 const ResAnmChr::NodeData::AnmData *anmData,
bool constant) {
160 return CalcResultFVS<ResAnmChr::FVS48Data>(frame, nodeData, anmData, constant);
163[[nodiscard]]
inline f32 CalcResult96(f32 frame,
const ResAnmChr::NodeData *nodeData,
164 const ResAnmChr::NodeData::AnmData *anmData,
bool constant) {
165 return CalcResultFVS<ResAnmChr::FVS96Data>(frame, nodeData, anmData, constant);
169template <
typename TTraits>
170[[nodiscard]] f32 CalcAnimationFVS(f32 frame,
const ResAnmChr::FVSData *pFVSData) {
171 auto first = TTraits::GetKeyFrame(pFVSData, 0);
172 auto last = TTraits::GetKeyFrame(pFVSData, parse<u16>(pFVSData->numFrameValues) - 1);
174 if (frame <= first.GetFrameF32()) {
175 return first.GetValue(pFVSData);
178 if (last.GetFrameF32() <= frame) {
179 return last.GetValue(pFVSData);
182 f32 frameOffset = frame - first.GetFrameF32();
183 f32 numKeyFrame =
static_cast<f32
>(parse<u16>(pFVSData->numFrameValues));
185 f32 f_estimatePos = parse<f32>(pFVSData->invKeyFrameRange) * (frameOffset * numKeyFrame);
186 u16 i_estimatePos =
static_cast<u16
>(f_estimatePos);
188 auto left = TTraits::GetKeyFrame(pFVSData, i_estimatePos);
189 auto quantized = TTraits::QuantizeFrame(frame);
191 if (quantized < left.GetFrame()) {
194 }
while (quantized < left.GetFrame());
198 }
while (left.GetFrame() <= quantized);
203 if (frame == left.GetFrameF32()) {
204 return left.GetValue(pFVSData);
207 auto right = left + 1;
209 f32 v0 = left.GetValue(pFVSData);
210 f32 t0 = left.GetSlope();
211 f32 v1 = right.GetValue(pFVSData);
212 f32 t1 = right.GetSlope();
214 f32 f0 = left.GetFrameF32();
215 f32 f1 = right.GetFrameF32();
217 f32 frameDelta = frame - f0;
218 f32 keyFrameDelta = f1 - f0;
220 f32 t = frameDelta * keyFrameDeltaInv;
228const ResAnmChr::NodeData::AnmData *GetAnmScale(f32 frame, EGG::Vector3f &result,
229 const ResAnmChr::NodeData *nodeData,
const ResAnmChr::NodeData::AnmData *anmData) {
230 u32 flags = parse<u32>(nodeData->flags);
232 switch (flags & ResAnmChr::NodeData::Flag::FLAG_SCALE_FMT_MASK) {
234 case ResAnmChr::NodeData::Flag::FLAG_SCALE_FVS32_FMT:
235 case ResAnmChr::NodeData::Flag::FLAG_SCALE_FVS48_FMT: {
236 result.x = CalcResult48(frame, nodeData, anmData++,
237 flags & ResAnmChr::NodeData::FLAG_SCALE_X_CONST);
239 if (flags & ResAnmChr::NodeData::FLAG_SCALE_UNIFORM) {
243 result.y = CalcResult48(frame, nodeData, anmData++,
244 flags & ResAnmChr::NodeData::Flag::FLAG_SCALE_Y_CONST);
245 result.z = CalcResult48(frame, nodeData, anmData++,
246 flags & ResAnmChr::NodeData::Flag::FLAG_SCALE_Z_CONST);
249 case ResAnmChr::NodeData::Flag::FLAG_SCALE_FVS96_FMT: {
250 result.x = CalcResult96(frame, nodeData, anmData++,
251 flags & ResAnmChr::NodeData::FLAG_SCALE_X_CONST);
253 if (flags & ResAnmChr::NodeData::FLAG_SCALE_UNIFORM) {
257 result.y = CalcResult96(frame, nodeData, anmData++,
258 flags & ResAnmChr::NodeData::FLAG_SCALE_Y_CONST);
259 result.z = CalcResult96(frame, nodeData, anmData++,
260 flags & ResAnmChr::NodeData::FLAG_SCALE_Z_CONST);
271void GetAnmResult_Stub(f32 , ChrAnmResult & ,
272 const ResAnmChr::InfoData & ,
const ResAnmChr::NodeData * ) {}
274void GetAnmResult_S(f32 frame, ChrAnmResult &result,
const ResAnmChr::InfoData & ,
275 const ResAnmChr::NodeData *nodeData) {
276 GetAnmScale(frame, result.s, nodeData, nodeData->anms);
277 result.rt = EGG::Matrix34f::ident;
280const std::array<ResAnmChr::GetAnmResultFunc, ResAnmChr::NUM_RESULT_FUNCS>
281 ResAnmChr::s_getAnmResultTable = {{
Represents the CHR0 file format, which pertains to model movement animations.
static constexpr f32 fms(f32 x, f32 y, f32 z)
Fused multiply-subtract operation.
static constexpr f32 finv(f32 x)
Fused Newton-Raphson operation.
static constexpr f32 fma(f32 x, f32 y, f32 z)
Fused multiply-add operation.
Frame values (FVS) animation data.