1 /**
2 * Mandelbulber v2, a 3D fractal generator ,=#MKNmMMKmmßMNWy,
3 * ,B" ]L,,p%%%,,,§;, "K
4 * Copyright (C) 2016-20 Mandelbulber Team §R-==%w["'~5]m%=L.=~5N
5 * ,=mm=§M ]=4 yJKA"/-Nsaj "Bw,==,,
6 * This file is part of Mandelbulber. §R.r= jw",M Km .mM FW ",§=ß., ,TN
7 * ,4R =%["w[N=7]J '"5=],""]]M,w,-; T=]M
8 * Mandelbulber is free software: §R.ß~-Q/M=,=5"v"]=Qf,'§"M= =,M.§ Rz]M"Kw
9 * you can redistribute it and/or §w "xDY.J ' -"m=====WeC=\ ""%""y=%"]"" §
10 * modify it under the terms of the "§M=M =D=4"N #"%==A%p M§ M6 R' #"=~.4M
11 * GNU General Public License as §W =, ][T"]C § § '§ e===~ U !§[Z ]N
12 * published by the 4M",,Jm=,"=e~ § § j]]""N BmM"py=ßM
13 * Free Software Foundation, ]§ T,M=& 'YmMMpM9MMM%=w=,,=MT]M m§;'§,
14 * either version 3 of the License, TWw [.j"5=~N[=§%=%W,T ]R,"=="Y[LFT ]N
15 * or (at your option) TW=,-#"%=;[ =Q:["V"" ],,M.m == ]N
16 * any later version. J§"mr"] ,=,," =="""J]= M"M"]==ß"
17 * §= "=C=4 §"eM "=B:m|4"]#F,§~
18 * Mandelbulber is distributed in "9w=,,]w em%wJ '"~" ,=,,ß"
19 * the hope that it will be useful, . "K= ,=RMMMßM"""
20 * but WITHOUT ANY WARRANTY; .'''
21 * without even the implied warranty
22 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 *
24 * See the GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with Mandelbulber. If not, see <http://www.gnu.org/licenses/>.
27 *
28 * ###########################################################################
29 *
30 * Authors: Krzysztof Marczak (buddhi1980@gmail.com)
31 *
32 * global method TextureMapping() - coordinate transformer for textures
33 *
34 * For the given parameters TextureMapping(...) determines the point x-y
35 * on the texture to use for processing
36 */
37
38 #include "texture_mapping.hpp"
39
40 #include "material.h"
41 #include "object_data.hpp"
42 #include "texture_enums.hpp"
43
TextureMapping(CVector3 inPoint,CVector3 normalVector,const cObjectData & objectData,const cMaterial * material,CVector3 * textureVectorX,CVector3 * textureVectorY)44 CVector2<float> TextureMapping(CVector3 inPoint, CVector3 normalVector,
45 const cObjectData &objectData, const cMaterial *material, CVector3 *textureVectorX,
46 CVector3 *textureVectorY)
47 {
48 CVector2<float> textureCoordinates;
49 CVector3 point = inPoint;
50 if (!material->textureFractalize)
51 {
52 point = point - objectData.position;
53 point = objectData.rotationMatrix.RotateVector(point);
54 point = point.mod(objectData.repeat);
55 point /= objectData.size;
56 }
57 point = material->rotMatrix.RotateVector(point);
58
59 normalVector = objectData.rotationMatrix.RotateVector(normalVector);
60
61 switch (material->textureMappingType)
62 {
63 case texture::mappingPlanar:
64 {
65 textureCoordinates = CVector2<float>(point.x, point.y);
66 textureCoordinates.x /= -material->textureScale.x;
67 textureCoordinates.y /= material->textureScale.y;
68 textureCoordinates.x -= material->textureCenter.x;
69 textureCoordinates.y -= material->textureCenter.y;
70
71 if (textureVectorX && textureVectorY)
72 {
73 CVector3 texX(1.0, 0.0, 0.0);
74 texX = objectData.rotationMatrix.Transpose().RotateVector(texX);
75 texX = material->rotMatrix.Transpose().RotateVector(texX);
76 *textureVectorX = texX;
77
78 CVector3 texY(0.0, -1.0, 0.0);
79 texY = objectData.rotationMatrix.Transpose().RotateVector(texY);
80 texY = material->rotMatrix.Transpose().RotateVector(texY);
81 *textureVectorY = texY;
82 }
83 break;
84 }
85 case texture::mappingCylindrical:
86 {
87 double alphaTexture = fmod(point.GetAlpha() + 2.0 * M_PI, 2.0 * M_PI);
88 textureCoordinates.x = alphaTexture / (2.0 * M_PI);
89 textureCoordinates.y = -point.z;
90 textureCoordinates.x /= material->textureScale.x;
91 textureCoordinates.y /= material->textureScale.y;
92 textureCoordinates.x -= material->textureCenter.x;
93 textureCoordinates.y -= material->textureCenter.y;
94
95 if (textureVectorX && textureVectorY)
96 {
97 CVector3 texY(0.0, 0.0, 1.0);
98 CVector3 texX = point.Cross(texY);
99 texX = objectData.rotationMatrix.Transpose().RotateVector(texX);
100 texX = material->rotMatrix.Transpose().RotateVector(texX);
101 *textureVectorX = texX;
102 texY = objectData.rotationMatrix.Transpose().RotateVector(texY);
103 texY = material->rotMatrix.Transpose().RotateVector(texY);
104 *textureVectorY = texY;
105 }
106
107 break;
108 }
109 case texture::mappingSpherical:
110 {
111 double alphaTexture = fmod(point.GetAlpha() + 2.0 * M_PI, 2.0 * M_PI);
112 double betaTexture = -point.GetBeta();
113 textureCoordinates.x = alphaTexture / (2.0 * M_PI);
114 textureCoordinates.y = betaTexture / M_PI;
115 textureCoordinates.x /= material->textureScale.x;
116 textureCoordinates.y /= material->textureScale.y;
117 textureCoordinates.x -= material->textureCenter.x;
118 textureCoordinates.y -= material->textureCenter.y;
119
120 if (textureVectorX && textureVectorY)
121 {
122 CVector3 texY(0.0, 0.0, -1.0);
123 CVector3 texX = texY.Cross(point);
124 texX.Normalize();
125 texY = texX.Cross(point);
126
127 texX = objectData.rotationMatrix.Transpose().RotateVector(texX);
128 texX = material->rotMatrix.Transpose().RotateVector(texX);
129 *textureVectorX = texX;
130 texY = objectData.rotationMatrix.Transpose().RotateVector(texY);
131 texY = material->rotMatrix.Transpose().RotateVector(texY);
132 *textureVectorY = texY;
133 }
134
135 break;
136 }
137 case texture::mappingCubic:
138 {
139 point /= material->textureScale;
140 point -= material->textureCenter;
141
142 CVector3 texX;
143 CVector3 texY;
144
145 if (fabs(normalVector.x) > fabs(normalVector.y))
146 {
147 if (fabs(normalVector.x) > fabs(normalVector.z))
148 {
149 // x
150 if (normalVector.x > 0)
151 textureCoordinates = CVector2<float>(point.y, -point.z);
152 else
153 textureCoordinates = CVector2<float>(-point.y, -point.z);
154
155 if (textureVectorX && textureVectorY)
156 {
157 if (normalVector.x > 0)
158 {
159 texX = CVector3(0.0, -1.0, 0.0);
160 texY = CVector3(0.0, 0.0, 1.0);
161 }
162 else
163 {
164 texX = CVector3(0.0, 1.0, 0.0);
165 texY = CVector3(0.0, 0.0, 1.0);
166 }
167 }
168 }
169 else
170 {
171 // z
172 if (normalVector.z > 0)
173 textureCoordinates = CVector2<float>(-point.x, point.y);
174 else
175 textureCoordinates = CVector2<float>(point.x, point.y);
176
177 if (textureVectorX && textureVectorY)
178 {
179 if (normalVector.z > 0)
180 {
181 texX = CVector3(1.0, 0.0, 0.0);
182 texY = CVector3(0.0, -1.0, 0.0);
183 }
184 else
185 {
186 texX = CVector3(-1.0, 0.0, 0.0);
187 texY = CVector3(0.0, -1.0, 0.0);
188 }
189 }
190 }
191 }
192 else
193 {
194 if (fabs(normalVector.y) > fabs(normalVector.z))
195 {
196 // y
197 if (normalVector.y > 0)
198 textureCoordinates = CVector2<float>(-point.x, -point.z);
199 else
200 textureCoordinates = CVector2<float>(point.x, -point.z);
201
202 if (textureVectorX && textureVectorY)
203 {
204 if (normalVector.y > 0)
205 {
206 texX = CVector3(1.0, 0.0, 0.0);
207 texY = CVector3(0.0, 0.0, 1.0);
208 }
209 else
210 {
211 texX = CVector3(-1.0, 0.0, 0.0);
212 texY = CVector3(0.0, 0.0, 1.0);
213 }
214 }
215 }
216 else
217 {
218 // z
219 if (normalVector.z > 0)
220 textureCoordinates = CVector2<float>(-point.x, point.y);
221 else
222 textureCoordinates = CVector2<float>(point.x, point.y);
223
224 if (textureVectorX && textureVectorY)
225 {
226 if (normalVector.z > 0)
227 {
228 texX = CVector3(1.0, 0.0, 0.0);
229 texY = CVector3(0.0, -1.0, 0.0);
230 }
231 else
232 {
233 texX = CVector3(-1.0, 0.0, 0.0);
234 texY = CVector3(0.0, -1.0, 0.0);
235 }
236 }
237 }
238 }
239
240 if (textureVectorX && textureVectorY)
241 {
242 texX = objectData.rotationMatrix.Transpose().RotateVector(texX);
243 texX = material->rotMatrix.Transpose().RotateVector(texX);
244 *textureVectorX = texX;
245 texY = objectData.rotationMatrix.Transpose().RotateVector(texY);
246 texY = material->rotMatrix.Transpose().RotateVector(texY);
247 *textureVectorY = texY;
248 }
249
250 break;
251 }
252 }
253 return textureCoordinates;
254 }
255