|
@@ -1575,6 +1575,7 @@ namespace Assimp {
|
|
|
|
|
|
// shading stuff and colors
|
|
|
SetShadingPropertiesCommon(out_mat, props);
|
|
|
+ SetShadingPropertiesRaw( out_mat, props, material.Textures(), mesh );
|
|
|
|
|
|
// texture assignments
|
|
|
SetTextureProperties(out_mat, material.Textures(), mesh);
|
|
@@ -2073,6 +2074,180 @@ namespace Assimp {
|
|
|
const float DispFactor = PropertyGet<float>(props, "DisplacementFactor", ok);
|
|
|
if (ok) {
|
|
|
out_mat->AddProperty(&DispFactor, 1, "$mat.displacementscaling", 0, 0);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTable& props, const TextureMap& textures, const MeshGeometry* const mesh)
|
|
|
+{
|
|
|
+ // Add all the unparsed properties with a "$raw." prefix
|
|
|
+
|
|
|
+ const std::string prefix = "$raw.";
|
|
|
+
|
|
|
+ for (const DirectPropertyMap::value_type& prop : props.GetUnparsedProperties()) {
|
|
|
+
|
|
|
+ std::string name = prefix + prop.first;
|
|
|
+
|
|
|
+ if (const TypedProperty<aiVector3D>* interpreted = prop.second->As<TypedProperty<aiVector3D> >())
|
|
|
+ {
|
|
|
+ out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0);
|
|
|
+ }
|
|
|
+ else if (const TypedProperty<aiColor3D>* interpreted = prop.second->As<TypedProperty<aiColor3D> >())
|
|
|
+ {
|
|
|
+ out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0);
|
|
|
+ }
|
|
|
+ else if (const TypedProperty<aiColor4D>* interpreted = prop.second->As<TypedProperty<aiColor4D> >())
|
|
|
+ {
|
|
|
+ out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0);
|
|
|
+ }
|
|
|
+ else if (const TypedProperty<float>* interpreted = prop.second->As<TypedProperty<float> >())
|
|
|
+ {
|
|
|
+ out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0);
|
|
|
+ }
|
|
|
+ else if (const TypedProperty<int>* interpreted = prop.second->As<TypedProperty<int> >())
|
|
|
+ {
|
|
|
+ out_mat->AddProperty(&interpreted->Value(), 1, name.c_str(), 0, 0);
|
|
|
+ }
|
|
|
+ else if (const TypedProperty<bool>* interpreted = prop.second->As<TypedProperty<bool> >())
|
|
|
+ {
|
|
|
+ int value = interpreted->Value() ? 1 : 0;
|
|
|
+ out_mat->AddProperty(&value, 1, name.c_str(), 0, 0);
|
|
|
+ }
|
|
|
+ else if (const TypedProperty<std::string>* interpreted = prop.second->As<TypedProperty<std::string> >())
|
|
|
+ {
|
|
|
+ const aiString value = aiString(interpreted->Value());
|
|
|
+ out_mat->AddProperty(&value, name.c_str(), 0, 0);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Add the textures' properties
|
|
|
+
|
|
|
+ for (TextureMap::const_iterator it = textures.begin(); it != textures.end(); it++) {
|
|
|
+
|
|
|
+ std::string name = prefix + it->first;
|
|
|
+
|
|
|
+ const Texture* const tex = (*it).second;
|
|
|
+ if (tex != nullptr)
|
|
|
+ {
|
|
|
+ aiString path;
|
|
|
+ path.Set(tex->RelativeFilename());
|
|
|
+
|
|
|
+ const Video* media = tex->Media();
|
|
|
+ if (media != nullptr && media->ContentLength() > 0) {
|
|
|
+ unsigned int index;
|
|
|
+
|
|
|
+ VideoMap::const_iterator it = textures_converted.find(media);
|
|
|
+ if (it != textures_converted.end()) {
|
|
|
+ index = (*it).second;
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ index = ConvertVideo(*media);
|
|
|
+ textures_converted[media] = index;
|
|
|
+ }
|
|
|
+
|
|
|
+ // setup texture reference string (copied from ColladaLoader::FindFilenameForEffectTexture)
|
|
|
+ path.data[0] = '*';
|
|
|
+ path.length = 1 + ASSIMP_itoa10(path.data + 1, MAXLEN - 1, index);
|
|
|
+ }
|
|
|
+
|
|
|
+ out_mat->AddProperty(&path, (name + "|file").c_str(), aiTextureType_UNKNOWN, 0);
|
|
|
+
|
|
|
+ aiUVTransform uvTrafo;
|
|
|
+ // XXX handle all kinds of UV transformations
|
|
|
+ uvTrafo.mScaling = tex->UVScaling();
|
|
|
+ uvTrafo.mTranslation = tex->UVTranslation();
|
|
|
+ out_mat->AddProperty(&uvTrafo, 1, (name + "|uvtrafo").c_str(), aiTextureType_UNKNOWN, 0);
|
|
|
+
|
|
|
+ int uvIndex = 0;
|
|
|
+
|
|
|
+ bool uvFound = false;
|
|
|
+ const std::string& uvSet = PropertyGet<std::string>(tex->Props(), "UVSet", uvFound);
|
|
|
+ if (uvFound) {
|
|
|
+ // "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.
|
|
|
+
|
|
|
+ std::vector<aiMaterial*>::iterator materialIt = std::find(materials.begin(), materials.end(), out_mat);
|
|
|
+ const unsigned int matIndex = static_cast<unsigned int>(std::distance(materials.begin(), materialIt));
|
|
|
+
|
|
|
+ uvIndex = -1;
|
|
|
+ if (!mesh)
|
|
|
+ {
|
|
|
+ for (const MeshMap::value_type& v : meshes_converted) {
|
|
|
+ const MeshGeometry* const mesh = dynamic_cast<const MeshGeometry*>(v.first);
|
|
|
+ if (!mesh) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ const MatIndexArray& 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 find 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");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ 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 find UV channel named " + uvSet + " in a mesh using this material");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (uvIndex == -1) {
|
|
|
+ uvIndex = index;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (uvIndex == -1) {
|
|
|
+ FBXImporter::LogWarn("failed to resolve UV channel " + uvSet + ", using first UV channel");
|
|
|
+ uvIndex = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ out_mat->AddProperty(&uvIndex, 1, (name + "|uvwsrc").c_str(), aiTextureType_UNKNOWN, 0);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|