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

PredatorCZ / RevilLib / 145

12 May 2024 10:02PM UTC coverage: 11.246% (-0.3%) from 11.536%
145

push

github

PredatorCZ
fix arc v4 load

757 of 6731 relevant lines covered (11.25%)

6713.75 hits per line

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

4.04
/src/mtf_lmt/bone_track.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 "bone_track.hpp"
19
#include "fixup_storage.hpp"
20
#include "pugixml.hpp"
21
#include "spike/reflect/reflector_xml.hpp"
22
#include "spike/uni/deleter_hybrid.hpp"
23

24
MAKE_ENUM(ENUMSCOPE(class TrackType_er
1✔
25
                    : uint8, TrackType_er),
26
          EMEMBER(LocalRotation), EMEMBER(LocalPosition), EMEMBER(LocalScale),
27
          EMEMBER(AbsoluteRotation), EMEMBER(AbsolutePosition));
28

29
MAKE_ENUM(ENUMSCOPE(class TrackV1BufferTypes
1✔
30
                    : uint8, TrackV1BufferTypes),
31
          EMEMBERVAL(SingleVector3, 1), EMEMBER(SinglePositionVector3),
32
          EMEMBERVAL(SingleRotationQuat3, 4), EMEMBER(HermiteVector3),
33
          EMEMBER(SphericalRotation), EMEMBERVAL(LinearVector3, 9));
34

35
MAKE_ENUM(ENUMSCOPE(class TrackV1_5BufferTypes
1✔
36
                    : uint8, TrackV1_5BufferTypes),
37
          EMEMBERVAL(SingleVector3, 1), EMEMBER(SinglePositionVector3),
38
          EMEMBERVAL(SingleRotationQuat3, 4), EMEMBER(HermiteVector3),
39
          EMEMBER(LinearRotationQuat4_14bit), EMEMBERVAL(LinearVector3, 9));
40

41
MAKE_ENUM(ENUMSCOPE(class TrackV2BufferTypes
1✔
42
                    : uint8, TrackV2BufferTypes),
43
          EMEMBERVAL(SingleVector3, 1), EMEMBER(SingleRotationQuat3),
44
          EMEMBER(LinearVector3), EMEMBER(BiLinearVector3_16bit),
45
          EMEMBER(BiLinearVector3_8bit), EMEMBER(LinearRotationQuat4_14bit),
46
          EMEMBER(BiLinearRotationQuat4_7bit),
47
          EMEMBERVAL(BiLinearRotationQuatXW_14bit, 11),
48
          EMEMBER(BiLinearRotationQuatYW_14bit),
49
          EMEMBER(BiLinearRotationQuatZW_14bit),
50
          EMEMBER(BiLinearRotationQuat4_11bit),
51
          EMEMBER(BiLinearRotationQuat4_9bit))
52

53
#include "bone_track.inl"
54

55
size_t LMTTrackInterface::NumFrames() const { return controller->NumFrames(); }
×
56

57
bool LMTTrackInterface::LMTTrackInterface::IsCubic() const {
×
58
  return controller->IsCubic();
×
59
}
60

61
void LMTTrackInterface::GetTangents(Vector4A16 &inTangs, Vector4A16 &outTangs,
×
62
                                    size_t frame) const {
63
  controller->GetTangents(inTangs, outTangs, frame);
×
64
}
65

66
void LMTTrackInterface::Evaluate(Vector4A16 &out, size_t frame) const {
×
67
  controller->Evaluate(out, frame);
×
68

69
  if (useMinMax) {
×
70
    out = minMax.max + minMax.min * out;
71
  }
72
}
73

74
int32 LMTTrackInterface::GetFrame(size_t frame) const {
×
75
  return controller->GetFrame(frame);
×
76
}
77

