|
@@ -2,7 +2,7 @@
|
|
|
Open Asset Import Library (assimp)
|
|
|
----------------------------------------------------------------------
|
|
|
|
|
|
-Copyright (c) 2006-2015, assimp team
|
|
|
+Copyright (c) 2006-2016, assimp team
|
|
|
All rights reserved.
|
|
|
|
|
|
Redistribution and use of this software in source and binary forms,
|
|
@@ -54,6 +54,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
#include "FBXUtil.h"
|
|
|
#include "FBXProperties.h"
|
|
|
#include "FBXImporter.h"
|
|
|
+#include "StringComparison.h"
|
|
|
#include "../include/assimp/scene.h"
|
|
|
#include <boost/foreach.hpp>
|
|
|
#include <boost/scoped_array.hpp>
|
|
@@ -148,6 +149,7 @@ public:
|
|
|
std::for_each(animations.begin(),animations.end(),Util::delete_fun<aiAnimation>());
|
|
|
std::for_each(lights.begin(),lights.end(),Util::delete_fun<aiLight>());
|
|
|
std::for_each(cameras.begin(),cameras.end(),Util::delete_fun<aiCamera>());
|
|
|
+ std::for_each(textures.begin(),textures.end(),Util::delete_fun<aiTexture>());
|
|
|
}
|
|
|
|
|
|
|
|
@@ -1449,6 +1451,36 @@ private:
|
|
|
return static_cast<unsigned int>(materials.size() - 1);
|
|
|
}
|
|
|
|
|
|
+ // ------------------------------------------------------------------------------------------------
|
|
|
+ // Video -> aiTexture
|
|
|
+ unsigned int ConvertVideo(const Video& video)
|
|
|
+ {
|
|
|
+ // generate empty output texture
|
|
|
+ aiTexture* out_tex = new aiTexture();
|
|
|
+ textures.push_back(out_tex);
|
|
|
+
|
|
|
+ // assuming the texture is compressed
|
|
|
+ out_tex->mWidth = static_cast<unsigned int>(video.ContentLength()); // total data size
|
|
|
+ out_tex->mHeight = 0; // fixed to 0
|
|
|
+
|
|
|
+ // steal the data from the Video to avoid an additional copy
|
|
|
+ out_tex->pcData = reinterpret_cast<aiTexel*>( const_cast<Video&>(video).RelinquishContent() );
|
|
|
+
|
|
|
+ // try to extract a hint from the file extension
|
|
|
+ const std::string& filename = video.FileName().empty() ? video.RelativeFilename() : video.FileName();
|
|
|
+ std::string ext = BaseImporter::GetExtension(filename);
|
|
|
+
|
|
|
+ if(ext == "jpeg") {
|
|
|
+ ext = "jpg";
|
|
|
+ }
|
|
|
+
|
|
|
+ if(ext.size() <= 3) {
|
|
|
+ memcpy(out_tex->achFormatHint, ext.c_str(), ext.size());
|
|
|
+ }
|
|
|
+
|
|
|
+ return static_cast<unsigned int>(textures.size() - 1);
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
void TrySetTextureProperties(aiMaterial* out_mat, const TextureMap& textures,
|
|
@@ -1466,6 +1498,24 @@ private:
|
|
|
aiString path;
|
|
|
path.Set(tex->RelativeFilename());
|
|
|
|
|
|
+ const Video* media = tex->Media();
|
|
|
+ if(media != 0 && 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,_AI_MATKEY_TEXTURE_BASE,target,0);
|
|
|
|
|
|
aiUVTransform uvTrafo;
|
|
@@ -2496,8 +2546,9 @@ private:
|
|
|
// need to convert from TRS order to SRT?
|
|
|
if(reverse_order) {
|
|
|
|
|
|
- aiVector3D def_scale, def_translate;
|
|
|
- aiQuaternion def_rot;
|
|
|
+ aiVector3D def_scale = PropertyGet(props,"Lcl Scaling",aiVector3D(1.f,1.f,1.f));
|
|
|
+ aiVector3D def_translate = PropertyGet(props,"Lcl Translation",aiVector3D(0.f,0.f,0.f));
|
|
|
+ aiVector3D def_rot = PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f));
|
|
|
|
|
|
KeyFrameListList scaling;
|
|
|
KeyFrameListList translation;
|
|
@@ -2506,24 +2557,14 @@ private:
|
|
|
if(chain[TransformationComp_Scaling] != iter_end) {
|
|
|
scaling = GetKeyframeList((*chain[TransformationComp_Scaling]).second, start, stop);
|
|
|
}
|
|
|
- else {
|
|
|
- def_scale = PropertyGet(props,"Lcl Scaling",aiVector3D(1.f,1.f,1.f));
|
|
|
- }
|
|
|
|
|
|
if(chain[TransformationComp_Translation] != iter_end) {
|
|
|
translation = GetKeyframeList((*chain[TransformationComp_Translation]).second, start, stop);
|
|
|
}
|
|
|
- else {
|
|
|
- def_translate = PropertyGet(props,"Lcl Translation",aiVector3D(0.f,0.f,0.f));
|
|
|
- }
|
|
|
|
|
|
if(chain[TransformationComp_Rotation] != iter_end) {
|
|
|
rotation = GetKeyframeList((*chain[TransformationComp_Rotation]).second, start, stop);
|
|
|
}
|
|
|
- else {
|
|
|
- def_rot = EulerToQuaternion(PropertyGet(props,"Lcl Rotation",aiVector3D(0.f,0.f,0.f)),
|
|
|
- target.RotationOrder());
|
|
|
- }
|
|
|
|
|
|
KeyFrameListList joined;
|
|
|
joined.insert(joined.end(), scaling.begin(), scaling.end());
|
|
@@ -2740,7 +2781,7 @@ private:
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
void InterpolateKeys(aiVectorKey* valOut,const KeyTimeList& keys, const KeyFrameListList& inputs,
|
|
|
- const bool geom,
|
|
|
+ const aiVector3D& def_value,
|
|
|
double& max_time,
|
|
|
double& min_time)
|
|
|
|
|
@@ -2754,10 +2795,7 @@ private:
|
|
|
next_pos.resize(inputs.size(),0);
|
|
|
|
|
|
BOOST_FOREACH(KeyTimeList::value_type time, keys) {
|
|
|
- float result[3] = {0.0f, 0.0f, 0.0f};
|
|
|
- if(geom) {
|
|
|
- result[0] = result[1] = result[2] = 1.0f;
|
|
|
- }
|
|
|
+ float result[3] = {def_value.x, def_value.y, def_value.z};
|
|
|
|
|
|
for (size_t i = 0; i < count; ++i) {
|
|
|
const KeyFrameList& kfl = inputs[i];
|
|
@@ -2782,12 +2820,7 @@ private:
|
|
|
const double factor = timeB == timeA ? 0. : static_cast<double>((time - timeA) / (timeB - timeA));
|
|
|
const float interpValue = static_cast<float>(valueA + (valueB - valueA) * factor);
|
|
|
|
|
|
- if(geom) {
|
|
|
- result[kfl.get<2>()] *= interpValue;
|
|
|
- }
|
|
|
- else {
|
|
|
- result[kfl.get<2>()] += interpValue;
|
|
|
- }
|
|
|
+ result[kfl.get<2>()] = interpValue;
|
|
|
}
|
|
|
|
|
|
// magic value to convert fbx times to seconds
|
|
@@ -2807,7 +2840,7 @@ private:
|
|
|
|
|
|
// ------------------------------------------------------------------------------------------------
|
|
|
void InterpolateKeys(aiQuatKey* valOut,const KeyTimeList& keys, const KeyFrameListList& inputs,
|
|
|
- const bool geom,
|
|
|
+ const aiVector3D& def_value,
|
|
|
double& maxTime,
|
|
|
double& minTime,
|
|
|
Model::RotOrder order)
|
|
@@ -2816,7 +2849,7 @@ private:
|
|
|
ai_assert(valOut);
|
|
|
|
|
|
boost::scoped_array<aiVectorKey> temp(new aiVectorKey[keys.size()]);
|
|
|
- InterpolateKeys(temp.get(),keys,inputs,geom,maxTime, minTime);
|
|
|
+ InterpolateKeys(temp.get(), keys, inputs, def_value, maxTime, minTime);
|
|
|
|
|
|
aiMatrix4x4 m;
|
|
|
|
|
@@ -2858,20 +2891,20 @@ private:
|
|
|
Model::RotOrder order,
|
|
|
const aiVector3D& def_scale,
|
|
|
const aiVector3D& def_translate,
|
|
|
- const aiQuaternion& def_rotation)
|
|
|
+ const aiVector3D& def_rotation)
|
|
|
{
|
|
|
if (rotation.size()) {
|
|
|
- InterpolateKeys(out_quat, times, rotation, false, maxTime, minTime, order);
|
|
|
+ InterpolateKeys(out_quat, times, rotation, def_rotation, maxTime, minTime, order);
|
|
|
}
|
|
|
else {
|
|
|
for (size_t i = 0; i < times.size(); ++i) {
|
|
|
out_quat[i].mTime = CONVERT_FBX_TIME(times[i]) * anim_fps;
|
|
|
- out_quat[i].mValue = def_rotation;
|
|
|
+ out_quat[i].mValue = EulerToQuaternion(def_rotation, order);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
if (scaling.size()) {
|
|
|
- InterpolateKeys(out_scale, times, scaling, true, maxTime, minTime);
|
|
|
+ InterpolateKeys(out_scale, times, scaling, def_scale, maxTime, minTime);
|
|
|
}
|
|
|
else {
|
|
|
for (size_t i = 0; i < times.size(); ++i) {
|
|
@@ -2881,7 +2914,7 @@ private:
|
|
|
}
|
|
|
|
|
|
if (translation.size()) {
|
|
|
- InterpolateKeys(out_translation, times, translation, false, maxTime, minTime);
|
|
|
+ InterpolateKeys(out_translation, times, translation, def_translate, maxTime, minTime);
|
|
|
}
|
|
|
else {
|
|
|
for (size_t i = 0; i < times.size(); ++i) {
|
|
@@ -2935,7 +2968,7 @@ private:
|
|
|
na->mNumScalingKeys = static_cast<unsigned int>(keys.size());
|
|
|
na->mScalingKeys = new aiVectorKey[keys.size()];
|
|
|
if (keys.size() > 0)
|
|
|
- InterpolateKeys(na->mScalingKeys, keys, inputs, true, maxTime, minTime);
|
|
|
+ InterpolateKeys(na->mScalingKeys, keys, inputs, aiVector3D(1.0f, 1.0f, 1.0f), maxTime, minTime);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -2955,7 +2988,7 @@ private:
|
|
|
na->mNumPositionKeys = static_cast<unsigned int>(keys.size());
|
|
|
na->mPositionKeys = new aiVectorKey[keys.size()];
|
|
|
if (keys.size() > 0)
|
|
|
- InterpolateKeys(na->mPositionKeys, keys, inputs, false, maxTime, minTime);
|
|
|
+ InterpolateKeys(na->mPositionKeys, keys, inputs, aiVector3D(0.0f, 0.0f, 0.0f), maxTime, minTime);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -2976,7 +3009,7 @@ private:
|
|
|
na->mNumRotationKeys = static_cast<unsigned int>(keys.size());
|
|
|
na->mRotationKeys = new aiQuatKey[keys.size()];
|
|
|
if (keys.size() > 0)
|
|
|
- InterpolateKeys(na->mRotationKeys, keys, inputs, false, maxTime, minTime, order);
|
|
|
+ InterpolateKeys(na->mRotationKeys, keys, inputs, aiVector3D(0.0f, 0.0f, 0.0f), maxTime, minTime, order);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -3024,6 +3057,13 @@ private:
|
|
|
|
|
|
std::swap_ranges(cameras.begin(),cameras.end(),out->mCameras);
|
|
|
}
|
|
|
+
|
|
|
+ if(textures.size()) {
|
|
|
+ out->mTextures = new aiTexture*[textures.size()]();
|
|
|
+ out->mNumTextures = static_cast<unsigned int>(textures.size());
|
|
|
+
|
|
|
+ std::swap_ranges(textures.begin(),textures.end(),out->mTextures);
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
|
|
@@ -3037,10 +3077,14 @@ private:
|
|
|
std::vector<aiAnimation*> animations;
|
|
|
std::vector<aiLight*> lights;
|
|
|
std::vector<aiCamera*> cameras;
|
|
|
+ std::vector<aiTexture*> textures;
|
|
|
|
|
|
typedef std::map<const Material*, unsigned int> MaterialMap;
|
|
|
MaterialMap materials_converted;
|
|
|
|
|
|
+ typedef std::map<const Video*, unsigned int> VideoMap;
|
|
|
+ VideoMap textures_converted;
|
|
|
+
|
|
|
typedef std::map<const Geometry*, std::vector<unsigned int> > MeshMap;
|
|
|
MeshMap meshes_converted;
|
|
|
|