File indexing completed on 2025-01-18 10:13:55
0001
0002
0003
0004 #ifndef VECGEOM_BASE_TRANSFORMATION3D_H_
0005 #define VECGEOM_BASE_TRANSFORMATION3D_H_
0006
0007 #include "VecGeom/base/Config.h"
0008 #include "VecGeom/base/Cuda.h"
0009 #include "VecGeom/base/Global.h"
0010
0011 #include "VecGeom/base/Vector3D.h"
0012 #include "VecGeom/backend/scalar/Backend.h"
0013 #ifdef VECGEOM_ENABLE_CUDA
0014 #include "VecGeom/backend/cuda/Interface.h"
0015 #endif
0016
0017 #include <algorithm>
0018 #include <cmath>
0019 #include <cstring>
0020 #include <iostream>
0021 #include <vector>
0022
0023 #ifdef VECGEOM_ROOT
0024 class TGeoMatrix;
0025 #endif
0026
0027 typedef int RotationCode;
0028 typedef int TranslationCode;
0029
0030 namespace vecgeom {
0031 namespace rotation {
0032 enum RotationId { kGeneric = -1, kDiagonal = 0x111, kIdentity = 0x200 };
0033 }
0034 namespace translation {
0035 enum TranslationId { kGeneric = -1, kIdentity = 0 };
0036 }
0037 }
0038
0039 namespace vecgeom {
0040
0041 VECGEOM_DEVICE_FORWARD_DECLARE(class Transformation3D;);
0042
0043 inline namespace VECGEOM_IMPL_NAMESPACE {
0044
0045 #ifndef VECCORE_CUDA
0046 }
0047 namespace cuda {
0048 class Transformation3D;
0049 }
0050 inline namespace VECGEOM_IMPL_NAMESPACE {
0051
0052 #endif
0053
0054 class Transformation3D {
0055
0056 private:
0057
0058
0059 Precision fTranslation[3];
0060 Precision fRotation[9];
0061 bool fIdentity;
0062 bool fHasRotation;
0063 bool fHasTranslation;
0064
0065 public:
0066 VECCORE_ATT_HOST_DEVICE
0067 constexpr Transformation3D()
0068 : fTranslation{0., 0., 0.}, fRotation{1., 0., 0., 0., 1., 0., 0., 0., 1.}, fIdentity(true), fHasRotation(false),
0069 fHasTranslation(false){};
0070
0071
0072
0073
0074
0075
0076
0077 VECCORE_ATT_HOST_DEVICE
0078 Transformation3D(const Precision tx, const Precision ty, const Precision tz)
0079 : fTranslation{tx, ty, tz}, fRotation{1., 0., 0., 0., 1., 0., 0., 0., 1.},
0080 fIdentity(tx == 0 && ty == 0 && tz == 0), fHasRotation(false), fHasTranslation(tx != 0 || ty != 0 || tz != 0)
0081 {
0082 }
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093 VECCORE_ATT_HOST_DEVICE
0094 Transformation3D(const Precision tx, const Precision ty, const Precision tz, const Precision phi,
0095 const Precision theta, const Precision psi);
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 VECCORE_ATT_HOST_DEVICE
0107 Transformation3D(const Precision tx, const Precision ty, const Precision tz, const Precision phi,
0108 const Precision theta, const Precision psi, Precision sx, Precision sy, Precision sz);
0109
0110
0111
0112
0113
0114
0115 VECCORE_ATT_HOST_DEVICE
0116 Transformation3D(const Precision tx, const Precision ty, const Precision tz, const Precision r0, const Precision r1,
0117 const Precision r2, const Precision r3, const Precision r4, const Precision r5, const Precision r6,
0118 const Precision r7, const Precision r8);
0119
0120
0121
0122
0123
0124 VECCORE_ATT_HOST_DEVICE
0125 Transformation3D(const Precision tx, const Precision ty, const Precision tz, const Precision r0, const Precision r1,
0126 const Precision r2, const Precision r3, const Precision r4, const Precision r5, const Precision r6,
0127 const Precision r7, const Precision r8, Precision sx, Precision sy, Precision sz);
0128
0129
0130
0131
0132
0133 VECCORE_ATT_HOST_DEVICE
0134 Transformation3D(const Precision *trans, const Precision *rot, bool has_trans, bool has_rot)
0135 {
0136 this->Set(trans, rot, has_trans, has_rot);
0137 }
0138
0139
0140
0141
0142
0143
0144
0145 VECCORE_ATT_HOST_DEVICE
0146 Transformation3D(const Vector3D<Precision> &axis, bool inverse = true);
0147
0148 VECCORE_ATT_HOST_DEVICE
0149 VECGEOM_FORCE_INLINE
0150 Transformation3D(Transformation3D const &other);
0151
0152 VECCORE_ATT_HOST_DEVICE
0153 VECGEOM_FORCE_INLINE
0154 Transformation3D &operator=(Transformation3D const &rhs);
0155
0156 VECCORE_ATT_HOST_DEVICE
0157 VECGEOM_FORCE_INLINE
0158 bool operator==(Transformation3D const &rhs) const;
0159
0160 VECCORE_ATT_HOST_DEVICE
0161 ~Transformation3D() {}
0162
0163 VECCORE_ATT_HOST_DEVICE
0164 void ApplyScale(const Precision sx, const Precision sy, const Precision sz)
0165 {
0166 fRotation[0] *= sx;
0167 fRotation[1] *= sy;
0168 fRotation[2] *= sz;
0169 fRotation[3] *= sx;
0170 fRotation[4] *= sy;
0171 fRotation[5] *= sz;
0172 fRotation[6] *= sx;
0173 fRotation[7] *= sy;
0174 fRotation[8] *= sz;
0175 }
0176
0177 VECCORE_ATT_HOST_DEVICE
0178 void Clear()
0179 {
0180 fTranslation[0] = 0.;
0181 fTranslation[1] = 0.;
0182 fTranslation[2] = 0.;
0183 fRotation[0] = 1.;
0184 fRotation[1] = 0.;
0185 fRotation[2] = 0.;
0186 fRotation[3] = 0.;
0187 fRotation[4] = 1.;
0188 fRotation[5] = 0.;
0189 fRotation[6] = 0.;
0190 fRotation[7] = 0.;
0191 fRotation[8] = 1.;
0192 fIdentity = true;
0193 fHasRotation = false;
0194 fHasTranslation = false;
0195 }
0196
0197 int MemorySize() const { return sizeof(*this); }
0198
0199 VECCORE_ATT_HOST_DEVICE
0200 void FixZeroes()
0201 {
0202 for (unsigned int i = 0; i < 9; ++i) {
0203 if (std::abs(fRotation[i]) < vecgeom::kTolerance) fRotation[i] = 0.;
0204 }
0205 for (unsigned int i = 0; i < 3; ++i) {
0206 if (std::abs(fTranslation[i]) < vecgeom::kTolerance) fTranslation[i] = 0.;
0207 }
0208 }
0209
0210 VECCORE_ATT_HOST_DEVICE
0211 VECGEOM_FORCE_INLINE
0212 Vector3D<Precision> Translation() const
0213 {
0214 return Vector3D<Precision>(fTranslation[0], fTranslation[1], fTranslation[2]);
0215 }
0216
0217 VECCORE_ATT_HOST_DEVICE
0218 VECGEOM_FORCE_INLINE
0219 Vector3D<Precision> Scale() const
0220 {
0221 Precision sx = std::sqrt(fRotation[0]*fRotation[0] + fRotation[3]*fRotation[3] + fRotation[6]*fRotation[6]);
0222 Precision sy = std::sqrt(fRotation[1]*fRotation[1] + fRotation[4]*fRotation[4] + fRotation[7]*fRotation[7]);
0223 Precision sz = std::sqrt(fRotation[2]*fRotation[2] + fRotation[5]*fRotation[5] + fRotation[8]*fRotation[8]);
0224
0225 if (Determinant() < 0) sz = -sz;
0226
0227 return Vector3D<Precision>(sx, sy, sz);
0228 }
0229
0230
0231
0232
0233
0234 VECCORE_ATT_HOST_DEVICE
0235 VECGEOM_FORCE_INLINE
0236 Precision Translation(const int index) const { return fTranslation[index]; }
0237
0238 VECCORE_ATT_HOST_DEVICE
0239 VECGEOM_FORCE_INLINE
0240 Precision const *Rotation() const { return fRotation; }
0241
0242
0243
0244
0245
0246 VECCORE_ATT_HOST_DEVICE
0247 VECGEOM_FORCE_INLINE
0248 Precision Rotation(const int index) const { return fRotation[index]; }
0249
0250 VECCORE_ATT_HOST_DEVICE
0251 VECGEOM_FORCE_INLINE
0252 bool IsIdentity() const { return fIdentity; }
0253
0254 VECCORE_ATT_HOST_DEVICE
0255 VECGEOM_FORCE_INLINE
0256 bool IsReflected() const { return Determinant() < 0; }
0257
0258 VECCORE_ATT_HOST_DEVICE
0259 VECGEOM_FORCE_INLINE
0260 bool HasRotation() const { return fHasRotation; }
0261
0262 VECCORE_ATT_HOST_DEVICE
0263 VECGEOM_FORCE_INLINE
0264 bool HasTranslation() const { return fHasTranslation; }
0265
0266 VECCORE_ATT_HOST_DEVICE
0267 void Print() const;
0268
0269
0270 void Print(std::ostream &) const;
0271
0272
0273
0274 VECCORE_ATT_HOST_DEVICE
0275 void SetTranslation(const Precision tx, const Precision ty, const Precision tz);
0276
0277 VECCORE_ATT_HOST_DEVICE
0278 void SetTranslation(Vector3D<Precision> const &vec);
0279
0280 VECCORE_ATT_HOST_DEVICE
0281 void SetProperties();
0282
0283 VECCORE_ATT_HOST_DEVICE
0284 void SetRotation(const Precision phi, const Precision theta, const Precision psi);
0285
0286 VECCORE_ATT_HOST_DEVICE
0287 void SetRotation(Vector3D<Precision> const &vec);
0288
0289 VECCORE_ATT_HOST_DEVICE
0290 void SetRotation(const Precision rot0, const Precision rot1, const Precision rot2, const Precision rot3,
0291 const Precision rot4, const Precision rot5, const Precision rot6, const Precision rot7,
0292 const Precision rot8);
0293
0294
0295
0296
0297
0298
0299 VECCORE_ATT_HOST_DEVICE
0300 VECGEOM_FORCE_INLINE
0301 void Set(const Precision *trans, const Precision *rot, bool has_trans, bool has_rot)
0302 {
0303 if (has_trans) {
0304 for (size_t i = 0; i < 3; ++i)
0305 fTranslation[i] = trans[i];
0306 }
0307
0308 if (has_rot) {
0309 for (size_t i = 0; i < 9; ++i)
0310 fRotation[i] = rot[i];
0311 }
0312
0313 fHasTranslation = has_trans;
0314 fHasRotation = has_rot;
0315 fIdentity = !fHasTranslation && !fHasRotation;
0316 }
0317
0318
0319
0320 VECCORE_ATT_HOST_DEVICE
0321 RotationCode GenerateRotationCode() const;
0322
0323 VECCORE_ATT_HOST_DEVICE
0324 TranslationCode GenerateTranslationCode() const;
0325
0326 private:
0327
0328
0329
0330 template <RotationCode code, typename InputType>
0331 VECGEOM_FORCE_INLINE
0332 VECCORE_ATT_HOST_DEVICE
0333 void DoRotation(Vector3D<InputType> const &master, Vector3D<InputType> &local) const;
0334
0335 template <RotationCode code, typename InputType>
0336 VECGEOM_FORCE_INLINE
0337 VECCORE_ATT_HOST_DEVICE
0338 void DoRotation_new(Vector3D<InputType> const &master, Vector3D<InputType> &local) const;
0339
0340 private:
0341 template <typename InputType>
0342 VECGEOM_FORCE_INLINE
0343 VECCORE_ATT_HOST_DEVICE
0344 void DoTranslation(Vector3D<InputType> const &master, Vector3D<InputType> &local) const;
0345
0346 template <bool vectortransform, typename InputType>
0347 VECGEOM_FORCE_INLINE
0348 VECCORE_ATT_HOST_DEVICE
0349 void InverseTransformKernel(Vector3D<InputType> const &local, Vector3D<InputType> &master) const;
0350
0351 public:
0352
0353
0354 template <TranslationCode trans_code, RotationCode rot_code, typename InputType>
0355 VECGEOM_FORCE_INLINE
0356 VECCORE_ATT_HOST_DEVICE
0357 void Transform(Vector3D<InputType> const &master, Vector3D<InputType> &local) const;
0358
0359 template <TranslationCode trans_code, RotationCode rot_code, typename InputType>
0360 VECGEOM_FORCE_INLINE
0361 VECCORE_ATT_HOST_DEVICE
0362 Vector3D<InputType> Transform(Vector3D<InputType> const &master) const;
0363
0364 template <typename InputType>
0365 VECGEOM_FORCE_INLINE
0366 VECCORE_ATT_HOST_DEVICE
0367 void Transform(Vector3D<InputType> const &master, Vector3D<InputType> &local) const;
0368
0369 template <typename InputType>
0370 VECGEOM_FORCE_INLINE
0371 VECCORE_ATT_HOST_DEVICE
0372 Vector3D<InputType> Transform(Vector3D<InputType> const &master) const;
0373
0374 template <RotationCode code, typename InputType>
0375 VECGEOM_FORCE_INLINE
0376 VECCORE_ATT_HOST_DEVICE
0377 void TransformDirection(Vector3D<InputType> const &master, Vector3D<InputType> &local) const;
0378
0379 template <RotationCode code, typename InputType>
0380 VECGEOM_FORCE_INLINE
0381 VECCORE_ATT_HOST_DEVICE
0382 Vector3D<InputType> TransformDirection(Vector3D<InputType> const &master) const;
0383
0384 template <typename InputType>
0385 VECGEOM_FORCE_INLINE
0386 VECCORE_ATT_HOST_DEVICE
0387 void TransformDirection(Vector3D<InputType> const &master, Vector3D<InputType> &local) const;
0388
0389 template <typename InputType>
0390 VECGEOM_FORCE_INLINE
0391 VECCORE_ATT_HOST_DEVICE
0392 Vector3D<InputType> TransformDirection(Vector3D<InputType> const &master) const;
0393
0394
0395
0396
0397 template <typename InputType>
0398 VECGEOM_FORCE_INLINE
0399 VECCORE_ATT_HOST_DEVICE
0400 void InverseTransform(Vector3D<InputType> const &local, Vector3D<InputType> &master) const;
0401
0402 template <typename InputType>
0403 VECGEOM_FORCE_INLINE
0404 VECCORE_ATT_HOST_DEVICE
0405 Vector3D<InputType> InverseTransform(Vector3D<InputType> const &local) const;
0406
0407
0408 template <typename InputType>
0409 VECGEOM_FORCE_INLINE
0410 VECCORE_ATT_HOST_DEVICE
0411 void InverseTransformDirection(Vector3D<InputType> const &master, Vector3D<InputType> &local) const;
0412
0413 template <typename InputType>
0414 VECGEOM_FORCE_INLINE
0415 VECCORE_ATT_HOST_DEVICE
0416 Vector3D<InputType> InverseTransformDirection(Vector3D<InputType> const &master) const;
0417
0418
0419 VECCORE_ATT_HOST_DEVICE
0420 VECGEOM_FORCE_INLINE
0421 void MultiplyFromRight(Transformation3D const &rhs);
0422
0423
0424 VECCORE_ATT_HOST_DEVICE
0425 VECGEOM_FORCE_INLINE
0426 void CopyFrom(Transformation3D const &rhs)
0427 {
0428
0429 copy(&rhs, &rhs + 1, this);
0430 }
0431
0432 VECCORE_ATT_HOST_DEVICE
0433 double Determinant() const
0434 {
0435
0436 double xx_ = fRotation[0];
0437 double zz_ = fRotation[8];
0438 double yy_ = fRotation[4];
0439 double xy_ = fRotation[1];
0440 double xz_ = fRotation[2];
0441 double yx_ = fRotation[3];
0442 double yz_ = fRotation[5];
0443 double zx_ = fRotation[6];
0444 double zy_ = fRotation[7];
0445
0446 double detxx = yy_ * zz_ - yz_ * zy_;
0447 double detxy = yx_ * zz_ - yz_ * zx_;
0448 double detxz = yx_ * zy_ - yy_ * zx_;
0449 double det = xx_ * detxx - xy_ * detxy + xz_ * detxz;
0450 return det;
0451 }
0452
0453
0454
0455
0456 VECCORE_ATT_HOST_DEVICE
0457 void Inverse(Transformation3D &inverse) const
0458 {
0459 double xx_ = fRotation[0];
0460 double zz_ = fRotation[8];
0461 double yy_ = fRotation[4];
0462 double xy_ = fRotation[1];
0463 double xz_ = fRotation[2];
0464 double yx_ = fRotation[3];
0465 double yz_ = fRotation[5];
0466 double zx_ = fRotation[6];
0467 double zy_ = fRotation[7];
0468 double dx_ = fTranslation[0];
0469 double dy_ = fTranslation[1];
0470 double dz_ = fTranslation[2];
0471
0472 double detxx = yy_ * zz_ - yz_ * zy_;
0473 double detxy = yx_ * zz_ - yz_ * zx_;
0474 double detxz = yx_ * zy_ - yy_ * zx_;
0475 double det = xx_ * detxx - xy_ * detxy + xz_ * detxz;
0476 #ifndef VECCORE_CUDA_DEVICE_COMPILATION
0477 if (det == 0) {
0478 std::cerr << "Transform3D::inverse error: zero determinant" << std::endl;
0479 }
0480 #endif
0481 det = 1. / det;
0482 detxx *= det;
0483 detxy *= det;
0484 detxz *= det;
0485 double detyx = (xy_ * zz_ - xz_ * zy_) * det;
0486 double detyy = (xx_ * zz_ - xz_ * zx_) * det;
0487 double detyz = (xx_ * zy_ - xy_ * zx_) * det;
0488 double detzx = (xy_ * yz_ - xz_ * yy_) * det;
0489 double detzy = (xx_ * yz_ - xz_ * yx_) * det;
0490 double detzz = (xx_ * yy_ - xy_ * yx_) * det;
0491 inverse.fRotation[0] = detxx;
0492 inverse.fRotation[1] = -detyx;
0493 inverse.fRotation[2] = detzx;
0494 inverse.fTranslation[0] = -detxx * dx_ + detyx * dy_ - detzx * dz_;
0495 inverse.fRotation[3] = -detxy, inverse.fRotation[4] = detyy, inverse.fRotation[5] = -detzy,
0496 inverse.fTranslation[1] = detxy * dx_ - detyy * dy_ + detzy * dz_;
0497 inverse.fRotation[6] = detxz, inverse.fRotation[7] = -detyz, inverse.fRotation[8] = detzz,
0498 inverse.fTranslation[2] = -detxz * dx_ + detyz * dy_ - detzz * dz_;
0499
0500 inverse.fHasTranslation = HasTranslation();
0501 inverse.fHasRotation = HasRotation();
0502 inverse.fIdentity = fIdentity;
0503 }
0504
0505
0506
0507 #ifdef VECGEOM_CUDA_INTERFACE
0508 size_t DeviceSizeOf() const { return DevicePtr<cuda::Transformation3D>::SizeOf(); }
0509 DevicePtr<cuda::Transformation3D> CopyToGpu() const;
0510 DevicePtr<cuda::Transformation3D> CopyToGpu(DevicePtr<cuda::Transformation3D> const gpu_ptr) const;
0511 static void CopyManyToGpu(const std::vector<Transformation3D const *> &trafos,
0512 const std::vector<DevicePtr<cuda::Transformation3D>> &gpu_ptrs);
0513 #endif
0514
0515 #ifdef VECGEOM_ROOT
0516
0517
0518 static TGeoMatrix *ConvertToTGeoMatrix(Transformation3D const&);
0519 #endif
0520
0521 public:
0522 static const Transformation3D kIdentity;
0523
0524 };
0525
0526 VECCORE_ATT_HOST_DEVICE
0527 Transformation3D::Transformation3D(Transformation3D const &other)
0528 : fIdentity(false), fHasRotation(false), fHasTranslation(false)
0529 {
0530 *this = other;
0531 }
0532
0533 VECCORE_ATT_HOST_DEVICE
0534 Transformation3D &Transformation3D::operator=(Transformation3D const &rhs)
0535 {
0536 copy(rhs.fTranslation, rhs.fTranslation + 3, fTranslation);
0537 copy(rhs.fRotation, rhs.fRotation + 9, fRotation);
0538 fIdentity = rhs.fIdentity;
0539 fHasTranslation = rhs.fHasTranslation;
0540 fHasRotation = rhs.fHasRotation;
0541 return *this;
0542 }
0543
0544 VECCORE_ATT_HOST_DEVICE
0545 bool Transformation3D::operator==(Transformation3D const &rhs) const
0546 {
0547 return equal(fTranslation, fTranslation + 3, rhs.fTranslation) && equal(fRotation, fRotation + 9, rhs.fRotation);
0548 }
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558 template <RotationCode code, typename InputType>
0559 VECGEOM_FORCE_INLINE
0560 VECCORE_ATT_HOST_DEVICE
0561 void Transformation3D::DoRotation(Vector3D<InputType> const &master, Vector3D<InputType> &local) const
0562 {
0563
0564 if (code == 0x1B1) {
0565 local[0] = master[0] * fRotation[0];
0566 local[1] = master[1] * fRotation[4] + master[2] * fRotation[7];
0567 local[2] = master[1] * fRotation[5] + master[2] * fRotation[8];
0568 return;
0569 }
0570 if (code == 0x18E) {
0571 local[0] = master[1] * fRotation[3];
0572 local[1] = master[0] * fRotation[1] + master[2] * fRotation[7];
0573 local[2] = master[0] * fRotation[2] + master[2] * fRotation[8];
0574 return;
0575 }
0576 if (code == 0x076) {
0577 local[0] = master[2] * fRotation[6];
0578 local[1] = master[0] * fRotation[1] + master[1] * fRotation[4];
0579 local[2] = master[0] * fRotation[2] + master[1] * fRotation[5];
0580 return;
0581 }
0582 if (code == 0x16A) {
0583 local[0] = master[1] * fRotation[3] + master[2] * fRotation[6];
0584 local[1] = master[0] * fRotation[1];
0585 local[2] = master[2] * fRotation[5] + master[2] * fRotation[8];
0586 return;
0587 }
0588 if (code == 0x155) {
0589 local[0] = master[0] * fRotation[0] + master[2] * fRotation[6];
0590 local[1] = master[1] * fRotation[4];
0591 local[2] = master[0] * fRotation[2] + master[2] * fRotation[8];
0592 return;
0593 }
0594 if (code == 0x0AD) {
0595 local[0] = master[0] * fRotation[0] + master[1] * fRotation[3];
0596 local[1] = master[2] * fRotation[7];
0597 local[2] = master[0] * fRotation[2] + master[1] * fRotation[5];
0598 return;
0599 }
0600 if (code == 0x0DC) {
0601 local[0] = master[1] * fRotation[3] + master[2] * fRotation[6];
0602 local[1] = master[1] * fRotation[4] + master[2] * fRotation[7];
0603 local[2] = master[0] * fRotation[2];
0604 return;
0605 }
0606 if (code == 0x0E3) {
0607 local[0] = master[0] * fRotation[0] + master[2] * fRotation[6];
0608 local[1] = master[0] * fRotation[1] + master[2] * fRotation[7];
0609 local[2] = master[1] * fRotation[5];
0610 return;
0611 }
0612 if (code == 0x11B) {
0613 local[0] = master[0] * fRotation[0] + master[1] * fRotation[3];
0614 local[1] = master[0] * fRotation[1] + master[1] * fRotation[4];
0615 local[2] = master[2] * fRotation[8];
0616 return;
0617 }
0618 if (code == 0x0A1) {
0619 local[0] = master[0] * fRotation[0];
0620 local[1] = master[2] * fRotation[7];
0621 local[2] = master[1] * fRotation[5];
0622 return;
0623 }
0624 if (code == 0x10A) {
0625 local[0] = master[1] * fRotation[3];
0626 local[1] = master[0] * fRotation[1];
0627 local[2] = master[2] * fRotation[8];
0628 return;
0629 }
0630 if (code == 0x046) {
0631 local[0] = master[1] * fRotation[3];
0632 local[1] = master[2] * fRotation[7];
0633 local[2] = master[0] * fRotation[2];
0634 return;
0635 }
0636 if (code == 0x062) {
0637 local[0] = master[2] * fRotation[6];
0638 local[1] = master[0] * fRotation[1];
0639 local[2] = master[1] * fRotation[5];
0640 return;
0641 }
0642 if (code == 0x054) {
0643 local[0] = master[2] * fRotation[6];
0644 local[1] = master[1] * fRotation[4];
0645 local[2] = master[0] * fRotation[2];
0646 return;
0647 }
0648
0649
0650 if (code == rotation::kDiagonal) {
0651 local[0] = master[0] * fRotation[0];
0652 local[1] = master[1] * fRotation[4];
0653 local[2] = master[2] * fRotation[8];
0654 return;
0655 }
0656
0657
0658 if (code == rotation::kIdentity) {
0659 local = master;
0660 return;
0661 }
0662
0663
0664 local[0] = master[0] * fRotation[0];
0665 local[1] = master[0] * fRotation[1];
0666 local[2] = master[0] * fRotation[2];
0667 local[0] += master[1] * fRotation[3];
0668 local[1] += master[1] * fRotation[4];
0669 local[2] += master[1] * fRotation[5];
0670 local[0] += master[2] * fRotation[6];
0671 local[1] += master[2] * fRotation[7];
0672 local[2] += master[2] * fRotation[8];
0673 }
0674
0675
0676
0677
0678
0679
0680
0681
0682
0683 template <RotationCode code, typename InputType>
0684 VECGEOM_FORCE_INLINE
0685 VECCORE_ATT_HOST_DEVICE
0686 void Transformation3D::DoRotation_new(Vector3D<InputType> const &master, Vector3D<InputType> &local) const
0687 {
0688
0689
0690 if (code == rotation::kIdentity) {
0691 local = master;
0692 return;
0693 }
0694
0695
0696 local = Vector3D<InputType>();
0697 if (code & 0x001) {
0698 local[0] += master[0] * fRotation[0];
0699 }
0700 if (code & 0x002) {
0701 local[1] += master[0] * fRotation[1];
0702 }
0703 if (code & 0x004) {
0704 local[2] += master[0] * fRotation[2];
0705 }
0706 if (code & 0x008) {
0707 local[0] += master[1] * fRotation[3];
0708 }
0709 if (code & 0x010) {
0710 local[1] += master[1] * fRotation[4];
0711 }
0712 if (code & 0x020) {
0713 local[2] += master[1] * fRotation[5];
0714 }
0715 if (code & 0x040) {
0716 local[0] += master[2] * fRotation[6];
0717 }
0718 if (code & 0x080) {
0719 local[1] += master[2] * fRotation[7];
0720 }
0721 if (code & 0x100) {
0722 local[2] += master[2] * fRotation[8];
0723 }
0724 }
0725
0726 template <typename InputType>
0727 VECGEOM_FORCE_INLINE
0728 VECCORE_ATT_HOST_DEVICE
0729 void Transformation3D::DoTranslation(Vector3D<InputType> const &master, Vector3D<InputType> &local) const
0730 {
0731
0732 local[0] = master[0] - fTranslation[0];
0733 local[1] = master[1] - fTranslation[1];
0734 local[2] = master[2] - fTranslation[2];
0735 }
0736
0737
0738
0739
0740
0741
0742
0743 template <TranslationCode trans_code, RotationCode rot_code, typename InputType>
0744 VECGEOM_FORCE_INLINE
0745 VECCORE_ATT_HOST_DEVICE
0746 void Transformation3D::Transform(Vector3D<InputType> const &master, Vector3D<InputType> &local) const
0747 {
0748
0749
0750 if (trans_code == translation::kIdentity && rot_code == rotation::kIdentity) {
0751 local = master;
0752 return;
0753 }
0754
0755
0756 if (trans_code != translation::kIdentity && rot_code == rotation::kIdentity) {
0757 DoTranslation(master, local);
0758 return;
0759 }
0760
0761
0762 if (trans_code == translation::kIdentity && rot_code != rotation::kIdentity) {
0763 DoRotation<rot_code>(master, local);
0764 return;
0765 }
0766
0767
0768 Vector3D<InputType> tmp;
0769 DoTranslation(master, tmp);
0770 DoRotation<rot_code>(tmp, local);
0771 }
0772
0773
0774
0775
0776
0777
0778
0779 template <TranslationCode trans_code, RotationCode rot_code, typename InputType>
0780 VECGEOM_FORCE_INLINE
0781 VECCORE_ATT_HOST_DEVICE
0782 Vector3D<InputType> Transformation3D::Transform(Vector3D<InputType> const &master) const
0783 {
0784
0785 Vector3D<InputType> local;
0786 Transform<trans_code, rot_code>(master, local);
0787 return local;
0788 }
0789
0790 template <typename InputType>
0791 VECGEOM_FORCE_INLINE
0792 VECCORE_ATT_HOST_DEVICE
0793 void Transformation3D::Transform(Vector3D<InputType> const &master, Vector3D<InputType> &local) const
0794 {
0795 Transform<translation::kGeneric, rotation::kGeneric>(master, local);
0796 }
0797 template <typename InputType>
0798 VECGEOM_FORCE_INLINE
0799 VECCORE_ATT_HOST_DEVICE
0800 Vector3D<InputType> Transformation3D::Transform(Vector3D<InputType> const &master) const
0801 {
0802 return Transform<translation::kGeneric, rotation::kGeneric>(master);
0803 }
0804
0805 template <bool transform_direction, typename InputType>
0806 VECGEOM_FORCE_INLINE
0807 VECCORE_ATT_HOST_DEVICE
0808 void Transformation3D::InverseTransformKernel(Vector3D<InputType> const &local, Vector3D<InputType> &master) const
0809 {
0810
0811
0812
0813
0814 if (transform_direction) {
0815 master[0] = local[0] * fRotation[0];
0816 master[0] += local[1] * fRotation[1];
0817 master[0] += local[2] * fRotation[2];
0818 master[1] = local[0] * fRotation[3];
0819 master[1] += local[1] * fRotation[4];
0820 master[1] += local[2] * fRotation[5];
0821 master[2] = local[0] * fRotation[6];
0822 master[2] += local[1] * fRotation[7];
0823 master[2] += local[2] * fRotation[8];
0824 } else {
0825 master[0] = fTranslation[0];
0826 master[0] += local[0] * fRotation[0];
0827 master[0] += local[1] * fRotation[1];
0828 master[0] += local[2] * fRotation[2];
0829 master[1] = fTranslation[1];
0830 master[1] += local[0] * fRotation[3];
0831 master[1] += local[1] * fRotation[4];
0832 master[1] += local[2] * fRotation[5];
0833 master[2] = fTranslation[2];
0834 master[2] += local[0] * fRotation[6];
0835 master[2] += local[1] * fRotation[7];
0836 master[2] += local[2] * fRotation[8];
0837 }
0838 }
0839
0840 template <typename InputType>
0841 VECGEOM_FORCE_INLINE
0842 VECCORE_ATT_HOST_DEVICE
0843 void Transformation3D::InverseTransform(Vector3D<InputType> const &local, Vector3D<InputType> &master) const
0844 {
0845 InverseTransformKernel<false, InputType>(local, master);
0846 }
0847
0848 template <typename InputType>
0849 VECGEOM_FORCE_INLINE
0850 VECCORE_ATT_HOST_DEVICE
0851 Vector3D<InputType> Transformation3D::InverseTransform(Vector3D<InputType> const &local) const
0852 {
0853 Vector3D<InputType> tmp;
0854 InverseTransform(local, tmp);
0855 return tmp;
0856 }
0857
0858 template <typename InputType>
0859 VECGEOM_FORCE_INLINE
0860 VECCORE_ATT_HOST_DEVICE
0861 void Transformation3D::InverseTransformDirection(Vector3D<InputType> const &local, Vector3D<InputType> &master) const
0862 {
0863 InverseTransformKernel<true, InputType>(local, master);
0864 }
0865
0866 template <typename InputType>
0867 VECGEOM_FORCE_INLINE
0868 VECCORE_ATT_HOST_DEVICE
0869 Vector3D<InputType> Transformation3D::InverseTransformDirection(Vector3D<InputType> const &local) const
0870 {
0871 Vector3D<InputType> tmp;
0872 InverseTransformDirection(local, tmp);
0873 return tmp;
0874 }
0875
0876 VECCORE_ATT_HOST_DEVICE
0877 VECGEOM_FORCE_INLINE
0878 void Transformation3D::MultiplyFromRight(Transformation3D const &rhs)
0879 {
0880
0881
0882 if (rhs.fIdentity) return;
0883 fIdentity = false;
0884
0885 if (rhs.HasTranslation()) {
0886 fHasTranslation = true;
0887
0888 fTranslation[0] += fRotation[0] * rhs.fTranslation[0];
0889 fTranslation[0] += fRotation[1] * rhs.fTranslation[1];
0890 fTranslation[0] += fRotation[2] * rhs.fTranslation[2];
0891
0892 fTranslation[1] += fRotation[3] * rhs.fTranslation[0];
0893 fTranslation[1] += fRotation[4] * rhs.fTranslation[1];
0894 fTranslation[1] += fRotation[5] * rhs.fTranslation[2];
0895
0896 fTranslation[2] += fRotation[6] * rhs.fTranslation[0];
0897 fTranslation[2] += fRotation[7] * rhs.fTranslation[1];
0898 fTranslation[2] += fRotation[8] * rhs.fTranslation[2];
0899 }
0900
0901 if (rhs.HasRotation()) {
0902 fHasRotation = true;
0903 Precision tmpx = fRotation[0];
0904 Precision tmpy = fRotation[1];
0905 Precision tmpz = fRotation[2];
0906
0907
0908 fRotation[0] = tmpx * rhs.fRotation[0];
0909 fRotation[1] = tmpx * rhs.fRotation[1];
0910 fRotation[2] = tmpx * rhs.fRotation[2];
0911 fRotation[0] += tmpy * rhs.fRotation[3];
0912 fRotation[1] += tmpy * rhs.fRotation[4];
0913 fRotation[2] += tmpy * rhs.fRotation[5];
0914 fRotation[0] += tmpz * rhs.fRotation[6];
0915 fRotation[1] += tmpz * rhs.fRotation[7];
0916 fRotation[2] += tmpz * rhs.fRotation[8];
0917
0918 tmpx = fRotation[3];
0919 tmpy = fRotation[4];
0920 tmpz = fRotation[5];
0921
0922
0923 fRotation[3] = tmpx * rhs.fRotation[0];
0924 fRotation[4] = tmpx * rhs.fRotation[1];
0925 fRotation[5] = tmpx * rhs.fRotation[2];
0926 fRotation[3] += tmpy * rhs.fRotation[3];
0927 fRotation[4] += tmpy * rhs.fRotation[4];
0928 fRotation[5] += tmpy * rhs.fRotation[5];
0929 fRotation[3] += tmpz * rhs.fRotation[6];
0930 fRotation[4] += tmpz * rhs.fRotation[7];
0931 fRotation[5] += tmpz * rhs.fRotation[8];
0932
0933 tmpx = fRotation[6];
0934 tmpy = fRotation[7];
0935 tmpz = fRotation[8];
0936
0937
0938 fRotation[6] = tmpx * rhs.fRotation[0];
0939 fRotation[7] = tmpx * rhs.fRotation[1];
0940 fRotation[8] = tmpx * rhs.fRotation[2];
0941 fRotation[6] += tmpy * rhs.fRotation[3];
0942 fRotation[7] += tmpy * rhs.fRotation[4];
0943 fRotation[8] += tmpy * rhs.fRotation[5];
0944 fRotation[6] += tmpz * rhs.fRotation[6];
0945 fRotation[7] += tmpz * rhs.fRotation[7];
0946 fRotation[8] += tmpz * rhs.fRotation[8];
0947 }
0948 }
0949
0950
0951
0952
0953
0954
0955
0956 template <RotationCode code, typename InputType>
0957 VECGEOM_FORCE_INLINE
0958 VECCORE_ATT_HOST_DEVICE
0959 void Transformation3D::TransformDirection(Vector3D<InputType> const &master, Vector3D<InputType> &local) const
0960 {
0961
0962
0963 if (code == rotation::kIdentity) {
0964 local = master;
0965 return;
0966 }
0967
0968
0969 DoRotation<code>(master, local);
0970 }
0971
0972
0973
0974
0975
0976
0977
0978 template <RotationCode code, typename InputType>
0979 VECGEOM_FORCE_INLINE
0980 VECCORE_ATT_HOST_DEVICE
0981 Vector3D<InputType> Transformation3D::TransformDirection(Vector3D<InputType> const &master) const
0982 {
0983
0984 Vector3D<InputType> local;
0985 TransformDirection<code>(master, local);
0986 return local;
0987 }
0988
0989 template <typename InputType>
0990 VECGEOM_FORCE_INLINE
0991 VECCORE_ATT_HOST_DEVICE
0992 void Transformation3D::TransformDirection(Vector3D<InputType> const &master, Vector3D<InputType> &local) const
0993 {
0994 TransformDirection<rotation::kGeneric>(master, local);
0995 }
0996
0997 template <typename InputType>
0998 VECGEOM_FORCE_INLINE
0999 VECCORE_ATT_HOST_DEVICE
1000 Vector3D<InputType> Transformation3D::TransformDirection(Vector3D<InputType> const &master) const
1001 {
1002 return TransformDirection<rotation::kGeneric>(master);
1003 }
1004
1005 std::ostream &operator<<(std::ostream &os, Transformation3D const &trans);
1006 }
1007 }
1008
1009 #endif