78
void LMTTrackInterface::GetValue(Vector4A16 &out, float time) const {
×
79
  float frameDelta = time * frameRate;
×
80
  int32 frame = static_cast<int32>(frameDelta);
×
81
  const size_t numCtrFrames = controller->NumFrames();
×
82

83
  if (!numCtrFrames) {
×
84
    if (useRefFrame) {
×
85
      out = GetRefData();
×
86
    }
87

88
    return;
×
89
  }
90

91
  if (useRefFrame) {
×
92
    if (loopFrame < 1) {
×
93
      if (!frame) {
×
94
        if (frameDelta < 0.0001f) {
×
95
          out = GetRefData();
×
96
        } else {
97
          frameDelta -= frame;
×
98
          Evaluate(out, 0);
×
99
          out = GetRefData() + (out - GetRefData()) * frameDelta;
×
100
        }
101

102
        return;
×
103
      }
104

105
      frame--;
×
106
      frameDelta -= 1.f;
×
107
    }
108
  }
109

110
  const int32 maxFrame = controller->GetFrame(numCtrFrames - 1);
×
111

112
  if (frame >= maxFrame) {
×
113
    Evaluate(out, numCtrFrames - 1);
×
114
  } else {
115
    for (size_t f = 1; f < numCtrFrames; f++) {
×
116
      int32 cFrame = controller->GetFrame(f);
×
117

118
      if (cFrame > frame) {
×
119
        const float boundFrame = static_cast<float>(cFrame);
×
120
        const float prevFrame = static_cast<float>(controller->GetFrame(f - 1));
×
121

122
        frameDelta = (prevFrame - frameDelta) / (prevFrame - boundFrame);
×
123

124
        controller->Interpolate(out, f - 1, frameDelta, minMax);
×
125
        break;
×
126
      }
127
    }
128
  }
129
}
130

131
uni::MotionTrack::TrackType_e LMTTrackInterface::TrackType() const {
×
132
  const auto iType = this->GetTrackType();
×
133

134
  switch (iType) {
×
135
  case TrackType_AbsolutePosition:
136
  case TrackType_LocalPosition:
137
    return MotionTrack::TrackType_e::Position;
138

139
  case TrackType_AbsoluteRotation:
×
140
  case TrackType_LocalRotation:
141
    return MotionTrack::TrackType_e::Rotation;
×
142

143
  default:
×
144
    return MotionTrack::TrackType_e::Scale;
×
145
  }
146
}
147

148
static const TrackTypesShared buffRemapRegistry[][16] = {
149
    {
150
        TrackTypesShared::None,
151
        TrackTypesShared::SingleVector3,
152
        TrackTypesShared::SingleVector3,
153
        TrackTypesShared::None,
154
        TrackTypesShared::StepRotationQuat3,
155
        TrackTypesShared::HermiteVector3,
156
        TrackTypesShared::SphericalRotation,
157
        TrackTypesShared::None,
158
        TrackTypesShared::None,
159
        TrackTypesShared::LinearVector3,
160
    },
161
    {
162
        TrackTypesShared::None,
163
        TrackTypesShared::SingleVector3,
164
        TrackTypesShared::SingleVector3,
165
        TrackTypesShared::None,
166
        TrackTypesShared::StepRotationQuat3,
167
        TrackTypesShared::HermiteVector3,
168
        TrackTypesShared::LinearRotationQuat4_14bit,
169
        TrackTypesShared::None,
170
        TrackTypesShared::None,
171
        TrackTypesShared::LinearVector3,
172
    },
173
    {
174
        TrackTypesShared::None,
175
        TrackTypesShared::SingleVector3,
176
        TrackTypesShared::StepRotationQuat3,
177
        TrackTypesShared::LinearVector3,
178
        TrackTypesShared::BiLinearVector3_16bit,
179
        TrackTypesShared::BiLinearVector3_8bit,
180
        TrackTypesShared::LinearRotationQuat4_14bit,
181
        TrackTypesShared::BiLinearRotationQuat4_7bit,
182
        TrackTypesShared::None,
183
        TrackTypesShared::None,
184
        TrackTypesShared::None,
185
        TrackTypesShared::BiLinearRotationQuatXW_14bit,
186
        TrackTypesShared::BiLinearRotationQuatYW_14bit,
187
        TrackTypesShared::BiLinearRotationQuatZW_14bit,
188
        TrackTypesShared::BiLinearRotationQuat4_11bit,
189
        TrackTypesShared::BiLinearRotationQuat4_9bit,
190
    },
191
};
192

193
struct LMTTrackMidInterface : LMTTrackInterface {
194
  clgen::BoneTrack::Interface interface;
195

196
  LMTTrackMidInterface(clgen::LayoutLookup rules, char *data)
×
197
      : interface{data, rules} {
×
198
    useRefFrame = interface.m(clgen::BoneTrack::referenceData) >= 0;
×
199
  }
200

201
  TrackType_e GetTrackType() const noexcept override {
×
202
    return static_cast<TrackType_e>(interface.TrackType());
×
203
  }
204

205
  size_t Stride() const override { return interface.layout->totalSize; }
×
206

207
  size_t BoneIndex() const noexcept override {
×
208
    if (interface.m(clgen::BoneTrack::boneID2) >= 0) {
×
209
      return interface.BoneID2();
×
210
    }
211

212
    auto boneID = interface.BoneID();
213
    return boneID == 0xff ? -1 : boneID;
×
214
  }
215

216
  uint32 BoneType() const noexcept override { return interface.BoneType(); }
×
217

218
  const Vector4A16 GetRefData() const override {
×
219
    return interface.ReferenceData();
×
220
  }
221

222
  bool UseTrackExtremes() const override {
×
223
    return interface.m(clgen::BoneTrack::extremes) >= 0;
×
224
  }
225

226
  std::string_view CompressionType() const override {
×
227
    static const std::string_view COMPRESSIONS[]{
228
        "None",
229
        "SingleVector3",
230
        "HermiteVector3",
231
        "StepRotationQuat3",
232
        "SphericalRotation",
233
        "LinearVector3",
234
        "BiLinearVector3_16bit",
235
        "BiLinearVector3_8bit",
236
        "LinearRotationQuat4_14bit",
237
        "BiLinearRotationQuat4_7bit",
238
        "BiLinearRotationQuatXW_14bit",
239
        "BiLinearRotationQuatYW_14bit",
240
        "BiLinearRotationQuatZW_14bit",
241
        "BiLinearRotationQuat4_11bit",
242
        "BiLinearRotationQuat4_9bit",
243
    };
244
    uint32 version = 0;
245

246
    if (interface.LayoutVersion() >= LMT56) {
×
247
      version = 2;
248
    } else if (interface.LayoutVersion() >= LMT51) {
×
249
      version = 1;
250
    }
251

252
    uint8 compression = uint8(interface.Compression());
253

254
    return COMPRESSIONS[uint32(buffRemapRegistry[version][compression])];
×
255
  }
256
};
257

258
template <>
259
void ProcessClass(LMTTrackMidInterface &item, LMTConstructorProperties flags) {
×
260
  if (!item.interface.BufferPtr().Check(flags.ptrStore)) {
×
261
    if (flags.swapEndian) {
×
262
      clgen::EndianSwap(item.interface);
×
263
    }
264

265
    item.interface.BufferPtr().Fixup(flags.base, flags.ptrStore);
×
266

267
    if (item.interface.LayoutVersion() >= LMT56) {
×
268
      item.interface.ExtremesPtr().Fixup(flags.base, flags.ptrStore);
×
269

270
      if (auto extr = item.interface.Extremes(); extr) {
×
271
        if (flags.swapEndian) {
×
272
          FByteswapper(*extr);
273
        }
274
      }
275

276
      if (flags.swapEndian) {
×
277
        FByteswapper(*reinterpret_cast<uint32 *>(
×
278
            item.interface.data +
×
279
            item.interface.m(clgen::BoneTrack::compression)));
×
280
      }
281
    }
282
  }
283

284
  if (auto extr = item.interface.Extremes(); extr) {
×
285
    item.useMinMax = true;
×
286
    memcpy(&item.minMax, extr, sizeof(TrackMinMax));
×
287
  }
288

289
  uint32 version = 0;
290

291
  if (item.interface.LayoutVersion() >= LMT56) {
×
292
    version = 2;
293
  } else if (item.interface.LayoutVersion() >= LMT51) {
×
294
    version = 1;
295
  }
296

297
  uint8 compression = uint8(item.interface.Compression());
298

299
  item.controller = LMTTrackInterface::LMTTrackControllerPtr(
×
300
      LMTTrackController::CreateCodec(buffRemapRegistry[version][compression]));
×
301

302
  if (item.controller) {
×
303
    item.controller->Assign(item.interface.Buffer(),
×
304
                            item.interface.BufferSize(), flags.swapEndian);
×
305
  }
306
}
307

308
template <>
309
void ProcessClass(LMTTrackInterface &item, LMTConstructorProperties flags) {
×
310
  ProcessClass(static_cast<LMTTrackMidInterface &>(item), flags);
×
311
}
312

313
using ptr_type_ = std::unique_ptr<LMTTrack>;
314

315
ptr_type_ LMTTrack::Create(const LMTConstructorProperties &props) {
×
316
  return std::make_unique<LMTTrackMidInterface>(
×
317
      clgen::LayoutLookup{static_cast<uint8>(props.version),
×
318
                          props.arch == LMTArchType::X64, false},
×
319
      static_cast<char *>(props.dataStart));
320
}
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

© 2026 Coveralls, Inc