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
17using namespace o2::gpu;
18
19constexpr 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]}}}; }
20
21void GPUDisplay::setAnimationPoint()
22{
23 if (mCfgL.animationMode & 4) // Spherical
24 {
25 float rxy = sqrtf(mXYZ[0] * mXYZ[0] + mXYZ[2] * mXYZ[2]);
26 float anglePhi = atan2f(mXYZ[0], mXYZ[2]);
27 float angleTheta = atan2f(mXYZ[1], rxy);
28 if (mAnimateVectors[0].size()) {
29 mAnimationCloseAngle(anglePhi, mAnimateVectors[2].back());
30 }
31 if (mAnimateVectors[0].size()) {
32 mAnimationCloseAngle(angleTheta, mAnimateVectors[3].back());
33 }
34 mAnimateVectors[1].emplace_back(0);
35 mAnimateVectors[2].emplace_back(anglePhi);
36 mAnimateVectors[3].emplace_back(angleTheta);
37 } else {
38 for (int32_t i = 0; i < 3; i++) {
39 mAnimateVectors[i + 1].emplace_back(mXYZ[i]);
40 }
41 // Cartesian
42 }
43 float r = sqrtf(mXYZ[0] * mXYZ[0] + mXYZ[1] * mXYZ[1] + mXYZ[2] * mXYZ[2]);
44 mAnimateVectors[4].emplace_back(r);
45 if (mCfgL.animationMode & 1) // Euler-angles
46 {
47 for (int32_t i = 0; i < 3; i++) {
48 float newangle = mAngle[i];
49 if (mAnimateVectors[0].size()) {
50 mAnimationCloseAngle(newangle, mAnimateVectors[i + 5].back());
51 }
52 mAnimateVectors[i + 5].emplace_back(newangle);
53 }
54 mAnimateVectors[8].emplace_back(0);
55 } else { // Quaternions
56 float v[4];
57 createQuaternionFromMatrix(v, mViewMatrixP);
58 if (mAnimateVectors[0].size()) {
59 mAnimateCloseQuaternion(v, mAnimateVectors[5].back(), mAnimateVectors[6].back(), mAnimateVectors[7].back(), mAnimateVectors[8].back());
60 }
61 for (int32_t i = 0; i < 4; i++) {
62 mAnimateVectors[i + 5].emplace_back(v[i]);
63 }
64 }
65 float delay = 0.f;
66 if (mAnimateVectors[0].size()) {
67 delay = mAnimateVectors[0].back() + ((int32_t)(mAnimationDelay * 20)) / 20.f;
68 }
69 mAnimateVectors[0].emplace_back(delay);
70 mAnimateConfig.emplace_back(mCfgL);
71}
72
73void GPUDisplay::resetAnimation()
74{
75 for (int32_t i = 0; i < 9; i++) {
76 mAnimateVectors[i].clear();
77 }
78 mAnimateConfig.clear();
79 mAnimate = 0;
80}
81
82void GPUDisplay::removeAnimationPoint()
83{
84 if (mAnimateVectors[0].size() == 0) {
85 return;
86 }
87 for (int32_t i = 0; i < 9; i++) {
88 mAnimateVectors[i].pop_back();
89 }
90 mAnimateConfig.pop_back();
91}
92
93void GPUDisplay::startAnimation()
94{
95 for (int32_t i = 0; i < 8; i++) {
96 mAnimationSplines[i].create(mAnimateVectors[0], mAnimateVectors[i + 1]);
97 }
98 mAnimationTimer.ResetStart();
99 mAnimationFrame = 0;
100 mAnimate = 1;
101 mAnimationLastBase = 0;
102}
103
104int32_t GPUDisplay::animateCamera(float& animateTime, float& mixSlaveImage, hmm_mat4& nextViewMatrix)
105{
106 float time = animateTime;
107 if (mAnimate && time < 0) {
108 if (mAnimateScreenshot) {
109 time = mAnimationFrame / 30.f;
110 } else {
111 time = mAnimationTimer.GetCurrentElapsedTime();
112 }
113
114 float maxTime = mAnimateVectors[0].back();
115 if (time >= maxTime) {
116 time = maxTime;
117 mAnimate = mAnimateScreenshot = 0;
118 SetInfo("Animation finished. (%1.2f seconds, %d frames)", time, mAnimationFrame);
119 } else {
120 SetInfo("Running mAnimation: time %1.2f/%1.2f, frames %d", time, maxTime, mAnimationFrame);
121 }
122 mAnimationFrame++;
123 }
124 if (!mAnimate) {
125 return 0;
126 }
127 float vals[8];
128 for (int32_t i = 0; i < 8; i++) {
129 vals[i] = mAnimationSplines[i].evaluate(time);
130 }
131 if (mAnimationChangeConfig && animateTime < 0) {
132 int32_t base = 0;
133 int32_t k = mAnimateVectors[0].size() - 1;
134 while (base < k && time > mAnimateVectors[0][base]) {
135 base++;
136 }
137 if (base > mAnimationLastBase + 1) {
138 mAnimationLastBase = base - 1;
139 }
140
141 if (base != mAnimationLastBase && mAnimateVectors[0][mAnimationLastBase] != mAnimateVectors[0][base] && memcmp(&mAnimateConfig[base], &mAnimateConfig[mAnimationLastBase], sizeof(mAnimateConfig[base]))) {
142 mixSlaveImage = 1.f - (time - mAnimateVectors[0][mAnimationLastBase]) / (mAnimateVectors[0][base] - mAnimateVectors[0][mAnimationLastBase]);
143 if (mixSlaveImage > 0) {
144 mCfgL = mAnimateConfig[mAnimationLastBase];
145 updateConfig();
146 DrawGLScene_internal(time, true);
147 }
148 }
149
150 if (memcmp(&mAnimateConfig[base], &mCfgL, sizeof(mCfgL))) {
151 mCfgL = mAnimateConfig[base];
152 updateConfig();
153 }
154 }
155
156 if (mCfgL.animationMode != 6) {
157 if (mCfgL.animationMode & 1) // Rotation from euler angles
158 {
159 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}});
160 } else { // Rotation from quaternion
161 const float mag = sqrtf(vals[4] * vals[4] + vals[5] * vals[5] + vals[6] * vals[6] + vals[7] * vals[7]);
162 if (mag < 0.0001f) {
163 vals[7] = 1;
164 } else {
165 for (int32_t i = 0; i < 4; i++) {
166 vals[4 + i] /= mag;
167 }
168 }
169
170 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];
171 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};
172 nextViewMatrix = nextViewMatrix * MY_HMM_FROM(mat);
173 }
174 }
175 if (mCfgL.animationMode & 4) // Compute cartesian translation from sperical coordinates (euler angles)
176 {
177 const float r = vals[3], phi = vals[1], theta = vals[2];
178 vals[2] = r * cosf(phi) * cosf(theta);
179 vals[0] = r * sinf(phi) * cosf(theta);
180 vals[1] = r * sinf(theta);
181 } else if (mCfgL.animationMode & 2) { // Scale cartesion translation to interpolated radius
182 float r = sqrtf(vals[0] * vals[0] + vals[1] * vals[1] + vals[2] * vals[2]);
183 if (fabsf(r) < 0.0001f) {
184 r = 1;
185 }
186 r = vals[3] / r;
187 for (int32_t i = 0; i < 3; i++) {
188 vals[i] *= r;
189 }
190 }
191 if (mCfgL.animationMode == 6) {
192 nextViewMatrix = HMM_LookAt({{vals[0], vals[1], vals[2]}}, {{0, 0, 0}}, {{0, 1, 0}});
193 } else {
194 nextViewMatrix = nextViewMatrix * HMM_Translate({{-vals[0], -vals[1], -vals[2]}});
195 }
196 return 1;
197}
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