• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PredatorCZ / RevilLib / 164

13 Nov 2025 11:19PM UTC coverage: 11.207% (+0.02%) from 11.187%
164

push

github

PredatorCZ
refactor mtf textures

0 of 114 new or added lines in 1 file covered. (0.0%)

802 existing lines in 3 files now uncovered.

757 of 6755 relevant lines covered (11.21%)

6709.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

15.94
/src/mtf_lmt/codecs.cpp
1
/*  Revil Format Library
2
    Copyright(C) 2017-2023 Lukas Cone
3

4
    This program is free software : you can redistribute it and / or modify
5
    it under the terms of the GNU General Public License as published by
6
    the Free Software Foundation, either version 3 of the License, or
7
    (at your option) any later version.
8

9
    This program is distributed in the hope that it will be useful,
10
    but WITHOUT ANY WARRANTY; without even the implied warranty of
11
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
12
    GNU General Public License for more details.
13

14
    You should have received a copy of the GNU General Public License
15
    along with this program.If not, see <https://www.gnu.org/licenses/>.
16
*/
17

18
#include "codecs.hpp"
19
#include "spike/io/binwritter_stream.hpp"
20
#include "spike/master_printer.hpp"
21
#include "spike/reflect/reflector_xml.hpp"
22
#include "spike/util/macroLoop.hpp"
23

24
#include <cmath>
25
#include <sstream>
26
#include <unordered_map>
27

28
REFLECT(CLASS(Buf_SingleVector3), MEMBER(data));
2✔
29
REFLECT(CLASS(Buf_LinearVector3), MEMBER(data), MEMBER(additiveFrames));
2✔
30
REFLECT(CLASS(Buf_HermiteVector3), MEMBER(flags), MEMBER(additiveFrames),
2✔
31
        MEMBER(data));
32

33
// https://en.wikipedia.org/wiki/Slerp
34
static Vector4A16 slerp(const Vector4A16 &v0, const Vector4A16 &_v1, float t) {
35
  Vector4A16 v1 = _v1;
×
36
  float dot = v0.Dot(v1);
37

38
  // If the dot product is negative, slerp won't take
39
  // the shorter path. Fix by reversing one quaternion.
40
  if (dot < 0.0f) {
×
41
    v1 *= -1;
42
    dot *= -1;
×
43
  }
44

45
  static const float DOT_THRESHOLD = 0.9995f;
46
  if (dot > DOT_THRESHOLD) {
×
47
    // If the inputs are too close for comfort, linearly interpolate
48
    // and normalize the result.
49

50
    Vector4A16 result = v0 + (v1 - v0) * t;
51
    return result.Normalize();
×
52
  }
53

54
  const float theta00 = acos(dot);   // theta00 = angle between input vectors
×
55
  const float theta01 = theta00 * t; // theta01 = angle between v0 and result
×
56
  const float theta02 = sin(theta01);
×
57
  const float theta03 = 1.0f / sin(theta00);
×
58
  const float s0 = cos(theta01) - dot * theta02 * theta03;
×
59
  const float s1 = theta02 * theta03;
×
60

61
  return ((v0 * s0) + (v1 * s1)).Normalized();
×
62
}
63

64
template <typename T>
65
Vector4A16 lerp(const Vector4A16 &v0, const Vector4A16 &v1, T t) {
66
  return v0 + (v1 - v0) * t;
67
}
68

69
static Vector4A16 additiveLerp(const TrackMinMax &minMax,
70
                               const Vector4A16 &value) {
71
  return minMax.max + minMax.min * value;
72
}
73

74
static Vector4A16 blerp(const Vector4A16 &v0, const Vector4A16 &v1,
75
                        const TrackMinMax &minMax, float t) {
76
  return lerp(additiveLerp(minMax, v0), additiveLerp(minMax, v1), t);
77
}
78

79
static Vector4A16 bslerp(const Vector4A16 &v0, const Vector4A16 &v1,
80
                         const TrackMinMax &minMax, float t) {
81
  return slerp(additiveLerp(minMax, v0), additiveLerp(minMax, v1), t);
×
82
}
83

84
template <class C>
85
void AppendToStringRaw(const C *clPtr, std::stringstream &buffer) {
×
86
  const uint8 *rawData = reinterpret_cast<const uint8 *>(clPtr);
87
  const size_t hexSize = clPtr->Size() * 2;
88
  size_t cBuff = 0;
89

90
  for (size_t i = 0; i < hexSize; i++) {
×
91
    bool idk = i & 1;
×
92
    char temp = 0x30 + (idk ? rawData[cBuff++] & 0xf : rawData[cBuff] >> 4);
×
93

94
    if (temp > 0x39) {
×
95
      temp += 7;
×
96
    }
97

98
    buffer << temp;
×
99
  }
100
}
101

×
102
template <class C>
103
std::string_view RetreiveFromRawString(C *clPtr, std::string_view buffer) {
104
  uint8 *rawData = reinterpret_cast<uint8 *>(clPtr);
105
  const size_t buffSize = clPtr->Size() * 2;
106
  size_t cBuff = 0;
×
107

×
108
  while (!buffer.empty() && cBuff < buffSize) {
×
109
    const int cRef = buffer.at(0);
110

×
111
    if (cRef < '0' || cRef > 'F' || (cRef > '9' && cRef < 'A')) {
×
112
      buffer.remove_prefix(1);
113
      continue;
114
    }
×
115

116
    if (!(cBuff & 1)) {
117
      rawData[cBuff] = atohLUT[cRef] << 4;
×
118
    } else {
119
      rawData[cBuff++] |= atohLUT[cRef];
120
    }
121

122
    buffer.remove_prefix(1);
×
123
  }
×
124

×
125
  if (cBuff < buffSize) {
126
    throw std::runtime_error("Raw buffer is too short!");
×
127
  }
×
128

129
  return buffer;
130
}
×
131

