vrshoot
diff libs/assimp/ComputeUVMappingProcess.cpp @ 0:b2f14e535253
initial commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 01 Feb 2014 19:58:19 +0200 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/libs/assimp/ComputeUVMappingProcess.cpp Sat Feb 01 19:58:19 2014 +0200 1.3 @@ -0,0 +1,504 @@ 1.4 +/* 1.5 +Open Asset Import Library (assimp) 1.6 +---------------------------------------------------------------------- 1.7 + 1.8 +Copyright (c) 2006-2012, assimp team 1.9 +All rights reserved. 1.10 + 1.11 +Redistribution and use of this software in source and binary forms, 1.12 +with or without modification, are permitted provided that the 1.13 +following conditions are met: 1.14 + 1.15 +* Redistributions of source code must retain the above 1.16 + copyright notice, this list of conditions and the 1.17 + following disclaimer. 1.18 + 1.19 +* Redistributions in binary form must reproduce the above 1.20 + copyright notice, this list of conditions and the 1.21 + following disclaimer in the documentation and/or other 1.22 + materials provided with the distribution. 1.23 + 1.24 +* Neither the name of the assimp team, nor the names of its 1.25 + contributors may be used to endorse or promote products 1.26 + derived from this software without specific prior 1.27 + written permission of the assimp team. 1.28 + 1.29 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1.30 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1.31 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 1.32 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 1.33 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 1.34 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 1.35 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 1.36 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 1.37 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 1.38 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 1.39 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 1.40 + 1.41 +---------------------------------------------------------------------- 1.42 +*/ 1.43 + 1.44 +/** @file GenUVCoords step */ 1.45 + 1.46 + 1.47 +#include "AssimpPCH.h" 1.48 +#include "ComputeUVMappingProcess.h" 1.49 +#include "ProcessHelper.h" 1.50 + 1.51 +using namespace Assimp; 1.52 + 1.53 +namespace { 1.54 + 1.55 + const static aiVector3D base_axis_y(0.f,1.f,0.f); 1.56 + const static aiVector3D base_axis_x(1.f,0.f,0.f); 1.57 + const static aiVector3D base_axis_z(0.f,0.f,1.f); 1.58 + const static float angle_epsilon = 0.95f; 1.59 +} 1.60 + 1.61 +// ------------------------------------------------------------------------------------------------ 1.62 +// Constructor to be privately used by Importer 1.63 +ComputeUVMappingProcess::ComputeUVMappingProcess() 1.64 +{ 1.65 + // nothing to do here 1.66 +} 1.67 + 1.68 +// ------------------------------------------------------------------------------------------------ 1.69 +// Destructor, private as well 1.70 +ComputeUVMappingProcess::~ComputeUVMappingProcess() 1.71 +{ 1.72 + // nothing to do here 1.73 +} 1.74 + 1.75 +// ------------------------------------------------------------------------------------------------ 1.76 +// Returns whether the processing step is present in the given flag field. 1.77 +bool ComputeUVMappingProcess::IsActive( unsigned int pFlags) const 1.78 +{ 1.79 + return (pFlags & aiProcess_GenUVCoords) != 0; 1.80 +} 1.81 + 1.82 +// ------------------------------------------------------------------------------------------------ 1.83 +// Check whether a ray intersects a plane and find the intersection point 1.84 +inline bool PlaneIntersect(const aiRay& ray, const aiVector3D& planePos, 1.85 + const aiVector3D& planeNormal, aiVector3D& pos) 1.86 +{ 1.87 + const float b = planeNormal * (planePos - ray.pos); 1.88 + float h = ray.dir * planeNormal; 1.89 + if ((h < 10e-5f && h > -10e-5f) || (h = b/h) < 0) 1.90 + return false; 1.91 + 1.92 + pos = ray.pos + (ray.dir * h); 1.93 + return true; 1.94 +} 1.95 + 1.96 +// ------------------------------------------------------------------------------------------------ 1.97 +// Find the first empty UV channel in a mesh 1.98 +inline unsigned int FindEmptyUVChannel (aiMesh* mesh) 1.99 +{ 1.100 + for (unsigned int m = 0; m < AI_MAX_NUMBER_OF_TEXTURECOORDS;++m) 1.101 + if (!mesh->mTextureCoords[m])return m; 1.102 + 1.103 + DefaultLogger::get()->error("Unable to compute UV coordinates, no free UV slot found"); 1.104 + return UINT_MAX; 1.105 +} 1.106 + 1.107 +// ------------------------------------------------------------------------------------------------ 1.108 +// Try to remove UV seams 1.109 +void RemoveUVSeams (aiMesh* mesh, aiVector3D* out) 1.110 +{ 1.111 + // TODO: just a very rough algorithm. I think it could be done 1.112 + // much easier, but I don't know how and am currently too tired to 1.113 + // to think about a better solution. 1.114 + 1.115 + const static float LOWER_LIMIT = 0.1f; 1.116 + const static float UPPER_LIMIT = 0.9f; 1.117 + 1.118 + const static float LOWER_EPSILON = 10e-3f; 1.119 + const static float UPPER_EPSILON = 1.f-10e-3f; 1.120 + 1.121 + for (unsigned int fidx = 0; fidx < mesh->mNumFaces;++fidx) 1.122 + { 1.123 + const aiFace& face = mesh->mFaces[fidx]; 1.124 + if (face.mNumIndices < 3) continue; // triangles and polygons only, please 1.125 + 1.126 + unsigned int small = face.mNumIndices, large = small; 1.127 + bool zero = false, one = false, round_to_zero = false; 1.128 + 1.129 + // Check whether this face lies on a UV seam. We can just guess, 1.130 + // but the assumption that a face with at least one very small 1.131 + // on the one side and one very large U coord on the other side 1.132 + // lies on a UV seam should work for most cases. 1.133 + for (unsigned int n = 0; n < face.mNumIndices;++n) 1.134 + { 1.135 + if (out[face.mIndices[n]].x < LOWER_LIMIT) 1.136 + { 1.137 + small = n; 1.138 + 1.139 + // If we have a U value very close to 0 we can't 1.140 + // round the others to 0, too. 1.141 + if (out[face.mIndices[n]].x <= LOWER_EPSILON) 1.142 + zero = true; 1.143 + else round_to_zero = true; 1.144 + } 1.145 + if (out[face.mIndices[n]].x > UPPER_LIMIT) 1.146 + { 1.147 + large = n; 1.148 + 1.149 + // If we have a U value very close to 1 we can't 1.150 + // round the others to 1, too. 1.151 + if (out[face.mIndices[n]].x >= UPPER_EPSILON) 1.152 + one = true; 1.153 + } 1.154 + } 1.155 + if (small != face.mNumIndices && large != face.mNumIndices) 1.156 + { 1.157 + for (unsigned int n = 0; n < face.mNumIndices;++n) 1.158 + { 1.159 + // If the u value is over the upper limit and no other u 1.160 + // value of that face is 0, round it to 0 1.161 + if (out[face.mIndices[n]].x > UPPER_LIMIT && !zero) 1.162 + out[face.mIndices[n]].x = 0.f; 1.163 + 1.164 + // If the u value is below the lower limit and no other u 1.165 + // value of that face is 1, round it to 1 1.166 + else if (out[face.mIndices[n]].x < LOWER_LIMIT && !one) 1.167 + out[face.mIndices[n]].x = 1.f; 1.168 + 1.169 + // The face contains both 0 and 1 as UV coords. This can occur 1.170 + // for faces which have an edge that lies directly on the seam. 1.171 + // Due to numerical inaccuracies one U coord becomes 0, the 1.172 + // other 1. But we do still have a third UV coord to determine 1.173 + // to which side we must round to. 1.174 + else if (one && zero) 1.175 + { 1.176 + if (round_to_zero && out[face.mIndices[n]].x >= UPPER_EPSILON) 1.177 + out[face.mIndices[n]].x = 0.f; 1.178 + else if (!round_to_zero && out[face.mIndices[n]].x <= LOWER_EPSILON) 1.179 + out[face.mIndices[n]].x = 1.f; 1.180 + } 1.181 + } 1.182 + } 1.183 + } 1.184 +} 1.185 + 1.186 +// ------------------------------------------------------------------------------------------------ 1.187 +void ComputeUVMappingProcess::ComputeSphereMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out) 1.188 +{ 1.189 + aiVector3D center, min, max; 1.190 + FindMeshCenter(mesh, center, min, max); 1.191 + 1.192 + // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ... 1.193 + // currently the mapping axis will always be one of x,y,z, except if the 1.194 + // PretransformVertices step is used (it transforms the meshes into worldspace, 1.195 + // thus changing the mapping axis) 1.196 + if (axis * base_axis_x >= angle_epsilon) { 1.197 + 1.198 + // For each point get a normalized projection vector in the sphere, 1.199 + // get its longitude and latitude and map them to their respective 1.200 + // UV axes. Problems occur around the poles ... unsolvable. 1.201 + // 1.202 + // The spherical coordinate system looks like this: 1.203 + // x = cos(lon)*cos(lat) 1.204 + // y = sin(lon)*cos(lat) 1.205 + // z = sin(lat) 1.206 + // 1.207 + // Thus we can derive: 1.208 + // lat = arcsin (z) 1.209 + // lon = arctan (y/x) 1.210 + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { 1.211 + const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize(); 1.212 + out[pnt] = aiVector3D((atan2 (diff.z, diff.y) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F, 1.213 + (asin (diff.x) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f); 1.214 + } 1.215 + } 1.216 + else if (axis * base_axis_y >= angle_epsilon) { 1.217 + // ... just the same again 1.218 + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { 1.219 + const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize(); 1.220 + out[pnt] = aiVector3D((atan2 (diff.x, diff.z) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F, 1.221 + (asin (diff.y) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f); 1.222 + } 1.223 + } 1.224 + else if (axis * base_axis_z >= angle_epsilon) { 1.225 + // ... just the same again 1.226 + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { 1.227 + const aiVector3D diff = (mesh->mVertices[pnt]-center).Normalize(); 1.228 + out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F, 1.229 + (asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f); 1.230 + } 1.231 + } 1.232 + // slower code path in case the mapping axis is not one of the coordinate system axes 1.233 + else { 1.234 + aiMatrix4x4 mTrafo; 1.235 + aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo); 1.236 + 1.237 + // again the same, except we're applying a transformation now 1.238 + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { 1.239 + const aiVector3D diff = ((mTrafo*mesh->mVertices[pnt])-center).Normalize(); 1.240 + out[pnt] = aiVector3D((atan2 (diff.y, diff.x) + AI_MATH_PI_F ) / AI_MATH_TWO_PI_F, 1.241 + (asin (diff.z) + AI_MATH_HALF_PI_F) / AI_MATH_PI_F, 0.f); 1.242 + } 1.243 + } 1.244 + 1.245 + 1.246 + // Now find and remove UV seams. A seam occurs if a face has a tcoord 1.247 + // close to zero on the one side, and a tcoord close to one on the 1.248 + // other side. 1.249 + RemoveUVSeams(mesh,out); 1.250 +} 1.251 + 1.252 +// ------------------------------------------------------------------------------------------------ 1.253 +void ComputeUVMappingProcess::ComputeCylinderMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out) 1.254 +{ 1.255 + aiVector3D center, min, max; 1.256 + 1.257 + // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ... 1.258 + // currently the mapping axis will always be one of x,y,z, except if the 1.259 + // PretransformVertices step is used (it transforms the meshes into worldspace, 1.260 + // thus changing the mapping axis) 1.261 + if (axis * base_axis_x >= angle_epsilon) { 1.262 + FindMeshCenter(mesh, center, min, max); 1.263 + const float diff = max.x - min.x; 1.264 + 1.265 + // If the main axis is 'z', the z coordinate of a point 'p' is mapped 1.266 + // directly to the texture V axis. The other axis is derived from 1.267 + // the angle between ( p.x - c.x, p.y - c.y ) and (1,0), where 1.268 + // 'c' is the center point of the mesh. 1.269 + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { 1.270 + const aiVector3D& pos = mesh->mVertices[pnt]; 1.271 + aiVector3D& uv = out[pnt]; 1.272 + 1.273 + uv.y = (pos.x - min.x) / diff; 1.274 + uv.x = (atan2 ( pos.z - center.z, pos.y - center.y) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI; 1.275 + } 1.276 + } 1.277 + else if (axis * base_axis_y >= angle_epsilon) { 1.278 + FindMeshCenter(mesh, center, min, max); 1.279 + const float diff = max.y - min.y; 1.280 + 1.281 + // just the same ... 1.282 + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { 1.283 + const aiVector3D& pos = mesh->mVertices[pnt]; 1.284 + aiVector3D& uv = out[pnt]; 1.285 + 1.286 + uv.y = (pos.y - min.y) / diff; 1.287 + uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI; 1.288 + } 1.289 + } 1.290 + else if (axis * base_axis_z >= angle_epsilon) { 1.291 + FindMeshCenter(mesh, center, min, max); 1.292 + const float diff = max.z - min.z; 1.293 + 1.294 + // just the same ... 1.295 + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { 1.296 + const aiVector3D& pos = mesh->mVertices[pnt]; 1.297 + aiVector3D& uv = out[pnt]; 1.298 + 1.299 + uv.y = (pos.z - min.z) / diff; 1.300 + uv.x = (atan2 ( pos.y - center.y, pos.x - center.x) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI; 1.301 + } 1.302 + } 1.303 + // slower code path in case the mapping axis is not one of the coordinate system axes 1.304 + else { 1.305 + aiMatrix4x4 mTrafo; 1.306 + aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo); 1.307 + FindMeshCenterTransformed(mesh, center, min, max,mTrafo); 1.308 + const float diff = max.y - min.y; 1.309 + 1.310 + // again the same, except we're applying a transformation now 1.311 + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt){ 1.312 + const aiVector3D pos = mTrafo* mesh->mVertices[pnt]; 1.313 + aiVector3D& uv = out[pnt]; 1.314 + 1.315 + uv.y = (pos.y - min.y) / diff; 1.316 + uv.x = (atan2 ( pos.x - center.x, pos.z - center.z) +(float)AI_MATH_PI ) / (float)AI_MATH_TWO_PI; 1.317 + } 1.318 + } 1.319 + 1.320 + // Now find and remove UV seams. A seam occurs if a face has a tcoord 1.321 + // close to zero on the one side, and a tcoord close to one on the 1.322 + // other side. 1.323 + RemoveUVSeams(mesh,out); 1.324 +} 1.325 + 1.326 +// ------------------------------------------------------------------------------------------------ 1.327 +void ComputeUVMappingProcess::ComputePlaneMapping(aiMesh* mesh,const aiVector3D& axis, aiVector3D* out) 1.328 +{ 1.329 + float diffu,diffv; 1.330 + aiVector3D center, min, max; 1.331 + 1.332 + // If the axis is one of x,y,z run a faster code path. It's worth the extra effort ... 1.333 + // currently the mapping axis will always be one of x,y,z, except if the 1.334 + // PretransformVertices step is used (it transforms the meshes into worldspace, 1.335 + // thus changing the mapping axis) 1.336 + if (axis * base_axis_x >= angle_epsilon) { 1.337 + FindMeshCenter(mesh, center, min, max); 1.338 + diffu = max.z - min.z; 1.339 + diffv = max.y - min.y; 1.340 + 1.341 + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { 1.342 + const aiVector3D& pos = mesh->mVertices[pnt]; 1.343 + out[pnt].Set((pos.z - min.z) / diffu,(pos.y - min.y) / diffv,0.f); 1.344 + } 1.345 + } 1.346 + else if (axis * base_axis_y >= angle_epsilon) { 1.347 + FindMeshCenter(mesh, center, min, max); 1.348 + diffu = max.x - min.x; 1.349 + diffv = max.z - min.z; 1.350 + 1.351 + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { 1.352 + const aiVector3D& pos = mesh->mVertices[pnt]; 1.353 + out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.f); 1.354 + } 1.355 + } 1.356 + else if (axis * base_axis_z >= angle_epsilon) { 1.357 + FindMeshCenter(mesh, center, min, max); 1.358 + diffu = max.y - min.y; 1.359 + diffv = max.z - min.z; 1.360 + 1.361 + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { 1.362 + const aiVector3D& pos = mesh->mVertices[pnt]; 1.363 + out[pnt].Set((pos.y - min.y) / diffu,(pos.x - min.x) / diffv,0.f); 1.364 + } 1.365 + } 1.366 + // slower code path in case the mapping axis is not one of the coordinate system axes 1.367 + else 1.368 + { 1.369 + aiMatrix4x4 mTrafo; 1.370 + aiMatrix4x4::FromToMatrix(axis,base_axis_y,mTrafo); 1.371 + FindMeshCenterTransformed(mesh, center, min, max,mTrafo); 1.372 + diffu = max.x - min.x; 1.373 + diffv = max.z - min.z; 1.374 + 1.375 + // again the same, except we're applying a transformation now 1.376 + for (unsigned int pnt = 0; pnt < mesh->mNumVertices;++pnt) { 1.377 + const aiVector3D pos = mTrafo * mesh->mVertices[pnt]; 1.378 + out[pnt].Set((pos.x - min.x) / diffu,(pos.z - min.z) / diffv,0.f); 1.379 + } 1.380 + } 1.381 + 1.382 + // shouldn't be necessary to remove UV seams ... 1.383 +} 1.384 + 1.385 +// ------------------------------------------------------------------------------------------------ 1.386 +void ComputeUVMappingProcess::ComputeBoxMapping(aiMesh* /*mesh*/, aiVector3D* /*out*/) 1.387 +{ 1.388 + DefaultLogger::get()->error("Mapping type currently not implemented"); 1.389 +} 1.390 + 1.391 +// ------------------------------------------------------------------------------------------------ 1.392 +void ComputeUVMappingProcess::Execute( aiScene* pScene) 1.393 +{ 1.394 + DefaultLogger::get()->debug("GenUVCoordsProcess begin"); 1.395 + char buffer[1024]; 1.396 + 1.397 + if (pScene->mFlags & AI_SCENE_FLAGS_NON_VERBOSE_FORMAT) 1.398 + throw DeadlyImportError("Post-processing order mismatch: expecting pseudo-indexed (\"verbose\") vertices here"); 1.399 + 1.400 + std::list<MappingInfo> mappingStack; 1.401 + 1.402 + /* Iterate through all materials and search for non-UV mapped textures 1.403 + */ 1.404 + for (unsigned int i = 0; i < pScene->mNumMaterials;++i) 1.405 + { 1.406 + mappingStack.clear(); 1.407 + aiMaterial* mat = pScene->mMaterials[i]; 1.408 + for (unsigned int a = 0; a < mat->mNumProperties;++a) 1.409 + { 1.410 + aiMaterialProperty* prop = mat->mProperties[a]; 1.411 + if (!::strcmp( prop->mKey.data, "$tex.mapping")) 1.412 + { 1.413 + aiTextureMapping& mapping = *((aiTextureMapping*)prop->mData); 1.414 + if (aiTextureMapping_UV != mapping) 1.415 + { 1.416 + if (!DefaultLogger::isNullLogger()) 1.417 + { 1.418 + sprintf(buffer, "Found non-UV mapped texture (%s,%i). Mapping type: %s", 1.419 + TextureTypeToString((aiTextureType)prop->mSemantic),prop->mIndex, 1.420 + MappingTypeToString(mapping)); 1.421 + 1.422 + DefaultLogger::get()->info(buffer); 1.423 + } 1.424 + 1.425 + if (aiTextureMapping_OTHER == mapping) 1.426 + continue; 1.427 + 1.428 + MappingInfo info (mapping); 1.429 + 1.430 + // Get further properties - currently only the major axis 1.431 + for (unsigned int a2 = 0; a2 < mat->mNumProperties;++a2) 1.432 + { 1.433 + aiMaterialProperty* prop2 = mat->mProperties[a2]; 1.434 + if (prop2->mSemantic != prop->mSemantic || prop2->mIndex != prop->mIndex) 1.435 + continue; 1.436 + 1.437 + if ( !::strcmp( prop2->mKey.data, "$tex.mapaxis")) { 1.438 + info.axis = *((aiVector3D*)prop2->mData); 1.439 + break; 1.440 + } 1.441 + } 1.442 + 1.443 + unsigned int idx; 1.444 + 1.445 + // Check whether we have this mapping mode already 1.446 + std::list<MappingInfo>::iterator it = std::find (mappingStack.begin(),mappingStack.end(), info); 1.447 + if (mappingStack.end() != it) 1.448 + { 1.449 + idx = (*it).uv; 1.450 + } 1.451 + else 1.452 + { 1.453 + /* We have found a non-UV mapped texture. Now 1.454 + * we need to find all meshes using this material 1.455 + * that we can compute UV channels for them. 1.456 + */ 1.457 + for (unsigned int m = 0; m < pScene->mNumMeshes;++m) 1.458 + { 1.459 + aiMesh* mesh = pScene->mMeshes[m]; 1.460 + unsigned int outIdx; 1.461 + if ( mesh->mMaterialIndex != i || ( outIdx = FindEmptyUVChannel(mesh) ) == UINT_MAX || 1.462 + !mesh->mNumVertices) 1.463 + { 1.464 + continue; 1.465 + } 1.466 + 1.467 + // Allocate output storage 1.468 + aiVector3D* p = mesh->mTextureCoords[outIdx] = new aiVector3D[mesh->mNumVertices]; 1.469 + 1.470 + switch (mapping) 1.471 + { 1.472 + case aiTextureMapping_SPHERE: 1.473 + ComputeSphereMapping(mesh,info.axis,p); 1.474 + break; 1.475 + case aiTextureMapping_CYLINDER: 1.476 + ComputeCylinderMapping(mesh,info.axis,p); 1.477 + break; 1.478 + case aiTextureMapping_PLANE: 1.479 + ComputePlaneMapping(mesh,info.axis,p); 1.480 + break; 1.481 + case aiTextureMapping_BOX: 1.482 + ComputeBoxMapping(mesh,p); 1.483 + break; 1.484 + default: 1.485 + ai_assert(false); 1.486 + } 1.487 + if (m && idx != outIdx) 1.488 + { 1.489 + DefaultLogger::get()->warn("UV index mismatch. Not all meshes assigned to " 1.490 + "this material have equal numbers of UV channels. The UV index stored in " 1.491 + "the material structure does therefore not apply for all meshes. "); 1.492 + } 1.493 + idx = outIdx; 1.494 + } 1.495 + info.uv = idx; 1.496 + mappingStack.push_back(info); 1.497 + } 1.498 + 1.499 + // Update the material property list 1.500 + mapping = aiTextureMapping_UV; 1.501 + ((aiMaterial*)mat)->AddProperty(&idx,1,AI_MATKEY_UVWSRC(prop->mSemantic,prop->mIndex)); 1.502 + } 1.503 + } 1.504 + } 1.505 + } 1.506 + DefaultLogger::get()->debug("GenUVCoordsProcess finished"); 1.507 +}