File indexing completed on 2026-04-17 08:35:29
0001
0002
0003 #ifndef VECGEOM_BASE_TRANSFORMATION3DMP_H_
0004 #define VECGEOM_BASE_TRANSFORMATION3DMP_H_
0005
0006 #include "VecGeom/base/Config.h"
0007 #include "VecGeom/base/Cuda.h"
0008 #include "VecGeom/base/Global.h"
0009
0010 #include <VecGeom/base/Transformation3D.h>
0011
0012 #include "VecGeom/base/Vector3D.h"
0013 #include "VecGeom/backend/scalar/Backend.h"
0014 #ifdef VECGEOM_ENABLE_CUDA
0015 #include "VecGeom/backend/cuda/Interface.h"
0016 #endif
0017
0018 #include <algorithm>
0019 #include <cmath>
0020 #include <cstring>
0021 #include <iostream>
0022 #include <vector>
0023
0024 #include <initializer_list>
0025
0026
0027
0028
0029 namespace vecgeom {
0030
0031 VECGEOM_DEVICE_FORWARD_DECLARE(class Transformation3DMP;);
0032
0033 inline namespace VECGEOM_IMPL_NAMESPACE {
0034
0035 #ifndef VECCORE_CUDA
0036 }
0037 namespace cuda {
0038 class Transformation3DMP;
0039 }
0040 inline namespace VECGEOM_IMPL_NAMESPACE {
0041
0042 #endif
0043
0044 template <typename Real_s>
0045 class Transformation3DMP {
0046
0047
0048
0049
0050 private:
0051
0052
0053 Real_s tx_{0.}, ty_{0.}, tz_{0.};
0054 Real_s rxx_{1.}, ryx_{0.}, rzx_{0.};
0055 Real_s rxy_{0.}, ryy_{1.}, rzy_{0.};
0056 Real_s rxz_{0.}, ryz_{0.}, rzz_{1.};
0057 bool fIdentity;
0058 bool fHasRotation;
0059 bool fHasTranslation;
0060
0061 public:
0062 VECCORE_ATT_HOST_DEVICE
0063 constexpr Transformation3DMP() : fIdentity(true), fHasRotation(false), fHasTranslation(false){};
0064
0065
0066
0067
0068
0069
0070 template <typename Real_i>
0071 Transformation3DMP(const Transformation3DMP<Real_i> &other)
0072 {
0073
0074 auto translation = other.Translation();
0075 tx_ = static_cast<Real_s>(translation[0]);
0076 ty_ = static_cast<Real_s>(translation[1]);
0077 tz_ = static_cast<Real_s>(translation[2]);
0078
0079
0080 auto rotation = other.Rotation();
0081 rxx_ = static_cast<Real_s>(rotation[0]);
0082 ryx_ = static_cast<Real_s>(rotation[1]);
0083 rzx_ = static_cast<Real_s>(rotation[2]);
0084 rxy_ = static_cast<Real_s>(rotation[3]);
0085 ryy_ = static_cast<Real_s>(rotation[4]);
0086 rzy_ = static_cast<Real_s>(rotation[5]);
0087 rxz_ = static_cast<Real_s>(rotation[6]);
0088 ryz_ = static_cast<Real_s>(rotation[7]);
0089 rzz_ = static_cast<Real_s>(rotation[8]);
0090
0091 fIdentity = other.IsIdentity();
0092 fHasRotation = other.HasRotation();
0093 fHasTranslation = other.HasTranslation();
0094 }
0095
0096
0097
0098
0099
0100
0101
0102 template <typename Real_i>
0103 VECCORE_ATT_HOST_DEVICE Transformation3DMP(const Real_i tx, const Real_i ty, const Real_i tz)
0104 : tx_{static_cast<Real_s>(tx)}, ty_{static_cast<Real_s>(ty)}, tz_{static_cast<Real_s>(tz)},
0105 fIdentity(tx == 0 && ty == 0 && tz == 0), fHasRotation(false), fHasTranslation(tx != 0 || ty != 0 || tz != 0)
0106 {
0107 }
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118 template <typename Real_i>
0119 VECCORE_ATT_HOST_DEVICE Transformation3DMP(const Real_i tx, const Real_i ty, const Real_i tz, const Real_i phi,
0120 const Real_i theta, const Real_i psi)
0121 : fIdentity(false), fHasRotation(true), fHasTranslation(true)
0122 {
0123 SetTranslation(tx, ty, tz);
0124 SetRotation(phi, theta, psi);
0125 SetProperties();
0126 }
0127
0128
0129 template <typename Real_i>
0130 Transformation3DMP(std::initializer_list<Real_i> values)
0131 {
0132 auto it = values.begin();
0133 tx_ = *it++;
0134 ty_ = *it++;
0135 tz_ = *it++;
0136 Real_i phi = *it++;
0137 Real_i theta = *it++;
0138 Real_i psi = *it;
0139 SetTranslation(tx_, ty_, tz_);
0140 SetRotation(phi, theta, psi);
0141 SetProperties();
0142 }
0143
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156 template <typename Real_i>
0157 VECCORE_ATT_HOST_DEVICE Transformation3DMP(const Real_i tx, const Real_i ty, const Real_i tz, const Real_i phi,
0158 const Real_i theta, const Real_i psi, Real_i sx, Real_i sy, Real_i sz)
0159 : fIdentity(false), fHasRotation(true), fHasTranslation(true)
0160 {
0161 SetTranslation(tx, ty, tz);
0162 SetRotation(phi, theta, psi);
0163 ApplyScale(sx, sy, sz);
0164 SetProperties();
0165 }
0166
0167
0168
0169
0170
0171 template <typename Real_i>
0172 VECCORE_ATT_HOST_DEVICE Transformation3DMP(const Real_i tx, const Real_i ty, const Real_i tz, const Real_i rxx,
0173 const Real_i ryx, const Real_i rzx, const Real_i rxy, const Real_i ryy,
0174 const Real_i rzy, const Real_i rxz, const Real_i ryz, const Real_i rzz)
0175 : fIdentity(false), fHasRotation(true), fHasTranslation(true)
0176 {
0177 SetTranslation(tx, ty, tz);
0178 SetRotation(rxx, ryx, rzx, rxy, ryy, rzy, rxz, ryz, rzz);
0179 SetProperties();
0180 }
0181
0182
0183
0184 template <typename Real_i>
0185 VECCORE_ATT_HOST_DEVICE Transformation3DMP(const Real_i tx, const Real_i ty, const Real_i tz,
0186 Transformation3DMP<Real_i> const &trot)
0187 {
0188 SetTranslation(tx, ty, tz);
0189 SetRotation(trot.Rotation()[0], trot.Rotation()[1], trot.Rotation()[2], trot.Rotation()[3], trot.Rotation()[4],
0190 trot.Rotation()[5], trot.Rotation()[6], trot.Rotation()[7], trot.Rotation()[8]);
0191 SetProperties();
0192 }
0193
0194
0195
0196
0197 template <typename Real_i>
0198 VECCORE_ATT_HOST_DEVICE Transformation3DMP(const Real_i tx, const Real_i ty, const Real_i tz, const Real_i rxx,
0199 const Real_i ryx, const Real_i rzx, const Real_i rxy, const Real_i ryy,
0200 const Real_i rzy, const Real_i rxz, const Real_i ryz, const Real_i rzz,
0201 Real_i sx, Real_i sy, Real_i sz)
0202 {
0203 SetTranslation(tx, ty, tz);
0204 SetRotation(rxx, ryx, rzx, rxy, ryy, rzy, rxz, ryz, rzz);
0205 ApplyScale(sx, sy, sz);
0206 SetProperties();
0207 }
0208
0209
0210
0211
0212
0213 template <typename Real_i>
0214 VECCORE_ATT_HOST_DEVICE Transformation3DMP(const Real_i *trans, const Real_i *rot, bool has_trans, bool has_rot)
0215 {
0216 this->Set(trans, rot, has_trans, has_rot);
0217 }
0218
0219
0220
0221
0222 VECCORE_ATT_HOST_DEVICE Transformation3DMP(Transformation3D const &other)
0223 {
0224 auto rot = other.Rotation();
0225 SetTranslation(other.Translation(0), other.Translation(1), other.Translation(2));
0226 SetRotation(rot[0], rot[1], rot[2], rot[3], rot[4], rot[5], rot[6], rot[7], rot[8]);
0227 SetProperties();
0228 }
0229
0230
0231
0232
0233
0234
0235
0236
0237
0238
0239 VECCORE_ATT_HOST_DEVICE
0240 VECGEOM_FORCE_INLINE
0241 bool operator==(Transformation3DMP const &rhs) const;
0242
0243 VECCORE_ATT_HOST_DEVICE
0244 VECGEOM_FORCE_INLINE
0245 Transformation3DMP operator*(Transformation3DMP const &tf) const;
0246
0247 VECCORE_ATT_HOST_DEVICE
0248 VECGEOM_FORCE_INLINE
0249 Transformation3DMP const &operator*=(Transformation3DMP const &rhs);
0250
0251
0252 VECCORE_ATT_HOST_DEVICE
0253 VECGEOM_FORCE_INLINE
0254 Transformation3DMP operator*(Transformation3D const &rhs) const;
0255
0256 VECCORE_ATT_HOST_DEVICE
0257 VECGEOM_FORCE_INLINE
0258 Transformation3DMP const &operator*=(Transformation3D const &rhs);
0259
0260 VECCORE_ATT_HOST_DEVICE
0261 ~Transformation3DMP() {}
0262
0263 template <typename Real_i>
0264 VECCORE_ATT_HOST_DEVICE void ApplyScale(const Real_i sx, const Real_i sy, const Real_i sz)
0265 {
0266 rxx_ *= static_cast<Real_s>(sx);
0267 ryx_ *= static_cast<Real_s>(sy);
0268 rzx_ *= static_cast<Real_s>(sz);
0269 rxy_ *= static_cast<Real_s>(sx);
0270 ryy_ *= static_cast<Real_s>(sy);
0271 rzy_ *= static_cast<Real_s>(sz);
0272 rxz_ *= static_cast<Real_s>(sx);
0273 ryz_ *= static_cast<Real_s>(sy);
0274 rzz_ *= static_cast<Real_s>(sz);
0275 }
0276
0277
0278 template <typename Real_i>
0279 VECCORE_ATT_HOST_DEVICE bool ApproxEqual(Transformation3DMP<Real_i> const &rhs,
0280 Real_i tolerance = kToleranceDist<Real_i>) const
0281 {
0282 auto const data1 = &tx_;
0283 auto const data2 = &rhs.tx_;
0284 for (int i = 0; i < 12; ++i)
0285 if (vecCore::math::Abs(data1[i] - data2[i]) > tolerance) return false;
0286 return true;
0287 }
0288
0289 VECCORE_ATT_HOST_DEVICE
0290 void Clear()
0291 {
0292 tx_ = 0.;
0293 ty_ = 0.;
0294 tz_ = 0.;
0295 rxx_ = 1.;
0296 ryx_ = 0.;
0297 rzx_ = 0.;
0298 rxy_ = 0.;
0299 ryy_ = 1.;
0300 rzy_ = 0.;
0301 rxz_ = 0.;
0302 ryz_ = 0.;
0303 rzz_ = 1.;
0304 fIdentity = true;
0305 fHasRotation = false;
0306 fHasTranslation = false;
0307 }
0308
0309 int MemorySize() const { return sizeof(*this); }
0310
0311 VECCORE_ATT_HOST_DEVICE
0312 void FixZeroes()
0313 {
0314 if (std::abs(tx_) < vecgeom::kTolerance) tx_ = 0.;
0315 if (std::abs(ty_) < vecgeom::kTolerance) ty_ = 0.;
0316 if (std::abs(tz_) < vecgeom::kTolerance) tz_ = 0.;
0317 if (std::abs(rxx_) < vecgeom::kTolerance) rxx_ = 0.;
0318 if (std::abs(ryx_) < vecgeom::kTolerance) ryx_ = 0.;
0319 if (std::abs(rzx_) < vecgeom::kTolerance) rzx_ = 0.;
0320 if (std::abs(rxy_) < vecgeom::kTolerance) rxy_ = 0.;
0321 if (std::abs(ryy_) < vecgeom::kTolerance) ryy_ = 0.;
0322 if (std::abs(rzy_) < vecgeom::kTolerance) rzy_ = 0.;
0323 if (std::abs(rxz_) < vecgeom::kTolerance) rxz_ = 0.;
0324 if (std::abs(ryz_) < vecgeom::kTolerance) ryz_ = 0.;
0325 if (std::abs(rzz_) < vecgeom::kTolerance) rzz_ = 0.;
0326 }
0327
0328 VECCORE_ATT_HOST_DEVICE
0329 VECGEOM_FORCE_INLINE
0330 Vector3D<Real_s> Translation() const { return Vector3D<Real_s>(tx_, ty_, tz_); }
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349 VECCORE_ATT_HOST_DEVICE
0350 VECGEOM_FORCE_INLINE
0351 Real_s Translation(const int index) const { return *(&tx_ + index); }
0352
0353 VECCORE_ATT_HOST_DEVICE
0354 VECGEOM_FORCE_INLINE
0355 Real_s const *Rotation() const { return &rxx_; }
0356
0357
0358
0359
0360
0361 VECCORE_ATT_HOST_DEVICE
0362 VECGEOM_FORCE_INLINE
0363 Real_s Rotation(const int index) const { return *(&rxx_ + index); }
0364
0365 VECCORE_ATT_HOST_DEVICE
0366 VECGEOM_FORCE_INLINE
0367 bool IsIdentity() const { return fIdentity; }
0368
0369 VECCORE_ATT_HOST_DEVICE
0370 VECGEOM_FORCE_INLINE
0371 bool IsXYRotation() const
0372 {
0373 return (fHasRotation && (std::abs(rzx_) < vecgeom::kTolerance) && (std::abs(rzy_) < vecgeom::kTolerance) &&
0374 (std::abs(rxz_) < vecgeom::kTolerance) && (std::abs(ryz_) < vecgeom::kTolerance) &&
0375 (std::abs(rzz_ - Real_s(1.)) < vecgeom::kTolerance));
0376 }
0377
0378 VECCORE_ATT_HOST_DEVICE
0379 VECGEOM_FORCE_INLINE
0380 bool IsXYFlipRotation() const
0381 {
0382 return (fHasRotation && (std::abs(rzx_) < vecgeom::kTolerance) && (std::abs(rzy_) < vecgeom::kTolerance) &&
0383 (std::abs(rxz_) < vecgeom::kTolerance) && (std::abs(ryz_) < vecgeom::kTolerance) &&
0384 (std::abs(rzz_ + Real_s(1.)) < vecgeom::kTolerance));
0385 }
0386
0387 VECCORE_ATT_HOST_DEVICE
0388 VECGEOM_FORCE_INLINE
0389 bool IsReflected() const { return Determinant() < 0; }
0390
0391 VECCORE_ATT_HOST_DEVICE
0392 VECGEOM_FORCE_INLINE
0393 bool HasRotation() const { return fHasRotation; }
0394
0395 VECCORE_ATT_HOST_DEVICE
0396 VECGEOM_FORCE_INLINE
0397 bool HasTranslation() const { return fHasTranslation; }
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407
0408 void Print(std::ostream &s) const
0409 {
0410 s << "Transformation3DMP {{" << tx_ << "," << ty_ << "," << tz_ << "}";
0411 s << "{" << rxx_ << "," << ryx_ << "," << rzx_ << "," << rxy_ << "," << ryy_ << "," << rzy_ << "," << rxz_ << ","
0412 << ryz_ << "," << rzz_ << "}}\n";
0413 }
0414
0415 VECCORE_ATT_HOST_DEVICE
0416 void Print() const
0417 {
0418 printf("Transformation3D {{%.2f, %.2f, %.2f}, ", tx_, ty_, tz_);
0419 printf("{%.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f, %.2f}}", rxx_, ryx_, rzx_, rxy_, ryy_, rzy_, rxz_, ryz_,
0420 rzz_);
0421 }
0422
0423 VECCORE_ATT_HOST_DEVICE
0424 void PrintG4() const
0425 {
0426 using vecCore::math::Abs;
0427 using vecCore::math::Max;
0428 constexpr double deviationTolerance = 1.0e-05;
0429 printf(" TransformationMP: \n");
0430
0431 bool UnitTr = !fHasRotation;
0432 double diagDeviation = Max(Abs(rxx_ - 1.0), Abs(ryy_ - 1.0), Abs(rzz_ - 1.0));
0433 double offdDeviationUL = Max(Abs(rxy_), Abs(rxz_), Abs(ryx_));
0434 double offdDeviationDR = Max(Abs(ryz_), Abs(rzx_), Abs(rzy_));
0435 double offdDeviation = Max(offdDeviationUL, offdDeviationDR);
0436
0437 if (UnitTr || Max(diagDeviation, offdDeviation) < deviationTolerance) {
0438 printf(" UNIT Rotation \n");
0439 } else {
0440 printf("rx/x,y,z: %.6g %.6g %.6g\nry/x,y,z: %.6g %.6g %.6g\nrz/x,y,z: %.6g %.6g %.6g\n", rxx_, rxy_, rxz_, ryx_,
0441 ryy_, ryz_, rzx_, rzy_, rzz_);
0442 }
0443
0444 printf("tr/x,y,z: %.6g %.6g %.6g\n", tx_, ty_, tz_);
0445 }
0446
0447
0448
0449 template <typename Real_i>
0450 VECCORE_ATT_HOST_DEVICE void SetTranslation(const Real_i tx, const Real_i ty, const Real_i tz)
0451 {
0452 tx_ = static_cast<Real_s>(tx);
0453 ty_ = static_cast<Real_s>(ty);
0454 tz_ = static_cast<Real_s>(tz);
0455 }
0456
0457 template <typename Real_i>
0458 VECCORE_ATT_HOST_DEVICE void SetTranslation(Vector3D<Real_i> const &vec)
0459 {
0460 SetTranslation(vec[0], vec[1], vec[2]);
0461 }
0462
0463
0464 VECCORE_ATT_HOST_DEVICE
0465 void SetProperties()
0466 {
0467 fHasTranslation = (fabs(tx_) > kTolerance || fabs(ty_) > kTolerance || fabs(tz_) > kTolerance) ? true : false;
0468 fHasRotation = (fabs(rxx_ - 1.) > kTolerance) || (fabs(ryx_) > kTolerance) || (fabs(rzx_) > kTolerance) ||
0469 (fabs(rxy_) > kTolerance) || (fabs(ryy_ - 1.) > kTolerance) || (fabs(rzy_) > kTolerance) ||
0470 (fabs(rxz_) > kTolerance) || (fabs(ryz_) > kTolerance) || (fabs(rzz_ - 1.) > kTolerance)
0471 ? true
0472 : false;
0473 fIdentity = !fHasTranslation && !fHasRotation;
0474 }
0475
0476 template <typename Real_i>
0477 VECCORE_ATT_HOST_DEVICE void SetRotation(const Real_i phi, const Real_i theta, const Real_i psi)
0478 {
0479
0480 const auto sinphi = sin(kDegToRad * phi);
0481 const auto cosphi = cos(kDegToRad * phi);
0482 const auto sinthe = sin(kDegToRad * theta);
0483 const auto costhe = cos(kDegToRad * theta);
0484 const auto sinpsi = sin(kDegToRad * psi);
0485 const auto cospsi = cos(kDegToRad * psi);
0486
0487 rxx_ = static_cast<Real_s>(cospsi * cosphi - costhe * sinphi * sinpsi);
0488 ryx_ = static_cast<Real_s>(-sinpsi * cosphi - costhe * sinphi * cospsi);
0489 rzx_ = static_cast<Real_s>(sinthe * sinphi);
0490 rxy_ = static_cast<Real_s>(cospsi * sinphi + costhe * cosphi * sinpsi);
0491 ryy_ = static_cast<Real_s>(-sinpsi * sinphi + costhe * cosphi * cospsi);
0492 rzy_ = static_cast<Real_s>(-sinthe * cosphi);
0493 rxz_ = static_cast<Real_s>(sinpsi * sinthe);
0494 ryz_ = static_cast<Real_s>(cospsi * sinthe);
0495 rzz_ = static_cast<Real_s>(costhe);
0496 }
0497
0498 template <typename Real_i>
0499 VECCORE_ATT_HOST_DEVICE void SetRotation(Vector3D<Real_i> const &vec)
0500 {
0501 SetRotation(vec[0], vec[1], vec[2]);
0502 }
0503
0504 template <typename Real_i>
0505 VECCORE_ATT_HOST_DEVICE void SetRotation(const Real_i xx, const Real_i yx, const Real_i zx, const Real_i xy,
0506 const Real_i yy, const Real_i zy, const Real_i xz, const Real_i yz,
0507 const Real_i zz)
0508 {
0509 rxx_ = static_cast<Real_s>(xx);
0510 ryx_ = static_cast<Real_s>(yx);
0511 rzx_ = static_cast<Real_s>(zx);
0512 rxy_ = static_cast<Real_s>(xy);
0513 ryy_ = static_cast<Real_s>(yy);
0514 rzy_ = static_cast<Real_s>(zy);
0515 rxz_ = static_cast<Real_s>(xz);
0516 ryz_ = static_cast<Real_s>(yz);
0517 rzz_ = static_cast<Real_s>(zz);
0518 }
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533 template <typename Real_i>
0534 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE void Set(const Real_i *trans, const Real_i *rot, bool has_trans,
0535 bool has_rot)
0536 {
0537 if (has_trans) {
0538 tx_ = static_cast<Real_s>(trans[0]);
0539 ty_ = static_cast<Real_s>(trans[1]);
0540 tz_ = static_cast<Real_s>(trans[2]);
0541 }
0542
0543 if (has_rot) {
0544 rxx_ = static_cast<Real_s>(rot[0]);
0545 ryx_ = static_cast<Real_s>(rot[1]);
0546 rzx_ = static_cast<Real_s>(rot[2]);
0547 rxy_ = static_cast<Real_s>(rot[3]);
0548 ryy_ = static_cast<Real_s>(rot[4]);
0549 rzy_ = static_cast<Real_s>(rot[5]);
0550 rxz_ = static_cast<Real_s>(rot[6]);
0551 ryz_ = static_cast<Real_s>(rot[7]);
0552 rzz_ = static_cast<Real_s>(rot[8]);
0553 }
0554
0555 fHasTranslation = has_trans;
0556 fHasRotation = has_rot;
0557 fIdentity = !fHasTranslation && !fHasRotation;
0558 }
0559
0560 private:
0561
0562
0563
0564 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void DoRotation(Vector3D<Real_s> const &master,
0565 Vector3D<Real_s> &local) const;
0566
0567 private:
0568 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void DoTranslation(Vector3D<Real_s> const &master,
0569 Vector3D<Real_s> &local) const;
0570
0571 template <bool vectortransform>
0572 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void InverseTransformKernel(Vector3D<Real_s> const &local,
0573 Vector3D<Real_s> &master) const;
0574
0575 public:
0576
0577
0578 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void Transform(Vector3D<Real_s> const &master,
0579 Vector3D<Real_s> &local) const;
0580
0581 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Real_s> Transform(Vector3D<Real_s> const &master) const;
0582
0583 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void TransformDirection(Vector3D<Real_s> const &master,
0584 Vector3D<Real_s> &local) const;
0585
0586 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Real_s> TransformDirection(
0587 Vector3D<Real_s> const &master) const;
0588
0589
0590
0591
0592 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void InverseTransform(Vector3D<Real_s> const &local,
0593 Vector3D<Real_s> &master) const;
0594
0595 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Real_s> InverseTransform(Vector3D<Real_s> const &local) const;
0596
0597
0598 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void InverseTransformDirection(Vector3D<Real_s> const &master,
0599 Vector3D<Real_s> &local) const;
0600
0601 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Real_s> InverseTransformDirection(
0602 Vector3D<Real_s> const &master) const;
0603
0604
0605 VECCORE_ATT_HOST_DEVICE
0606 VECGEOM_FORCE_INLINE
0607 void MultiplyFromRight(Transformation3DMP const &rhs);
0608
0609 VECCORE_ATT_HOST_DEVICE
0610 VECGEOM_FORCE_INLINE
0611 void MultiplyFromRight(Transformation3D const &rhs);
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624
0625
0626
0627
0628
0629
0630
0631
0632
0633
0634
0635 VECCORE_ATT_HOST_DEVICE
0636 double Determinant() const
0637 {
0638
0639 double xx_ = rxx_;
0640 double xy_ = rxy_;
0641 double xz_ = rxz_;
0642 double yx_ = ryx_;
0643 double yy_ = ryy_;
0644 double yz_ = ryz_;
0645 double zx_ = rzx_;
0646 double zy_ = rzy_;
0647 double zz_ = rzz_;
0648
0649 double detxx = yy_ * zz_ - yz_ * zy_;
0650 double detxy = yx_ * zz_ - yz_ * zx_;
0651 double detxz = yx_ * zy_ - yy_ * zx_;
0652 double det = xx_ * detxx - xy_ * detxy + xz_ * detxz;
0653 return det;
0654 }
0655
0656
0657
0658
0659
0660
0661
0662
0663
0664
0665
0666
0667
0668
0669
0670
0671
0672
0673
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683
0684
0685
0686
0687
0688
0689
0690
0691
0692
0693
0694
0695
0696
0697
0698
0699
0700
0701
0702
0703
0704 VECCORE_ATT_HOST_DEVICE
0705 Transformation3DMP<Real_s> Inverse() const
0706 {
0707 Real_s ttx = -tx_, tty = -ty_, ttz = -tz_;
0708 return Transformation3DMP<Real_s>(ttx * rxx_ + tty * rxy_ + ttz * rxz_, ttx * ryx_ + tty * ryy_ + ttz * ryz_,
0709 ttx * rzx_ + tty * rzy_ + ttz * rzz_, rxx_, rxy_, rxz_, ryx_, ryy_, ryz_, rzx_,
0710 rzy_, rzz_);
0711 }
0712
0713
0714
0715 #ifdef VECGEOM_CUDA_INTERFACE
0716 size_t DeviceSizeOf() const { return DevicePtr<cuda::Transformation3DMP>::SizeOf(); }
0717 DevicePtr<cuda::Transformation3DMP> CopyToGpu() const;
0718 DevicePtr<cuda::Transformation3DMP> CopyToGpu(DevicePtr<cuda::Transformation3DMP> const gpu_ptr) const;
0719 static void CopyManyToGpu(const std::vector<Transformation3DMP const *> &trafos,
0720 const std::vector<DevicePtr<cuda::Transformation3DMP>> &gpu_ptrs);
0721 #endif
0722
0723
0724
0725
0726
0727
0728
0729 public:
0730 static const Transformation3DMP kIdentity;
0731
0732 };
0733
0734 template <typename Real_t>
0735 VECCORE_ATT_HOST_DEVICE bool Transformation3DMP<Real_t>::operator==(Transformation3DMP<Real_t> const &rhs) const
0736 {
0737 return equal(&tx_, &tx_ + 12, &rhs.tx_);
0738 }
0739
0740
0741
0742
0743
0744
0745 template <typename Real_s>
0746 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void Transformation3DMP<Real_s>::DoRotation(Vector3D<Real_s> const &master,
0747 Vector3D<Real_s> &local) const
0748 {
0749 local[0] = master[0] * rxx_;
0750 local[1] = master[0] * ryx_;
0751 local[2] = master[0] * rzx_;
0752 local[0] += master[1] * rxy_;
0753 local[1] += master[1] * ryy_;
0754 local[2] += master[1] * rzy_;
0755 local[0] += master[2] * rxz_;
0756 local[1] += master[2] * ryz_;
0757 local[2] += master[2] * rzz_;
0758 }
0759
0760 template <typename Real_s>
0761 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void Transformation3DMP<Real_s>::DoTranslation(
0762 Vector3D<Real_s> const &master, Vector3D<Real_s> &local) const
0763 {
0764
0765 local[0] = master[0] - tx_;
0766 local[1] = master[1] - ty_;
0767 local[2] = master[2] - tz_;
0768 }
0769
0770
0771
0772
0773
0774
0775
0776 template <typename Real_s>
0777 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void Transformation3DMP<Real_s>::Transform(Vector3D<Real_s> const &master,
0778 Vector3D<Real_s> &local) const
0779 {
0780 Vector3D<Real_s> tmp;
0781 DoTranslation(master, tmp);
0782 DoRotation(tmp, local);
0783 }
0784
0785
0786
0787
0788
0789
0790
0791 template <typename Real_s>
0792 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Real_s> Transformation3DMP<Real_s>::Transform(
0793 Vector3D<Real_s> const &master) const
0794 {
0795
0796 Vector3D<Real_s> local;
0797 Transform(master, local);
0798 return local;
0799 }
0800
0801 template <typename Real_s>
0802 template <bool transform_direction>
0803 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void Transformation3DMP<Real_s>::InverseTransformKernel(
0804 Vector3D<Real_s> const &local, Vector3D<Real_s> &master) const
0805 {
0806
0807
0808
0809
0810 if (transform_direction) {
0811 master[0] = local[0] * rxx_;
0812 master[0] += local[1] * ryx_;
0813 master[0] += local[2] * rzx_;
0814 master[1] = local[0] * rxy_;
0815 master[1] += local[1] * ryy_;
0816 master[1] += local[2] * rzy_;
0817 master[2] = local[0] * rxz_;
0818 master[2] += local[1] * ryz_;
0819 master[2] += local[2] * rzz_;
0820 } else {
0821 master[0] = tx_;
0822 master[0] += local[0] * rxx_;
0823 master[0] += local[1] * ryx_;
0824 master[0] += local[2] * rzx_;
0825 master[1] = ty_;
0826 master[1] += local[0] * rxy_;
0827 master[1] += local[1] * ryy_;
0828 master[1] += local[2] * rzy_;
0829 master[2] = tz_;
0830 master[2] += local[0] * rxz_;
0831 master[2] += local[1] * ryz_;
0832 master[2] += local[2] * rzz_;
0833 }
0834 }
0835
0836 template <typename Real_s>
0837 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void Transformation3DMP<Real_s>::InverseTransform(
0838 Vector3D<Real_s> const &local, Vector3D<Real_s> &master) const
0839 {
0840 InverseTransformKernel<false>(local, master);
0841 }
0842
0843 template <typename Real_s>
0844 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Real_s> Transformation3DMP<Real_s>::InverseTransform(
0845 Vector3D<Real_s> const &local) const
0846 {
0847 Vector3D<Real_s> tmp;
0848 InverseTransform(local, tmp);
0849 return tmp;
0850 }
0851
0852 template <typename Real_s>
0853 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void Transformation3DMP<Real_s>::InverseTransformDirection(
0854 Vector3D<Real_s> const &local, Vector3D<Real_s> &master) const
0855 {
0856 InverseTransformKernel<true>(local, master);
0857 }
0858
0859 template <typename Real_s>
0860 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Real_s> Transformation3DMP<Real_s>::InverseTransformDirection(
0861 Vector3D<Real_s> const &local) const
0862 {
0863 Vector3D<Real_s> tmp;
0864 InverseTransformDirection(local, tmp);
0865 return tmp;
0866 }
0867
0868 template <typename Real_s>
0869 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Transformation3DMP<Real_s> Transformation3DMP<Real_s>::operator*(
0870 Transformation3DMP<Real_s> const &rhs) const
0871 {
0872 if (rhs.fIdentity) return Transformation3DMP<Real_s>(*this);
0873 return Transformation3DMP<Real_s>(tx_ * rhs.rxx_ + ty_ * rhs.ryx_ + tz_ * rhs.rzx_ + rhs.tx_,
0874 tx_ * rhs.rxy_ + ty_ * rhs.ryy_ + tz_ * rhs.rzy_ + rhs.ty_,
0875 tx_ * rhs.rxz_ + ty_ * rhs.ryz_ + tz_ * rhs.rzz_ + rhs.tz_,
0876 rxx_ * rhs.rxx_ + rxy_ * rhs.ryx_ + rxz_ * rhs.rzx_,
0877 ryx_ * rhs.rxx_ + ryy_ * rhs.ryx_ + ryz_ * rhs.rzx_,
0878 rzx_ * rhs.rxx_ + rzy_ * rhs.ryx_ + rzz_ * rhs.rzx_,
0879 rxx_ * rhs.rxy_ + rxy_ * rhs.ryy_ + rxz_ * rhs.rzy_,
0880 ryx_ * rhs.rxy_ + ryy_ * rhs.ryy_ + ryz_ * rhs.rzy_,
0881 rzx_ * rhs.rxy_ + rzy_ * rhs.ryy_ + rzz_ * rhs.rzy_,
0882 rxx_ * rhs.rxz_ + rxy_ * rhs.ryz_ + rxz_ * rhs.rzz_,
0883 ryx_ * rhs.rxz_ + ryy_ * rhs.ryz_ + ryz_ * rhs.rzz_,
0884 rzx_ * rhs.rxz_ + rzy_ * rhs.ryz_ + rzz_ * rhs.rzz_);
0885 }
0886
0887 template <typename Real_s>
0888 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Transformation3DMP<Real_s> Transformation3DMP<Real_s>::operator*(
0889 Transformation3D const &rhs) const
0890 {
0891 if (rhs.IsIdentity()) return Transformation3DMP<Real_s>(*this);
0892 return Transformation3DMP<Real_s>(
0893 tx_ * rhs.Rotation()[0] + ty_ * rhs.Rotation()[3] + tz_ * rhs.Rotation()[6] + rhs.Translation(0),
0894 tx_ * rhs.Rotation()[1] + ty_ * rhs.Rotation()[4] + tz_ * rhs.Rotation()[7] + rhs.Translation(1),
0895 tx_ * rhs.Rotation()[2] + ty_ * rhs.Rotation()[5] + tz_ * rhs.Rotation()[8] + rhs.Translation(2),
0896 rxx_ * rhs.Rotation()[0] + rxy_ * rhs.Rotation()[3] + rxz_ * rhs.Rotation()[6],
0897 ryx_ * rhs.Rotation()[0] + ryy_ * rhs.Rotation()[3] + ryz_ * rhs.Rotation()[6],
0898 rzx_ * rhs.Rotation()[0] + rzy_ * rhs.Rotation()[3] + rzz_ * rhs.Rotation()[6],
0899 rxx_ * rhs.Rotation()[1] + rxy_ * rhs.Rotation()[4] + rxz_ * rhs.Rotation()[7],
0900 ryx_ * rhs.Rotation()[1] + ryy_ * rhs.Rotation()[4] + ryz_ * rhs.Rotation()[7],
0901 rzx_ * rhs.Rotation()[1] + rzy_ * rhs.Rotation()[4] + rzz_ * rhs.Rotation()[7],
0902 rxx_ * rhs.Rotation()[2] + rxy_ * rhs.Rotation()[5] + rxz_ * rhs.Rotation()[8],
0903 ryx_ * rhs.Rotation()[2] + ryy_ * rhs.Rotation()[5] + ryz_ * rhs.Rotation()[8],
0904 rzx_ * rhs.Rotation()[2] + rzy_ * rhs.Rotation()[5] + rzz_ * rhs.Rotation()[8]);
0905 }
0906
0907 template <typename Real_s>
0908 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Transformation3DMP<Real_s> const &Transformation3DMP<Real_s>::operator*=(
0909 Transformation3DMP<Real_s> const &rhs)
0910 {
0911 if (rhs.fIdentity) return *this;
0912 fIdentity = false;
0913
0914 fHasTranslation |= rhs.HasTranslation();
0915 if (fHasTranslation) {
0916 auto tx = tx_ * rhs.rxx_ + ty_ * rhs.ryx_ + tz_ * rhs.rzx_ + rhs.tx_;
0917 auto ty = tx_ * rhs.rxy_ + ty_ * rhs.ryy_ + tz_ * rhs.rzy_ + rhs.ty_;
0918 auto tz = tx_ * rhs.rxz_ + ty_ * rhs.ryz_ + tz_ * rhs.rzz_ + rhs.tz_;
0919 tx_ = tx;
0920 ty_ = ty;
0921 tz_ = tz;
0922 }
0923
0924 fHasRotation |= rhs.HasRotation();
0925 if (rhs.HasRotation()) {
0926 auto rxx = rxx_ * rhs.rxx_ + rxy_ * rhs.ryx_ + rxz_ * rhs.rzx_;
0927 auto ryx = ryx_ * rhs.rxx_ + ryy_ * rhs.ryx_ + ryz_ * rhs.rzx_;
0928 auto rzx = rzx_ * rhs.rxx_ + rzy_ * rhs.ryx_ + rzz_ * rhs.rzx_;
0929 auto rxy = rxx_ * rhs.rxy_ + rxy_ * rhs.ryy_ + rxz_ * rhs.rzy_;
0930 auto ryy = ryx_ * rhs.rxy_ + ryy_ * rhs.ryy_ + ryz_ * rhs.rzy_;
0931 auto rzy = rzx_ * rhs.rxy_ + rzy_ * rhs.ryy_ + rzz_ * rhs.rzy_;
0932 auto rxz = rxx_ * rhs.rxz_ + rxy_ * rhs.ryz_ + rxz_ * rhs.rzz_;
0933 auto ryz = ryx_ * rhs.rxz_ + ryy_ * rhs.ryz_ + ryz_ * rhs.rzz_;
0934 auto rzz = rzx_ * rhs.rxz_ + rzy_ * rhs.ryz_ + rzz_ * rhs.rzz_;
0935
0936 rxx_ = rxx;
0937 rxy_ = rxy;
0938 rxz_ = rxz;
0939 ryx_ = ryx;
0940 ryy_ = ryy;
0941 ryz_ = ryz;
0942 rzx_ = rzx;
0943 rzy_ = rzy;
0944 rzz_ = rzz;
0945 }
0946
0947 return *this;
0948 }
0949
0950
0951
0952
0953 template <typename Real_s>
0954 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE Transformation3DMP<Real_s> const &Transformation3DMP<Real_s>::operator*=(
0955 Transformation3D const &rhs)
0956 {
0957 if (rhs.IsIdentity()) return *this;
0958 fIdentity = false;
0959
0960 fHasTranslation |= rhs.HasTranslation();
0961 if (fHasTranslation) {
0962 auto tx = tx_ * rhs.Rotation()[0] + ty_ * rhs.Rotation()[1] + tz_ * rhs.Rotation()[2] + rhs.Translation(0);
0963 auto ty = tx_ * rhs.Rotation()[3] + ty_ * rhs.Rotation()[4] + tz_ * rhs.Rotation()[5] + rhs.Translation(1);
0964 auto tz = tx_ * rhs.Rotation()[6] + ty_ * rhs.Rotation()[7] + tz_ * rhs.Rotation()[8] + rhs.Translation(2);
0965 tx_ = static_cast<Real_s>(tx);
0966 ty_ = static_cast<Real_s>(ty);
0967 tz_ = static_cast<Real_s>(tz);
0968 }
0969
0970 fHasRotation |= rhs.HasRotation();
0971 if (rhs.HasRotation()) {
0972 auto rxx = rxx_ * rhs.Rotation()[0] + rxy_ * rhs.Rotation()[1] + rxz_ * rhs.Rotation()[2];
0973 auto ryx = ryx_ * rhs.Rotation()[0] + ryy_ * rhs.Rotation()[1] + ryz_ * rhs.Rotation()[2];
0974 auto rzx = rzx_ * rhs.Rotation()[0] + rzy_ * rhs.Rotation()[1] + rzz_ * rhs.Rotation()[2];
0975 auto rxy = rxx_ * rhs.Rotation()[3] + rxy_ * rhs.Rotation()[4] + rxz_ * rhs.Rotation()[5];
0976 auto ryy = ryx_ * rhs.Rotation()[3] + ryy_ * rhs.Rotation()[4] + ryz_ * rhs.Rotation()[5];
0977 auto rzy = rzx_ * rhs.Rotation()[3] + rzy_ * rhs.Rotation()[4] + rzz_ * rhs.Rotation()[5];
0978 auto rxz = rxx_ * rhs.Rotation()[6] + rxy_ * rhs.Rotation()[7] + rxz_ * rhs.Rotation()[8];
0979 auto ryz = ryx_ * rhs.Rotation()[6] + ryy_ * rhs.Rotation()[7] + ryz_ * rhs.Rotation()[8];
0980 auto rzz = rzx_ * rhs.Rotation()[6] + rzy_ * rhs.Rotation()[7] + rzz_ * rhs.Rotation()[8];
0981
0982 rxx_ = static_cast<Real_s>(rxx);
0983 rxy_ = static_cast<Real_s>(rxy);
0984 rxz_ = static_cast<Real_s>(rxz);
0985 ryx_ = static_cast<Real_s>(ryx);
0986 ryy_ = static_cast<Real_s>(ryy);
0987 ryz_ = static_cast<Real_s>(ryz);
0988 rzx_ = static_cast<Real_s>(rzx);
0989 rzy_ = static_cast<Real_s>(rzy);
0990 rzz_ = static_cast<Real_s>(rzz);
0991 }
0992
0993 return *this;
0994 }
0995
0996 template <typename Real_s>
0997 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE void Transformation3DMP<Real_s>::MultiplyFromRight(
0998 Transformation3DMP<Real_s> const &rhs)
0999 {
1000
1001
1002 if (rhs.fIdentity) return;
1003 fIdentity = false;
1004
1005 if (rhs.HasTranslation()) {
1006 fHasTranslation = true;
1007
1008 tx_ += rxx_ * rhs.tx_;
1009 tx_ += ryx_ * rhs.ty_;
1010 tx_ += rzx_ * rhs.tz_;
1011
1012 ty_ += rxy_ * rhs.tx_;
1013 ty_ += ryy_ * rhs.ty_;
1014 ty_ += rzy_ * rhs.tz_;
1015
1016 tz_ += rxz_ * rhs.tx_;
1017 tz_ += ryz_ * rhs.ty_;
1018 tz_ += rzz_ * rhs.tz_;
1019 }
1020
1021 if (rhs.HasRotation()) {
1022 fHasRotation = true;
1023 Precision tmpx = rxx_;
1024 Precision tmpy = ryx_;
1025 Precision tmpz = rzx_;
1026
1027
1028 rxx_ = tmpx * rhs.rxx_;
1029 ryx_ = tmpx * rhs.ryx_;
1030 rzx_ = tmpx * rhs.rzx_;
1031 rxx_ += tmpy * rhs.rxy_;
1032 ryx_ += tmpy * rhs.ryy_;
1033 rzx_ += tmpy * rhs.rzy_;
1034 rxx_ += tmpz * rhs.rxz_;
1035 ryx_ += tmpz * rhs.ryz_;
1036 rzx_ += tmpz * rhs.rzz_;
1037
1038 tmpx = rxy_;
1039 tmpy = ryy_;
1040 tmpz = rzy_;
1041
1042
1043 rxy_ = tmpx * rhs.rxx_;
1044 ryy_ = tmpx * rhs.ryx_;
1045 rzy_ = tmpx * rhs.rzx_;
1046 rxy_ += tmpy * rhs.rxy_;
1047 ryy_ += tmpy * rhs.ryy_;
1048 rzy_ += tmpy * rhs.rzy_;
1049 rxy_ += tmpz * rhs.rxz_;
1050 ryy_ += tmpz * rhs.ryz_;
1051 rzy_ += tmpz * rhs.rzz_;
1052
1053 tmpx = rxz_;
1054 tmpy = ryz_;
1055 tmpz = rzz_;
1056
1057
1058 rxz_ = tmpx * rhs.rxx_;
1059 ryz_ = tmpx * rhs.ryx_;
1060 rzz_ = tmpx * rhs.rzx_;
1061 rxz_ += tmpy * rhs.rxy_;
1062 ryz_ += tmpy * rhs.ryy_;
1063 rzz_ += tmpy * rhs.rzy_;
1064 rxz_ += tmpz * rhs.rxz_;
1065 ryz_ += tmpz * rhs.ryz_;
1066 rzz_ += tmpz * rhs.rzz_;
1067 }
1068 }
1069
1070
1071
1072 template <typename Real_s>
1073 VECCORE_ATT_HOST_DEVICE VECGEOM_FORCE_INLINE void Transformation3DMP<Real_s>::MultiplyFromRight(
1074 Transformation3D const &rhs)
1075 {
1076
1077
1078 if (rhs.IsIdentity()) return;
1079 fIdentity = false;
1080
1081 if (rhs.HasTranslation()) {
1082 fHasTranslation = true;
1083
1084 tx_ += rxx_ * static_cast<Real_s>(rhs.Translation(0));
1085 tx_ += ryx_ * static_cast<Real_s>(rhs.Translation(1));
1086 tx_ += rzx_ * static_cast<Real_s>(rhs.Translation(2));
1087
1088 ty_ += rxy_ * static_cast<Real_s>(rhs.Translation(0));
1089 ty_ += ryy_ * static_cast<Real_s>(rhs.Translation(1));
1090 ty_ += rzy_ * static_cast<Real_s>(rhs.Translation(2));
1091
1092 tz_ += rxz_ * static_cast<Real_s>(rhs.Translation(0));
1093 tz_ += ryz_ * static_cast<Real_s>(rhs.Translation(1));
1094 tz_ += rzz_ * static_cast<Real_s>(rhs.Translation(2));
1095 }
1096
1097 if (rhs.HasRotation()) {
1098 fHasRotation = true;
1099 Real_s tmpx = rxx_;
1100 Real_s tmpy = ryx_;
1101 Real_s tmpz = rzx_;
1102
1103
1104 rxx_ = tmpx * static_cast<Real_s>(rhs.Rotation()[0]);
1105 ryx_ = tmpx * static_cast<Real_s>(rhs.Rotation()[1]);
1106 rzx_ = tmpx * static_cast<Real_s>(rhs.Rotation()[2]);
1107 rxx_ += tmpy * static_cast<Real_s>(rhs.Rotation()[3]);
1108 ryx_ += tmpy * static_cast<Real_s>(rhs.Rotation()[4]);
1109 rzx_ += tmpy * static_cast<Real_s>(rhs.Rotation()[5]);
1110 rxx_ += tmpz * static_cast<Real_s>(rhs.Rotation()[6]);
1111 ryx_ += tmpz * static_cast<Real_s>(rhs.Rotation()[7]);
1112 rzx_ += tmpz * static_cast<Real_s>(rhs.Rotation()[8]);
1113
1114 tmpx = rxy_;
1115 tmpy = ryy_;
1116 tmpz = rzy_;
1117
1118
1119 rxy_ = tmpx * static_cast<Real_s>(rhs.Rotation()[0]);
1120 ryy_ = tmpx * static_cast<Real_s>(rhs.Rotation()[1]);
1121 rzy_ = tmpx * static_cast<Real_s>(rhs.Rotation()[2]);
1122 rxy_ += tmpy * static_cast<Real_s>(rhs.Rotation()[3]);
1123 ryy_ += tmpy * static_cast<Real_s>(rhs.Rotation()[4]);
1124 rzy_ += tmpy * static_cast<Real_s>(rhs.Rotation()[5]);
1125 rxy_ += tmpz * static_cast<Real_s>(rhs.Rotation()[6]);
1126 ryy_ += tmpz * static_cast<Real_s>(rhs.Rotation()[7]);
1127 rzy_ += tmpz * static_cast<Real_s>(rhs.Rotation()[8]);
1128
1129 tmpx = rxz_;
1130 tmpy = ryz_;
1131 tmpz = rzz_;
1132
1133
1134 rxz_ = tmpx * static_cast<Real_s>(rhs.Rotation()[0]);
1135 ryz_ = tmpx * static_cast<Real_s>(rhs.Rotation()[1]);
1136 rzz_ = tmpx * static_cast<Real_s>(rhs.Rotation()[2]);
1137 rxz_ += tmpy * static_cast<Real_s>(rhs.Rotation()[3]);
1138 ryz_ += tmpy * static_cast<Real_s>(rhs.Rotation()[4]);
1139 rzz_ += tmpy * static_cast<Real_s>(rhs.Rotation()[5]);
1140 rxz_ += tmpz * static_cast<Real_s>(rhs.Rotation()[6]);
1141 ryz_ += tmpz * static_cast<Real_s>(rhs.Rotation()[7]);
1142 rzz_ += tmpz * static_cast<Real_s>(rhs.Rotation()[8]);
1143 }
1144 }
1145
1146
1147
1148
1149
1150
1151
1152 template <typename Real_s>
1153 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE void Transformation3DMP<Real_s>::TransformDirection(
1154 Vector3D<Real_s> const &master, Vector3D<Real_s> &local) const
1155 {
1156 DoRotation(master, local);
1157 }
1158
1159
1160
1161
1162
1163
1164
1165 template <typename Real_s>
1166 VECGEOM_FORCE_INLINE VECCORE_ATT_HOST_DEVICE Vector3D<Real_s> Transformation3DMP<Real_s>::TransformDirection(
1167 Vector3D<Real_s> const &master) const
1168 {
1169
1170 Vector3D<Real_s> local;
1171 TransformDirection(master, local);
1172 return local;
1173 }
1174
1175 template <typename Real_s>
1176 std::ostream &operator<<(std::ostream &os, Transformation3DMP<Real_s> const &trans)
1177 {
1178 os << "TransformationMP {" << trans.Translation() << ", " << "(" << trans.Rotation(0) << ", " << trans.Rotation(1)
1179 << ", " << trans.Rotation(2) << ", " << trans.Rotation(3) << ", " << trans.Rotation(4) << ", " << trans.Rotation(5)
1180 << ", " << trans.Rotation(6) << ", " << trans.Rotation(7) << ", " << trans.Rotation(8) << ")}" << "; identity("
1181 << trans.IsIdentity() << "); rotation(" << trans.HasRotation() << ")";
1182 return os;
1183 }
1184 }
1185 }
1186
1187 #endif