132
static auto SeekTo(std::string_view buffer, const char T = '\n') {
133
  while (!buffer.empty()) {
×
134
    if (buffer.front() == T) {
135
      buffer.remove_prefix(1);
136
      return buffer;
137
    }
138

×
139
    buffer.remove_prefix(1);
×
140
  }
×
141

142
  return buffer;
×
143
}
×
144

145
size_t Buf_SingleVector3::Size() const { return 12; }
146

×
147
void Buf_SingleVector3::AppendToString(std::stringstream &buffer) const {
148
  ReflectorWrap<const Buf_SingleVector3> tRefl(this);
149

×
150
  buffer << tRefl["data"].ReflectedValue();
151
}
152

153
std::string_view
154
Buf_SingleVector3::RetreiveFromString(std::string_view buffer) {
×
155
  buffer = es::SkipStartWhitespace(buffer, true);
×
156

×
157
  ReflectorWrap<Buf_SingleVector3> tRefl(this);
158
  tRefl["data"] = buffer;
×
159
  return SeekTo(buffer);
×
160
}
161

162
void Buf_SingleVector3::Evaluate(Vector4A16 &out) const {
×
163
  out = Vector4A16(data, 1.0f);
164
}
165

×
166
void Buf_SingleVector3::Devaluate(const Vector4A16 &in) { data = in; }
167

168
void Buf_SingleVector3::GetFrame(int32 &currentFrame) const { currentFrame++; }
169

170
int32 Buf_SingleVector3::GetFrame() const { return 1; }
×
171

×
172
void Buf_SingleVector3::Interpolate(Vector4A16 &out,
×
173
                                    const Buf_SingleVector3 &rightFrame,
174
                                    float delta, const TrackMinMax &) const {
×
175
  Vector4A16 startPoint, endPoint;
×
176

177
  Evaluate(startPoint);
178
  rightFrame.Evaluate(endPoint);
×
179

180
  out = lerp(startPoint, endPoint, delta);
181
}
×
182

183
void Buf_SingleVector3::SwapEndian() { FByteswapper(data); }
184

185
void Buf_StepRotationQuat3::Evaluate(Vector4A16 &out) const {
186
  out = Vector4A16(data.X, data.Y, data.Z, 0.0f);
×
187
  out.QComputeElement();
×
188
}
×
189

190
void Buf_StepRotationQuat3::Interpolate(Vector4A16 &out,
×
191
                                        const Buf_StepRotationQuat3 &rightFrame,
×
192
                                        float delta,
193
                                        const TrackMinMax &) const {
194
  Vector4A16 startPoint, endPoint;
×
195

196
  Evaluate(startPoint);
197
  rightFrame.Evaluate(endPoint);
198

199
  out = slerp(startPoint, endPoint, delta);
×
200
}
201

202
size_t Buf_LinearVector3::Size() const { return 16; }
203

204
void Buf_LinearVector3::AppendToString(std::stringstream &buffer) const {
×
205
  ReflectorWrap<const Buf_LinearVector3> tRefl(this);
×
206

207
  buffer << "{ " << tRefl["data"].ReflectedValue() << ", "
×
208
         << tRefl["additiveFrames"].ReflectedValue() << " }";
209
}
×
210

211
std::string_view
212
Buf_LinearVector3::RetreiveFromString(std::string_view buffer) {
213
  buffer = SeekTo(buffer, '{');
×
214
  buffer = es::SkipStartWhitespace(buffer, true);
215

216
  ReflectorWrap<Buf_LinearVector3> tRefl(this);
217
  tRefl["data"] = buffer;
218

219
  buffer = SeekTo(buffer, ']');
220
  buffer = SeekTo(buffer, ',');
221
  buffer = es::SkipStartWhitespace(buffer, true);
222

×
223
  tRefl["additiveFrames"] = buffer;
224

225
  return SeekTo(buffer);
226
}
227

×
228
void Buf_LinearVector3::Devaluate(const Vector4A16 &in) { data = in; }
229

230
void Buf_LinearVector3::Evaluate(Vector4A16 &out) const {
231
  out = Vector4A16(data, 1.0f);
232
}
×
233

×
234
void Buf_LinearVector3::GetFrame(int32 &currentFrame) const {
235
  currentFrame += additiveFrames;
×
236
}
237

×
238
int32 Buf_LinearVector3::GetFrame() const { return additiveFrames; }
239

240
void Buf_LinearVector3::SetFrame(uint64 frame) {
241
  additiveFrames = static_cast<int32>(frame);
×
242
}
243

244
void Buf_LinearVector3::Interpolate(Vector4A16 &out,
245
                                    const Buf_LinearVector3 &rightFrame,
246
                                    float delta, const TrackMinMax &) const {
247
  Vector4A16 startPoint, endPoint;
248

249
  Evaluate(startPoint);
250
  rightFrame.Evaluate(endPoint);
×
251

252
  out = lerp(startPoint, endPoint, delta);
253
}
254

255
void Buf_LinearVector3::SwapEndian() {
×
256
  FByteswapper(data);
257
  FByteswapper(additiveFrames);
258
}
259

260
size_t Buf_HermiteVector3::Size() const { return size; }
×
261

×
262
void Buf_HermiteVector3::AppendToString(std::stringstream &buffer) const {
263
  ReflectorWrap<const Buf_HermiteVector3> tRefl(this);
×
264

265
  buffer << "{ " << tRefl["data"].ReflectedValue() << ", "
×
266
         << tRefl["additiveFrames"].ReflectedValue() << ", "
267
         << tRefl["flags"].ReflectedValue();
268

269
  size_t curTang = 0;
×
270

271
  for (size_t f = 0; f < 6; f++) {
272
    if (flags[static_cast<Buf_HermiteVector3_Flags>(f)]) {
273
      buffer << ", " << tangents[curTang++];
274
    }
275
  }
276

277
  buffer << " }";
278
}
×
279

280
std::string_view
281
Buf_HermiteVector3::RetreiveFromString(std::string_view buffer) {
282
  buffer = SeekTo(buffer, '{');
283
  buffer = es::SkipStartWhitespace(buffer, true);
×
284

285
  ReflectorWrap<Buf_HermiteVector3> tRefl(this);
286
  tRefl["data"] = buffer;
287

288
  buffer = SeekTo(buffer, ',');
×
289
  buffer = es::SkipStartWhitespace(buffer, true);
×
290

291
  tRefl["additiveFrames"] = buffer;
×
292

293
  buffer = SeekTo(buffer, ',');
×
294
  buffer = es::SkipStartWhitespace(buffer, true);
295

296
  tRefl["flags"] = buffer;
297

×
298
  buffer = SeekTo(buffer, ',');
299
  buffer = es::SkipStartWhitespace(buffer, true);
300

301
  size_t curTang = 0;
302

303
  for (size_t f = 0; f < 6; f++) {
304
    if (flags[static_cast<Buf_HermiteVector3_Flags>(f)]) {
305
      tangents[curTang++] = static_cast<float>(std::atof(buffer.data()));
306
      buffer = SeekTo(buffer, ',');
×
307
      buffer = es::SkipStartWhitespace(buffer, true);
308
    }
309
  }
310

311
  size = static_cast<uint8>(sizeof(Buf_HermiteVector3) - (6 - curTang) * 4);
×
312

313
  return SeekTo(buffer);
314
}
315

316
void Buf_HermiteVector3::Evaluate(Vector4A16 &out) const {
×
317
  out = Vector4A16(data, 1.0f);
×
318
}
319

×
320
void Buf_HermiteVector3::GetTangents(Vector4A16 &inTangs,
321
                                     Vector4A16 &outTangs) const {
×
322
  size_t currentTangIndex = 0;
323

324
  inTangs.X = flags[Buf_HermiteVector3_Flags::InTangentX]
325
                  ? tangents[currentTangIndex++]
×
326
                  : 0.0f;
327
  inTangs.Y = flags[Buf_HermiteVector3_Flags::InTangentY]
328
                  ? tangents[currentTangIndex++]
329
                  : 0.0f;
330
  inTangs.Z = flags[Buf_HermiteVector3_Flags::InTangentZ]
331
                  ? tangents[currentTangIndex++]
332
                  : 0.0f;
333
  outTangs.X = flags[Buf_HermiteVector3_Flags::OutTangentX]
334
                   ? tangents[currentTangIndex++]
×
335
                   : 0.0f;
336
  outTangs.Y = flags[Buf_HermiteVector3_Flags::OutTangentY]
337
                   ? tangents[currentTangIndex++]
338
                   : 0.0f;
339
  outTangs.Z = flags[Buf_HermiteVector3_Flags::OutTangentZ]
×
340
                   ? tangents[currentTangIndex++]
341
                   : 0.0f;
342
}
343

344
void Buf_HermiteVector3::GetFrame(int32 &currentFrame) const {
×
345
  currentFrame += additiveFrames;
×
346
}
347

×
348
int32 Buf_HermiteVector3::GetFrame() const { return additiveFrames; }
349

×
350
void Buf_HermiteVector3::SetFrame(uint64 frame) {
351
  additiveFrames = static_cast<uint16>(frame);
352
}
353

×
354
void Buf_HermiteVector3::Interpolate(Vector4A16 &out,
355
                                     const Buf_HermiteVector3 &rightFrame,
356
                                     float delta, const TrackMinMax &) const {
357
  Vector4A16 startPoint, endPoint, startPointOutTangent, endPointInTangent,
358
      dummy;
359

360
  Evaluate(startPoint);
361
  rightFrame.Evaluate(endPoint);
362
  GetTangents(startPointOutTangent, endPointInTangent);
×
363

364
  const float deltaP2 = delta * delta;
365
  const float deltaP3 = delta * deltaP2;
366
  const float deltaP32 = deltaP3 * 2;
367
  const float deltaP23 = deltaP2 * 3;
×
368
  const float h1 = deltaP32 - deltaP23 + 1;
369
  const float h2 = -deltaP32 + deltaP23;
370
  const float h3 = deltaP3 - 2 * deltaP2 + delta;
371
  const float h4 = deltaP3 - deltaP2;
372

×
373
  out = startPoint * h1 + endPoint * h2 + startPointOutTangent * h3 +
×
374
        endPointInTangent * h4;
375
}
×
376

377
void Buf_HermiteVector3::SwapEndian() {
×
378
  FByteswapper(additiveFrames);
379
  FByteswapper(data);
380

381
  size_t curTang = 0;
×
382

383
  for (size_t f = 0; f < 6; f++) {
384
    if (flags[static_cast<Buf_HermiteVector3_Flags>(f)]) {
385
      FByteswapper(tangents[curTang]);
386
      curTang++;
387
    }
388
  }
389
}
390

×
391
size_t Buf_SphericalRotation::Size() const { return 8; }
392

393
void Buf_SphericalRotation::AppendToString(std::stringstream &buffer) const {
394
  AppendToStringRaw(this, buffer);
395
}
396

397
std::string_view
×
398
Buf_SphericalRotation::RetreiveFromString(std::string_view buffer) {
×
399
  return RetreiveFromRawString(this, buffer);
400
}
×
401

402
void Buf_SphericalRotation::Devaluate(const Vector4A16 &_in) {
403
  Vector4A16 in = _in;
404
  data ^= data & dataField;
405

406
  if (in.W < 0.0f) {
407
    in = -in;
408
  }
409

×
410
  if (in.X < 0.0f) {
411
    in.X *= -1;
×
412
    data |= 1ULL << 53;
413
  }
414

×
415
  if (in.Y < 0.0f) {
416
    in.Y *= -1;
417
    data |= 1ULL << 54;
418
  }
×
419

420
  if (in.Z < 0.0f) {
421
    in.Z *= -1;
422
    data |= 1ULL << 55;
×
423
  }
×
424

425
  const float R = sqrtf(1.0f - in.W);
426
  const float magnitude_safe = sqrtf(1.0f - (in.W * in.W));
×
427
  const float magnitude = magnitude_safe < 0.001f ? 1.0f : magnitude_safe;
1✔
428

429
  const float phi = asinf(in.Y / magnitude);
430
  const float theta = asinf(in.X / (cosf(phi) * magnitude));
2✔
431

432
  data |= static_cast<uint64>(theta * componentMultiplierInv) & componentMask;
×
433
  data |= (static_cast<uint64>(phi * componentMultiplierInv) & componentMask)
434
          << 17;
×
435
  data |= (static_cast<uint64>(R * componentMaskW) & componentMaskW) << 34;
436
}
×
437

