Merge branch 'master' into develop_kimkulling
commit
e01e77a6c7
|
@ -117,6 +117,7 @@ bool D3MFExporter::exportArchive( const char *file ) {
|
|||
if ( nullptr == m_zipArchive ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ok |= exportContentTypes();
|
||||
ok |= export3DModel();
|
||||
ok |= exportRelations();
|
||||
|
@ -181,6 +182,8 @@ bool D3MFExporter::export3DModel() {
|
|||
mModelOutput << "<" << XmlTag::resources << ">";
|
||||
mModelOutput << std::endl;
|
||||
|
||||
writeMetaData();
|
||||
|
||||
writeBaseMaterials();
|
||||
|
||||
writeObjects();
|
||||
|
@ -209,6 +212,29 @@ void D3MFExporter::writeHeader() {
|
|||
mModelOutput << std::endl;
|
||||
}
|
||||
|
||||
void D3MFExporter::writeMetaData() {
|
||||
if ( nullptr == mScene->mMetaData ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const unsigned int numMetaEntries( mScene->mMetaData->mNumProperties );
|
||||
if ( 0 == numMetaEntries ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const aiString *key;
|
||||
const aiMetadataEntry *entry(nullptr);
|
||||
for ( size_t i = 0; i < numMetaEntries; ++i ) {
|
||||
mScene->mMetaData->Get( i, key, entry );
|
||||
std::string k( key->C_Str() );
|
||||
aiString value;
|
||||
mScene->mMetaData->Get( k, value );
|
||||
mModelOutput << "<" << XmlTag::meta << " " << XmlTag::meta_name << "=\"" << key->C_Str() << "\">";
|
||||
mModelOutput << value.C_Str();
|
||||
mModelOutput << "</" << XmlTag::meta << ">" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void D3MFExporter::writeBaseMaterials() {
|
||||
mModelOutput << "<basematerials id=\"1\">\n";
|
||||
std::string strName, hexDiffuseColor , tmp;
|
||||
|
|
|
@ -76,6 +76,7 @@ public:
|
|||
|
||||
protected:
|
||||
void writeHeader();
|
||||
void writeMetaData();
|
||||
void writeBaseMaterials();
|
||||
void writeObjects();
|
||||
void writeMesh( aiMesh *mesh );
|
||||
|
|
|
@ -103,6 +103,8 @@ public:
|
|||
//
|
||||
} else if ( nodeName == D3MF::XmlTag::basematerials ) {
|
||||
ReadBaseMaterials();
|
||||
} else if ( nodeName == D3MF::XmlTag::meta ) {
|
||||
ReadMetadata();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,19 +112,31 @@ public:
|
|||
scene->mRootNode->mName.Set( "3MF" );
|
||||
}
|
||||
|
||||
// import the metadata
|
||||
if ( !mMetaData.empty() ) {
|
||||
const size_t numMeta( mMetaData.size() );
|
||||
scene->mMetaData = aiMetadata::Alloc( numMeta );
|
||||
for ( size_t i = 0; i < numMeta; ++i ) {
|
||||
aiString val( mMetaData[ i ].value );
|
||||
scene->mMetaData->Set( i, mMetaData[ i ].name, val );
|
||||
}
|
||||
}
|
||||
|
||||
// import the meshes
|
||||
scene->mNumMeshes = static_cast<unsigned int>( mMeshes.size());
|
||||
scene->mMeshes = new aiMesh*[scene->mNumMeshes]();
|
||||
|
||||
std::copy( mMeshes.begin(), mMeshes.end(), scene->mMeshes);
|
||||
|
||||
// import the materials
|
||||
scene->mNumMaterials = static_cast<unsigned int>( mMatArray.size() );
|
||||
if ( 0 != scene->mNumMaterials ) {
|
||||
scene->mMaterials = new aiMaterial*[ scene->mNumMaterials ];
|
||||
std::copy( mMatArray.begin(), mMatArray.end(), scene->mMaterials );
|
||||
}
|
||||
|
||||
// create the scenegraph
|
||||
scene->mRootNode->mNumChildren = static_cast<unsigned int>(children.size());
|
||||
scene->mRootNode->mChildren = new aiNode*[scene->mRootNode->mNumChildren]();
|
||||
|
||||
std::copy(children.begin(), children.end(), scene->mRootNode->mChildren);
|
||||
}
|
||||
|
||||
|
@ -181,6 +195,21 @@ private:
|
|||
return mesh;
|
||||
}
|
||||
|
||||
void ReadMetadata() {
|
||||
const std::string name = xmlReader->getAttributeValue( D3MF::XmlTag::meta_name.c_str() );
|
||||
xmlReader->read();
|
||||
const std::string value = xmlReader->getNodeData();
|
||||
|
||||
if ( name.empty() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
MetaEntry entry;
|
||||
entry.name = name;
|
||||
entry.value = value;
|
||||
mMetaData.push_back( entry );
|
||||
}
|
||||
|
||||
void ImportVertices(aiMesh* mesh) {
|
||||
std::vector<aiVector3D> vertices;
|
||||
while(ReadToEndElement(D3MF::XmlTag::vertices)) {
|
||||
|
@ -254,7 +283,7 @@ private:
|
|||
MatIdArray = it->second;
|
||||
}
|
||||
}
|
||||
MatIdArray.push_back( newMatIdx );
|
||||
MatIdArray.push_back( static_cast<unsigned int>( newMatIdx ) );
|
||||
mMatId2MatArray[ mActiveMatGroup ] = MatIdArray;
|
||||
}
|
||||
|
||||
|
@ -372,8 +401,12 @@ private:
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
struct MetaEntry {
|
||||
std::string name;
|
||||
std::string value;
|
||||
};
|
||||
std::vector<MetaEntry> mMetaData;
|
||||
std::vector<aiMesh*> mMeshes;
|
||||
MatArray mMatArray;
|
||||
unsigned int mActiveMatGroup;
|
||||
|
|
|
@ -76,7 +76,7 @@ bool DefaultIOSystem::Exists( const char* pFile) const
|
|||
#ifdef _WIN32
|
||||
wchar_t fileName16[PATHLIMIT];
|
||||
|
||||
bool isUnicode = IsTextUnicode(pFile, strlen(pFile), NULL);
|
||||
bool isUnicode = IsTextUnicode(pFile, static_cast<int>(strlen(pFile)), NULL);
|
||||
if (isUnicode) {
|
||||
|
||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, pFile, -1, fileName16, PATHLIMIT);
|
||||
|
@ -110,7 +110,7 @@ IOStream* DefaultIOSystem::Open( const char* strFile, const char* strMode)
|
|||
FILE* file;
|
||||
#ifdef _WIN32
|
||||
wchar_t fileName16[PATHLIMIT];
|
||||
bool isUnicode = IsTextUnicode(strFile, strlen(strFile), NULL );
|
||||
bool isUnicode = IsTextUnicode(strFile, static_cast<int>(strlen(strFile)), NULL );
|
||||
if (isUnicode) {
|
||||
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, strFile, -1, fileName16, PATHLIMIT);
|
||||
std::string mode8(strMode);
|
||||
|
@ -158,7 +158,7 @@ inline static void MakeAbsolutePath (const char* in, char* _out)
|
|||
{
|
||||
ai_assert(in && _out);
|
||||
#if defined( _MSC_VER ) || defined( __MINGW32__ )
|
||||
bool isUnicode = IsTextUnicode(in, strlen(in), NULL);
|
||||
bool isUnicode = IsTextUnicode(in, static_cast<int>(strlen(in)), NULL);
|
||||
if (isUnicode) {
|
||||
wchar_t out16[PATHLIMIT];
|
||||
wchar_t in16[PATHLIMIT];
|
||||
|
|
|
@ -99,22 +99,22 @@ void EmbedTexturesProcess::Execute(aiScene* pScene) {
|
|||
}
|
||||
|
||||
bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
|
||||
uint32_t imageSize = 0;
|
||||
std::streampos imageSize = 0;
|
||||
std::string imagePath = path;
|
||||
|
||||
// Test path directly
|
||||
std::ifstream file(imagePath, std::ios::binary | std::ios::ate);
|
||||
if ((imageSize = file.tellg()) == -1u) {
|
||||
if ((imageSize = file.tellg()) == std::streampos(-1)) {
|
||||
DefaultLogger::get()->warn("EmbedTexturesProcess: Cannot find image: " + imagePath + ". Will try to find it in root folder.");
|
||||
|
||||
// Test path in root path
|
||||
imagePath = mRootPath + path;
|
||||
file.open(imagePath, std::ios::binary | std::ios::ate);
|
||||
if ((imageSize = file.tellg()) == -1u) {
|
||||
if ((imageSize = file.tellg()) == std::streampos(-1)) {
|
||||
// Test path basename in root path
|
||||
imagePath = mRootPath + path.substr(path.find_last_of("\\/") + 1u);
|
||||
file.open(imagePath, std::ios::binary | std::ios::ate);
|
||||
if ((imageSize = file.tellg()) == -1u) {
|
||||
if ((imageSize = file.tellg()) == std::streampos(-1)) {
|
||||
DefaultLogger::get()->error("EmbedTexturesProcess: Unable to embed texture: " + path + ".");
|
||||
return false;
|
||||
}
|
||||
|
@ -134,7 +134,7 @@ bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
|
|||
// Add the new texture
|
||||
auto pTexture = new aiTexture();
|
||||
pTexture->mHeight = 0; // Means that this is still compressed
|
||||
pTexture->mWidth = imageSize;
|
||||
pTexture->mWidth = static_cast<uint32_t>(imageSize);
|
||||
pTexture->pcData = imageContent;
|
||||
|
||||
auto extension = path.substr(path.find_last_of('.') + 1u);
|
||||
|
|
|
@ -308,7 +308,8 @@ bool IsVerboseFormat(const aiScene* pScene) {
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing, const ExportProperties* pProperties) {
|
||||
aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const char* pPath,
|
||||
unsigned int pPreprocessing, const ExportProperties* pProperties) {
|
||||
ASSIMP_BEGIN_EXCEPTION_REGION();
|
||||
|
||||
// when they create scenes from scratch, users will likely create them not in verbose
|
||||
|
|
|
@ -704,7 +704,7 @@ void Converter::GenerateTransformationNodeChain( const Model& model, std::vector
|
|||
aiMatrix4x4::Scaling( GeometricScaling, chain[ TransformationComp_GeometricScaling ] );
|
||||
aiVector3D GeometricScalingInverse = GeometricScaling;
|
||||
bool canscale = true;
|
||||
for (size_t i = 0; i < 3; ++i) {
|
||||
for (unsigned int i = 0; i < 3; ++i) {
|
||||
if ( std::fabs( GeometricScalingInverse[i] ) > zero_epsilon ) {
|
||||
GeometricScalingInverse[i] = 1.0f / GeometricScaling[i];
|
||||
} else {
|
||||
|
@ -1887,11 +1887,11 @@ void Converter::SetShadingPropertiesCommon( aiMaterial* out_mat, const PropertyT
|
|||
|
||||
// TransparentColor / TransparencyFactor... gee thanks FBX :rolleyes:
|
||||
const aiColor3D& Transparent = GetColorPropertyFactored( props, "TransparentColor", "TransparencyFactor", ok );
|
||||
float CalculatedOpacity = 1.0;
|
||||
float CalculatedOpacity = 1.0f;
|
||||
if ( ok ) {
|
||||
out_mat->AddProperty( &Transparent, 1, AI_MATKEY_COLOR_TRANSPARENT );
|
||||
// as calculated by FBX SDK 2017:
|
||||
CalculatedOpacity = 1.0 - ((Transparent.r + Transparent.g + Transparent.b) / 3.0);
|
||||
CalculatedOpacity = 1.0f - ((Transparent.r + Transparent.g + Transparent.b) / 3.0f);
|
||||
}
|
||||
|
||||
// use of TransparencyFactor is inconsistent.
|
||||
|
|
|
@ -182,7 +182,7 @@ void FBX::Node::Begin(Assimp::StreamWriterLE &s)
|
|||
s.PutU4(0); // total property section length
|
||||
|
||||
// node name
|
||||
s.PutU1(name.size()); // length of node name
|
||||
s.PutU1(uint8_t(name.size())); // length of node name
|
||||
s.PutString(name); // node name as raw bytes
|
||||
|
||||
// property data comes after here
|
||||
|
@ -217,8 +217,8 @@ void FBX::Node::EndProperties(
|
|||
ai_assert(pos > property_start);
|
||||
size_t property_section_size = pos - property_start;
|
||||
s.Seek(start_pos + 4);
|
||||
s.PutU4(num_properties);
|
||||
s.PutU4(property_section_size);
|
||||
s.PutU4(uint32_t(num_properties));
|
||||
s.PutU4(uint32_t(property_section_size));
|
||||
s.Seek(pos);
|
||||
}
|
||||
|
||||
|
@ -232,7 +232,7 @@ void FBX::Node::End(
|
|||
// now go back and write initial pos
|
||||
this->end_pos = s.Tell();
|
||||
s.Seek(start_pos);
|
||||
s.PutU4(end_pos);
|
||||
s.PutU4(uint32_t(end_pos));
|
||||
s.Seek(end_pos);
|
||||
}
|
||||
|
||||
|
@ -251,9 +251,9 @@ void FBX::Node::WritePropertyNode(
|
|||
Node node(name);
|
||||
node.Begin(s);
|
||||
s.PutU1('d');
|
||||
s.PutU4(v.size()); // number of elements
|
||||
s.PutU4(uint32_t(v.size())); // number of elements
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
s.PutU4(v.size() * 8); // data size
|
||||
s.PutU4(uint32_t(v.size()) * 8); // data size
|
||||
for (auto it = v.begin(); it != v.end(); ++it) { s.PutF8(*it); }
|
||||
node.EndProperties(s, 1);
|
||||
node.End(s, false);
|
||||
|
@ -271,9 +271,9 @@ void FBX::Node::WritePropertyNode(
|
|||
Node node(name);
|
||||
node.Begin(s);
|
||||
s.PutU1('i');
|
||||
s.PutU4(v.size()); // number of elements
|
||||
s.PutU4(uint32_t(v.size())); // number of elements
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
s.PutU4(v.size() * 4); // data size
|
||||
s.PutU4(uint32_t(v.size()) * 4); // data size
|
||||
for (auto it = v.begin(); it != v.end(); ++it) { s.PutI4(*it); }
|
||||
node.EndProperties(s, 1);
|
||||
node.End(s, false);
|
||||
|
|
|
@ -127,8 +127,8 @@ FBX::Property::Property(const aiMatrix4x4& vm)
|
|||
: type('d'), data(8*16)
|
||||
{
|
||||
double* d = reinterpret_cast<double*>(data.data());
|
||||
for (size_t c = 0; c < 4; ++c) {
|
||||
for (size_t r = 0; r < 4; ++r) {
|
||||
for (unsigned int c = 0; c < 4; ++c) {
|
||||
for (unsigned int r = 0; r < 4; ++r) {
|
||||
d[4*c+r] = vm[r][c];
|
||||
}
|
||||
}
|
||||
|
@ -164,15 +164,15 @@ void FBX::Property::Dump(Assimp::StreamWriterLE &s)
|
|||
case 'L': s.PutI8(*(reinterpret_cast<int64_t*>(data.data()))); return;
|
||||
case 'S':
|
||||
case 'R':
|
||||
s.PutU4(data.size());
|
||||
s.PutU4(uint32_t(data.size()));
|
||||
for (size_t i = 0; i < data.size(); ++i) { s.PutU1(data[i]); }
|
||||
return;
|
||||
case 'i':
|
||||
N = data.size() / 4;
|
||||
s.PutU4(N); // number of elements
|
||||
s.PutU4(uint32_t(N)); // number of elements
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(data.size()); // data size
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
d = data.data();
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutI4((reinterpret_cast<int32_t*>(d))[i]);
|
||||
|
@ -180,10 +180,10 @@ void FBX::Property::Dump(Assimp::StreamWriterLE &s)
|
|||
return;
|
||||
case 'd':
|
||||
N = data.size() / 8;
|
||||
s.PutU4(N); // number of elements
|
||||
s.PutU4(uint32_t(N)); // number of elements
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(data.size()); // data size
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
d = data.data();
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutF8((reinterpret_cast<double*>(d))[i]);
|
||||
|
|
|
@ -460,7 +460,7 @@ size_t count_images(const aiScene* scene) {
|
|||
){
|
||||
const aiTextureType textype = static_cast<aiTextureType>(tt);
|
||||
const size_t texcount = mat->GetTextureCount(textype);
|
||||
for (size_t j = 0; j < texcount; ++j) {
|
||||
for (unsigned int j = 0; j < texcount; ++j) {
|
||||
mat->GetTexture(textype, j, &texpath);
|
||||
images.insert(std::string(texpath.C_Str()));
|
||||
}
|
||||
|
@ -593,7 +593,7 @@ void FBXExporter::WriteDefinitions ()
|
|||
|
||||
// Model / FbxNode
|
||||
// <~~ node heirarchy
|
||||
count = count_nodes(mScene->mRootNode) - 1; // (not counting root node)
|
||||
count = int32_t(count_nodes(mScene->mRootNode)) - 1; // (not counting root node)
|
||||
if (count) {
|
||||
n = FBX::Node("ObjectType", Property("Model"));
|
||||
n.AddChild("Count", count);
|
||||
|
@ -763,7 +763,7 @@ void FBXExporter::WriteDefinitions ()
|
|||
|
||||
// Video / FbxVideo
|
||||
// one for each image file.
|
||||
count = count_images(mScene);
|
||||
count = int32_t(count_images(mScene));
|
||||
if (count) {
|
||||
n = FBX::Node("ObjectType", Property("Video"));
|
||||
n.AddChild("Count", count);
|
||||
|
@ -792,7 +792,7 @@ void FBXExporter::WriteDefinitions ()
|
|||
|
||||
// Texture / FbxFileTexture
|
||||
// <~~ aiTexture
|
||||
count = count_textures(mScene);
|
||||
count = int32_t(count_textures(mScene));
|
||||
if (count) {
|
||||
n = FBX::Node("ObjectType", Property("Texture"));
|
||||
n.AddChild("Count", count);
|
||||
|
@ -848,7 +848,7 @@ void FBXExporter::WriteDefinitions ()
|
|||
}
|
||||
|
||||
// Deformer
|
||||
count = count_deformers(mScene);
|
||||
count = int32_t(count_deformers(mScene));
|
||||
if (count) {
|
||||
n = FBX::Node("ObjectType", Property("Deformer"));
|
||||
n.AddChild("Count", count);
|
||||
|
@ -943,7 +943,7 @@ void FBXExporter::WriteObjects ()
|
|||
std::vector<int32_t> vertex_indices;
|
||||
// map of vertex value to its index in the data vector
|
||||
std::map<aiVector3D,size_t> index_by_vertex_value;
|
||||
size_t index = 0;
|
||||
int32_t index = 0;
|
||||
for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
|
||||
aiVector3D vtx = m->mVertices[vi];
|
||||
auto elem = index_by_vertex_value.find(vtx);
|
||||
|
@ -955,7 +955,7 @@ void FBXExporter::WriteObjects ()
|
|||
flattened_vertices.push_back(vtx[2]);
|
||||
++index;
|
||||
} else {
|
||||
vertex_indices.push_back(elem->second);
|
||||
vertex_indices.push_back(int32_t(elem->second));
|
||||
}
|
||||
}
|
||||
FBX::Node::WritePropertyNode(
|
||||
|
@ -1052,7 +1052,7 @@ void FBXExporter::WriteObjects ()
|
|||
std::vector<double> uv_data;
|
||||
std::vector<int32_t> uv_indices;
|
||||
std::map<aiVector3D,int32_t> index_by_uv;
|
||||
size_t index = 0;
|
||||
int32_t index = 0;
|
||||
for (size_t fi = 0; fi < m->mNumFaces; ++fi) {
|
||||
const aiFace &f = m->mFaces[fi];
|
||||
for (size_t pvi = 0; pvi < f.mNumIndices; ++pvi) {
|
||||
|
@ -1062,7 +1062,7 @@ void FBXExporter::WriteObjects ()
|
|||
if (elem == index_by_uv.end()) {
|
||||
index_by_uv[uv] = index;
|
||||
uv_indices.push_back(index);
|
||||
for (size_t x = 0; x < m->mNumUVComponents[uvi]; ++x) {
|
||||
for (unsigned int x = 0; x < m->mNumUVComponents[uvi]; ++x) {
|
||||
uv_data.push_back(uv[x]);
|
||||
}
|
||||
++index;
|
||||
|
@ -1208,13 +1208,13 @@ void FBXExporter::WriteObjects ()
|
|||
// and usualy are completely ignored when loading.
|
||||
// One notable exception is the "Opacity" property,
|
||||
// which Blender uses as (1.0 - alpha).
|
||||
c.r = 0; c.g = 0; c.b = 0;
|
||||
c.r = 0.0f; c.g = 0.0f; c.b = 0.0f;
|
||||
m->Get(AI_MATKEY_COLOR_EMISSIVE, c);
|
||||
p.AddP70vector("Emissive", c.r, c.g, c.b);
|
||||
c.r = 0.2; c.g = 0.2; c.b = 0.2;
|
||||
c.r = 0.2f; c.g = 0.2f; c.b = 0.2f;
|
||||
m->Get(AI_MATKEY_COLOR_AMBIENT, c);
|
||||
p.AddP70vector("Ambient", c.r, c.g, c.b);
|
||||
c.r = 0.8; c.g = 0.8; c.b = 0.8;
|
||||
c.r = 0.8f; c.g = 0.8f; c.b = 0.8f;
|
||||
m->Get(AI_MATKEY_COLOR_DIFFUSE, c);
|
||||
p.AddP70vector("Diffuse", c.r, c.g, c.b);
|
||||
// The FBX SDK determines "Opacity" from transparency colour (RGB)
|
||||
|
@ -1223,29 +1223,29 @@ void FBXExporter::WriteObjects ()
|
|||
// so we should take it from AI_MATKEY_OPACITY if possible.
|
||||
// It might make more sense to use TransparencyFactor,
|
||||
// but Blender actually loads "Opacity" correctly, so let's use it.
|
||||
f = 1.0;
|
||||
f = 1.0f;
|
||||
if (m->Get(AI_MATKEY_COLOR_TRANSPARENT, c) == aiReturn_SUCCESS) {
|
||||
f = 1.0 - ((c.r + c.g + c.b) / 3);
|
||||
f = 1.0f - ((c.r + c.g + c.b) / 3.0f);
|
||||
}
|
||||
m->Get(AI_MATKEY_OPACITY, f);
|
||||
p.AddP70double("Opacity", f);
|
||||
if (phong) {
|
||||
// specular color is multiplied by shininess_strength
|
||||
c.r = 0.2; c.g = 0.2; c.b = 0.2;
|
||||
c.r = 0.2f; c.g = 0.2f; c.b = 0.2f;
|
||||
m->Get(AI_MATKEY_COLOR_SPECULAR, c);
|
||||
f = 1.0;
|
||||
f = 1.0f;
|
||||
m->Get(AI_MATKEY_SHININESS_STRENGTH, f);
|
||||
p.AddP70vector("Specular", f*c.r, f*c.g, f*c.b);
|
||||
f = 20.0;
|
||||
f = 20.0f;
|
||||
m->Get(AI_MATKEY_SHININESS, f);
|
||||
p.AddP70double("Shininess", f);
|
||||
// Legacy "Reflectivity" is F*F*((R+G+B)/3),
|
||||
// where F is the proportion of light reflected (AKA reflectivity),
|
||||
// and RGB is the reflective colour of the material.
|
||||
// No idea why, but we might as well set it the same way.
|
||||
f = 0.0;
|
||||
f = 0.0f;
|
||||
m->Get(AI_MATKEY_REFLECTIVITY, f);
|
||||
c.r = 1.0, c.g = 1.0, c.b = 1.0;
|
||||
c.r = 1.0f, c.g = 1.0f, c.b = 1.0f;
|
||||
m->Get(AI_MATKEY_COLOR_REFLECTIVE, c);
|
||||
p.AddP70double("Reflectivity", f*f*((c.r+c.g+c.b)/3.0));
|
||||
}
|
||||
|
@ -1269,7 +1269,7 @@ void FBXExporter::WriteObjects ()
|
|||
const aiTextureType textype = static_cast<aiTextureType>(tt);
|
||||
const size_t texcount = mat->GetTextureCount(textype);
|
||||
for (size_t j = 0; j < texcount; ++j) {
|
||||
mat->GetTexture(textype, j, &texpath);
|
||||
mat->GetTexture(textype, (unsigned int)j, &texpath);
|
||||
const std::string texstring = texpath.C_Str();
|
||||
auto elem = uid_by_image.find(texstring);
|
||||
if (elem == uid_by_image.end()) {
|
||||
|
@ -1591,7 +1591,7 @@ void FBXExporter::WriteObjects ()
|
|||
std::vector<int32_t> vertex_indices;
|
||||
// map of vertex value to its index in the data vector
|
||||
std::map<aiVector3D,size_t> index_by_vertex_value;
|
||||
size_t index = 0;
|
||||
int32_t index = 0;
|
||||
for (size_t vi = 0; vi < m->mNumVertices; ++vi) {
|
||||
aiVector3D vtx = m->mVertices[vi];
|
||||
auto elem = index_by_vertex_value.find(vtx);
|
||||
|
@ -1600,7 +1600,7 @@ void FBXExporter::WriteObjects ()
|
|||
index_by_vertex_value[vtx] = index;
|
||||
++index;
|
||||
} else {
|
||||
vertex_indices.push_back(elem->second);
|
||||
vertex_indices.push_back(int32_t(elem->second));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1616,7 +1616,7 @@ void FBXExporter::WriteObjects ()
|
|||
// as it can be instanced to many nodes.
|
||||
// All we can do is assume no instancing,
|
||||
// and take the first node we find that contains the mesh.
|
||||
aiNode* mesh_node = get_node_for_mesh(mi, mScene->mRootNode);
|
||||
aiNode* mesh_node = get_node_for_mesh((unsigned int)mi, mScene->mRootNode);
|
||||
aiMatrix4x4 mesh_xform = get_world_transform(mesh_node, mScene);
|
||||
|
||||
// now make a subdeformer for each bone in the skeleton
|
||||
|
@ -1682,7 +1682,7 @@ void FBXExporter::WriteObjects ()
|
|||
|
||||
// this should be the same as the bone's mOffsetMatrix.
|
||||
// if it's not the same, the skeleton isn't in the bind pose.
|
||||
const float epsilon = 1e-5; // some error is to be expected
|
||||
const float epsilon = 1e-5f; // some error is to be expected
|
||||
bool bone_xform_okay = true;
|
||||
if (b && ! tr.Equal(b->mOffsetMatrix, epsilon)) {
|
||||
not_in_bind_pose.insert(b);
|
||||
|
@ -2002,7 +2002,7 @@ void FBXExporter::WriteModelNodes(
|
|||
transform_chain.emplace_back(elem->first, t);
|
||||
break;
|
||||
case 'r': // rotation
|
||||
r *= DEG;
|
||||
r *= float(DEG);
|
||||
transform_chain.emplace_back(elem->first, r);
|
||||
break;
|
||||
case 's': // scale
|
||||
|
|
|
@ -55,6 +55,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/SceneCombiner.h>
|
||||
#include <assimp/StringUtils.h>
|
||||
#include <assimp/fast_atof.h>
|
||||
#include <assimp/metadata.h>
|
||||
#include <assimp/Hash.h>
|
||||
#include "time.h"
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
@ -1003,7 +1004,12 @@ void SceneCombiner::CopyScene(aiScene** _dest,const aiScene* src,bool allocate)
|
|||
*_dest = new aiScene();
|
||||
}
|
||||
aiScene* dest = *_dest;
|
||||
ai_assert(dest);
|
||||
ai_assert(nullptr != dest);
|
||||
|
||||
// copy metadata
|
||||
if ( nullptr != src->mMetaData ) {
|
||||
dest->mMetaData = new aiMetadata( *src->mMetaData );
|
||||
}
|
||||
|
||||
// copy animations
|
||||
dest->mNumAnimations = src->mNumAnimations;
|
||||
|
|
|
@ -1076,8 +1076,8 @@ std::string XFileParser::GetNextToken() {
|
|||
return s;
|
||||
}
|
||||
len = ReadBinDWord();
|
||||
const int bounds( mEnd - mP );
|
||||
const int iLen( len );
|
||||
const int bounds = int( mEnd - mP );
|
||||
const int iLen = int( len );
|
||||
if ( iLen < 0 ) {
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ public:
|
|||
|
||||
// ---------------------------------------------------------------------
|
||||
~StreamWriter() {
|
||||
stream->Write(&buffer[0], 1, buffer.size());
|
||||
stream->Write(buffer.data(), 1, buffer.size());
|
||||
stream->Flush();
|
||||
}
|
||||
|
||||
|
@ -114,7 +114,7 @@ public:
|
|||
/** Flush the contents of the internal buffer, and the output IOStream */
|
||||
void Flush()
|
||||
{
|
||||
stream->Write(&buffer[0], 1, buffer.size());
|
||||
stream->Write(buffer.data(), 1, buffer.size());
|
||||
stream->Flush();
|
||||
buffer.clear();
|
||||
cursor = 0;
|
||||
|
|
|
@ -67,6 +67,7 @@ typedef enum aiMetadataType {
|
|||
AI_DOUBLE = 4,
|
||||
AI_AISTRING = 5,
|
||||
AI_AIVECTOR3D = 6,
|
||||
AI_META_MAX = 7,
|
||||
|
||||
#ifndef SWIG
|
||||
FORCE_32BIT = INT_MAX
|
||||
|
@ -130,17 +131,78 @@ struct aiMetadata {
|
|||
*/
|
||||
aiMetadata()
|
||||
: mNumProperties(0)
|
||||
, mKeys(NULL)
|
||||
, mValues(NULL) {
|
||||
, mKeys(nullptr)
|
||||
, mValues(nullptr) {
|
||||
// empty
|
||||
}
|
||||
|
||||
aiMetadata( const aiMetadata &rhs )
|
||||
: mNumProperties( rhs.mNumProperties )
|
||||
, mKeys( nullptr )
|
||||
, mValues( nullptr ) {
|
||||
mKeys = new aiString[ mNumProperties ];
|
||||
for ( unsigned int i = 0; i < mNumProperties; ++i ) {
|
||||
mKeys[ i ] = rhs.mKeys[ i ];
|
||||
}
|
||||
mValues = new aiMetadataEntry[ mNumProperties ];
|
||||
for ( unsigned int i = 0; i < mNumProperties; ++i ) {
|
||||
mValues[ i ].mType = rhs.mValues[ i ].mType;
|
||||
switch ( rhs.mValues[ i ].mType ) {
|
||||
case AI_BOOL:
|
||||
mValues[ i ].mData = new bool( rhs.mValues[i].mData );
|
||||
break;
|
||||
case AI_INT32: {
|
||||
int32_t v;
|
||||
::memcpy( &v, rhs.mValues[ i ].mData, sizeof( int32_t ) );
|
||||
mValues[ i ].mData = new int32_t( v );
|
||||
}
|
||||
break;
|
||||
case AI_UINT64: {
|
||||
uint64_t v;
|
||||
::memcpy( &v, rhs.mValues[ i ].mData, sizeof( uint64_t ) );
|
||||
mValues[ i ].mData = new uint64_t( v );
|
||||
}
|
||||
break;
|
||||
case AI_FLOAT: {
|
||||
float v;
|
||||
::memcpy( &v, rhs.mValues[ i ].mData, sizeof( float ) );
|
||||
mValues[ i ].mData = new float( v );
|
||||
}
|
||||
break;
|
||||
case AI_DOUBLE: {
|
||||
double v;
|
||||
::memcpy( &v, rhs.mValues[ i ].mData, sizeof( double ) );
|
||||
mValues[ i ].mData = new double( v );
|
||||
}
|
||||
break;
|
||||
case AI_AISTRING: {
|
||||
aiString v;
|
||||
rhs.Get<aiString>( mKeys[ i ], v );
|
||||
mValues[ i ].mData = new aiString( v );
|
||||
}
|
||||
break;
|
||||
case AI_AIVECTOR3D: {
|
||||
aiVector3D v;
|
||||
rhs.Get<aiVector3D>( mKeys[ i ], v );
|
||||
mValues[ i ].mData = new aiVector3D( v );
|
||||
}
|
||||
break;
|
||||
#ifndef SWIG
|
||||
case FORCE_32BIT:
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief The destructor.
|
||||
*/
|
||||
~aiMetadata() {
|
||||
delete [] mKeys;
|
||||
mKeys = NULL;
|
||||
mKeys = nullptr;
|
||||
if (mValues) {
|
||||
// Delete each metadata entry
|
||||
for (unsigned i=0; i<mNumProperties; ++i) {
|
||||
|
@ -177,7 +239,7 @@ struct aiMetadata {
|
|||
|
||||
// Delete the metadata array
|
||||
delete [] mValues;
|
||||
mValues = NULL;
|
||||
mValues = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -208,8 +270,8 @@ struct aiMetadata {
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
inline void Add(const std::string& key, const T& value)
|
||||
{
|
||||
inline
|
||||
void Add(const std::string& key, const T& value) {
|
||||
aiString* new_keys = new aiString[mNumProperties + 1];
|
||||
aiMetadataEntry* new_values = new aiMetadataEntry[mNumProperties + 1];
|
||||
|
||||
|
@ -256,7 +318,7 @@ struct aiMetadata {
|
|||
|
||||
template<typename T>
|
||||
inline
|
||||
bool Get( unsigned index, T& value ) {
|
||||
bool Get( unsigned index, T& value ) const {
|
||||
// In range assertion
|
||||
if ( index >= mNumProperties ) {
|
||||
return false;
|
||||
|
@ -277,7 +339,7 @@ struct aiMetadata {
|
|||
|
||||
template<typename T>
|
||||
inline
|
||||
bool Get( const aiString& key, T& value ) {
|
||||
bool Get( const aiString& key, T& value ) const {
|
||||
// Search for the given key
|
||||
for ( unsigned int i = 0; i < mNumProperties; ++i ) {
|
||||
if ( mKeys[ i ] == key ) {
|
||||
|
@ -288,7 +350,8 @@ struct aiMetadata {
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool Get( const std::string& key, T& value ) {
|
||||
inline
|
||||
bool Get( const std::string& key, T& value ) const {
|
||||
return Get(aiString(key), value);
|
||||
}
|
||||
|
||||
|
@ -297,7 +360,8 @@ struct aiMetadata {
|
|||
/// \param [out] pKey - pointer to the key value.
|
||||
/// \param [out] pEntry - pointer to the entry: type and value.
|
||||
/// \return false - if pIndex is out of range, else - true.
|
||||
inline bool Get(size_t index, const aiString*& key, const aiMetadataEntry*& entry) {
|
||||
inline
|
||||
bool Get(size_t index, const aiString*& key, const aiMetadataEntry*& entry) const {
|
||||
if ( index >= mNumProperties ) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -181,3 +181,74 @@ TEST_F( utMetadata, get_set_aiVector3D_Test ) {
|
|||
EXPECT_TRUE( success );
|
||||
}
|
||||
|
||||
TEST_F( utMetadata, copy_test ) {
|
||||
m_data = aiMetadata::Alloc( AI_META_MAX );
|
||||
bool bv = true;
|
||||
m_data->Set( 0, "bool", bv );
|
||||
int32_t i32v = -10;
|
||||
m_data->Set( 1, "int32", i32v );
|
||||
uint64_t ui64v = static_cast<uint64_t>( 10 );
|
||||
m_data->Set( 2, "uint64", ui64v );
|
||||
float fv = 1.0f;
|
||||
m_data->Set( 3, "float", fv );
|
||||
double dv = 2.0;
|
||||
m_data->Set( 4, "double", dv );
|
||||
const aiString strVal( std::string( "test" ) );
|
||||
m_data->Set( 5, "aiString", strVal );
|
||||
aiVector3D vecVal( 1, 2, 3 );
|
||||
m_data->Set( 6, "aiVector3D", vecVal );
|
||||
|
||||
aiMetadata copy( *m_data );
|
||||
EXPECT_EQ( 7, copy.mNumProperties );
|
||||
|
||||
// bool test
|
||||
{
|
||||
bool v;
|
||||
EXPECT_TRUE( copy.Get( "bool", v ) );
|
||||
EXPECT_EQ( bv, v );
|
||||
}
|
||||
|
||||
// int32_t test
|
||||
{
|
||||
int32_t v;
|
||||
bool ok = copy.Get( "int32", v );
|
||||
EXPECT_TRUE( ok );
|
||||
EXPECT_EQ( i32v, v );
|
||||
}
|
||||
|
||||
// uint64_t test
|
||||
{
|
||||
uint64_t v;
|
||||
bool ok = copy.Get( "uint64", v );
|
||||
EXPECT_TRUE( ok );
|
||||
EXPECT_EQ( ui64v, v );
|
||||
}
|
||||
|
||||
// float test
|
||||
{
|
||||
float v;
|
||||
EXPECT_TRUE( copy.Get( "float", v ) );
|
||||
EXPECT_EQ( fv, v );
|
||||
}
|
||||
|
||||
// double test
|
||||
{
|
||||
double v;
|
||||
EXPECT_TRUE( copy.Get( "double", v ) );
|
||||
EXPECT_EQ( dv, v );
|
||||
}
|
||||
|
||||
// bool test
|
||||
{
|
||||
aiString v;
|
||||
EXPECT_TRUE( copy.Get( "aiString", v ) );
|
||||
EXPECT_EQ( strVal, v );
|
||||
}
|
||||
|
||||
// bool test
|
||||
{
|
||||
aiVector3D v;
|
||||
EXPECT_TRUE( copy.Get( "aiVector3D", v ) );
|
||||
EXPECT_EQ( vecVal, v );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue