- fbx: texture conversion & UV channel mapping.
parent
a0c45f9190
commit
c7ee6fd70f
|
@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "FBXDocument.h"
|
#include "FBXDocument.h"
|
||||||
#include "FBXUtil.h"
|
#include "FBXUtil.h"
|
||||||
#include "FBXProperties.h"
|
#include "FBXProperties.h"
|
||||||
|
#include "FBXImporter.h"
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
namespace FBX {
|
namespace FBX {
|
||||||
|
@ -125,6 +126,8 @@ private:
|
||||||
aiMesh* out_mesh = new aiMesh();
|
aiMesh* out_mesh = new aiMesh();
|
||||||
meshes.push_back(out_mesh);
|
meshes.push_back(out_mesh);
|
||||||
|
|
||||||
|
sourceMeshes.push_back(&mesh);
|
||||||
|
|
||||||
// copy vertices
|
// copy vertices
|
||||||
out_mesh->mNumVertices = static_cast<size_t>(vertices.size());
|
out_mesh->mNumVertices = static_cast<size_t>(vertices.size());
|
||||||
out_mesh->mVertices = new aiVector3D[vertices.size()];
|
out_mesh->mVertices = new aiVector3D[vertices.size()];
|
||||||
|
@ -245,10 +248,115 @@ private:
|
||||||
str.Set(material.Name());
|
str.Set(material.Name());
|
||||||
out_mat->AddProperty(&str,AI_MATKEY_NAME);
|
out_mat->AddProperty(&str,AI_MATKEY_NAME);
|
||||||
|
|
||||||
|
// shading stuff and colors
|
||||||
SetShadingPropertiesCommon(out_mat,props);
|
SetShadingPropertiesCommon(out_mat,props);
|
||||||
|
|
||||||
|
// texture assignments
|
||||||
|
SetTextureProperties(out_mat,material.Textures());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures, const std::string& propName, aiTextureType target)
|
||||||
|
{
|
||||||
|
TextureMap::const_iterator it = textures.find(propName);
|
||||||
|
if(it == textures.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Texture* const tex = (*it).second;
|
||||||
|
|
||||||
|
aiString path;
|
||||||
|
path.Set(tex->RelativeFilename());
|
||||||
|
|
||||||
|
out_mat->AddProperty(&path,_AI_MATKEY_TEXTURE_BASE,target,0);
|
||||||
|
|
||||||
|
aiUVTransform uvTrafo;
|
||||||
|
// XXX handle all kinds of UV transformations
|
||||||
|
uvTrafo.mScaling = tex->UVScaling();
|
||||||
|
uvTrafo.mTranslation = tex->UVTranslation();
|
||||||
|
out_mat->AddProperty(&uvTrafo,1,_AI_MATKEY_UVTRANSFORM_BASE,target,0);
|
||||||
|
|
||||||
|
const PropertyTable& props = tex->Props();
|
||||||
|
|
||||||
|
int uvIndex = 0;
|
||||||
|
|
||||||
|
bool ok;
|
||||||
|
const std::string& uvSet = PropertyGet<std::string>(props,"UVSet",ok);
|
||||||
|
if(ok) {
|
||||||
|
// "default" is the name which usually appears in the FbxFileTexture template
|
||||||
|
if(uvSet != "default" && uvSet.length()) {
|
||||||
|
// this is a bit awkward - we need to find a mesh that uses this
|
||||||
|
// material and scan its UV channels for the given UV name because
|
||||||
|
// assimp references UV channels by index, not by name.
|
||||||
|
|
||||||
|
// XXX: the case that UV channels may appear in different orders
|
||||||
|
// in meshes is unhandled. A possible solution would be to sort
|
||||||
|
// the UV channels alphabetically, but this would have the side
|
||||||
|
// effect that the primary (first) UV channel would sometimes
|
||||||
|
// be moved, causing trouble when users read only the first
|
||||||
|
// UV channel and ignore UV channel assignments altogether.
|
||||||
|
|
||||||
|
const unsigned int matIndex = std::distance(materials.begin(),
|
||||||
|
std::find(materials.begin(),materials.end(),out_mat)
|
||||||
|
);
|
||||||
|
|
||||||
|
uvIndex = -1;
|
||||||
|
BOOST_FOREACH(const MeshGeometry* mesh,sourceMeshes) {
|
||||||
|
ai_assert(mesh);
|
||||||
|
|
||||||
|
const std::vector<unsigned int>& mats = mesh->GetMaterialIndices();
|
||||||
|
if(std::find(mats.begin(),mats.end(),matIndex) == mats.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int index = -1;
|
||||||
|
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
||||||
|
if(mesh->GetTextureCoords(i).empty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const std::string& name = mesh->GetTextureCoordChannelName(i);
|
||||||
|
if(name == uvSet) {
|
||||||
|
index = static_cast<int>(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(index == -1) {
|
||||||
|
FBXImporter::LogWarn("did not found UV channel named " + uvSet + " in a mesh using this material");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(uvIndex == -1) {
|
||||||
|
uvIndex = index;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
FBXImporter::LogWarn("the UV channel named " + uvSet +
|
||||||
|
" appears at different positions in meshes, results will be wrong");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out_mat->AddProperty(&uvIndex,1,_AI_MATKEY_UVWSRC_BASE,target,0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
void SetTextureProperties(aiMaterial* out_mat, const TextureMap& textures)
|
||||||
|
{
|
||||||
|
TrySetTextureProperties(out_mat, textures, "DiffuseColor", aiTextureType_DIFFUSE);
|
||||||
|
TrySetTextureProperties(out_mat, textures, "AmbientColor", aiTextureType_AMBIENT);
|
||||||
|
TrySetTextureProperties(out_mat, textures, "EmissiveColor", aiTextureType_EMISSIVE);
|
||||||
|
TrySetTextureProperties(out_mat, textures, "SpecularColor", aiTextureType_SPECULAR);
|
||||||
|
TrySetTextureProperties(out_mat, textures, "TransparentColor", aiTextureType_OPACITY);
|
||||||
|
TrySetTextureProperties(out_mat, textures, "ReflectionColor", aiTextureType_REFLECTION);
|
||||||
|
TrySetTextureProperties(out_mat, textures, "DisplacementColor", aiTextureType_DISPLACEMENT);
|
||||||
|
TrySetTextureProperties(out_mat, textures, "NormalMap", aiTextureType_NORMALS);
|
||||||
|
TrySetTextureProperties(out_mat, textures, "Bump", aiTextureType_HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
aiColor3D GetColorPropertyFromMaterial(const PropertyTable& props,const std::string& baseName, bool& result)
|
aiColor3D GetColorPropertyFromMaterial(const PropertyTable& props,const std::string& baseName, bool& result)
|
||||||
{
|
{
|
||||||
|
@ -355,6 +463,8 @@ private:
|
||||||
std::vector<aiMesh*> meshes;
|
std::vector<aiMesh*> meshes;
|
||||||
std::vector<aiMaterial*> materials;
|
std::vector<aiMaterial*> materials;
|
||||||
|
|
||||||
|
std::vector<const MeshGeometry*> sourceMeshes;
|
||||||
|
|
||||||
aiScene* const out;
|
aiScene* const out;
|
||||||
const FBX::Document& doc;
|
const FBX::Document& doc;
|
||||||
};
|
};
|
||||||
|
|
|
@ -282,6 +282,13 @@ public:
|
||||||
return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : uvs[index];
|
return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? empty : uvs[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Get a UV coordinate slot, returns an empty array if
|
||||||
|
* the requested slot does not exist. */
|
||||||
|
std::string GetTextureCoordChannelName(unsigned int index) const {
|
||||||
|
return index >= AI_MAX_NUMBER_OF_TEXTURECOORDS ? "" : uvNames[index];
|
||||||
|
}
|
||||||
|
|
||||||
/** Get a vertex color coordinate slot, returns an empty array if
|
/** Get a vertex color coordinate slot, returns an empty array if
|
||||||
* the requested slot does not exist. */
|
* the requested slot does not exist. */
|
||||||
const std::vector<aiColor4D>& GetVertexColors(unsigned int index) const {
|
const std::vector<aiColor4D>& GetVertexColors(unsigned int index) const {
|
||||||
|
@ -336,6 +343,8 @@ private:
|
||||||
std::vector<aiVector3D> tangents;
|
std::vector<aiVector3D> tangents;
|
||||||
std::vector<aiVector3D> binormals;
|
std::vector<aiVector3D> binormals;
|
||||||
std::vector<aiVector3D> normals;
|
std::vector<aiVector3D> normals;
|
||||||
|
|
||||||
|
std::string uvNames[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
||||||
std::vector<aiVector2D> uvs[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
std::vector<aiVector2D> uvs[AI_MAX_NUMBER_OF_TEXTURECOORDS];
|
||||||
std::vector<aiColor4D> colors[AI_MAX_NUMBER_OF_COLOR_SETS];
|
std::vector<aiColor4D> colors[AI_MAX_NUMBER_OF_COLOR_SETS];
|
||||||
|
|
||||||
|
|
|
@ -221,6 +221,12 @@ void MeshGeometry::ReadVertexData(const std::string& type, int index, const Scop
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Element* Name = source["Name"];
|
||||||
|
uvNames[index] = "";
|
||||||
|
if(Name) {
|
||||||
|
uvNames[index] = ParseTokenAsString(GetRequiredToken(*Name,0));
|
||||||
|
}
|
||||||
|
|
||||||
ReadVertexDataUV(uvs[index],source,
|
ReadVertexDataUV(uvs[index],source,
|
||||||
MappingInformationType,
|
MappingInformationType,
|
||||||
ReferenceInformationType
|
ReferenceInformationType
|
||||||
|
|
Loading…
Reference in New Issue