438
void Buf_SphericalRotation::Evaluate(Vector4A16 &out) const {
439
  out.X = static_cast<float>(data & componentMask);
440
  out.Y = static_cast<float>((data >> 17) & componentMask);
441
  float wComp =
442
      static_cast<float>((data >> 34) & componentMaskW) * componentMultiplierW;
443
  out *= componentMultiplier;
444

×
445
  const Vector4A16 var1(sinf(out.X), sinf(out.Y), cosf(out.X), cosf(out.Y));
446

447
  // Optimized Taylor series expansion of sin function, this is faster by 4ms
×
448
  // on debug, 1-2ms on release /wo inline Since this library is not frame
449
  // time heavy, it's disabled If enabled: invert out.X before sign check
×
450
  /*
1✔
451
  out.Z = out.X - fPI2;
452
  out.W = out.Y - fPI2;
453

454
  const Vector4A16 fvar1 = out * out;
×
455
  const Vector4A16 fvar2 = out * 9.53992f;
456
  const Vector4A16 var1 = out * (out - fPI) * (out + fPI) * (fvar1 - fvar2
457
  + 25.0493f) * (fvar1 + fvar2 + 25.0493f) * -0.000161476f;
458
  */
459

460
  wComp = 1.0f - (wComp * wComp);
461
  float magnitude = sqrtf(1.0f - (wComp * wComp));
462

463
  out.X = var1.X * var1.W * magnitude;
×
464
  out.Y = var1.Y * magnitude;
465
  out.Z = var1.Z * var1.W * magnitude;
466
  out.W = wComp;
×
467

468
  if ((data >> 53) & 1) {
×
469
    out.X *= -1;
470
  }
471

×
472
  if ((data >> 54) & 1) {
×
473
    out.Y *= -1;
474
  }
475

476
  if ((data >> 55) & 1) {
×
477
    out.Z *= -1;
478
  }
479
}
480

481
void Buf_SphericalRotation::GetFrame(int32 &currentFrame) const {
×
482
  currentFrame += data >> 56;
483
}
484

485
int32 Buf_SphericalRotation::GetFrame() const { return data >> 56; }
486

487
void Buf_SphericalRotation::SetFrame(uint64 frame) {
×
488
  data ^= data & frameField;
489
  data |= frame << 56;
×
490
}
491

492
void Buf_SphericalRotation::Interpolate(Vector4A16 &out,
1✔
493
                                        const Buf_SphericalRotation &rightFrame,
494
                                        float delta,
×
495
                                        const TrackMinMax &) const {
1✔
496
  Vector4A16 startPoint, endPoint;
497

498
  Evaluate(startPoint);
×
499
  rightFrame.Evaluate(endPoint);
×
500

501
  out = slerp(startPoint, endPoint, delta);
502
}
×
503

504
void Buf_SphericalRotation::SwapEndian() { FByteswapper(data); }
×
505

×
506
size_t Buf_BiLinearVector3_16bit::Size() const { return 8; }
507

508
void Buf_BiLinearVector3_16bit::AppendToString(
×
509
    std::stringstream &buffer) const {
510
  AppendToStringRaw(this, buffer);
511
}
512

513
std::string_view
514
Buf_BiLinearVector3_16bit::RetreiveFromString(std::string_view buffer) {
515
  return RetreiveFromRawString(this, buffer);
516
}
×
517

518
void Buf_BiLinearVector3_16bit::Evaluate(Vector4A16 &out) const {
519
  out = Vector4A16(data.Convert<float>(), 1.0f) * componentMultiplier;
×
520
}
×
521

×
522
void Buf_BiLinearVector3_16bit::Devaluate(const Vector4A16 &in) {
523
  data = USVector4((in * componentMultiplierInv).Convert<uint16>());
524
}
×
525

526
void Buf_BiLinearVector3_16bit::GetFrame(int32 &currentFrame) const {
×
527
  currentFrame += additiveFrames;
528
}
529

×
530
int32 Buf_BiLinearVector3_16bit::GetFrame() const { return additiveFrames; }
×
UNCOV
531

×
532
void Buf_BiLinearVector3_16bit::SetFrame(uint64 frame) {
533
  additiveFrames = static_cast<uint16>(frame);
534
}
535

×
536
void Buf_BiLinearVector3_16bit::Interpolate(
×
UNCOV
537
    Vector4A16 &out, const Buf_BiLinearVector3_16bit &rightFrame, float delta,
×
538
    const TrackMinMax &minMax) const {
539
  Vector4A16 startPoint, endPoint;
540

UNCOV
541
  Evaluate(startPoint);
×
542
  rightFrame.Evaluate(endPoint);
543

544
  out = blerp(startPoint, endPoint, minMax, delta);
UNCOV
545
}
×
546

547
void Buf_BiLinearVector3_16bit::SwapEndian() {
548
  FByteswapper(data);
549
  FByteswapper(additiveFrames);
UNCOV
550
}
×
551

552
constexpr float __Buf_BiLinearVector3_16bit_componentMask =
553
    static_cast<float>(Buf_BiLinearVector3_16bit::componentMask);
554

UNCOV
555
const Vector4A16 Buf_BiLinearVector3_16bit::componentMultiplierInv =
×
556
    Vector4A16(__Buf_BiLinearVector3_16bit_componentMask,
557
               __Buf_BiLinearVector3_16bit_componentMask,
558
               __Buf_BiLinearVector3_16bit_componentMask, 1.0f);
559

UNCOV
560
const Vector4A16 Buf_BiLinearVector3_16bit::componentMultiplier =
×
561
    Vector4A16(1.0f) / componentMultiplierInv;
562

563
size_t Buf_BiLinearVector3_8bit::Size() const { return 4; }
564

565
void Buf_BiLinearVector3_8bit::AppendToString(std::stringstream &buffer) const {
566
  AppendToStringRaw(this, buffer);
567
}
×
568

×
UNCOV
569
std::string_view
×
570
Buf_BiLinearVector3_8bit::RetreiveFromString(std::string_view buffer) {
571
  return RetreiveFromRawString(this, buffer);
572
}
573

574
void Buf_BiLinearVector3_8bit::Evaluate(Vector4A16 &out) const {
UNCOV
575
  out = Vector4A16(data.Convert<float>(), 1.0f) * componentMultiplier;
×
576
}
UNCOV
577

×
578
void Buf_BiLinearVector3_8bit::Devaluate(const Vector4A16 &in) {
579
  data = UCVector4((in * componentMultiplierInv).Convert<uint8>());
580
}
×
UNCOV
581

×
582
void Buf_BiLinearVector3_8bit::GetFrame(int32 &currentFrame) const {
583
  currentFrame += additiveFrames;
UNCOV
584
}
×
585

586
int32 Buf_BiLinearVector3_8bit::GetFrame() const { return additiveFrames; }
587

588
void Buf_BiLinearVector3_8bit::SetFrame(uint64 frame) {
×
UNCOV
589
  additiveFrames = static_cast<uint8>(frame);
×
590
}
591

×
UNCOV
592
void Buf_BiLinearVector3_8bit::Interpolate(
×
593
    Vector4A16 &out, const Buf_BiLinearVector3_8bit &rightFrame, float delta,
594
    const TrackMinMax &minMax) const {
×
UNCOV
595
  Vector4A16 startPoint, endPoint;
×
596

597
  Evaluate(startPoint);
×
UNCOV
598
  rightFrame.Evaluate(endPoint);
×
599

600
  out = blerp(startPoint, endPoint, minMax, delta);
×
UNCOV
601
}
×
602

603
constexpr float __Buf_BiLinearVector3_8bit_componentMask =
×
UNCOV
604
    static_cast<float>(Buf_BiLinearVector3_8bit::componentMask);
×
605

606
const Vector4A16 Buf_BiLinearVector3_8bit::componentMultiplierInv =
607
    Vector4A16(__Buf_BiLinearVector3_8bit_componentMask,
608
               __Buf_BiLinearVector3_8bit_componentMask,
×
UNCOV
609
               __Buf_BiLinearVector3_8bit_componentMask, 1.0f);
×
610

611
const Vector4A16 Buf_BiLinearVector3_8bit::componentMultiplier =
UNCOV
612
    Vector4A16(1.0f) / componentMultiplierInv;
×
613

614
void Buf_LinearRotationQuat4_14bit::Evaluate(Vector4A16 &out) const {
×
UNCOV
615
  out = IVector4A16(static_cast<int32>(data >> 42),
×
616
                    static_cast<int32>(data >> 28),
617
                    static_cast<int32>(data >> 14), static_cast<int32>(data)) &
UNCOV
618
        componentMask;
×
619

620
  const Vector4A16 signedHalf(Vector4A16(static_cast<float>(componentMask)) -
621
                              out);
622
  const Vector4A16 multSign(out.X > componentSignMax ? -1.0f : 0.0f,
623
                            out.Y > componentSignMax ? -1.0f : 0.0f,
624
                            out.Z > componentSignMax ? -1.0f : 0.0f,
625
                            out.W > componentSignMax ? -1.0f : 0.0f);
UNCOV
626

×
627
  out *= multSign + 1.0f;
628
  out += signedHalf * multSign;
×
629
  out *= componentMultiplier;
×
630
}
×
631

×
632
void Buf_LinearRotationQuat4_14bit::Devaluate(const Vector4A16 &_in) {
×
633
  Vector4A16 in = _in;
×
634
  data ^= data & dataField;
×
UNCOV
635

×
636
  in *= componentMultiplierInv;
637

638
  if (in.W < 0.0f) {
639
    data |= componentMask - static_cast<uint64>(-in.W);
640
  } else {
641
    data |= static_cast<uint64>(in.W);
×
642
  }
×
UNCOV
643

×
644
  if (in.Z < 0.0f) {
645
    data |= (componentMask - static_cast<uint64>(-in.Z)) << 14;
646
  } else {
647
    data |= static_cast<uint64>(in.Z) << 14;
×
648
  }
×
649

×
UNCOV
650
  if (in.Y < 0.0f) {
×
651
    data |= (componentMask - static_cast<uint64>(-in.Y)) << 28;
652
  } else {
653
    data |= static_cast<uint64>(in.Y) << 28;
654
  }
UNCOV
655

×
656
  if (in.X < 0.0f) {
657
    data |= (componentMask - static_cast<uint64>(-in.X)) << 42;
×
UNCOV
658
  } else {
×
659
    data |= static_cast<uint64>(in.X) << 42;
660
  }
661
}
662

×
UNCOV
663
void Buf_LinearRotationQuat4_14bit::Interpolate(
×
664
    Vector4A16 &out, const Buf_LinearRotationQuat4_14bit &rightFrame,
665
    float delta, const TrackMinMax &) const {
666
  Vector4A16 startPoint, endPoint;
1✔
667

1✔
668
  Evaluate(startPoint);
1✔
669
  rightFrame.Evaluate(endPoint);
670

1✔
671
  out = slerp(startPoint, endPoint, delta);
672
}
673

674
size_t Buf_BiLinearRotationQuat4_7bit::Size() const { return 4; }
1✔
675

