MCPcopy Create free account
hub / github.com/assimp/assimp / ComputeSphereMapping

Method ComputeSphereMapping

code/PostProcessing/ComputeUVMappingProcess.cpp:152–211  ·  view source on GitHub ↗

------------------------------------------------------------------------------------------------

Source from the content-addressed store, hash-verified

150
151// ------------------------------------------------------------------------------------------------
152void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh *mesh, const aiVector3D &axis, aiVector3D *out) {
153 aiVector3D center, min, max;
154 FindMeshCenter(mesh, center, min, max);
155
156 // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ...
157 // currently the mapping axis will always be one of x,y,z, except if the
158 // PretransformVertices step is used (it transforms the meshes into worldspace,
159 // thus changing the mapping axis)
160 if (axis * base_axis_x >= angle_epsilon) {
161
162 // For each point get a normalized projection vector in the sphere,
163 // get its longitude and latitude and map them to their respective
164 // UV axes. Problems occur around the poles ... unsolvable.
165 //
166 // The spherical coordinate system looks like this:
167 // x = cos(lon)*cos(lat)
168 // y = sin(lon)*cos(lat)
169 // z = sin(lat)
170 //
171 // Thus we can derive:
172 // lat = arcsin (z)
173 // lon = arctan (y/x)
174 for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
175 const aiVector3D diff = (mesh->mVertices[pnt] - center).Normalize();
176 out[pnt] = aiVector3D((std::atan2(diff.z, diff.y) + AI_MATH_PI_F) / AI_MATH_TWO_PI_F,
177 (std::asin(diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
178 }
179 } else if (axis * base_axis_y >= angle_epsilon) {
180 // ... just the same again
181 for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
182 const aiVector3D diff = (mesh->mVertices[pnt] - center).Normalize();
183 out[pnt] = aiVector3D((std::atan2(diff.x, diff.z) + AI_MATH_PI_F) / AI_MATH_TWO_PI_F,
184 (std::asin(diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
185 }
186 } else if (axis * base_axis_z >= angle_epsilon) {
187 // ... just the same again
188 for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
189 const aiVector3D diff = (mesh->mVertices[pnt] - center).Normalize();
190 out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F) / AI_MATH_TWO_PI_F,
191 (std::asin(diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
192 }
193 }
194 // slower code path in case the mapping axis is not one of the coordinate system axes
195 else {
196 aiMatrix4x4 mTrafo;
197 aiMatrix4x4::FromToMatrix(axis, base_axis_y, mTrafo);
198
199 // again the same, except we're applying a transformation now
200 for (unsigned int pnt = 0; pnt < mesh->mNumVertices; ++pnt) {
201 const aiVector3D diff = ((mTrafo * mesh->mVertices[pnt]) - center).Normalize();
202 out[pnt] = aiVector3D((std::atan2(diff.y, diff.x) + AI_MATH_PI_F) / AI_MATH_TWO_PI_F,
203 (std::asin(diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.0);
204 }
205 }
206
207 // Now find and remove UV seams. A seam occurs if a face has a tcoord
208 // close to zero on the one side, and a tcoord close to one on the
209 // other side.

Callers

nothing calls this directly

Calls 4

FindMeshCenterFunction · 0.85
aiVector3DClass · 0.85
RemoveUVSeamsFunction · 0.85
NormalizeMethod · 0.45

Tested by

no test coverage detected