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

PredatorCZ / HavokLib / 89

06 Nov 2025 01:09PM UTC coverage: 63.837% (-3.2%) from 67.014%
89

push

github

PredatorCZ
s

3354 of 5254 relevant lines covered (63.84%)

129082.83 hits per line

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

51.52
/source/core_motion.cpp
1
/*  Havok Format Library
2
    Copyright(C) 2016-2022 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 "internal/hka_animation.hpp"
19
#include "internal/hka_defaultanimrefframe.hpp"
20

21
void hkaAniTrackHandle::GetValue(uni::RTSValue &output, float time) const {
5,803,200✔
22
  hdl->GetValue(output, time, index);
5,803,200✔
23
}
5,803,200✔
24

25
// https://en.wikipedia.org/wiki/Slerp
26
static Vector4A16 SLerp(const Vector4A16 &v0, const Vector4A16 &_v1, float t) {
3,794,400✔
27
  Vector4A16 v1 = _v1;
3,794,400✔
28
  float dot = v0.Dot(v1);
3,794,400✔
29

30
  // If the dot product is negative, slerp won't take
31
  // the shorter path. Fix by reversing one quaternion.
32
  if (dot < 0.0f) {
3,794,400✔
33
    v1 *= -1;
×
34
    dot *= -1;
×
35
  }
36

37
  static const float DOT_THRESHOLD = 0.9995f;
38
  if (dot > DOT_THRESHOLD) {
3,794,400✔
39
    // If the inputs are too close for comfort, linearly interpolate
40
    // and normalize the result.
41

42
    Vector4A16 result = v0 + (v1 - v0) * t;
3,275,512✔
43
    return result.Normalize();
3,275,512✔
44
  }
45

46
  const float theta00 = acos(dot);   // theta00 = angle between input vectors
518,888✔
47
  const float theta01 = theta00 * t; // theta01 = angle between v0 and result
518,888✔
48
  const float theta02 = sin(theta01);
518,888✔
49
  const float theta03 = 1.0f / sin(theta00);
518,888✔
50
  const float s0 = cos(theta01) - dot * theta02 * theta03;
518,888✔
51
  const float s1 = theta02 * theta03;
518,888✔
52

53
  return (v0 * s0) + (v1 * s1);
518,888✔
54
}
55

56
static Vector4A16 Lerp(const Vector4A16 &v1, const Vector4A16 &v2,
7,588,800✔
57
                       float delta) {
58
  return v1 + (v2 - v1) * delta;
7,588,800✔
59
}
60

61
void hkaAnimationLerpSampler::GetValue(uni::RTSValue &output, float time,
3,794,400✔
62
                                       size_t trackID) const {
63
  const float frameFull = time * frameRate;
3,794,400✔
64
  int32 frame = static_cast<int32>(frameFull);
3,794,400✔
65
  float delta = frameFull - frame;
3,794,400✔
66
  const int32 endFrame = static_cast<int32>(numFrames - 1);
3,794,400✔
67

68
  if (frameFull >= endFrame) {
3,794,400✔
69
    frame = endFrame;
×
70
    delta = 0.f;
×
71
  }
72

73
  if (!delta) {
3,794,400✔
74
    GetFrame(trackID, frame, output);
×
75
  } else {
76
    hkQTransform start;
3,794,400✔
77
    GetFrame(trackID, frame++, start);
3,794,400✔
78
    hkQTransform end;
3,794,400✔
79
    GetFrame(trackID, frame, end);
3,794,400✔
80

81
    output.translation = ::Lerp(start.translation, end.translation, delta);
3,794,400✔
82
    output.rotation = ::SLerp(start.rotation, end.rotation, delta);
3,794,400✔
83
    output.scale = ::Lerp(start.scale, end.scale, delta);
3,794,400✔
84
  }
85
}
3,794,400✔
86

87
void hkaAnimatedReferenceFrameInternalInterface::GetValue(uni::RTSValue &output,
×
88
                                                          float time) const {
89
  const float frameFull = time * frameRate;
×
90
  int32 frame = static_cast<int32>(frameFull);
×
91
  float delta = frameFull - frame;
×
92
  const auto numFrames = GetNumFrames();
×
93
  const int32 endFrame = static_cast<int32>(numFrames - 1);
×
94

95
  if (frameFull >= endFrame) {
×
96
    frame = endFrame;
×
97
    delta = 0.f;
×
98
  }
99

100
  auto ConvertRefFrame = [&](const Vector4A16 &input) {
×
101
    uni::RTSValue retVal;
×
102
    retVal.translation = Vector4A16(input, 1.f);
×
103
    retVal.rotation.X = sinf(input.W * 0.5f);
×
104
    retVal.rotation.Y = retVal.rotation.X;
×
105
    retVal.rotation.Z = retVal.rotation.X;
×
106
    retVal.rotation *= GetUp();
×
107
    retVal.rotation.W = cosf(input.W * 0.5f);
×
108
    return retVal;
×
109
  };
110

111
  if (!delta) {
×
112
    auto cFrame = GetRefFrame(frame);
×
113
    output = ConvertRefFrame(cFrame);
×
114
  } else {
115
    auto frame0 = GetRefFrame(frame++);
×
116
    auto frame1 = GetRefFrame(frame);
×
117

118
    hkQTransform start = ConvertRefFrame(frame0);
×
119
    hkQTransform end = ConvertRefFrame(frame1);
×
120

121
    output.translation = ::Lerp(start.translation, end.translation, delta);
×
122
    output.rotation = ::SLerp(start.rotation, end.rotation, delta);
×
123
  }
124
}
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