×
UNCOV
676
void Buf_BiLinearRotationQuat4_7bit::AppendToString(
×
677
    std::stringstream &buffer) const {
678
  AppendToStringRaw(this, buffer);
679
}
1✔
680

1✔
681
std::string_view
1✔
682
Buf_BiLinearRotationQuat4_7bit::RetreiveFromString(std::string_view buffer) {
683
  return RetreiveFromRawString(this, buffer);
684
}
1✔
685

686
void Buf_BiLinearRotationQuat4_7bit::Evaluate(Vector4A16 &out) const {
1✔
687
  out = IVector4A16(data >> 21, data >> 14, data >> 7, data) & componentMask;
688
  out *= componentMultiplier;
689
}
1✔
690

1✔
691
void Buf_BiLinearRotationQuat4_7bit::Devaluate(const Vector4A16 &in) {
1✔
692
  data ^= data & dataField;
693

1✔
694
  UIVector4A16 store(IVector4A16(in * componentMultiplierInv));
1✔
695

696
  data |= store.W;
1✔
697
  data |= store.Z << 7;
1✔
698
  data |= store.Y << 14;
1✔
699
  data |= store.X << 21;
1✔
700
}
1✔
701

702
void Buf_BiLinearRotationQuat4_7bit::GetFrame(int32 &currentFrame) const {
1✔
703
  currentFrame += data >> 28;
1✔
704
}
1✔
705

1✔
706
int32 Buf_BiLinearRotationQuat4_7bit::GetFrame() const { return data >> 28; }
1✔
707

708
void Buf_BiLinearRotationQuat4_7bit::SetFrame(uint64 frame) {
709
  data ^= data & frameField;
1✔
710
  data |= frame << 28;
711
}
712

713
void Buf_BiLinearRotationQuat4_7bit::Interpolate(
714
    Vector4A16 &out, const Buf_BiLinearRotationQuat4_7bit &rightFrame,
715
    float delta, const TrackMinMax &minMax) const {
716
  Vector4A16 startPoint, endPoint;
717

718
  Evaluate(startPoint);
719
  rightFrame.Evaluate(endPoint);
720

721
  out = bslerp(startPoint, endPoint, minMax, delta);
722
}
723

724
void Buf_BiLinearRotationQuat4_7bit::SwapEndian() { FByteswapper(data); }
1✔
725

1✔
726
void Buf_BiLinearRotationQuatXW_14bit::Evaluate(Vector4A16 &out) const {
727
  out = IVector4A16(data, 0, 0, data >> 14) & componentMask;
1✔
728
  out *= componentMultiplier;
1✔
729
}
1✔
730

1✔
731
void Buf_BiLinearRotationQuatXW_14bit::Devaluate(const Vector4A16 &in) {
732
  data ^= data & dataField;
1✔
UNCOV
733

×
734
  UIVector4A16 store(IVector4A16(in * componentMultiplierInv));
735

736
  data |= store.X;
1✔
737
  data |= store.W << 14;
1✔
738
}
739

740
void Buf_BiLinearRotationQuatXW_14bit::Interpolate(
1✔
741
    Vector4A16 &out, const Buf_BiLinearRotationQuatXW_14bit &rightFrame,
1✔
742
    float delta, const TrackMinMax &minMax) const {
743
  Vector4A16 startPoint, endPoint;
1✔
744

745
  Evaluate(startPoint);
×
UNCOV
746
  rightFrame.Evaluate(endPoint);
×
747

748
  out = bslerp(startPoint, endPoint, minMax, delta);
UNCOV
749
}
×
750

751
void Buf_BiLinearRotationQuatYW_14bit::Evaluate(Vector4A16 &out) const {
×
752
  out = IVector4A16(0, data, 0, data >> 14) & componentMask;
×
UNCOV
753
  out *= componentMultiplier;
×
754
}
755

UNCOV
756
void Buf_BiLinearRotationQuatYW_14bit::Devaluate(const Vector4A16 &in) {
×
757
  data ^= data & dataField;
758

759
  UIVector4A16 store(IVector4A16(in * componentMultiplierInv));
760

761
  data |= store.Y;
762
  data |= store.W << 14;
×
UNCOV
763
}
×
764

UNCOV
765
void Buf_BiLinearRotationQuatYW_14bit::Interpolate(
×
766
    Vector4A16 &out, const Buf_BiLinearRotationQuatYW_14bit &rightFrame,
767
    float delta, const TrackMinMax &minMax) const {
UNCOV
768
  Vector4A16 startPoint, endPoint;
×
769

UNCOV
770
  Evaluate(startPoint);
×
771
  rightFrame.Evaluate(endPoint);
UNCOV
772

×
773
  out = bslerp(startPoint, endPoint, minMax, delta);
UNCOV
774
}
×
775

776
void Buf_BiLinearRotationQuatZW_14bit::Evaluate(Vector4A16 &out) const {
777
  out = IVector4A16(0, 0, data, data >> 14) & componentMask;
778
  out *= componentMultiplier;
×
UNCOV
779
}
×
780

781
void Buf_BiLinearRotationQuatZW_14bit::Devaluate(const Vector4A16 &in) {
UNCOV
782
  data ^= data & dataField;
×
783

784
  UIVector4A16 store(IVector4A16(in * componentMultiplierInv));
785

UNCOV
786
  data |= store.Z;
×
787
  data |= store.W << 14;
1✔
788
}
789

790
void Buf_BiLinearRotationQuatZW_14bit::Interpolate(
×
UNCOV
791
    Vector4A16 &out, const Buf_BiLinearRotationQuatZW_14bit &rightFrame,
×
792
    float delta, const TrackMinMax &minMax) const {
793
  Vector4A16 startPoint, endPoint;
UNCOV
794

×
795
  Evaluate(startPoint);
796
  rightFrame.Evaluate(endPoint);
×
UNCOV
797

×
798
  out = bslerp(startPoint, endPoint, minMax, delta);
799
}
UNCOV
800

