1 | |
2 | // |
3 | // This source file is part of appleseed. |
4 | // Visit http://appleseedhq.net/ for additional information and resources. |
5 | // |
6 | // This software is released under the MIT license. |
7 | // |
8 | // Copyright (c) 2012-2013 Esteban Tovagliari, Jupiter Jazz Limited |
9 | // Copyright (c) 2014-2017 Esteban Tovagliari, The appleseedhq Organization |
10 | // |
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy |
12 | // of this software and associated documentation files (the "Software"), to deal |
13 | // in the Software without restriction, including without limitation the rights |
14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
15 | // copies of the Software, and to permit persons to whom the Software is |
16 | // furnished to do so, subject to the following conditions: |
17 | // |
18 | // The above copyright notice and this permission notice shall be included in |
19 | // all copies or substantial portions of the Software. |
20 | // |
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN |
27 | // THE SOFTWARE. |
28 | // |
29 | |
30 | #ifndef APPLESEED_PYTHON_UNALIGNEDTRANSFORM_H |
31 | #define APPLESEED_PYTHON_UNALIGNEDTRANSFORM_H |
32 | |
33 | // appleseed.python headers. |
34 | #include "pyseed.h" // has to be first, to avoid redefinition warnings |
35 | #include "unalignedmatrix44.h" |
36 | |
37 | // appleseed.foundation headers. |
38 | #include "foundation/math/transform.h" |
39 | |
40 | namespace foundation |
41 | { |
42 | |
43 | template <typename T> |
44 | class UnalignedTransform |
45 | { |
46 | public: |
47 | UnalignedTransform() |
48 | : m_local_to_parent(UnalignedMatrix44<T>::identity()) |
49 | , m_parent_to_local(UnalignedMatrix44<T>::identity()) |
50 | { |
51 | } |
52 | |
53 | explicit UnalignedTransform(const Transform<T>& xform) |
54 | : m_local_to_parent(UnalignedMatrix44<T>(xform.get_local_to_parent())) |
55 | , m_parent_to_local(UnalignedMatrix44<T>(xform.get_parent_to_local())) |
56 | { |
57 | } |
58 | |
59 | explicit UnalignedTransform(const UnalignedMatrix44<T>& local_to_parent) |
60 | : m_local_to_parent(local_to_parent) |
61 | , m_parent_to_local(invert_matrix(m_local_to_parent)) |
62 | { |
63 | } |
64 | |
65 | template <typename U> |
66 | explicit UnalignedTransform(const UnalignedTransform<U>& other) |
67 | : m_local_to_parent(other.get_local_to_parent()) |
68 | , m_parent_to_local(other.get_parent_to_local()) |
69 | { |
70 | } |
71 | |
72 | UnalignedTransform( |
73 | const UnalignedMatrix44<T>& local_to_parent, |
74 | const UnalignedMatrix44<T>& parent_to_local) |
75 | { |
76 | Matrix<T, 4, 4> aligned_local_to_parent = local_to_parent.as_foundation_matrix(); |
77 | Matrix<T, 4, 4> aligned_parent_to_local = parent_to_local.as_foundation_matrix(); |
78 | |
79 | // Check that local_to_parent * aligned_parent_to_local == identity, if not, throw an exception before the assert fires. |
80 | if (feq(aligned_local_to_parent * aligned_parent_to_local, Matrix<T, 4, 4>::identity(), make_eps<T>(1.0e-6f, 1.0e-9))) |
81 | { |
82 | m_local_to_parent = UnalignedMatrix44<T>(local_to_parent); |
83 | m_parent_to_local = UnalignedMatrix44<T>(parent_to_local); |
84 | } |
85 | else |
86 | { |
87 | PyErr_SetString(PyExc_RuntimeError, "Matrices passed to appleseed.Transform are not inverses of each other" ); |
88 | boost::python::throw_error_already_set(); |
89 | } |
90 | } |
91 | |
92 | static UnalignedTransform identity() |
93 | { |
94 | return UnalignedTransform( |
95 | UnalignedMatrix44<T>::identity(), |
96 | UnalignedMatrix44<T>::identity()); |
97 | } |
98 | |
99 | Transform<T> as_foundation_transform() const |
100 | { |
101 | return Transform<T>( |
102 | get_local_to_parent().as_foundation_matrix(), |
103 | get_parent_to_local().as_foundation_matrix()); |
104 | } |
105 | |
106 | const UnalignedMatrix44<T>& get_local_to_parent() const { return m_local_to_parent;} |
107 | const UnalignedMatrix44<T>& get_parent_to_local() const { return m_parent_to_local;} |
108 | |
109 | UnalignedTransform operator*(const UnalignedTransform& rhs) const |
110 | { |
111 | return UnalignedTransform(this->as_foundation_transform() * rhs.as_foundation_transform()); |
112 | } |
113 | |
114 | Vector<T, 3> point_to_local(const Vector<T, 3>& p) const |
115 | { |
116 | return m_parent_to_local.transform_point(p); |
117 | } |
118 | |
119 | Vector<T, 3> point_to_parent(const Vector<T, 3>& p) const |
120 | { |
121 | return m_local_to_parent.transform_point(p); |
122 | } |
123 | |
124 | Vector<T, 3> vector_to_local(const Vector<T, 3>& v) const |
125 | { |
126 | return m_parent_to_local.transform_vector(v); |
127 | } |
128 | |
129 | Vector<T, 3> vector_to_parent(const Vector<T, 3>& v) const |
130 | { |
131 | return m_local_to_parent.transform_vector(v); |
132 | } |
133 | |
134 | Vector<T, 3> normal_to_local(const Vector<T, 3>& n) const |
135 | { |
136 | return m_local_to_parent.transform_normal(n); |
137 | } |
138 | |
139 | Vector<T, 3> normal_to_parent(const Vector<T, 3>& n) const |
140 | { |
141 | return m_parent_to_local.transform_normal(n); |
142 | } |
143 | |
144 | private: |
145 | UnalignedMatrix44<T> m_local_to_parent; |
146 | UnalignedMatrix44<T> m_parent_to_local; |
147 | }; |
148 | |
149 | template <typename T> |
150 | inline std::ostream& operator<<(std::ostream& s, const UnalignedTransform<T>& xform) |
151 | { |
152 | return s << xform.as_foundation_transform(); |
153 | } |
154 | |
155 | typedef UnalignedTransform<float> UnalignedTransformf; |
156 | typedef UnalignedTransform<double> UnalignedTransformd; |
157 | |
158 | } // namespace foundation |
159 | |
160 | #endif // !APPLESEED_PYTHON_UNALIGNEDTRANSFORM_H |
161 | |