1 /*************************************************************************/
2 /*  math_fieldwise.cpp                                                   */
3 /*************************************************************************/
4 /*                       This file is part of:                           */
5 /*                           GODOT ENGINE                                */
6 /*                      https://godotengine.org                          */
7 /*************************************************************************/
8 /* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
9 /* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
10 /*                                                                       */
11 /* Permission is hereby granted, free of charge, to any person obtaining */
12 /* a copy of this software and associated documentation files (the       */
13 /* "Software"), to deal in the Software without restriction, including   */
14 /* without limitation the rights to use, copy, modify, merge, publish,   */
15 /* distribute, sublicense, and/or sell copies of the Software, and to    */
16 /* permit persons to whom the Software is furnished to do so, subject to */
17 /* the following conditions:                                             */
18 /*                                                                       */
19 /* The above copyright notice and this permission notice shall be        */
20 /* included in all copies or substantial portions of the Software.       */
21 /*                                                                       */
22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
29 /*************************************************************************/
30 
31 #ifdef TOOLS_ENABLED
32 
33 #include "math_fieldwise.h"
34 
35 #define SETUP_TYPE(m_type)    \
36 	m_type source = p_source; \
37 	m_type target = p_target;
38 #define TRY_TRANSFER_FIELD(m_name, m_member) \
39 	if (p_field == m_name) {                 \
40 		target.m_member = source.m_member;   \
41 	}
42 
fieldwise_assign(const Variant & p_target,const Variant & p_source,const String & p_field)43 Variant fieldwise_assign(const Variant &p_target, const Variant &p_source, const String &p_field) {
44 
45 	ERR_FAIL_COND_V(p_target.get_type() != p_source.get_type(), p_target);
46 
47 	/* clang-format makes a mess of this macro usage */
48 	/* clang-format off */
49 
50 	switch (p_source.get_type()) {
51 
52 		case Variant::VECTOR2: {
53 
54 			SETUP_TYPE(Vector2)
55 
56 			/**/ TRY_TRANSFER_FIELD("x", x)
57 			else TRY_TRANSFER_FIELD("y", y)
58 
59 			return target;
60 		}
61 
62 		case Variant::RECT2: {
63 
64 			SETUP_TYPE(Rect2)
65 
66 			/**/ TRY_TRANSFER_FIELD("x", position.x)
67 			else TRY_TRANSFER_FIELD("y", position.y)
68 			else TRY_TRANSFER_FIELD("w", size.x)
69 			else TRY_TRANSFER_FIELD("h", size.y)
70 
71 			return target;
72 		}
73 
74 		case Variant::VECTOR3: {
75 
76 			SETUP_TYPE(Vector3)
77 
78 			/**/ TRY_TRANSFER_FIELD("x", x)
79 			else TRY_TRANSFER_FIELD("y", y)
80 			else TRY_TRANSFER_FIELD("z", z)
81 
82 			return target;
83 		}
84 
85 		case Variant::PLANE: {
86 
87 			SETUP_TYPE(Plane)
88 
89 			/**/ TRY_TRANSFER_FIELD("x", normal.x)
90 			else TRY_TRANSFER_FIELD("y", normal.y)
91 			else TRY_TRANSFER_FIELD("z", normal.z)
92 			else TRY_TRANSFER_FIELD("d", d)
93 
94 			return target;
95 		}
96 
97 		case Variant::QUAT: {
98 
99 			SETUP_TYPE(Quat)
100 
101 			/**/ TRY_TRANSFER_FIELD("x", x)
102 			else TRY_TRANSFER_FIELD("y", y)
103 			else TRY_TRANSFER_FIELD("z", z)
104 			else TRY_TRANSFER_FIELD("w", w)
105 
106 			return target;
107 		}
108 
109 		case Variant::AABB: {
110 
111 			SETUP_TYPE(AABB)
112 
113 			/**/ TRY_TRANSFER_FIELD("px", position.x)
114 			else TRY_TRANSFER_FIELD("py", position.y)
115 			else TRY_TRANSFER_FIELD("pz", position.z)
116 			else TRY_TRANSFER_FIELD("sx", size.x)
117 			else TRY_TRANSFER_FIELD("sy", size.y)
118 			else TRY_TRANSFER_FIELD("sz", size.z)
119 
120 			return target;
121 		}
122 
123 		case Variant::TRANSFORM2D: {
124 
125 			SETUP_TYPE(Transform2D)
126 
127 			/**/ TRY_TRANSFER_FIELD("xx", elements[0][0])
128 			else TRY_TRANSFER_FIELD("xy", elements[0][1])
129 			else TRY_TRANSFER_FIELD("yx", elements[1][0])
130 			else TRY_TRANSFER_FIELD("yy", elements[1][1])
131 			else TRY_TRANSFER_FIELD("ox", elements[2][0])
132 			else TRY_TRANSFER_FIELD("oy", elements[2][1])
133 
134 			return target;
135 		}
136 
137 		case Variant::BASIS: {
138 
139 			SETUP_TYPE(Basis)
140 
141 			/**/ TRY_TRANSFER_FIELD("xx", elements[0][0])
142 			else TRY_TRANSFER_FIELD("xy", elements[0][1])
143 			else TRY_TRANSFER_FIELD("xz", elements[0][2])
144 			else TRY_TRANSFER_FIELD("yx", elements[1][0])
145 			else TRY_TRANSFER_FIELD("yy", elements[1][1])
146 			else TRY_TRANSFER_FIELD("yz", elements[1][2])
147 			else TRY_TRANSFER_FIELD("zx", elements[2][0])
148 			else TRY_TRANSFER_FIELD("zy", elements[2][1])
149 			else TRY_TRANSFER_FIELD("zz", elements[2][2])
150 
151 			return target;
152 		}
153 
154 		case Variant::TRANSFORM: {
155 
156 			SETUP_TYPE(Transform)
157 
158 			/**/ TRY_TRANSFER_FIELD("xx", basis.elements[0][0])
159 			else TRY_TRANSFER_FIELD("xy", basis.elements[0][1])
160 			else TRY_TRANSFER_FIELD("xz", basis.elements[0][2])
161 			else TRY_TRANSFER_FIELD("yx", basis.elements[1][0])
162 			else TRY_TRANSFER_FIELD("yy", basis.elements[1][1])
163 			else TRY_TRANSFER_FIELD("yz", basis.elements[1][2])
164 			else TRY_TRANSFER_FIELD("zx", basis.elements[2][0])
165 			else TRY_TRANSFER_FIELD("zy", basis.elements[2][1])
166 			else TRY_TRANSFER_FIELD("zz", basis.elements[2][2])
167 			else TRY_TRANSFER_FIELD("xo", origin.x)
168 			else TRY_TRANSFER_FIELD("yo", origin.y)
169 			else TRY_TRANSFER_FIELD("zo", origin.z)
170 
171 			return target;
172 		}
173 
174 		default: {
175 			ERR_FAIL_V(p_target);
176 		}
177 	}
178 	/* clang-format on */
179 }
180 
181 #endif // TOOLS_ENABLED
182