×
801
size_t Buf_BiLinearRotationQuat4_11bit::Size() const { return 6; }
802

803
void Buf_BiLinearRotationQuat4_11bit::AppendToString(
804
    std::stringstream &buffer) const {
805
  AppendToStringRaw(this, buffer);
806
}
807

UNCOV
808
std::string_view
×
809
Buf_BiLinearRotationQuat4_11bit::RetreiveFromString(std::string_view buffer) {
810
  return RetreiveFromRawString(this, buffer);
811
}
×
812

×
UNCOV
813
void Buf_BiLinearRotationQuat4_11bit::Evaluate(Vector4A16 &out) const {
×
814
  const uint64 &rVal = reinterpret_cast<const uint64 &>(data);
815

816
  out = IVector4A16(static_cast<int32>(rVal),
817
                    static_cast<int32>(((rVal >> 11) << 6) | (data[1] & 0x3f)),
818
                    static_cast<int32>((rVal >> 22) << 1 | (data[2] & 1)),
819
                    static_cast<int32>(rVal >> 33)) &
820
        componentMask;
821
  out *= componentMultiplier;
822
}
823

824
void Buf_BiLinearRotationQuat4_11bit::Devaluate(const Vector4A16 &in) {
825
  uint64 &rVal = reinterpret_cast<uint64 &>(data);
826

UNCOV
827
  rVal ^= rVal & 0xFFFFFFFFFFF;
×
828

829
  t_Vector4<uint64> store = (in * componentMultiplierInv).Convert<uint64>();
×
UNCOV
830

×
831
  rVal |= store.X;
832
  rVal |= (store.Y >> 6 | (store.Y & 0x3f) << 5) << 11;
833
  rVal |= (store.Z >> 1 | (store.Z & 1) << 10) << 22;
834
  rVal |= store.W << 33;
×
UNCOV
835
}
×
836

837
void Buf_BiLinearRotationQuat4_11bit::GetFrame(int32 &currentFrame) const {
UNCOV
838
  currentFrame += data.Z >> 12;
×
839
}
840

841
void Buf_BiLinearRotationQuat4_11bit::Interpolate(
UNCOV
842
    Vector4A16 &out, const Buf_BiLinearRotationQuat4_11bit &rightFrame,
×
843
    float delta, const TrackMinMax &minMax) const {
1✔
844
  Vector4A16 startPoint, endPoint;
845

846
  Evaluate(startPoint);
×
UNCOV
847
  rightFrame.Evaluate(endPoint);
×
848

849
  out = bslerp(startPoint, endPoint, minMax, delta);
UNCOV
850
}
×
851

852
void Buf_BiLinearRotationQuat4_11bit::SwapEndian() { FByteswapper(data); }
×
UNCOV
853

×
854
size_t Buf_BiLinearRotationQuat4_9bit::Size() const { return 5; }
855

UNCOV
856
void Buf_BiLinearRotationQuat4_9bit::AppendToString(
×
857
    std::stringstream &buffer) const {
858
  AppendToStringRaw(this, buffer);
859
}
860

861
std::string_view
862
Buf_BiLinearRotationQuat4_9bit::RetreiveFromString(std::string_view buffer) {
863
  return RetreiveFromRawString(this, buffer);
UNCOV
864
}
×
865

866
void Buf_BiLinearRotationQuat4_9bit::Evaluate(Vector4A16 &out) const {
867
  const uint64 &rVal = reinterpret_cast<const uint64 &>(data);
868

869
  out = IVector4A16(static_cast<int32>((rVal << 1) | (data[1] & 1)),
870
                    static_cast<int32>(((rVal >> 9) << 2) | (data[2] & 3)),
871
                    static_cast<int32>(((rVal >> 18) << 3) | (data[3] & 7)),
872
                    static_cast<int32>(((rVal >> 27) << 4) | (data[4] & 0xf))) &
873
        componentMask;
874
  out *= componentMultiplier;
875
}
876

877
void Buf_BiLinearRotationQuat4_9bit::Devaluate(const Vector4A16 &in) {
878
  uint64 &rVal = reinterpret_cast<uint64 &>(data);
1✔
879

1✔
880
  rVal ^= rVal & 0xFFFFFFFFF;
1✔
881

1✔
882
  t_Vector4<uint64> store = (in * componentMultiplierInv).Convert<uint64>();
883

884
  rVal |= store.X >> 1 | (store.X & 1) << 8;
885
  rVal |= (store.Y >> 2 | (store.Y & 3) << 7) << 9;
886
  rVal |= (store.Z >> 3 | (store.Z & 7) << 6) << 18;
887
  rVal |= (store.W >> 4 | (store.W & 0xf) << 5) << 27;
888
}
889

2✔
890
void Buf_BiLinearRotationQuat4_9bit::GetFrame(int32 &currentFrame) const {
891
  currentFrame += data[4] >> 4;
892
}
893

894
void Buf_BiLinearRotationQuat4_9bit::Interpolate(
1✔
895
    Vector4A16 &out, const Buf_BiLinearRotationQuat4_9bit &rightFrame,
896
    float delta, const TrackMinMax &minMax) const {
1✔
897
  Vector4A16 startPoint, endPoint;
1✔
898

1✔
899
  Evaluate(startPoint);
900
  rightFrame.Evaluate(endPoint);
901

902
  out = bslerp(startPoint, endPoint, minMax, delta);
1✔
UNCOV
903
}
×
904

905
template <class C>
1✔
906
void Buff_EvalShared<C>::ToString(std::string &strBuff,
907
                                  size_t numIdents) const {
908
  static const char *idents[] = {
1✔
909
      "", "\t", "\t\t", "\t\t\t", "\t\t\t\t", "\t\t\t\t\t",
1✔
910
  };
UNCOV
911
  std::stringstream str;
×
912
  str << std::endl << idents[numIdents];
913

914
  size_t curLine = 1;
1✔
915

1✔
916
  for (auto &d : data) {
UNCOV
917
    d.AppendToString(str);
×
918

919
    if (!(curLine % C::NEWLINEMOD)) {
920
      str << std::endl << idents[numIdents];
1✔
UNCOV
921
    }
×
922

923
    curLine++;
1✔
924
  }
925

1✔
926
  if (!((curLine - 1) % C::NEWLINEMOD)) {
UNCOV
927
    str.seekp(-1, std::ios_base::cur) << '\0';
×
928
  } else {
929
    str << std::endl << idents[numIdents - 1];
930
  }
931

932
  strBuff = std::move(str).str();
×
UNCOV
933
}
×
934

UNCOV
935
template <class C> void Buff_EvalShared<C>::FromString(std::string_view input) {
×
936
  for (auto &d : data) {
937
    input = d.RetreiveFromString(input);
UNCOV
938
  }
×
939
}
UNCOV
940

×
941
template <class C>
UNCOV
942
void Buff_EvalShared<C>::Assign(char *ptr, size_t size, bool swapEndian) {
×
943
  if constexpr (!C::VARIABLE_SIZE) {
944
    data = {reinterpret_cast<C *>(ptr), reinterpret_cast<C *>(ptr + size)};
945
  } else {
946
    const char *bufferEnd = ptr + size;
×
UNCOV
947

×
948
    while (ptr < bufferEnd) {
949
      C *block = reinterpret_cast<C *>(ptr);
UNCOV
950
      internalData.push_back(*block);
×
951
      ptr += block->Size();
1✔
952
    }
953

954
    data = internalData;
UNCOV
955
  }
×
956

1✔
957
  if (swapEndian) {
958
    SwapEndian();
959
  }
960

1✔
961
  frames.resize(NumFrames());
1✔
962
  int32 currentFrame = 0;
1✔
963
  size_t curFrameID = 0;
1✔
964

965
  for (auto &f : frames) {
966
    f = currentFrame;
×
UNCOV
967
    data[curFrameID++].GetFrame(currentFrame);
×
968
  }
969
}
UNCOV
970

×
971
template <class C> void Buff_EvalShared<C>::Save(BinWritterRef wr) const {
972
  if constexpr (!C::VARIABLE_SIZE) {
×
973
    if (!wr.SwappedEndian()) {
×
UNCOV
974
      wr.WriteBuffer(reinterpret_cast<const char *>(data.data()),
×
975
                     data.size() * sizeof(typename decltype(data)::value_type));
976
    } else {
UNCOV
977
      wr.WriteContainer(data);
×
978
    }
979
  } else {
980
    for (auto &r : data) {
981
      C tmp = r;
982
      tmp.SwapEndian();
983
      wr.WriteBuffer(reinterpret_cast<const char *>(&tmp), r.Size());
984
    }
UNCOV
985
  }
×
986
}
987

UNCOV
988
template <class C> void Buff_EvalShared<C>::SwapEndian() {
×
989
  for (auto &d : data) {
UNCOV
990
    d.SwapEndian();
×
991
  }
1✔
992
}
993

994
template <class Derived> LMTTrackController *_creatorDummyBuffEval() {
UNCOV
995
  return new Buff_EvalShared<Derived>();
×
996
}
1✔
997

998
#define TCON_REG(val) {TrackTypesShared::val, _creatorDummyBuffEval<Buf_##val>},
999

1000
#define TCONFRC_REG(val)                                                       \
1✔
1001
  {TrackTypesShared::val, [] { return Buf_##val::componentMultiplier; }()},
1✔
1002

1003
namespace std {
UNCOV
1004
template <> struct hash<TrackTypesShared> {
×
1005
  uint32 operator()(const TrackTypesShared &t) const {
1006
    return static_cast<uint32>(t);
1007
  }
1008
};
1009
} // namespace std
1010

1011
static const std::unordered_map<TrackTypesShared, LMTTrackController *(*)()>
UNCOV
1012
    codecRegistry = {
×
1013
        {TrackTypesShared::None, nullptr},
1014
        StaticFor(TCON_REG, SingleVector3, HermiteVector3, StepRotationQuat3,
UNCOV
1015
                  SphericalRotation, LinearVector3, BiLinearVector3_16bit,
×
1016
                  BiLinearVector3_8bit, LinearRotationQuat4_14bit,
1✔
1017
                  BiLinearRotationQuat4_7bit, BiLinearRotationQuatXW_14bit,
1018
                  BiLinearRotationQuatYW_14bit, BiLinearRotationQuatZW_14bit,
1019
                  BiLinearRotationQuat4_11bit, BiLinearRotationQuat4_9bit)};
UNCOV
1020

×
1021
static const std::unordered_map<TrackTypesShared, float> fracRegistry = {
1✔
1022
    {TrackTypesShared::BiLinearVector3_16bit,
1023
     Buf_BiLinearVector3_16bit::componentMultiplier.X},
1024
    {TrackTypesShared::BiLinearVector3_8bit,
1025
     Buf_BiLinearVector3_8bit::componentMultiplier.X},
1✔
1026
    StaticFor(TCONFRC_REG, LinearRotationQuat4_14bit,
1✔
1027
              BiLinearRotationQuat4_7bit, BiLinearRotationQuatXW_14bit,
1028
              BiLinearRotationQuatYW_14bit, BiLinearRotationQuatZW_14bit,
UNCOV
1029
              BiLinearRotationQuat4_11bit, BiLinearRotationQuat4_9bit)};
×
1030

1031
LMTTrackController *LMTTrackController::CreateCodec(TrackTypesShared cType) {
1032
  if (codecRegistry.count(cType)) {
1033
    return codecRegistry.at(cType)();
1034
  }
1035

1036
  return nullptr;
UNCOV
1037
}
×
1038

1039
float LMTTrackController::GetTrackMaxFrac(TrackTypesShared type) {
UNCOV
1040
  if (fracRegistry.count(type)) {
×
1041
    return fracRegistry.at(type);
1✔
1042
  }
1043

1044
  return FLT_MAX;
UNCOV
1045
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc