Project
Loading...
Searching...
No Matches
GPUDisplayAnimation.cxx
Go to the documentation of this file.
1// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3// All rights not expressly granted are reserved.
4//
5// This software is distributed under the terms of the GNU General Public
6// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7//
8// In applying this license CERN does not waive the privileges and immunities
9// granted to it by virtue of its status as an Intergovernmental Organization
10// or submit itself to any jurisdiction.
11
14
15#include "GPUDisplay.h"
16#include "frontend/GPUDisplayInfo.inc"
17#include "GPUCommonMath.h"
18
19using namespace o2::gpu;
20
21constexpr hmm_mat4 MY_HMM_FROM(float (&v)[16]) { return {{{v[0], v[1], v[2], v[3]}, {v[4], v[5], v[6], v[7]}, {v[8], v[9], v[10], v[11]}, {v[12], v[13], v[14], v[15]}}}; }
22
23void GPUDisplay::setAnimationPoint()
24{
25 if (mCfgL.animationMode & 4) // Spherical
26 {
27 float rxy = sqrtf(mXYZ[0] * mXYZ[0] + mXYZ[2] * mXYZ[2]);
28 float anglePhi = atan2f(mXYZ[0], mXYZ[2]);
29 float angleTheta = atan2f(mXYZ[1], rxy);
30 if (mAnimateVectors[0].size()) {
31 mAnimationCloseAngle(anglePhi, mAnimateVectors[2].back());
32 }
33 if (mAnimateVectors[0].size()) {
34 mAnimationCloseAngle(angleTheta, mAnimateVectors[3].back());
35 }
36 mAnimateVectors[1].emplace_back(0);
37 mAnimateVectors[2].emplace_back(anglePhi);
38 mAnimateVectors[3].emplace_back(angleTheta);
39 } else {
40 for (int32_t i = 0; i < 3; i++) {
41 mAnimateVectors[i + 1].emplace_back(mXYZ[i]);
42 }
43 // Cartesian
44 }
45 float r = sqrtf(mXYZ[0] * mXYZ[0] + mXYZ[1] * mXYZ[1] + mXYZ[2] * mXYZ[2]);
46 mAnimateVectors[4].emplace_back(r);
47 if (mCfgL.animationMode & 1) // Euler-angles
48 {
49 for (int32_t i = 0; i < 3; i++) {
50 float newangle = mAngle[i];
51 if (mAnimateVectors[0].size()) {
52 mAnimationCloseAngle(newangle, mAnimateVectors[i + 5].back());
53 }
54 mAnimateVectors[i + 5].emplace_back(newangle);
55 }
56 mAnimateVectors[8].emplace_back(0);
57 } else { // Quaternions
58 float v[4];
59 createQuaternionFromMatrix(v, mViewMatrixP);
60 if (mAnimateVectors[0].size()) {
61 mAnimateCloseQuaternion(v, mAnimateVectors[5].back(), mAnimateVectors[6].back(), mAnimateVectors[7].back(), mAnimateVectors[8].back());
62 }
63 for (int32_t i = 0; i < 4; i++) {
64 mAnimateVectors[i + 5].emplace_back(v[i]);
65 }
66 }
67 float delay = 0.f;
68 if (mAnimateVectors[0].size()) {
69 delay = mAnimateVectors[0].back() + ((int32_t)(mAnimationDelay * 20)) / 20.f;
70 }
71 mAnimateVectors[0].emplace_back(delay);
72 mAnimateConfig.emplace_back(mCfgL);
73}
74
75void GPUDisplay::resetAnimation()
76{
77 for (int32_t i = 0; i < 9; i++) {
78 mAnimateVectors[i].clear();
79 }
80 mAnimateConfig.clear();
81 mAnimate = 0;
82}
83
84void GPUDisplay::removeAnimationPoint()
85{
86 if (mAnimateVectors[0].size() == 0) {
87 return;
88 }
89 for (int32_t i = 0; i < 9; i++) {
90 mAnimateVectors[i].pop_back();
91 }
92 mAnimateConfig.pop_back();
93}
94
95void GPUDisplay::startAnimation()
96{
97 for (int32_t i = 0; i < 8; i++) {
98 mAnimationSplines[i].create(mAnimateVectors[0], mAnimateVectors[i + 1]);
99 }
100 mAnimationTimer.ResetStart();
101 mAnimationFrame = 0;
102 mAnimate = 1;
103 mAnimationLastBase = 0;
104}
105
106int32_t GPUDisplay::animateCamera(float& animateTime, float& mixSlaveImage, hmm_mat4& nextViewMatrix)
107{
108 float time = animateTime;
109 if (mAnimate && time < 0) {
110 if (mAnimateScreenshot) {
111 time = mAnimationFrame / 30.f;
112 } else {
113 time = mAnimationTimer.GetCurrentElapsedTime();
114 }
115
116 float maxTime = mAnimateVectors[0].back();
117 if (time >= maxTime) {
118 time = maxTime;
119 mAnimate = mAnimateScreenshot = 0;
120 SetInfo("Animation finished. (%1.2f seconds, %d frames)", time, mAnimationFrame);
121 } else {
122 SetInfo("Running mAnimation: time %1.2f/%1.2f, frames %d", time, maxTime, mAnimationFrame);
123 }
124 mAnimationFrame++;
125 }
126 if (!mAnimate) {
127 return 0;
128 }
129 float vals[8];
130 for (int32_t i = 0; i < 8; i++) {
131 vals[i] = mAnimationSplines[i].evaluate(time);
132 }
133 if (mAnimationChangeConfig && animateTime < 0) {
134 int32_t base = 0;
135 int32_t k = mAnimateVectors[0].size() - 1;
136 while (base < k && time > mAnimateVectors[0][base]) {
137 base++;
138 }
139 if (base > mAnimationLastBase + 1) {
140 mAnimationLastBase = base - 1;
141 }
142
143 if (base != mAnimationLastBase && mAnimateVectors[0][mAnimationLastBase] != mAnimateVectors[0][base] && memcmp(&mAnimateConfig[base], &mAnimateConfig[mAnimationLastBase], sizeof(mAnimateConfig[base]))) {
144 mixSlaveImage = 1.f - (time - mAnimateVectors[0][mAnimationLastBase]) / (mAnimateVectors[0][base] - mAnimateVectors[0][mAnimationLastBase]);
145 if (mixSlaveImage > 0) {
146 mCfgL = mAnimateConfig[mAnimationLastBase];
147 updateConfig();
148 DrawGLScene_internal(time, true);
149 }
150 }
151
152 if (memcmp(&mAnimateConfig[base], &mCfgL, sizeof(mCfgL))) {
153 mCfgL = mAnimateConfig[base];
154 updateConfig();
155 }
156 }
157
158 if (mCfgL.animationMode != 6) {
159 if (mCfgL.animationMode & 1) // Rotation from euler angles
160 {
161 nextViewMatrix = nextViewMatrix * HMM_Rotate(-vals[4] * 180.f / CAMath::Pi(), {{1, 0, 0}}) * HMM_Rotate(vals[5] * 180.f / CAMath::Pi(), {{0, 1, 0}}) * HMM_Rotate(-vals[6] * 180.f / CAMath::Pi(), {{0, 0, 1}});
162 } else { // Rotation from quaternion
163 const float mag = sqrtf(vals[4] * vals[4] + vals[5] * vals[5] + vals[6] * vals[6] + vals[7] * vals[7]);
164 if (mag < 0.0001f) {
165 vals[7] = 1;
166 } else {
167 for (int32_t i = 0; i < 4; i++) {
168 vals[4 + i] /= mag;
169 }
170 }
171
172 float xx = vals[4] * vals[4], xy = vals[4] * vals[5], xz = vals[4] * vals[6], xw = vals[4] * vals[7], yy = vals[5] * vals[5], yz = vals[5] * vals[6], yw = vals[5] * vals[7], zz = vals[6] * vals[6], zw = vals[6] * vals[7];
173 float mat[16] = {1 - 2 * (yy + zz), 2 * (xy - zw), 2 * (xz + yw), 0, 2 * (xy + zw), 1 - 2 * (xx + zz), 2 * (yz - xw), 0, 2 * (xz - yw), 2 * (yz + xw), 1 - 2 * (xx + yy), 0, 0, 0, 0, 1};
174 nextViewMatrix = nextViewMatrix * MY_HMM_FROM(mat);
175 }
176 }
177 if (mCfgL.animationMode & 4) // Compute cartesian translation from sperical coordinates (euler angles)
178 {
179 const float r = vals[3], phi = vals[1], theta = vals[2];
180 vals[2] = r * cosf(phi) * cosf(theta);
181 vals[0] = r * sinf(phi) * cosf(theta);
182 vals[1] = r * sinf(theta);
183 } else if (mCfgL.animationMode & 2) { // Scale cartesion translation to interpolated radius
184 float r = sqrtf(vals[0] * vals[0] + vals[1] * vals[1] + vals[2] * vals[2]);
185 if (fabsf(r) < 0.0001f) {
186 r = 1;
187 }
188 r = vals[3] / r;
189 for (int32_t i = 0; i < 3; i++) {
190 vals[i] *= r;
191 }
192 }
193 if (mCfgL.animationMode == 6) {
194 nextViewMatrix = HMM_LookAt({{vals[0], vals[1], vals[2]}}, {{0, 0, 0}}, {{0, 1, 0}});
195 } else {
196 nextViewMatrix = nextViewMatrix * HMM_Translate({{-vals[0], -vals[1], -vals[2]}});
197 }
198 return 1;
199}
int16_t time
Definition RawEventData.h:4
int32_t i
constexpr hmm_mat4 MY_HMM_FROM(float(&v)[16])
HMM_INLINE hmm_mat4 HMM_Translate(hmm_vec3 Translation)
HMM_EXTERN hmm_mat4 HMM_LookAt(hmm_vec3 Eye, hmm_vec3 Center, hmm_vec3 Up)
HMM_EXTERN hmm_mat4 HMM_Rotate(float Angle, hmm_vec3 Axis)
double GetCurrentElapsedTime(bool reset=false)
Definition timer.cxx:110
void ResetStart()
Definition timer.cxx:63
GLsizeiptr size
Definition glcorearb.h:659
const GLdouble * v
Definition glcorearb.h:832
GLboolean r
Definition glcorearb.h:1233