Merge remote-tracking branch 'origin/master' into HEAD
This commit is contained in:
@@ -348,16 +348,16 @@ struct Texture {
|
||||
// empty
|
||||
}
|
||||
|
||||
Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(std::move(other.mTextureBlend)),
|
||||
Texture(Texture &&other) AI_NO_EXCEPT : mTextureBlend(other.mTextureBlend),
|
||||
mMapName(std::move(other.mMapName)),
|
||||
mOffsetU(std::move(other.mOffsetU)),
|
||||
mOffsetV(std::move(other.mOffsetV)),
|
||||
mScaleU(std::move(other.mScaleU)),
|
||||
mScaleV(std::move(other.mScaleV)),
|
||||
mRotation(std::move(other.mRotation)),
|
||||
mMapMode(std::move(other.mMapMode)),
|
||||
bPrivate(std::move(other.bPrivate)),
|
||||
iUVSrc(std::move(other.iUVSrc)) {
|
||||
mOffsetU(other.mOffsetU),
|
||||
mOffsetV(other.mOffsetV),
|
||||
mScaleU(other.mScaleU),
|
||||
mScaleV(other.mScaleV),
|
||||
mRotation(other.mRotation),
|
||||
mMapMode(other.mMapMode),
|
||||
bPrivate(other.bPrivate),
|
||||
iUVSrc(other.iUVSrc) {
|
||||
// empty
|
||||
}
|
||||
|
||||
@@ -366,16 +366,16 @@ struct Texture {
|
||||
return *this;
|
||||
}
|
||||
|
||||
mTextureBlend = std::move(other.mTextureBlend);
|
||||
mTextureBlend = other.mTextureBlend;
|
||||
mMapName = std::move(other.mMapName);
|
||||
mOffsetU = std::move(other.mOffsetU);
|
||||
mOffsetV = std::move(other.mOffsetV);
|
||||
mScaleU = std::move(other.mScaleU);
|
||||
mScaleV = std::move(other.mScaleV);
|
||||
mRotation = std::move(other.mRotation);
|
||||
mMapMode = std::move(other.mMapMode);
|
||||
bPrivate = std::move(other.bPrivate);
|
||||
iUVSrc = std::move(other.iUVSrc);
|
||||
mOffsetU = other.mOffsetU;
|
||||
mOffsetV = other.mOffsetV;
|
||||
mScaleU = other.mScaleU;
|
||||
mScaleV = other.mScaleV;
|
||||
mRotation = other.mRotation;
|
||||
mMapMode = other.mMapMode;
|
||||
bPrivate = other.bPrivate;
|
||||
iUVSrc = other.iUVSrc;
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -461,13 +461,13 @@ struct Material {
|
||||
|
||||
//! Move constructor. This is explicitly written because MSVC doesn't support defaulting it
|
||||
Material(Material &&other) AI_NO_EXCEPT : mName(std::move(other.mName)),
|
||||
mDiffuse(std::move(other.mDiffuse)),
|
||||
mSpecularExponent(std::move(other.mSpecularExponent)),
|
||||
mShininessStrength(std::move(other.mShininessStrength)),
|
||||
mSpecular(std::move(other.mSpecular)),
|
||||
mAmbient(std::move(other.mAmbient)),
|
||||
mShading(std::move(other.mShading)),
|
||||
mTransparency(std::move(other.mTransparency)),
|
||||
mDiffuse(other.mDiffuse),
|
||||
mSpecularExponent(other.mSpecularExponent),
|
||||
mShininessStrength(other.mShininessStrength),
|
||||
mSpecular(other.mSpecular),
|
||||
mAmbient(other.mAmbient),
|
||||
mShading(other.mShading),
|
||||
mTransparency(other.mTransparency),
|
||||
sTexDiffuse(std::move(other.sTexDiffuse)),
|
||||
sTexOpacity(std::move(other.sTexOpacity)),
|
||||
sTexSpecular(std::move(other.sTexSpecular)),
|
||||
@@ -475,10 +475,10 @@ struct Material {
|
||||
sTexBump(std::move(other.sTexBump)),
|
||||
sTexEmissive(std::move(other.sTexEmissive)),
|
||||
sTexShininess(std::move(other.sTexShininess)),
|
||||
mBumpHeight(std::move(other.mBumpHeight)),
|
||||
mEmissive(std::move(other.mEmissive)),
|
||||
mBumpHeight(other.mBumpHeight),
|
||||
mEmissive(other.mEmissive),
|
||||
sTexAmbient(std::move(other.sTexAmbient)),
|
||||
mTwoSided(std::move(other.mTwoSided)) {
|
||||
mTwoSided(other.mTwoSided) {
|
||||
// empty
|
||||
}
|
||||
|
||||
@@ -488,13 +488,13 @@ struct Material {
|
||||
}
|
||||
|
||||
mName = std::move(other.mName);
|
||||
mDiffuse = std::move(other.mDiffuse);
|
||||
mSpecularExponent = std::move(other.mSpecularExponent);
|
||||
mShininessStrength = std::move(other.mShininessStrength),
|
||||
mSpecular = std::move(other.mSpecular);
|
||||
mAmbient = std::move(other.mAmbient);
|
||||
mShading = std::move(other.mShading);
|
||||
mTransparency = std::move(other.mTransparency);
|
||||
mDiffuse = other.mDiffuse;
|
||||
mSpecularExponent = other.mSpecularExponent;
|
||||
mShininessStrength = other.mShininessStrength,
|
||||
mSpecular = other.mSpecular;
|
||||
mAmbient = other.mAmbient;
|
||||
mShading = other.mShading;
|
||||
mTransparency = other.mTransparency;
|
||||
sTexDiffuse = std::move(other.sTexDiffuse);
|
||||
sTexOpacity = std::move(other.sTexOpacity);
|
||||
sTexSpecular = std::move(other.sTexSpecular);
|
||||
@@ -502,10 +502,10 @@ struct Material {
|
||||
sTexBump = std::move(other.sTexBump);
|
||||
sTexEmissive = std::move(other.sTexEmissive);
|
||||
sTexShininess = std::move(other.sTexShininess);
|
||||
mBumpHeight = std::move(other.mBumpHeight);
|
||||
mEmissive = std::move(other.mEmissive);
|
||||
mBumpHeight = other.mBumpHeight;
|
||||
mEmissive = other.mEmissive;
|
||||
sTexAmbient = std::move(other.sTexAmbient);
|
||||
mTwoSided = std::move(other.mTwoSided);
|
||||
mTwoSided = other.mTwoSided;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -95,8 +95,8 @@ struct Material : public D3DS::Material {
|
||||
Material(Material &&other) AI_NO_EXCEPT
|
||||
: D3DS::Material(std::move(other)),
|
||||
avSubMaterials(std::move(other.avSubMaterials)),
|
||||
pcInstance(std::move(other.pcInstance)),
|
||||
bNeed(std::move(other.bNeed)) {
|
||||
pcInstance(other.pcInstance),
|
||||
bNeed(other.bNeed) {
|
||||
other.pcInstance = nullptr;
|
||||
}
|
||||
|
||||
@@ -108,8 +108,8 @@ struct Material : public D3DS::Material {
|
||||
//D3DS::Material::operator=(std::move(other));
|
||||
|
||||
avSubMaterials = std::move(other.avSubMaterials);
|
||||
pcInstance = std::move(other.pcInstance);
|
||||
bNeed = std::move(other.bNeed);
|
||||
pcInstance = other.pcInstance;
|
||||
bNeed = other.bNeed;
|
||||
|
||||
other.pcInstance = nullptr;
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ AI_WONT_RETURN void B3DImporter::Oops() {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AI_WONT_RETURN void B3DImporter::Fail(string str) {
|
||||
AI_WONT_RETURN void B3DImporter::Fail(const string &str) {
|
||||
#ifdef DEBUG_B3D
|
||||
ASSIMP_LOG_ERROR("Error in B3D file data: ", str);
|
||||
#endif
|
||||
|
||||
@@ -96,7 +96,7 @@ private:
|
||||
};
|
||||
|
||||
AI_WONT_RETURN void Oops() AI_WONT_RETURN_SUFFIX;
|
||||
AI_WONT_RETURN void Fail( std::string str ) AI_WONT_RETURN_SUFFIX;
|
||||
AI_WONT_RETURN void Fail(const std::string &str) AI_WONT_RETURN_SUFFIX;
|
||||
|
||||
void ReadTEXS();
|
||||
void ReadBRUS();
|
||||
|
||||
@@ -679,7 +679,7 @@ void BlenderImporter::BuildMaterials(ConversionData &conv_data) {
|
||||
|
||||
BuildDefaultMaterial(conv_data);
|
||||
|
||||
for (std::shared_ptr<Material> mat : conv_data.materials_raw) {
|
||||
for (const std::shared_ptr<Material> &mat : conv_data.materials_raw) {
|
||||
|
||||
// reset per material global counters
|
||||
for (size_t i = 0; i < sizeof(conv_data.next_texture) / sizeof(conv_data.next_texture[0]); ++i) {
|
||||
|
||||
@@ -230,7 +230,7 @@ void COBImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertTexture(std::shared_ptr<Texture> tex, aiMaterial *out, aiTextureType type) {
|
||||
void ConvertTexture(const std::shared_ptr<Texture> &tex, aiMaterial *out, aiTextureType type) {
|
||||
const aiString path(tex->path);
|
||||
out->AddProperty(&path, AI_MATKEY_TEXTURE(type, 0));
|
||||
out->AddProperty(&tex->transform, 1, AI_MATKEY_UVTRANSFORM(type, 0));
|
||||
|
||||
@@ -453,7 +453,7 @@ void ColladaParser::PostProcessRootAnimations() {
|
||||
|
||||
temp.mSubAnims.push_back(clip);
|
||||
|
||||
for (std::string animationID : it.second) {
|
||||
for (const std::string &animationID : it.second) {
|
||||
AnimationLibrary::iterator animation = mAnimationLibrary.find(animationID);
|
||||
|
||||
if (animation != mAnimationLibrary.end()) {
|
||||
|
||||
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2021, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -1766,6 +1766,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const TextureMap
|
||||
// XXX handle all kinds of UV transformations
|
||||
uvTrafo.mScaling = tex->UVScaling();
|
||||
uvTrafo.mTranslation = tex->UVTranslation();
|
||||
uvTrafo.mRotation = tex->UVRotation();
|
||||
out_mat->AddProperty(&uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, 0);
|
||||
|
||||
const PropertyTable &props = tex->Props();
|
||||
@@ -1885,6 +1886,7 @@ void FBXConverter::TrySetTextureProperties(aiMaterial *out_mat, const LayeredTex
|
||||
// XXX handle all kinds of UV transformations
|
||||
uvTrafo.mScaling = tex->UVScaling();
|
||||
uvTrafo.mTranslation = tex->UVTranslation();
|
||||
uvTrafo.mRotation = tex->UVRotation();
|
||||
out_mat->AddProperty(&uvTrafo, 1, _AI_MATKEY_UVTRANSFORM_BASE, target, texIndex);
|
||||
|
||||
const PropertyTable &props = tex->Props();
|
||||
@@ -2324,6 +2326,7 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial *out_mat, const PropertyTa
|
||||
// XXX handle all kinds of UV transformations
|
||||
uvTrafo.mScaling = tex->UVScaling();
|
||||
uvTrafo.mTranslation = tex->UVTranslation();
|
||||
uvTrafo.mRotation = tex->UVRotation();
|
||||
out_mat->AddProperty(&uvTrafo, 1, (name + "|uvtrafo").c_str(), aiTextureType_UNKNOWN, 0);
|
||||
|
||||
int uvIndex = 0;
|
||||
@@ -2599,7 +2602,7 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) {
|
||||
anim->mMorphMeshChannels = new aiMeshMorphAnim *[numMorphMeshChannels];
|
||||
anim->mNumMorphMeshChannels = numMorphMeshChannels;
|
||||
unsigned int i = 0;
|
||||
for (auto morphAnimIt : morphAnimDatas) {
|
||||
for (const auto &morphAnimIt : morphAnimDatas) {
|
||||
morphAnimData *animData = morphAnimIt.second;
|
||||
unsigned int numKeys = static_cast<unsigned int>(animData->size());
|
||||
aiMeshMorphAnim *meshMorphAnim = new aiMeshMorphAnim();
|
||||
|
||||
@@ -57,9 +57,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <assimp/DefaultLogger.hpp>
|
||||
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
@@ -248,10 +249,8 @@ Object::~Object()
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
FileGlobalSettings::FileGlobalSettings(const Document& doc, std::shared_ptr<const PropertyTable> props)
|
||||
: props(props)
|
||||
, doc(doc)
|
||||
{
|
||||
FileGlobalSettings::FileGlobalSettings(const Document &doc, std::shared_ptr<const PropertyTable> props) :
|
||||
props(std::move(props)), doc(doc) {
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
@@ -500,6 +500,10 @@ public:
|
||||
return uvScaling;
|
||||
}
|
||||
|
||||
const ai_real &UVRotation() const {
|
||||
return uvRotation;
|
||||
}
|
||||
|
||||
const PropertyTable& Props() const {
|
||||
ai_assert(props.get());
|
||||
return *props.get();
|
||||
@@ -517,6 +521,7 @@ public:
|
||||
private:
|
||||
aiVector2D uvTrans;
|
||||
aiVector2D uvScaling;
|
||||
ai_real uvRotation;
|
||||
|
||||
std::string type;
|
||||
std::string relativeFileName;
|
||||
|
||||
@@ -144,9 +144,8 @@ void FBX::Node::AddP70time(
|
||||
// public member functions for writing nodes to stream
|
||||
|
||||
void FBX::Node::Dump(
|
||||
std::shared_ptr<Assimp::IOStream> outfile,
|
||||
bool binary, int indent
|
||||
) {
|
||||
const std::shared_ptr<Assimp::IOStream> &outfile,
|
||||
bool binary, int indent) {
|
||||
if (binary) {
|
||||
Assimp::StreamWriterLE outstream(outfile);
|
||||
DumpBinary(outstream);
|
||||
|
||||
@@ -157,9 +157,8 @@ public: // member functions for writing data to a file or stream
|
||||
|
||||
// write the full node to the given file or stream
|
||||
void Dump(
|
||||
std::shared_ptr<Assimp::IOStream> outfile,
|
||||
bool binary, int indent
|
||||
);
|
||||
const std::shared_ptr<Assimp::IOStream> &outfile,
|
||||
bool binary, int indent);
|
||||
void Dump(Assimp::StreamWriterLE &s, bool binary, int indent);
|
||||
|
||||
// these other functions are for writing data piece by piece.
|
||||
|
||||
@@ -541,10 +541,17 @@ void FBXExporter::WriteReferences ()
|
||||
// (before any actual data is written)
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
size_t count_nodes(const aiNode* n) {
|
||||
size_t count = 1;
|
||||
size_t count_nodes(const aiNode* n, const aiNode* root) {
|
||||
size_t count;
|
||||
if (n == root) {
|
||||
count = n->mNumMeshes; // (not counting root node)
|
||||
} else if (n->mNumMeshes > 1) {
|
||||
count = n->mNumMeshes + 1;
|
||||
} else {
|
||||
count = 1;
|
||||
}
|
||||
for (size_t i = 0; i < n->mNumChildren; ++i) {
|
||||
count += count_nodes(n->mChildren[i]);
|
||||
count += count_nodes(n->mChildren[i], root);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
@@ -714,7 +721,7 @@ void FBXExporter::WriteDefinitions ()
|
||||
|
||||
// Model / FbxNode
|
||||
// <~~ node hierarchy
|
||||
count = int32_t(count_nodes(mScene->mRootNode)) - 1; // (not counting root node)
|
||||
count = int32_t(count_nodes(mScene->mRootNode, mScene->mRootNode));
|
||||
if (count) {
|
||||
n = FBX::Node("ObjectType", "Model");
|
||||
n.AddChild("Count", count);
|
||||
@@ -1681,6 +1688,10 @@ void FBXExporter::WriteObjects ()
|
||||
// link the image data to the texture
|
||||
connections.emplace_back("C", "OO", image_uid, texture_uid);
|
||||
|
||||
aiUVTransform trafo;
|
||||
unsigned int max = sizeof(aiUVTransform);
|
||||
aiGetMaterialFloatArray(mat, AI_MATKEY_UVTRANSFORM(aiTextureType_DIFFUSE, 0), (float *)&trafo, &max);
|
||||
|
||||
// now write the actual texture node
|
||||
FBX::Node tnode("Texture");
|
||||
// TODO: some way to determine texture name?
|
||||
@@ -1691,6 +1702,9 @@ void FBXExporter::WriteObjects ()
|
||||
tnode.AddChild("Version", int32_t(202));
|
||||
tnode.AddChild("TextureName", texture_name);
|
||||
FBX::Node p("Properties70");
|
||||
p.AddP70vectorA("Translation", trafo.mTranslation[0], trafo.mTranslation[1], 0.0);
|
||||
p.AddP70vectorA("Rotation", 0, 0, trafo.mRotation);
|
||||
p.AddP70vectorA("Scaling", trafo.mScaling[0], trafo.mScaling[1], 0.0);
|
||||
p.AddP70enum("CurrentTextureBlendMode", 0); // TODO: verify
|
||||
//p.AddP70string("UVSet", ""); // TODO: how should this work?
|
||||
p.AddP70bool("UseMaterial", 1);
|
||||
@@ -2196,7 +2210,65 @@ void FBXExporter::WriteObjects ()
|
||||
bpnode.Dump(outstream, binary, indent);
|
||||
}*/
|
||||
|
||||
// TODO: cameras, lights
|
||||
// lights
|
||||
indent = 1;
|
||||
lights_uids.clear();
|
||||
for (size_t li = 0; li < mScene->mNumLights; ++li) {
|
||||
aiLight* l = mScene->mLights[li];
|
||||
|
||||
int64_t uid = generate_uid();
|
||||
const std::string lightNodeAttributeName = l->mName.C_Str() + FBX::SEPARATOR + "NodeAttribute";
|
||||
|
||||
FBX::Node lna("NodeAttribute");
|
||||
lna.AddProperties(uid, lightNodeAttributeName, "Light");
|
||||
FBX::Node lnap("Properties70");
|
||||
|
||||
// Light color.
|
||||
lnap.AddP70colorA("Color", l->mColorDiffuse.r, l->mColorDiffuse.g, l->mColorDiffuse.b);
|
||||
|
||||
// TODO Assimp light description is quite concise and do not handle light intensity.
|
||||
// Default value to 1000W.
|
||||
lnap.AddP70numberA("Intensity", 1000);
|
||||
|
||||
// FBXLight::EType conversion
|
||||
switch (l->mType) {
|
||||
case aiLightSource_POINT:
|
||||
lnap.AddP70enum("LightType", 0);
|
||||
break;
|
||||
case aiLightSource_DIRECTIONAL:
|
||||
lnap.AddP70enum("LightType", 1);
|
||||
break;
|
||||
case aiLightSource_SPOT:
|
||||
lnap.AddP70enum("LightType", 2);
|
||||
lnap.AddP70numberA("InnerAngle", AI_RAD_TO_DEG(l->mAngleInnerCone));
|
||||
lnap.AddP70numberA("OuterAngle", AI_RAD_TO_DEG(l->mAngleOuterCone));
|
||||
break;
|
||||
// TODO Assimp do not handle 'area' nor 'volume' lights, but FBX does.
|
||||
/*case aiLightSource_AREA:
|
||||
lnap.AddP70enum("LightType", 3);
|
||||
lnap.AddP70enum("AreaLightShape", 0); // 0=Rectangle, 1=Sphere
|
||||
break;
|
||||
case aiLightSource_VOLUME:
|
||||
lnap.AddP70enum("LightType", 4);
|
||||
break;*/
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// Did not understood how to configure the decay so disabling attenuation.
|
||||
lnap.AddP70enum("DecayType", 0);
|
||||
|
||||
// Dump to FBX stream
|
||||
lna.AddChild(lnap);
|
||||
lna.AddChild("TypeFlags", FBX::FBXExportProperty("Light"));
|
||||
lna.AddChild("GeometryVersion", FBX::FBXExportProperty(int32_t(124)));
|
||||
lna.Dump(outstream, binary, indent);
|
||||
|
||||
// Store name and uid (will be used later when parsing scene nodes)
|
||||
lights_uids[l->mName.C_Str()] = uid;
|
||||
}
|
||||
|
||||
// TODO: cameras
|
||||
|
||||
// write nodes (i.e. model hierarchy)
|
||||
// start at root node
|
||||
@@ -2600,10 +2672,19 @@ void FBXExporter::WriteModelNodes(
|
||||
// and connect them
|
||||
connections.emplace_back("C", "OO", node_attribute_uid, node_uid);
|
||||
} else {
|
||||
// generate a null node so we can add children to it
|
||||
WriteModelNode(
|
||||
outstream, binary, node, node_uid, "Null", transform_chain
|
||||
);
|
||||
const auto& lightIt = lights_uids.find(node->mName.C_Str());
|
||||
if(lightIt != lights_uids.end()) {
|
||||
// Node has a light connected to it.
|
||||
WriteModelNode(
|
||||
outstream, binary, node, node_uid, "Light", transform_chain
|
||||
);
|
||||
connections.emplace_back("C", "OO", lightIt->second, node_uid);
|
||||
} else {
|
||||
// generate a null node so we can add children to it
|
||||
WriteModelNode(
|
||||
outstream, binary, node, node_uid, "Null", transform_chain
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// if more than one child mesh, make nodes for each mesh
|
||||
@@ -2625,17 +2706,14 @@ void FBXExporter::WriteModelNodes(
|
||||
],
|
||||
new_node_uid
|
||||
);
|
||||
// write model node
|
||||
FBX::Node m("Model");
|
||||
|
||||
aiNode new_node;
|
||||
// take name from mesh name, if it exists
|
||||
std::string name = mScene->mMeshes[node->mMeshes[i]]->mName.C_Str();
|
||||
name += FBX::SEPARATOR + "Model";
|
||||
m.AddProperties(new_node_uid, name, "Mesh");
|
||||
m.AddChild("Version", int32_t(232));
|
||||
FBX::Node p("Properties70");
|
||||
p.AddP70enum("InheritType", 1);
|
||||
m.AddChild(p);
|
||||
m.Dump(outstream, binary, 1);
|
||||
new_node.mName = mScene->mMeshes[node->mMeshes[i]]->mName;
|
||||
// write model node
|
||||
WriteModelNode(
|
||||
outstream, binary, &new_node, new_node_uid, "Mesh", std::vector<std::pair<std::string,aiVector3D>>()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2647,16 +2725,14 @@ void FBXExporter::WriteModelNodes(
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void FBXExporter::WriteAnimationCurveNode(
|
||||
StreamWriterLE& outstream,
|
||||
int64_t uid,
|
||||
const std::string& name, // "T", "R", or "S"
|
||||
aiVector3D default_value,
|
||||
std::string property_name, // "Lcl Translation" etc
|
||||
int64_t layer_uid,
|
||||
int64_t node_uid
|
||||
) {
|
||||
StreamWriterLE &outstream,
|
||||
int64_t uid,
|
||||
const std::string &name, // "T", "R", or "S"
|
||||
aiVector3D default_value,
|
||||
const std::string &property_name, // "Lcl Translation" etc
|
||||
int64_t layer_uid,
|
||||
int64_t node_uid) {
|
||||
FBX::Node n("AnimationCurveNode");
|
||||
n.AddProperties(uid, name + FBX::SEPARATOR + "AnimCurveNode", "");
|
||||
FBX::Node p("Properties70");
|
||||
@@ -2671,7 +2747,6 @@ void FBXExporter::WriteAnimationCurveNode(
|
||||
this->connections.emplace_back("C", "OP", uid, node_uid, property_name);
|
||||
}
|
||||
|
||||
|
||||
void FBXExporter::WriteAnimationCurve(
|
||||
StreamWriterLE& outstream,
|
||||
double default_value,
|
||||
|
||||
@@ -63,10 +63,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
struct aiScene;
|
||||
struct aiNode;
|
||||
//struct aiMaterial;
|
||||
struct aiLight;
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
namespace Assimp {
|
||||
class IOSystem;
|
||||
class IOStream;
|
||||
class ExportProperties;
|
||||
@@ -95,6 +94,7 @@ namespace Assimp
|
||||
std::vector<int64_t> mesh_uids;
|
||||
std::vector<int64_t> material_uids;
|
||||
std::map<const aiNode*,int64_t> node_uids;
|
||||
std::map<std::string,int64_t> lights_uids;
|
||||
|
||||
// this crude unique-ID system is actually fine
|
||||
int64_t last_uid = 999999;
|
||||
@@ -154,14 +154,13 @@ namespace Assimp
|
||||
FBX::TransformInheritance ti_type=FBX::TransformInheritance_RSrs
|
||||
);
|
||||
void WriteAnimationCurveNode(
|
||||
StreamWriterLE& outstream,
|
||||
int64_t uid,
|
||||
const std::string& name, // "T", "R", or "S"
|
||||
aiVector3D default_value,
|
||||
std::string property_name, // "Lcl Translation" etc
|
||||
int64_t animation_layer_uid,
|
||||
int64_t node_uid
|
||||
);
|
||||
StreamWriterLE &outstream,
|
||||
int64_t uid,
|
||||
const std::string &name, // "T", "R", or "S"
|
||||
aiVector3D default_value,
|
||||
const std::string &property_name, // "Lcl Translation" etc
|
||||
int64_t animation_layer_uid,
|
||||
int64_t node_uid);
|
||||
void WriteAnimationCurve(
|
||||
StreamWriterLE& outstream,
|
||||
double default_value,
|
||||
|
||||
@@ -210,6 +210,11 @@ Texture::Texture(uint64_t id, const Element& element, const Document& doc, const
|
||||
uvTrans.y = trans.y;
|
||||
}
|
||||
|
||||
const aiVector3D &rotation = PropertyGet<aiVector3D>(*props, "Rotation", ok);
|
||||
if (ok) {
|
||||
uvRotation = rotation.z;
|
||||
}
|
||||
|
||||
// resolve video links
|
||||
if(doc.Settings().readTextures) {
|
||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID());
|
||||
|
||||
@@ -52,6 +52,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "FBXDocumentUtil.h"
|
||||
#include "FBXProperties.h"
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
||||
@@ -172,10 +174,8 @@ PropertyTable::PropertyTable()
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
PropertyTable::PropertyTable(const Element& element, std::shared_ptr<const PropertyTable> templateProps)
|
||||
: templateProps(templateProps)
|
||||
, element(&element)
|
||||
{
|
||||
PropertyTable::PropertyTable(const Element &element, std::shared_ptr<const PropertyTable> templateProps) :
|
||||
templateProps(std::move(templateProps)), element(&element) {
|
||||
const Scope& scope = GetRequiredScope(element);
|
||||
for(const ElementMap::value_type& v : scope.Elements()) {
|
||||
if(v.first != "P") {
|
||||
@@ -199,7 +199,6 @@ PropertyTable::PropertyTable(const Element& element, std::shared_ptr<const Prope
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
PropertyTable::~PropertyTable()
|
||||
{
|
||||
|
||||
@@ -513,7 +513,7 @@ void ProcessPolygonalBoundedBooleanHalfSpaceDifference(const Schema_2x3::IfcPoly
|
||||
}
|
||||
|
||||
// we got a list of in-out-combinations of intersections. That should be an even number of intersections, or
|
||||
// we're fucked.
|
||||
// we are facing a non-recoverable error.
|
||||
if ((intersections.size() & 1) != 0) {
|
||||
IFCImporter::LogWarn("Odd number of intersections, can't work with that. Omitting half space boundary check.");
|
||||
continue;
|
||||
|
||||
@@ -740,7 +740,7 @@ bool ProcessGeometricItem(const Schema_2x3::IfcRepresentationItem& geo, unsigned
|
||||
bool fix_orientation = false;
|
||||
std::shared_ptr< TempMesh > meshtmp = std::make_shared<TempMesh>();
|
||||
if(const Schema_2x3::IfcShellBasedSurfaceModel* shellmod = geo.ToPtr<Schema_2x3::IfcShellBasedSurfaceModel>()) {
|
||||
for(std::shared_ptr<const Schema_2x3::IfcShell> shell :shellmod->SbsmBoundary) {
|
||||
for (const std::shared_ptr<const Schema_2x3::IfcShell> &shell : shellmod->SbsmBoundary) {
|
||||
try {
|
||||
const ::Assimp::STEP::EXPRESS::ENTITY& e = shell->To<::Assimp::STEP::EXPRESS::ENTITY>();
|
||||
const Schema_2x3::IfcConnectedFaceSet& fs = conv.db.MustGetObject(e).To<Schema_2x3::IfcConnectedFaceSet>();
|
||||
|
||||
@@ -75,7 +75,7 @@ static void FillMaterial(aiMaterial* mat,const IFC::Schema_2x3::IfcSurfaceStyle*
|
||||
mat->AddProperty(&name,AI_MATKEY_NAME);
|
||||
|
||||
// now see which kinds of surface information are present
|
||||
for(std::shared_ptr< const IFC::Schema_2x3::IfcSurfaceStyleElementSelect > sel2 : surf->Styles) {
|
||||
for (const std::shared_ptr<const IFC::Schema_2x3::IfcSurfaceStyleElementSelect> &sel2 : surf->Styles) {
|
||||
if (const IFC::Schema_2x3::IfcSurfaceStyleShading* shade = sel2->ResolveSelectPtr<IFC::Schema_2x3::IfcSurfaceStyleShading>(conv.db)) {
|
||||
aiColor4D col_base,col;
|
||||
|
||||
@@ -124,7 +124,7 @@ static void FillMaterial(aiMaterial* mat,const IFC::Schema_2x3::IfcSurfaceStyle*
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -134,7 +134,7 @@ unsigned int ProcessMaterials(uint64_t id, unsigned int prevMatId, ConversionDat
|
||||
for(;range.first != range.second; ++range.first) {
|
||||
if(const IFC::Schema_2x3::IfcStyledItem* const styled = conv.db.GetObject((*range.first).second)->ToPtr<IFC::Schema_2x3::IfcStyledItem>()) {
|
||||
for(const IFC::Schema_2x3::IfcPresentationStyleAssignment& as : styled->Styles) {
|
||||
for(std::shared_ptr<const IFC::Schema_2x3::IfcPresentationStyleSelect> sel : as.Styles) {
|
||||
for (const std::shared_ptr<const IFC::Schema_2x3::IfcPresentationStyleSelect> &sel : as.Styles) {
|
||||
|
||||
if( const IFC::Schema_2x3::IfcSurfaceStyle* const surf = sel->ResolveSelectPtr<IFC::Schema_2x3::IfcSurfaceStyle>(conv.db) ) {
|
||||
// try to satisfy from cache
|
||||
|
||||
@@ -54,6 +54,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <assimp/mesh.h>
|
||||
#include <assimp/material.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
struct aiNode;
|
||||
|
||||
namespace Assimp {
|
||||
@@ -137,14 +139,10 @@ struct TempOpening
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
TempOpening(const IFC::Schema_2x3::IfcSolidModel* solid,IfcVector3 extrusionDir,
|
||||
std::shared_ptr<TempMesh> profileMesh,
|
||||
std::shared_ptr<TempMesh> profileMesh2D)
|
||||
: solid(solid)
|
||||
, extrusionDir(extrusionDir)
|
||||
, profileMesh(profileMesh)
|
||||
, profileMesh2D(profileMesh2D)
|
||||
{
|
||||
TempOpening(const IFC::Schema_2x3::IfcSolidModel *solid, IfcVector3 extrusionDir,
|
||||
std::shared_ptr<TempMesh> profileMesh,
|
||||
std::shared_ptr<TempMesh> profileMesh2D) :
|
||||
solid(solid), extrusionDir(extrusionDir), profileMesh(std::move(profileMesh)), profileMesh2D(std::move(profileMesh2D)) {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------
|
||||
|
||||
@@ -318,7 +318,7 @@ void LWSImporter::SetupNodeName(aiNode *nd, LWS::NodeDesc &src) {
|
||||
} else {
|
||||
++s;
|
||||
}
|
||||
std::string::size_type t = src.path.substr(s).find_last_of(".");
|
||||
std::string::size_type t = src.path.substr(s).find_last_of('.');
|
||||
|
||||
nd->mName.length = ::ai_snprintf(nd->mName.data, MAXLEN, "%s_(%08X)", src.path.substr(s).substr(0, t).c_str(), combined);
|
||||
return;
|
||||
|
||||
@@ -655,7 +655,7 @@ void M3DImporter::convertPose(const M3DWrapper &m3d, aiMatrix4x4 *m, unsigned in
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// find a node by name
|
||||
aiNode *M3DImporter::findNode(aiNode *pNode, aiString name) {
|
||||
aiNode *M3DImporter::findNode(aiNode *pNode, const aiString &name) {
|
||||
ai_assert(pNode != nullptr);
|
||||
ai_assert(mScene != nullptr);
|
||||
|
||||
|
||||
@@ -89,8 +89,8 @@ private:
|
||||
// helper functions
|
||||
aiColor4D mkColor(uint32_t c);
|
||||
void convertPose(const M3DWrapper &m3d, aiMatrix4x4 *m, unsigned int posid, unsigned int orientid);
|
||||
aiNode *findNode(aiNode *pNode, aiString name);
|
||||
void calculateOffsetMatrix(aiNode *pNode, aiMatrix4x4 *m);
|
||||
aiNode *findNode(aiNode *pNode, const aiString &name);
|
||||
void calculateOffsetMatrix(aiNode *pNode, aiMatrix4x4 *m);
|
||||
void populateMesh(const M3DWrapper &m3d, aiMesh *pMesh, std::vector<aiFace> *faces, std::vector<aiVector3D> *verteces,
|
||||
std::vector<aiVector3D> *normals, std::vector<aiVector3D> *texcoords, std::vector<aiColor4D> *colors,
|
||||
std::vector<unsigned int> *vertexids);
|
||||
|
||||
@@ -415,8 +415,8 @@ bool OgreImporter::ReadTextureUnit(const std::string &textureUnitName, stringstr
|
||||
|
||||
// User defined Assimp config property to detect texture type from filename.
|
||||
if (m_detectTextureTypeFromFilename) {
|
||||
size_t posSuffix = textureRef.find_last_of(".");
|
||||
size_t posUnderscore = textureRef.find_last_of("_");
|
||||
size_t posSuffix = textureRef.find_last_of('.');
|
||||
size_t posUnderscore = textureRef.find_last_of('_');
|
||||
|
||||
if (posSuffix != string::npos && posUnderscore != string::npos && posSuffix > posUnderscore) {
|
||||
string identifier = ai_tolower(textureRef.substr(posUnderscore, posSuffix - posUnderscore));
|
||||
|
||||
@@ -99,7 +99,7 @@ static void extractIds(const std::string &key, int &id1, int &id2) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string::size_type pos = key.find(".");
|
||||
const std::string::size_type pos = key.find('.');
|
||||
if (std::string::npos == pos) {
|
||||
return;
|
||||
}
|
||||
@@ -208,7 +208,7 @@ void Q3BSPFileImporter::separateMapName(const std::string &importName, std::stri
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string::size_type pos = importName.rfind(",");
|
||||
const std::string::size_type pos = importName.rfind(',');
|
||||
if (std::string::npos == pos) {
|
||||
archiveName = importName;
|
||||
return;
|
||||
|
||||
@@ -49,8 +49,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "STEPFileEncoding.h"
|
||||
#include <assimp/TinyFormatter.h>
|
||||
#include <assimp/fast_atof.h>
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
@@ -87,7 +88,7 @@ static const char *ISO_Token = "ISO-10303-21;";
|
||||
static const char *FILE_SCHEMA_Token = "FILE_SCHEMA";
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
STEP::DB* STEP::ReadFileHeader(std::shared_ptr<IOStream> stream) {
|
||||
std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(stream));
|
||||
std::shared_ptr<StreamReaderLE> reader = std::shared_ptr<StreamReaderLE>(new StreamReaderLE(std::move(stream)));
|
||||
std::unique_ptr<STEP::DB> db = std::unique_ptr<STEP::DB>(new STEP::DB(reader));
|
||||
|
||||
LineSplitter &splitter = db->GetSplitter();
|
||||
|
||||
@@ -634,7 +634,7 @@ private:
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline bool operator==(std::shared_ptr<LazyObject> lo, T whatever) {
|
||||
inline bool operator==(const std::shared_ptr<LazyObject> &lo, T whatever) {
|
||||
return *lo == whatever; // XXX use std::forward if we have 0x
|
||||
}
|
||||
|
||||
@@ -816,7 +816,7 @@ public:
|
||||
typedef std::pair<RefMap::const_iterator, RefMap::const_iterator> RefMapRange;
|
||||
|
||||
private:
|
||||
DB(std::shared_ptr<StreamReaderLE> reader) :
|
||||
DB(const std::shared_ptr<StreamReaderLE> &reader) :
|
||||
reader(reader), splitter(*reader, true, true), evaluated_count(), schema(nullptr) {}
|
||||
|
||||
public:
|
||||
|
||||
@@ -530,8 +530,8 @@ void XFileExporter::writePath(const aiString &path)
|
||||
while( str.find( "\\\\") != std::string::npos)
|
||||
str.replace( str.find( "\\\\"), 2, "\\");
|
||||
|
||||
while( str.find( "\\") != std::string::npos)
|
||||
str.replace( str.find( "\\"), 1, "/");
|
||||
while (str.find('\\') != std::string::npos)
|
||||
str.replace(str.find('\\'), 1, "/");
|
||||
|
||||
mOutput << str;
|
||||
|
||||
|
||||
@@ -63,9 +63,9 @@ class X3DExporter {
|
||||
// empty
|
||||
}
|
||||
|
||||
SAttribute(SAttribute && rhs) :
|
||||
Name(std::move(rhs.Name)),
|
||||
Value(std::move(rhs.Value)) {
|
||||
SAttribute(SAttribute &&rhs) AI_NO_EXCEPT :
|
||||
Name(rhs.Name),
|
||||
Value(rhs.Value) {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
|
||||
@@ -456,11 +456,10 @@ namespace glTF
|
||||
/// \param [in] pDecodedData - pointer to decoded data array.
|
||||
/// \param [in] pDecodedData_Length - size of encoded region, in bytes.
|
||||
/// \param [in] pID - ID of the region.
|
||||
SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t* pDecodedData, const size_t pDecodedData_Length, const std::string pID)
|
||||
: Offset(pOffset), EncodedData_Length(pEncodedData_Length), DecodedData(pDecodedData), DecodedData_Length(pDecodedData_Length), ID(pID)
|
||||
{}
|
||||
SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID) :
|
||||
Offset(pOffset), EncodedData_Length(pEncodedData_Length), DecodedData(pDecodedData), DecodedData_Length(pDecodedData_Length), ID(pID) {}
|
||||
|
||||
/// \fn ~SEncodedRegion()
|
||||
/// \fn ~SEncodedRegion()
|
||||
/// Destructor.
|
||||
~SEncodedRegion() { delete [] DecodedData; }
|
||||
};
|
||||
@@ -1149,8 +1148,7 @@ namespace glTF
|
||||
|
||||
void ReadExtensionsUsed(Document& doc);
|
||||
|
||||
|
||||
IOStream* OpenFile(std::string path, const char* mode, bool absolute = false);
|
||||
IOStream *OpenFile(const std::string &path, const char *mode, bool absolute = false);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -1377,7 +1377,7 @@ inline void Asset::ReadExtensionsUsed(Document &doc) {
|
||||
#undef CHECK_EXT
|
||||
}
|
||||
|
||||
inline IOStream *Asset::OpenFile(std::string path, const char *mode, bool absolute) {
|
||||
inline IOStream *Asset::OpenFile(const std::string& path, const char *mode, bool absolute) {
|
||||
#ifdef ASSIMP_API
|
||||
(void)absolute;
|
||||
return mIOSystem->Open(path, mode);
|
||||
|
||||
@@ -405,8 +405,7 @@ void glTFExporter::ExportMaterials()
|
||||
* Search through node hierarchy and find the node containing the given meshID.
|
||||
* Returns true on success, and false otherwise.
|
||||
*/
|
||||
bool FindMeshNode(Ref<Node>& nodeIn, Ref<Node>& meshNode, std::string meshID)
|
||||
{
|
||||
bool FindMeshNode(Ref<Node> &nodeIn, Ref<Node> &meshNode, const std::string &meshID) {
|
||||
for (unsigned int i = 0; i < nodeIn->meshes.size(); ++i) {
|
||||
if (meshID.compare(nodeIn->meshes[i]->id) == 0) {
|
||||
meshNode = nodeIn;
|
||||
|
||||
@@ -356,6 +356,53 @@ struct Nullable {
|
||||
isPresent(true) {}
|
||||
};
|
||||
|
||||
struct CustomExtension {
|
||||
//
|
||||
// A struct containing custom extension data added to a glTF2 file
|
||||
// Has to contain Object, Array, String, Double, Uint64, and Int64 at a minimum
|
||||
// String, Double, Uint64, and Int64 are stored in the Nullables
|
||||
// Object and Array are stored in the std::vector
|
||||
//
|
||||
std::string name;
|
||||
|
||||
Nullable<std::string> mStringValue;
|
||||
Nullable<double> mDoubleValue;
|
||||
Nullable<uint64_t> mUint64Value;
|
||||
Nullable<int64_t> mInt64Value;
|
||||
Nullable<bool> mBoolValue;
|
||||
|
||||
// std::vector<CustomExtension> handles both Object and Array
|
||||
Nullable<std::vector<CustomExtension>> mValues;
|
||||
|
||||
operator bool() const {
|
||||
return Size() != 0;
|
||||
}
|
||||
|
||||
size_t Size() const {
|
||||
if (mValues.isPresent) {
|
||||
return mValues.value.size();
|
||||
} else if (mStringValue.isPresent || mDoubleValue.isPresent || mUint64Value.isPresent || mInt64Value.isPresent || mBoolValue.isPresent) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
CustomExtension() = default;
|
||||
|
||||
~CustomExtension() = default;
|
||||
|
||||
CustomExtension(const CustomExtension &other) :
|
||||
name(other.name),
|
||||
mStringValue(other.mStringValue),
|
||||
mDoubleValue(other.mDoubleValue),
|
||||
mUint64Value(other.mUint64Value),
|
||||
mInt64Value(other.mInt64Value),
|
||||
mBoolValue(other.mBoolValue),
|
||||
mValues(other.mValues) {
|
||||
// empty
|
||||
}
|
||||
};
|
||||
|
||||
//! Base class for all glTF top-level objects
|
||||
struct Object {
|
||||
int index; //!< The index of this object within its property container
|
||||
@@ -363,6 +410,9 @@ struct Object {
|
||||
std::string id; //!< The globally unique ID used to reference this object
|
||||
std::string name; //!< The user-defined name of this object
|
||||
|
||||
CustomExtension customExtensions;
|
||||
CustomExtension extras;
|
||||
|
||||
//! Objects marked as special are not exported (used to emulate the binary body buffer)
|
||||
virtual bool IsSpecial() const { return false; }
|
||||
|
||||
@@ -377,6 +427,9 @@ struct Object {
|
||||
inline Value *FindArray(Value &val, const char *id);
|
||||
inline Value *FindObject(Value &val, const char *id);
|
||||
inline Value *FindExtension(Value &val, const char *extensionId);
|
||||
|
||||
inline void ReadExtensions(Value &val);
|
||||
inline void ReadExtras(Value &val);
|
||||
};
|
||||
|
||||
//
|
||||
@@ -408,7 +461,7 @@ public:
|
||||
/// \param [in] pDecodedData - pointer to decoded data array.
|
||||
/// \param [in] pDecodedData_Length - size of encoded region, in bytes.
|
||||
/// \param [in] pID - ID of the region.
|
||||
SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string pID) :
|
||||
SEncodedRegion(const size_t pOffset, const size_t pEncodedData_Length, uint8_t *pDecodedData, const size_t pDecodedData_Length, const std::string &pID) :
|
||||
Offset(pOffset),
|
||||
EncodedData_Length(pEncodedData_Length),
|
||||
DecodedData(pDecodedData),
|
||||
@@ -834,50 +887,6 @@ struct Mesh : public Object {
|
||||
void Read(Value &pJSON_Object, Asset &pAsset_Root);
|
||||
};
|
||||
|
||||
struct CustomExtension : public Object {
|
||||
//
|
||||
// A struct containing custom extension data added to a glTF2 file
|
||||
// Has to contain Object, Array, String, Double, Uint64, and Int64 at a minimum
|
||||
// String, Double, Uint64, and Int64 are stored in the Nullables
|
||||
// Object and Array are stored in the std::vector
|
||||
//
|
||||
|
||||
Nullable<std::string> mStringValue;
|
||||
Nullable<double> mDoubleValue;
|
||||
Nullable<uint64_t> mUint64Value;
|
||||
Nullable<int64_t> mInt64Value;
|
||||
Nullable<bool> mBoolValue;
|
||||
|
||||
// std::vector<CustomExtension> handles both Object and Array
|
||||
Nullable<std::vector<CustomExtension>> mValues;
|
||||
|
||||
operator bool() const {
|
||||
return Size() != 0;
|
||||
}
|
||||
|
||||
size_t Size() const {
|
||||
if (mValues.isPresent) {
|
||||
return mValues.value.size();
|
||||
} else if (mStringValue.isPresent || mDoubleValue.isPresent || mUint64Value.isPresent || mInt64Value.isPresent || mBoolValue.isPresent) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
CustomExtension() = default;
|
||||
|
||||
CustomExtension(const CustomExtension &other)
|
||||
: Object(other)
|
||||
, mStringValue(other.mStringValue)
|
||||
, mDoubleValue(other.mDoubleValue)
|
||||
, mUint64Value(other.mUint64Value)
|
||||
, mInt64Value(other.mInt64Value)
|
||||
, mBoolValue(other.mBoolValue)
|
||||
, mValues(other.mValues)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct Node : public Object {
|
||||
std::vector<Ref<Node>> children;
|
||||
std::vector<Ref<Mesh>> meshes;
|
||||
@@ -896,8 +905,6 @@ struct Node : public Object {
|
||||
|
||||
Ref<Node> parent; //!< This is not part of the glTF specification. Used as a helper.
|
||||
|
||||
CustomExtension extensions;
|
||||
|
||||
Node() {}
|
||||
void Read(Value &obj, Asset &r);
|
||||
};
|
||||
@@ -1188,7 +1195,7 @@ private:
|
||||
void ReadExtensionsUsed(Document &doc);
|
||||
void ReadExtensionsRequired(Document &doc);
|
||||
|
||||
IOStream *OpenFile(std::string path, const char *mode, bool absolute = false);
|
||||
IOStream *OpenFile(const std::string &path, const char *mode, bool absolute = false);
|
||||
};
|
||||
|
||||
inline std::string getContextForErrorMessages(const std::string &id, const std::string &name) {
|
||||
|
||||
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2021, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -304,6 +303,43 @@ inline Value *FindObject(Document &doc, const char *memberId) {
|
||||
inline Value *FindExtension(Value &val, const char *extensionId) {
|
||||
return FindExtensionInContext(val, extensionId, "the document");
|
||||
}
|
||||
|
||||
inline CustomExtension ReadExtensions(const char *name, Value &obj) {
|
||||
CustomExtension ret;
|
||||
ret.name = name;
|
||||
if (obj.IsObject()) {
|
||||
ret.mValues.isPresent = true;
|
||||
for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) {
|
||||
auto &val = it->value;
|
||||
ret.mValues.value.push_back(ReadExtensions(it->name.GetString(), val));
|
||||
}
|
||||
} else if (obj.IsArray()) {
|
||||
ret.mValues.value.reserve(obj.Size());
|
||||
ret.mValues.isPresent = true;
|
||||
for (unsigned int i = 0; i < obj.Size(); ++i) {
|
||||
ret.mValues.value.push_back(ReadExtensions(name, obj[i]));
|
||||
}
|
||||
} else if (obj.IsNumber()) {
|
||||
if (obj.IsUint64()) {
|
||||
ret.mUint64Value.value = obj.GetUint64();
|
||||
ret.mUint64Value.isPresent = true;
|
||||
} else if (obj.IsInt64()) {
|
||||
ret.mInt64Value.value = obj.GetInt64();
|
||||
ret.mInt64Value.isPresent = true;
|
||||
} else if (obj.IsDouble()) {
|
||||
ret.mDoubleValue.value = obj.GetDouble();
|
||||
ret.mDoubleValue.isPresent = true;
|
||||
}
|
||||
} else if (obj.IsString()) {
|
||||
ReadValue(obj, ret.mStringValue);
|
||||
ret.mStringValue.isPresent = true;
|
||||
} else if (obj.IsBool()) {
|
||||
ret.mBoolValue.value = obj.GetBool();
|
||||
ret.mBoolValue.isPresent = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
inline Value *Object::FindString(Value &val, const char *memberId) {
|
||||
@@ -330,6 +366,18 @@ inline Value *Object::FindExtension(Value &val, const char *extensionId) {
|
||||
return FindExtensionInContext(val, extensionId, id.c_str(), name.c_str());
|
||||
}
|
||||
|
||||
inline void Object::ReadExtensions(Value &val) {
|
||||
if (Value *curExtensions = FindObject(val, "extensions")) {
|
||||
this->customExtensions = glTF2::ReadExtensions("extensions", *curExtensions);
|
||||
}
|
||||
}
|
||||
|
||||
inline void Object::ReadExtras(Value &val) {
|
||||
if (Value *curExtras = FindObject(val, "extras")) {
|
||||
this->extras = glTF2::ReadExtensions("extras", *curExtras);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ASSIMP_ENABLE_DRACO
|
||||
|
||||
template <typename T>
|
||||
@@ -569,6 +617,8 @@ Ref<T> LazyDict<T>::Retrieve(unsigned int i) {
|
||||
inst->oIndex = i;
|
||||
ReadMember(obj, "name", inst->name);
|
||||
inst->Read(obj, mAsset);
|
||||
inst->ReadExtensions(obj);
|
||||
inst->ReadExtras(obj);
|
||||
|
||||
Ref<T> result = Add(inst.release());
|
||||
mRecursiveReferenceCheck.erase(i);
|
||||
@@ -733,12 +783,13 @@ inline void Buffer::EncodedRegion_Mark(const size_t pOffset, const size_t pEncod
|
||||
}
|
||||
|
||||
inline void Buffer::EncodedRegion_SetCurrent(const std::string &pID) {
|
||||
if ((EncodedRegion_Current != nullptr) && (EncodedRegion_Current->ID == pID)) return;
|
||||
if ((EncodedRegion_Current != nullptr) && (EncodedRegion_Current->ID == pID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (SEncodedRegion *reg : EncodedRegion_List) {
|
||||
if (reg->ID == pID) {
|
||||
EncodedRegion_Current = reg;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -788,10 +839,13 @@ inline bool Buffer::ReplaceData_joint(const size_t pBufferData_Offset, const siz
|
||||
}
|
||||
|
||||
inline size_t Buffer::AppendData(uint8_t *data, size_t length) {
|
||||
size_t offset = this->byteLength;
|
||||
const size_t offset = this->byteLength;
|
||||
|
||||
// Force alignment to 4 bits
|
||||
Grow((length + 3) & ~3);
|
||||
const size_t paddedLength = (length + 3) & ~3;
|
||||
Grow(paddedLength);
|
||||
memcpy(mData.get() + offset, data, length);
|
||||
memset(mData.get() + offset + length, 0, paddedLength - length);
|
||||
return offset;
|
||||
}
|
||||
|
||||
@@ -820,9 +874,7 @@ inline void Buffer::Grow(size_t amount) {
|
||||
//
|
||||
// struct BufferView
|
||||
//
|
||||
|
||||
inline void BufferView::Read(Value &obj, Asset &r) {
|
||||
|
||||
if (Value *bufferVal = FindUInt(obj, "buffer")) {
|
||||
buffer = r.buffers.Retrieve(bufferVal->GetUint());
|
||||
}
|
||||
@@ -842,16 +894,21 @@ inline void BufferView::Read(Value &obj, Asset &r) {
|
||||
}
|
||||
|
||||
inline uint8_t *BufferView::GetPointer(size_t accOffset) {
|
||||
if (!buffer) return nullptr;
|
||||
if (!buffer) {
|
||||
return nullptr;
|
||||
}
|
||||
uint8_t *basePtr = buffer->GetPointer();
|
||||
if (!basePtr) return nullptr;
|
||||
if (!basePtr) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t offset = accOffset + byteOffset;
|
||||
if (buffer->EncodedRegion_Current != nullptr) {
|
||||
const size_t begin = buffer->EncodedRegion_Current->Offset;
|
||||
const size_t end = begin + buffer->EncodedRegion_Current->DecodedData_Length;
|
||||
if ((offset >= begin) && (offset < end))
|
||||
if ((offset >= begin) && (offset < end)) {
|
||||
return &buffer->EncodedRegion_Current->DecodedData[offset - begin];
|
||||
}
|
||||
}
|
||||
|
||||
return basePtr + offset;
|
||||
@@ -877,18 +934,18 @@ inline void Accessor::Sparse::PatchData(unsigned int elementSize) {
|
||||
while (pIndices != indicesEnd) {
|
||||
size_t offset;
|
||||
switch (indicesType) {
|
||||
case ComponentType_UNSIGNED_BYTE:
|
||||
offset = *pIndices;
|
||||
break;
|
||||
case ComponentType_UNSIGNED_SHORT:
|
||||
offset = *reinterpret_cast<uint16_t *>(pIndices);
|
||||
break;
|
||||
case ComponentType_UNSIGNED_INT:
|
||||
offset = *reinterpret_cast<uint32_t *>(pIndices);
|
||||
break;
|
||||
default:
|
||||
// have fun with float and negative values from signed types as indices.
|
||||
throw DeadlyImportError("Unsupported component type in index.");
|
||||
case ComponentType_UNSIGNED_BYTE:
|
||||
offset = *pIndices;
|
||||
break;
|
||||
case ComponentType_UNSIGNED_SHORT:
|
||||
offset = *reinterpret_cast<uint16_t *>(pIndices);
|
||||
break;
|
||||
case ComponentType_UNSIGNED_INT:
|
||||
offset = *reinterpret_cast<uint32_t *>(pIndices);
|
||||
break;
|
||||
default:
|
||||
// have fun with float and negative values from signed types as indices.
|
||||
throw DeadlyImportError("Unsupported component type in index.");
|
||||
}
|
||||
|
||||
offset *= elementSize;
|
||||
@@ -900,7 +957,6 @@ inline void Accessor::Sparse::PatchData(unsigned int elementSize) {
|
||||
}
|
||||
|
||||
inline void Accessor::Read(Value &obj, Asset &r) {
|
||||
|
||||
if (Value *bufferViewVal = FindUInt(obj, "bufferView")) {
|
||||
bufferView = r.bufferViews.Retrieve(bufferViewVal->GetUint());
|
||||
}
|
||||
@@ -1612,9 +1668,9 @@ inline void Mesh::Read(Value &pJSON_Object, Asset &pAsset_Root) {
|
||||
}
|
||||
}
|
||||
|
||||
Value *extras = FindObject(pJSON_Object, "extras");
|
||||
if (nullptr != extras) {
|
||||
if (Value *curTargetNames = FindArray(*extras, "targetNames")) {
|
||||
Value *curExtras = FindObject(pJSON_Object, "extras");
|
||||
if (nullptr != curExtras) {
|
||||
if (Value *curTargetNames = FindArray(*curExtras, "targetNames")) {
|
||||
this->targetNames.resize(curTargetNames->Size());
|
||||
for (unsigned int i = 0; i < curTargetNames->Size(); ++i) {
|
||||
Value &targetNameValue = (*curTargetNames)[i];
|
||||
@@ -1683,42 +1739,6 @@ inline void Light::Read(Value &obj, Asset & /*r*/) {
|
||||
}
|
||||
}
|
||||
|
||||
inline CustomExtension ReadExtensions(const char *name, Value &obj) {
|
||||
CustomExtension ret;
|
||||
ret.name = name;
|
||||
if (obj.IsObject()) {
|
||||
ret.mValues.isPresent = true;
|
||||
for (auto it = obj.MemberBegin(); it != obj.MemberEnd(); ++it) {
|
||||
auto &val = it->value;
|
||||
ret.mValues.value.push_back(ReadExtensions(it->name.GetString(), val));
|
||||
}
|
||||
} else if (obj.IsArray()) {
|
||||
ret.mValues.value.reserve(obj.Size());
|
||||
ret.mValues.isPresent = true;
|
||||
for (unsigned int i = 0; i < obj.Size(); ++i) {
|
||||
ret.mValues.value.push_back(ReadExtensions(name, obj[i]));
|
||||
}
|
||||
} else if (obj.IsNumber()) {
|
||||
if (obj.IsUint64()) {
|
||||
ret.mUint64Value.value = obj.GetUint64();
|
||||
ret.mUint64Value.isPresent = true;
|
||||
} else if (obj.IsInt64()) {
|
||||
ret.mInt64Value.value = obj.GetInt64();
|
||||
ret.mInt64Value.isPresent = true;
|
||||
} else if (obj.IsDouble()) {
|
||||
ret.mDoubleValue.value = obj.GetDouble();
|
||||
ret.mDoubleValue.isPresent = true;
|
||||
}
|
||||
} else if (obj.IsString()) {
|
||||
ReadValue(obj, ret.mStringValue);
|
||||
ret.mStringValue.isPresent = true;
|
||||
} else if (obj.IsBool()) {
|
||||
ret.mBoolValue.value = obj.GetBool();
|
||||
ret.mBoolValue.isPresent = true;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline void Node::Read(Value &obj, Asset &r) {
|
||||
if (name.empty()) {
|
||||
name = id;
|
||||
@@ -1775,8 +1795,6 @@ inline void Node::Read(Value &obj, Asset &r) {
|
||||
|
||||
Value *curExtensions = FindObject(obj, "extensions");
|
||||
if (nullptr != curExtensions) {
|
||||
this->extensions = ReadExtensions("extensions", *curExtensions);
|
||||
|
||||
if (r.extensionsUsed.KHR_lights_punctual) {
|
||||
if (Value *ext = FindObject(*curExtensions, "KHR_lights_punctual")) {
|
||||
Value *curLight = FindUInt(*ext, "light");
|
||||
@@ -2132,7 +2150,7 @@ inline void Asset::ReadExtensionsUsed(Document &doc) {
|
||||
#undef CHECK_EXT
|
||||
}
|
||||
|
||||
inline IOStream *Asset::OpenFile(std::string path, const char *mode, bool /*absolute*/) {
|
||||
inline IOStream *Asset::OpenFile(const std::string& path, const char *mode, bool /*absolute*/) {
|
||||
#ifdef ASSIMP_API
|
||||
return mIOSystem->Open(path, mode);
|
||||
#else
|
||||
|
||||
@@ -118,14 +118,14 @@ glTF2Exporter::glTF2Exporter(const char* filename, IOSystem* pIOSystem, const ai
|
||||
ExportScene();
|
||||
|
||||
ExportAnimations();
|
||||
|
||||
|
||||
// export extras
|
||||
if(mProperties->HasPropertyCallback("extras"))
|
||||
{
|
||||
std::function<void*(void*)> ExportExtras = mProperties->GetPropertyCallback("extras");
|
||||
mAsset->extras = (rapidjson::Value*)ExportExtras(0);
|
||||
}
|
||||
|
||||
|
||||
AssetWriter writer(*mAsset);
|
||||
|
||||
if (isBinary) {
|
||||
@@ -436,11 +436,11 @@ inline void SetSamplerWrap(SamplerWrap& wrap, aiTextureMapMode map)
|
||||
};
|
||||
}
|
||||
|
||||
void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref<Texture> texture, aiTextureType tt, unsigned int slot)
|
||||
void glTF2Exporter::GetTexSampler(const aiMaterial& mat, Ref<Texture> texture, aiTextureType tt, unsigned int slot)
|
||||
{
|
||||
aiString aId;
|
||||
std::string id;
|
||||
if (aiGetMaterialString(mat, AI_MATKEY_GLTF_MAPPINGID(tt, slot), &aId) == AI_SUCCESS) {
|
||||
if (aiGetMaterialString(&mat, AI_MATKEY_GLTF_MAPPINGID(tt, slot), &aId) == AI_SUCCESS) {
|
||||
id = aId.C_Str();
|
||||
}
|
||||
|
||||
@@ -455,49 +455,52 @@ void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref<Texture> texture, a
|
||||
SamplerMagFilter filterMag;
|
||||
SamplerMinFilter filterMin;
|
||||
|
||||
if (aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_U(tt, slot), (int*)&mapU) == AI_SUCCESS) {
|
||||
if (aiGetMaterialInteger(&mat, AI_MATKEY_MAPPINGMODE_U(tt, slot), (int*)&mapU) == AI_SUCCESS) {
|
||||
SetSamplerWrap(texture->sampler->wrapS, mapU);
|
||||
}
|
||||
|
||||
if (aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_V(tt, slot), (int*)&mapV) == AI_SUCCESS) {
|
||||
if (aiGetMaterialInteger(&mat, AI_MATKEY_MAPPINGMODE_V(tt, slot), (int*)&mapV) == AI_SUCCESS) {
|
||||
SetSamplerWrap(texture->sampler->wrapT, mapV);
|
||||
}
|
||||
|
||||
if (aiGetMaterialInteger(mat, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(tt, slot), (int*)&filterMag) == AI_SUCCESS) {
|
||||
if (aiGetMaterialInteger(&mat, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(tt, slot), (int*)&filterMag) == AI_SUCCESS) {
|
||||
texture->sampler->magFilter = filterMag;
|
||||
}
|
||||
|
||||
if (aiGetMaterialInteger(mat, AI_MATKEY_GLTF_MAPPINGFILTER_MIN(tt, slot), (int*)&filterMin) == AI_SUCCESS) {
|
||||
if (aiGetMaterialInteger(&mat, AI_MATKEY_GLTF_MAPPINGFILTER_MIN(tt, slot), (int*)&filterMin) == AI_SUCCESS) {
|
||||
texture->sampler->minFilter = filterMin;
|
||||
}
|
||||
|
||||
aiString name;
|
||||
if (aiGetMaterialString(mat, AI_MATKEY_GLTF_MAPPINGNAME(tt, slot), &name) == AI_SUCCESS) {
|
||||
if (aiGetMaterialString(&mat, AI_MATKEY_GLTF_MAPPINGNAME(tt, slot), &name) == AI_SUCCESS) {
|
||||
texture->sampler->name = name.C_Str();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void glTF2Exporter::GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int slot)
|
||||
void glTF2Exporter::GetMatTexProp(const aiMaterial& mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int slot)
|
||||
{
|
||||
std::string textureKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName;
|
||||
|
||||
mat->Get(textureKey.c_str(), tt, slot, prop);
|
||||
mat.Get(textureKey.c_str(), tt, slot, prop);
|
||||
}
|
||||
|
||||
void glTF2Exporter::GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int slot)
|
||||
void glTF2Exporter::GetMatTexProp(const aiMaterial& mat, float& prop, const char* propName, aiTextureType tt, unsigned int slot)
|
||||
{
|
||||
std::string textureKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName;
|
||||
|
||||
mat->Get(textureKey.c_str(), tt, slot, prop);
|
||||
mat.Get(textureKey.c_str(), tt, slot, prop);
|
||||
}
|
||||
|
||||
void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTextureType tt, unsigned int slot = 0)
|
||||
void glTF2Exporter::GetMatTex(const aiMaterial& mat, Ref<Texture>& texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot = 0)
|
||||
{
|
||||
if (mat->GetTextureCount(tt) > 0) {
|
||||
if (mat.GetTextureCount(tt) > 0) {
|
||||
aiString tex;
|
||||
|
||||
if (mat->Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) {
|
||||
// Read texcoord (UV map index)
|
||||
mat.Get(AI_MATKEY_UVWSRC(tt, slot), texCoord);
|
||||
|
||||
if (mat.Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) {
|
||||
std::string path = tex.C_Str();
|
||||
|
||||
if (path.size() > 0) {
|
||||
@@ -515,11 +518,10 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTe
|
||||
std::string imgId = mAsset->FindUniqueID("", "image");
|
||||
texture->source = mAsset->images.Create(imgId);
|
||||
|
||||
if (path[0] == '*') { // embedded
|
||||
aiTexture* curTex = mScene->mTextures[atoi(&path[1])];
|
||||
|
||||
const aiTexture* curTex = mScene->GetEmbeddedTexture(path.c_str());
|
||||
if (curTex != nullptr) { // embedded
|
||||
texture->source->name = curTex->mFilename.C_Str();
|
||||
|
||||
|
||||
//basisu: embedded ktx2, bu
|
||||
if (curTex->achFormatHint[0]) {
|
||||
std::string mimeType = "image/";
|
||||
@@ -541,7 +543,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTe
|
||||
mimeType += curTex->achFormatHint;
|
||||
texture->source->mimeType = mimeType;
|
||||
}
|
||||
|
||||
|
||||
// The asset has its own buffer, see Image::SetData
|
||||
//basisu: "image/ktx2", "image/basis" as is
|
||||
texture->source->SetData(reinterpret_cast<uint8_t *>(curTex->pcData), curTex->mWidth, *mAsset);
|
||||
@@ -554,7 +556,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTe
|
||||
useBasisUniversal = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//basisu
|
||||
if(useBasisUniversal) {
|
||||
mAsset->extensionsUsed.KHR_texture_basisu = true;
|
||||
@@ -568,45 +570,45 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTe
|
||||
}
|
||||
}
|
||||
|
||||
void glTF2Exporter::GetMatTex(const aiMaterial* mat, TextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
|
||||
void glTF2Exporter::GetMatTex(const aiMaterial& mat, TextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
|
||||
{
|
||||
Ref<Texture>& texture = prop.texture;
|
||||
|
||||
GetMatTex(mat, texture, tt, slot);
|
||||
GetMatTex(mat, texture, prop.texCoord, tt, slot);
|
||||
|
||||
if (texture) {
|
||||
GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
|
||||
}
|
||||
//if (texture) {
|
||||
// GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
|
||||
//}
|
||||
}
|
||||
|
||||
void glTF2Exporter::GetMatTex(const aiMaterial* mat, NormalTextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
|
||||
void glTF2Exporter::GetMatTex(const aiMaterial& mat, NormalTextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
|
||||
{
|
||||
Ref<Texture>& texture = prop.texture;
|
||||
|
||||
GetMatTex(mat, texture, tt, slot);
|
||||
GetMatTex(mat, texture, prop.texCoord, tt, slot);
|
||||
|
||||
if (texture) {
|
||||
GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
|
||||
//GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
|
||||
GetMatTexProp(mat, prop.scale, "scale", tt, slot);
|
||||
}
|
||||
}
|
||||
|
||||
void glTF2Exporter::GetMatTex(const aiMaterial* mat, OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
|
||||
void glTF2Exporter::GetMatTex(const aiMaterial& mat, OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
|
||||
{
|
||||
Ref<Texture>& texture = prop.texture;
|
||||
|
||||
GetMatTex(mat, texture, tt, slot);
|
||||
GetMatTex(mat, texture, prop.texCoord, tt, slot);
|
||||
|
||||
if (texture) {
|
||||
GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
|
||||
//GetMatTexProp(mat, prop.texCoord, "texCoord", tt, slot);
|
||||
GetMatTexProp(mat, prop.strength, "strength", tt, slot);
|
||||
}
|
||||
}
|
||||
|
||||
aiReturn glTF2Exporter::GetMatColor(const aiMaterial* mat, vec4& prop, const char* propName, int type, int idx)
|
||||
aiReturn glTF2Exporter::GetMatColor(const aiMaterial& mat, vec4& prop, const char* propName, int type, int idx) const
|
||||
{
|
||||
aiColor4D col;
|
||||
aiReturn result = mat->Get(propName, type, idx, col);
|
||||
aiReturn result = mat.Get(propName, type, idx, col);
|
||||
|
||||
if (result == AI_SUCCESS) {
|
||||
prop[0] = col.r; prop[1] = col.g; prop[2] = col.b; prop[3] = col.a;
|
||||
@@ -615,37 +617,116 @@ aiReturn glTF2Exporter::GetMatColor(const aiMaterial* mat, vec4& prop, const cha
|
||||
return result;
|
||||
}
|
||||
|
||||
aiReturn glTF2Exporter::GetMatColor(const aiMaterial* mat, vec3& prop, const char* propName, int type, int idx)
|
||||
aiReturn glTF2Exporter::GetMatColor(const aiMaterial& mat, vec3& prop, const char* propName, int type, int idx) const
|
||||
{
|
||||
aiColor3D col;
|
||||
aiReturn result = mat->Get(propName, type, idx, col);
|
||||
aiReturn result = mat.Get(propName, type, idx, col);
|
||||
|
||||
if (result == AI_SUCCESS) {
|
||||
prop[0] = col.r; prop[1] = col.g; prop[2] = col.b;
|
||||
prop[0] = col.r;
|
||||
prop[1] = col.g;
|
||||
prop[2] = col.b;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool glTF2Exporter::GetMatSpecGloss(const aiMaterial &mat, glTF2::PbrSpecularGlossiness &pbrSG) {
|
||||
bool result = false;
|
||||
// If has Glossiness, a Specular Color or Specular Texture, use the KHR_materials_pbrSpecularGlossiness extension
|
||||
// NOTE: This extension is being considered for deprecation (Dec 2020), may be replaced by KHR_material_specular
|
||||
|
||||
if (mat.Get(AI_MATKEY_GLOSSINESS_FACTOR, pbrSG.glossinessFactor) == AI_SUCCESS) {
|
||||
result = true;
|
||||
} else {
|
||||
// Don't have explicit glossiness, convert from pbr roughness or legacy shininess
|
||||
float shininess;
|
||||
if (mat.Get(AI_MATKEY_ROUGHNESS_FACTOR, shininess) == AI_SUCCESS) {
|
||||
pbrSG.glossinessFactor = 1.0f - shininess; // Extension defines this way
|
||||
} else if (mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) {
|
||||
pbrSG.glossinessFactor = shininess / 1000;
|
||||
}
|
||||
}
|
||||
|
||||
if (GetMatColor(mat, pbrSG.specularFactor, AI_MATKEY_COLOR_SPECULAR) == AI_SUCCESS) {
|
||||
result = true;
|
||||
}
|
||||
// Add any appropriate textures
|
||||
GetMatTex(mat, pbrSG.specularGlossinessTexture, aiTextureType_SPECULAR);
|
||||
|
||||
result = result || pbrSG.specularGlossinessTexture.texture;
|
||||
|
||||
if (result) {
|
||||
// Likely to always have diffuse
|
||||
GetMatTex(mat, pbrSG.diffuseTexture, aiTextureType_DIFFUSE);
|
||||
GetMatColor(mat, pbrSG.diffuseFactor, AI_MATKEY_COLOR_DIFFUSE);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool glTF2Exporter::GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen) {
|
||||
// Return true if got any valid Sheen properties or textures
|
||||
if (GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_SHEEN_COLOR_FACTOR) != aiReturn_SUCCESS)
|
||||
return false;
|
||||
|
||||
// Default Sheen color factor {0,0,0} disables Sheen, so do not export
|
||||
if (sheen.sheenColorFactor == defaultSheenFactor)
|
||||
return false;
|
||||
|
||||
mat.Get(AI_MATKEY_SHEEN_ROUGHNESS_FACTOR, sheen.sheenRoughnessFactor);
|
||||
|
||||
GetMatTex(mat, sheen.sheenColorTexture, AI_MATKEY_SHEEN_COLOR_TEXTURE);
|
||||
GetMatTex(mat, sheen.sheenRoughnessTexture, AI_MATKEY_SHEEN_ROUGHNESS_TEXTURE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool glTF2Exporter::GetMatClearcoat(const aiMaterial &mat, glTF2::MaterialClearcoat &clearcoat) {
|
||||
if (mat.Get(AI_MATKEY_CLEARCOAT_FACTOR, clearcoat.clearcoatFactor) != aiReturn_SUCCESS) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clearcoat factor of zero disables Clearcoat, so do not export
|
||||
if (clearcoat.clearcoatFactor == 0.0f)
|
||||
return false;
|
||||
|
||||
mat.Get(AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR, clearcoat.clearcoatRoughnessFactor);
|
||||
|
||||
GetMatTex(mat, clearcoat.clearcoatTexture, AI_MATKEY_CLEARCOAT_TEXTURE);
|
||||
GetMatTex(mat, clearcoat.clearcoatRoughnessTexture, AI_MATKEY_CLEARCOAT_ROUGHNESS_TEXTURE);
|
||||
GetMatTex(mat, clearcoat.clearcoatNormalTexture, AI_MATKEY_CLEARCOAT_NORMAL_TEXTURE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool glTF2Exporter::GetMatTransmission(const aiMaterial &mat, glTF2::MaterialTransmission &transmission) {
|
||||
bool result = mat.Get(AI_MATKEY_TRANSMISSION_FACTOR, transmission.transmissionFactor) == aiReturn_SUCCESS;
|
||||
GetMatTex(mat, transmission.transmissionTexture, AI_MATKEY_TRANSMISSION_TEXTURE);
|
||||
return result || transmission.transmissionTexture.texture;
|
||||
}
|
||||
|
||||
void glTF2Exporter::ExportMaterials()
|
||||
{
|
||||
aiString aiName;
|
||||
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
|
||||
const aiMaterial* mat = mScene->mMaterials[i];
|
||||
ai_assert(mScene->mMaterials[i] != nullptr);
|
||||
|
||||
const aiMaterial & mat = *(mScene->mMaterials[i]);
|
||||
|
||||
std::string id = "material_" + ai_to_string(i);
|
||||
|
||||
Ref<Material> m = mAsset->materials.Create(id);
|
||||
|
||||
std::string name;
|
||||
if (mat->Get(AI_MATKEY_NAME, aiName) == AI_SUCCESS) {
|
||||
if (mat.Get(AI_MATKEY_NAME, aiName) == AI_SUCCESS) {
|
||||
name = aiName.C_Str();
|
||||
}
|
||||
name = mAsset->FindUniqueID(name, "material");
|
||||
|
||||
m->name = name;
|
||||
|
||||
GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE);
|
||||
GetMatTex(mat, m->pbrMetallicRoughness.baseColorTexture, aiTextureType_BASE_COLOR);
|
||||
|
||||
if (!m->pbrMetallicRoughness.baseColorTexture.texture) {
|
||||
//if there wasn't a baseColorTexture defined in the source, fallback to any diffuse texture
|
||||
@@ -654,26 +735,26 @@ void glTF2Exporter::ExportMaterials()
|
||||
|
||||
GetMatTex(mat, m->pbrMetallicRoughness.metallicRoughnessTexture, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE);
|
||||
|
||||
if (GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR) != AI_SUCCESS) {
|
||||
if (GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_BASE_COLOR) != AI_SUCCESS) {
|
||||
// if baseColorFactor wasn't defined, then the source is likely not a metallic roughness material.
|
||||
//a fallback to any diffuse color should be used instead
|
||||
GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE);
|
||||
}
|
||||
|
||||
if (mat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR, m->pbrMetallicRoughness.metallicFactor) != AI_SUCCESS) {
|
||||
if (mat.Get(AI_MATKEY_METALLIC_FACTOR, m->pbrMetallicRoughness.metallicFactor) != AI_SUCCESS) {
|
||||
//if metallicFactor wasn't defined, then the source is likely not a PBR file, and the metallicFactor should be 0
|
||||
m->pbrMetallicRoughness.metallicFactor = 0;
|
||||
}
|
||||
|
||||
// get roughness if source is gltf2 file
|
||||
if (mat->Get(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR, m->pbrMetallicRoughness.roughnessFactor) != AI_SUCCESS) {
|
||||
if (mat.Get(AI_MATKEY_ROUGHNESS_FACTOR, m->pbrMetallicRoughness.roughnessFactor) != AI_SUCCESS) {
|
||||
// otherwise, try to derive and convert from specular + shininess values
|
||||
aiColor4D specularColor;
|
||||
ai_real shininess;
|
||||
|
||||
if (
|
||||
mat->Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS &&
|
||||
mat->Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS
|
||||
mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS &&
|
||||
mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS
|
||||
) {
|
||||
// convert specular color to luminance
|
||||
float specularIntensity = specularColor[0] * 0.2125f + specularColor[1] * 0.7154f + specularColor[2] * 0.0721f;
|
||||
@@ -694,103 +775,60 @@ void glTF2Exporter::ExportMaterials()
|
||||
GetMatTex(mat, m->emissiveTexture, aiTextureType_EMISSIVE);
|
||||
GetMatColor(mat, m->emissiveFactor, AI_MATKEY_COLOR_EMISSIVE);
|
||||
|
||||
mat->Get(AI_MATKEY_TWOSIDED, m->doubleSided);
|
||||
mat->Get(AI_MATKEY_GLTF_ALPHACUTOFF, m->alphaCutoff);
|
||||
mat.Get(AI_MATKEY_TWOSIDED, m->doubleSided);
|
||||
mat.Get(AI_MATKEY_GLTF_ALPHACUTOFF, m->alphaCutoff);
|
||||
|
||||
float opacity;
|
||||
aiString alphaMode;
|
||||
|
||||
if (mat->Get(AI_MATKEY_GLTF_ALPHAMODE, alphaMode) == AI_SUCCESS) {
|
||||
if (mat.Get(AI_MATKEY_OPACITY, opacity) == AI_SUCCESS) {
|
||||
if (opacity < 1) {
|
||||
m->alphaMode = "BLEND";
|
||||
m->pbrMetallicRoughness.baseColorFactor[3] *= opacity;
|
||||
}
|
||||
}
|
||||
if (mat.Get(AI_MATKEY_GLTF_ALPHAMODE, alphaMode) == AI_SUCCESS) {
|
||||
m->alphaMode = alphaMode.C_Str();
|
||||
} else {
|
||||
float opacity;
|
||||
|
||||
if (mat->Get(AI_MATKEY_OPACITY, opacity) == AI_SUCCESS) {
|
||||
if (opacity < 1) {
|
||||
m->alphaMode = "BLEND";
|
||||
m->pbrMetallicRoughness.baseColorFactor[3] *= opacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool hasPbrSpecularGlossiness = false;
|
||||
mat->Get(AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS, hasPbrSpecularGlossiness);
|
||||
|
||||
if (hasPbrSpecularGlossiness) {
|
||||
|
||||
if (!mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness) {
|
||||
mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness = true;
|
||||
}
|
||||
|
||||
{
|
||||
// KHR_materials_pbrSpecularGlossiness extension
|
||||
// NOTE: This extension is being considered for deprecation (Dec 2020)
|
||||
PbrSpecularGlossiness pbrSG;
|
||||
|
||||
GetMatColor(mat, pbrSG.diffuseFactor, AI_MATKEY_COLOR_DIFFUSE);
|
||||
GetMatColor(mat, pbrSG.specularFactor, AI_MATKEY_COLOR_SPECULAR);
|
||||
|
||||
if (mat->Get(AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR, pbrSG.glossinessFactor) != AI_SUCCESS) {
|
||||
float shininess;
|
||||
|
||||
if (mat->Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) {
|
||||
pbrSG.glossinessFactor = shininess / 1000;
|
||||
}
|
||||
if (GetMatSpecGloss(mat, pbrSG)) {
|
||||
mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness = true;
|
||||
m->pbrSpecularGlossiness = Nullable<PbrSpecularGlossiness>(pbrSG);
|
||||
}
|
||||
|
||||
GetMatTex(mat, pbrSG.diffuseTexture, aiTextureType_DIFFUSE);
|
||||
GetMatTex(mat, pbrSG.specularGlossinessTexture, aiTextureType_SPECULAR);
|
||||
|
||||
m->pbrSpecularGlossiness = Nullable<PbrSpecularGlossiness>(pbrSG);
|
||||
}
|
||||
|
||||
bool unlit;
|
||||
if (mat->Get(AI_MATKEY_GLTF_UNLIT, unlit) == AI_SUCCESS && unlit) {
|
||||
// glTFv2 is either PBR or Unlit
|
||||
aiShadingMode shadingMode = aiShadingMode_PBR_BRDF;
|
||||
mat.Get(AI_MATKEY_SHADING_MODEL, shadingMode);
|
||||
if (shadingMode == aiShadingMode_Unlit) {
|
||||
mAsset->extensionsUsed.KHR_materials_unlit = true;
|
||||
m->unlit = true;
|
||||
}
|
||||
} else {
|
||||
// These extensions are not compatible with KHR_materials_unlit or KHR_materials_pbrSpecularGlossiness
|
||||
if (!m->pbrSpecularGlossiness.isPresent) {
|
||||
// Sheen
|
||||
MaterialSheen sheen;
|
||||
if (GetMatSheen(mat, sheen)) {
|
||||
mAsset->extensionsUsed.KHR_materials_sheen = true;
|
||||
m->materialSheen = Nullable<MaterialSheen>(sheen);
|
||||
}
|
||||
|
||||
bool hasMaterialSheen = false;
|
||||
mat->Get(AI_MATKEY_GLTF_MATERIAL_SHEEN, hasMaterialSheen);
|
||||
MaterialClearcoat clearcoat;
|
||||
if (GetMatClearcoat(mat, clearcoat)) {
|
||||
mAsset->extensionsUsed.KHR_materials_clearcoat = true;
|
||||
m->materialClearcoat = Nullable<MaterialClearcoat>(clearcoat);
|
||||
}
|
||||
|
||||
if (hasMaterialSheen) {
|
||||
mAsset->extensionsUsed.KHR_materials_sheen = true;
|
||||
|
||||
MaterialSheen sheen;
|
||||
|
||||
GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR);
|
||||
mat->Get(AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR, sheen.sheenRoughnessFactor);
|
||||
GetMatTex(mat, sheen.sheenColorTexture, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE);
|
||||
GetMatTex(mat, sheen.sheenRoughnessTexture, AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE);
|
||||
|
||||
m->materialSheen = Nullable<MaterialSheen>(sheen);
|
||||
}
|
||||
|
||||
bool hasMaterialClearcoat = false;
|
||||
mat->Get(AI_MATKEY_GLTF_MATERIAL_CLEARCOAT, hasMaterialClearcoat);
|
||||
|
||||
if (hasMaterialClearcoat) {
|
||||
mAsset->extensionsUsed.KHR_materials_clearcoat= true;
|
||||
|
||||
MaterialClearcoat clearcoat;
|
||||
|
||||
mat->Get(AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR, clearcoat.clearcoatFactor);
|
||||
mat->Get(AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR, clearcoat.clearcoatRoughnessFactor);
|
||||
GetMatTex(mat, clearcoat.clearcoatTexture, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE);
|
||||
GetMatTex(mat, clearcoat.clearcoatRoughnessTexture, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE);
|
||||
GetMatTex(mat, clearcoat.clearcoatNormalTexture, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE);
|
||||
|
||||
m->materialClearcoat = Nullable<MaterialClearcoat>(clearcoat);
|
||||
}
|
||||
|
||||
bool hasMaterialTransmission = false;
|
||||
mat->Get(AI_MATKEY_GLTF_MATERIAL_TRANSMISSION, hasMaterialTransmission);
|
||||
|
||||
if (hasMaterialTransmission) {
|
||||
mAsset->extensionsUsed.KHR_materials_transmission = true;
|
||||
|
||||
MaterialTransmission transmission;
|
||||
|
||||
mat->Get(AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR, transmission.transmissionFactor);
|
||||
GetMatTex(mat, transmission.transmissionTexture, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE);
|
||||
|
||||
m->materialTransmission = Nullable<MaterialTransmission>(transmission);
|
||||
MaterialTransmission transmission;
|
||||
if (GetMatTransmission(mat, transmission)) {
|
||||
mAsset->extensionsUsed.KHR_materials_transmission = true;
|
||||
m->materialTransmission = Nullable<MaterialTransmission>(transmission);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -799,8 +837,7 @@ void glTF2Exporter::ExportMaterials()
|
||||
* Search through node hierarchy and find the node containing the given meshID.
|
||||
* Returns true on success, and false otherwise.
|
||||
*/
|
||||
bool FindMeshNode(Ref<Node>& nodeIn, Ref<Node>& meshNode, std::string meshID)
|
||||
{
|
||||
bool FindMeshNode(Ref<Node> &nodeIn, Ref<Node> &meshNode, const std::string &meshID) {
|
||||
for (unsigned int i = 0; i < nodeIn->meshes.size(); ++i) {
|
||||
if (meshID.compare(nodeIn->meshes[i]->id) == 0) {
|
||||
meshNode = nodeIn;
|
||||
|
||||
@@ -72,6 +72,10 @@ namespace glTF2
|
||||
struct OcclusionTextureInfo;
|
||||
struct Node;
|
||||
struct Texture;
|
||||
struct PbrSpecularGlossiness;
|
||||
struct MaterialSheen;
|
||||
struct MaterialClearcoat;
|
||||
struct MaterialTransmission;
|
||||
|
||||
// Vec/matrix types, as raw float arrays
|
||||
typedef float (vec2)[2];
|
||||
@@ -97,15 +101,19 @@ namespace Assimp
|
||||
|
||||
protected:
|
||||
void WriteBinaryData(IOStream* outfile, std::size_t sceneLength);
|
||||
void GetTexSampler(const aiMaterial* mat, glTF2::Ref<glTF2::Texture> texture, aiTextureType tt, unsigned int slot);
|
||||
void GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int idx);
|
||||
void GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int idx);
|
||||
void GetMatTex(const aiMaterial* mat, glTF2::Ref<glTF2::Texture>& texture, aiTextureType tt, unsigned int slot);
|
||||
void GetMatTex(const aiMaterial* mat, glTF2::TextureInfo& prop, aiTextureType tt, unsigned int slot);
|
||||
void GetMatTex(const aiMaterial* mat, glTF2::NormalTextureInfo& prop, aiTextureType tt, unsigned int slot);
|
||||
void GetMatTex(const aiMaterial* mat, glTF2::OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot);
|
||||
aiReturn GetMatColor(const aiMaterial* mat, glTF2::vec4& prop, const char* propName, int type, int idx);
|
||||
aiReturn GetMatColor(const aiMaterial* mat, glTF2::vec3& prop, const char* propName, int type, int idx);
|
||||
void GetTexSampler(const aiMaterial& mat, glTF2::Ref<glTF2::Texture> texture, aiTextureType tt, unsigned int slot);
|
||||
void GetMatTexProp(const aiMaterial& mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int idx);
|
||||
void GetMatTexProp(const aiMaterial& mat, float& prop, const char* propName, aiTextureType tt, unsigned int idx);
|
||||
void GetMatTex(const aiMaterial& mat, glTF2::Ref<glTF2::Texture>& texture, unsigned int &texCoord, aiTextureType tt, unsigned int slot);
|
||||
void GetMatTex(const aiMaterial& mat, glTF2::TextureInfo& prop, aiTextureType tt, unsigned int slot);
|
||||
void GetMatTex(const aiMaterial& mat, glTF2::NormalTextureInfo& prop, aiTextureType tt, unsigned int slot);
|
||||
void GetMatTex(const aiMaterial& mat, glTF2::OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot);
|
||||
aiReturn GetMatColor(const aiMaterial& mat, glTF2::vec4& prop, const char* propName, int type, int idx) const;
|
||||
aiReturn GetMatColor(const aiMaterial& mat, glTF2::vec3& prop, const char* propName, int type, int idx) const;
|
||||
bool GetMatSpecGloss(const aiMaterial& mat, glTF2::PbrSpecularGlossiness& pbrSG);
|
||||
bool GetMatSheen(const aiMaterial& mat, glTF2::MaterialSheen& sheen);
|
||||
bool GetMatClearcoat(const aiMaterial& mat, glTF2::MaterialClearcoat& clearcoat);
|
||||
bool GetMatTransmission(const aiMaterial& mat, glTF2::MaterialTransmission& transmission);
|
||||
void ExportMetadata();
|
||||
void ExportMaterials();
|
||||
void ExportMeshes();
|
||||
|
||||
@@ -165,7 +165,8 @@ inline void SetMaterialTextureProperty(std::vector<int> &embeddedTexIdxs, Asset
|
||||
}
|
||||
|
||||
mat->AddProperty(&uri, AI_MATKEY_TEXTURE(texType, texSlot));
|
||||
mat->AddProperty(&prop.texCoord, 1, AI_MATKEY_GLTF_TEXTURE_TEXCOORD(texType, texSlot));
|
||||
const int uvIndex = static_cast<int>(prop.texCoord);
|
||||
mat->AddProperty(&uvIndex, 1, AI_MATKEY_UVWSRC(texType, texSlot));
|
||||
|
||||
if (prop.textureTransformSupported) {
|
||||
aiUVTransform transform;
|
||||
@@ -208,6 +209,11 @@ inline void SetMaterialTextureProperty(std::vector<int> &embeddedTexIdxs, Asset
|
||||
if (sampler->minFilter != SamplerMinFilter::UNSET) {
|
||||
mat->AddProperty(&sampler->minFilter, 1, AI_MATKEY_GLTF_MAPPINGFILTER_MIN(texType, texSlot));
|
||||
}
|
||||
} else {
|
||||
// Use glTFv2 default sampler
|
||||
const aiTextureMapMode default_wrap = aiTextureMapMode_Wrap;
|
||||
mat->AddProperty(&default_wrap, 1, AI_MATKEY_MAPPINGMODE_U(texType, texSlot));
|
||||
mat->AddProperty(&default_wrap, 1, AI_MATKEY_MAPPINGMODE_V(texType, texSlot));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -238,16 +244,18 @@ static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, M
|
||||
aimat->AddProperty(&str, AI_MATKEY_NAME);
|
||||
}
|
||||
|
||||
// Set Assimp DIFFUSE and BASE COLOR to the pbrMetallicRoughness base color and texture for backwards compatibility
|
||||
// Technically should not load any pbrMetallicRoughness if extensionsRequired contains KHR_materials_pbrSpecularGlossiness
|
||||
SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_COLOR_DIFFUSE);
|
||||
SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR);
|
||||
SetMaterialColorProperty(r, mat.pbrMetallicRoughness.baseColorFactor, aimat, AI_MATKEY_BASE_COLOR);
|
||||
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_DIFFUSE);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.baseColorTexture, aimat, aiTextureType_BASE_COLOR);
|
||||
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, mat.pbrMetallicRoughness.metallicRoughnessTexture, aimat, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE);
|
||||
|
||||
aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR);
|
||||
aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR);
|
||||
aimat->AddProperty(&mat.pbrMetallicRoughness.metallicFactor, 1, AI_MATKEY_METALLIC_FACTOR);
|
||||
aimat->AddProperty(&mat.pbrMetallicRoughness.roughnessFactor, 1, AI_MATKEY_ROUGHNESS_FACTOR);
|
||||
|
||||
float roughnessAsShininess = 1 - mat.pbrMetallicRoughness.roughnessFactor;
|
||||
roughnessAsShininess *= roughnessAsShininess * 1000;
|
||||
@@ -259,6 +267,7 @@ static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, M
|
||||
SetMaterialColorProperty(r, mat.emissiveFactor, aimat, AI_MATKEY_COLOR_EMISSIVE);
|
||||
|
||||
aimat->AddProperty(&mat.doubleSided, 1, AI_MATKEY_TWOSIDED);
|
||||
aimat->AddProperty(&mat.pbrMetallicRoughness.baseColorFactor[3], 1, AI_MATKEY_OPACITY);
|
||||
|
||||
aiString alphaMode(mat.alphaMode);
|
||||
aimat->AddProperty(&alphaMode, AI_MATKEY_GLTF_ALPHAMODE);
|
||||
@@ -268,52 +277,58 @@ static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, M
|
||||
if (mat.pbrSpecularGlossiness.isPresent) {
|
||||
PbrSpecularGlossiness &pbrSG = mat.pbrSpecularGlossiness.value;
|
||||
|
||||
aimat->AddProperty(&mat.pbrSpecularGlossiness.isPresent, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS);
|
||||
SetMaterialColorProperty(r, pbrSG.diffuseFactor, aimat, AI_MATKEY_COLOR_DIFFUSE);
|
||||
SetMaterialColorProperty(r, pbrSG.specularFactor, aimat, AI_MATKEY_COLOR_SPECULAR);
|
||||
|
||||
float glossinessAsShininess = pbrSG.glossinessFactor * 1000.0f;
|
||||
aimat->AddProperty(&glossinessAsShininess, 1, AI_MATKEY_SHININESS);
|
||||
aimat->AddProperty(&pbrSG.glossinessFactor, 1, AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR);
|
||||
aimat->AddProperty(&pbrSG.glossinessFactor, 1, AI_MATKEY_GLOSSINESS_FACTOR);
|
||||
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.diffuseTexture, aimat, aiTextureType_DIFFUSE);
|
||||
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, pbrSG.specularGlossinessTexture, aimat, aiTextureType_SPECULAR);
|
||||
}
|
||||
|
||||
// glTFv2 is either PBR or Unlit
|
||||
aiShadingMode shadingMode = aiShadingMode_PBR_BRDF;
|
||||
if (mat.unlit) {
|
||||
aimat->AddProperty(&mat.unlit, 1, AI_MATKEY_GLTF_UNLIT);
|
||||
shadingMode = aiShadingMode_Unlit;
|
||||
}
|
||||
|
||||
//KHR_materials_sheen
|
||||
aimat->AddProperty(&shadingMode, 1, AI_MATKEY_SHADING_MODEL);
|
||||
|
||||
|
||||
// KHR_materials_sheen
|
||||
if (mat.materialSheen.isPresent) {
|
||||
MaterialSheen &sheen = mat.materialSheen.value;
|
||||
|
||||
aimat->AddProperty(&mat.materialSheen.isPresent, 1, AI_MATKEY_GLTF_MATERIAL_SHEEN);
|
||||
SetMaterialColorProperty(r, sheen.sheenColorFactor, aimat, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR);
|
||||
aimat->AddProperty(&sheen.sheenRoughnessFactor, 1, AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenColorTexture, aimat, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenRoughnessTexture, aimat, AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE);
|
||||
// Default value {0,0,0} disables Sheen
|
||||
if (sheen.sheenColorFactor != defaultSheenFactor) {
|
||||
SetMaterialColorProperty(r, sheen.sheenColorFactor, aimat, AI_MATKEY_SHEEN_COLOR_FACTOR);
|
||||
aimat->AddProperty(&sheen.sheenRoughnessFactor, 1, AI_MATKEY_SHEEN_ROUGHNESS_FACTOR);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenColorTexture, aimat, AI_MATKEY_SHEEN_COLOR_TEXTURE);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenRoughnessTexture, aimat, AI_MATKEY_SHEEN_ROUGHNESS_TEXTURE);
|
||||
}
|
||||
}
|
||||
|
||||
//KHR_materials_clearcoat
|
||||
// KHR_materials_clearcoat
|
||||
if (mat.materialClearcoat.isPresent) {
|
||||
MaterialClearcoat &clearcoat = mat.materialClearcoat.value;
|
||||
|
||||
aimat->AddProperty(&mat.materialClearcoat.isPresent, 1, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT);
|
||||
aimat->AddProperty(&clearcoat.clearcoatFactor, 1, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR);
|
||||
aimat->AddProperty(&clearcoat.clearcoatRoughnessFactor, 1, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatTexture, aimat, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatRoughnessTexture, aimat, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatNormalTexture, aimat, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE);
|
||||
// Default value 0.0 disables clearcoat
|
||||
if (clearcoat.clearcoatFactor != 0.0f) {
|
||||
aimat->AddProperty(&clearcoat.clearcoatFactor, 1, AI_MATKEY_CLEARCOAT_FACTOR);
|
||||
aimat->AddProperty(&clearcoat.clearcoatRoughnessFactor, 1, AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatTexture, aimat, AI_MATKEY_CLEARCOAT_TEXTURE);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatRoughnessTexture, aimat, AI_MATKEY_CLEARCOAT_ROUGHNESS_TEXTURE);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatNormalTexture, aimat, AI_MATKEY_CLEARCOAT_NORMAL_TEXTURE);
|
||||
}
|
||||
}
|
||||
|
||||
//KHR_materials_transmission
|
||||
// KHR_materials_transmission
|
||||
if (mat.materialTransmission.isPresent) {
|
||||
MaterialTransmission &transmission = mat.materialTransmission.value;
|
||||
|
||||
aimat->AddProperty(&mat.materialTransmission.isPresent, 1, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION);
|
||||
aimat->AddProperty(&transmission.transmissionFactor, 1, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, transmission.transmissionTexture, aimat, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE);
|
||||
aimat->AddProperty(&transmission.transmissionFactor, 1, AI_MATKEY_TRANSMISSION_FACTOR);
|
||||
SetMaterialTextureProperty(embeddedTexIdxs, r, transmission.transmissionTexture, aimat, AI_MATKEY_TRANSMISSION_TEXTURE);
|
||||
}
|
||||
|
||||
return aimat;
|
||||
@@ -489,7 +504,7 @@ void glTF2Importer::ImportMeshes(glTF2::Asset &r) {
|
||||
"\" does not match the vertex count");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
auto componentType = attr.color[c]->componentType;
|
||||
if (componentType == glTF2::ComponentType_FLOAT) {
|
||||
attr.color[c]->ExtractData(aim->mColors[c]);
|
||||
@@ -984,6 +999,14 @@ void ParseExtensions(aiMetadata *metadata, const CustomExtension &extension) {
|
||||
}
|
||||
}
|
||||
|
||||
void ParseExtras(aiMetadata *metadata, const CustomExtension &extension) {
|
||||
if (extension.mValues.isPresent) {
|
||||
for (size_t i = 0; i < extension.mValues.value.size(); ++i) {
|
||||
ParseExtensions(metadata, extension.mValues.value[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &meshOffsets, glTF2::Ref<glTF2::Node> &ptr) {
|
||||
Node &node = *ptr;
|
||||
|
||||
@@ -1002,9 +1025,14 @@ aiNode *ImportNode(aiScene *pScene, glTF2::Asset &r, std::vector<unsigned int> &
|
||||
}
|
||||
}
|
||||
|
||||
if (node.extensions) {
|
||||
if (node.customExtensions || node.extras) {
|
||||
ainode->mMetaData = new aiMetadata;
|
||||
ParseExtensions(ainode->mMetaData, node.extensions);
|
||||
if (node.customExtensions) {
|
||||
ParseExtensions(ainode->mMetaData, node.customExtensions);
|
||||
}
|
||||
if (node.extras) {
|
||||
ParseExtras(ainode->mMetaData, node.extras);
|
||||
}
|
||||
}
|
||||
|
||||
GetNodeTransform(ainode->mTransformation, node);
|
||||
@@ -1498,7 +1526,8 @@ void glTF2Importer::ImportCommonMetadata(glTF2::Asset& a) {
|
||||
const bool hasVersion = !a.asset.version.empty();
|
||||
const bool hasGenerator = !a.asset.generator.empty();
|
||||
const bool hasCopyright = !a.asset.copyright.empty();
|
||||
if (hasVersion || hasGenerator || hasCopyright) {
|
||||
const bool hasSceneMetadata = a.scene->customExtensions;
|
||||
if (hasVersion || hasGenerator || hasCopyright || hasSceneMetadata) {
|
||||
mScene->mMetaData = new aiMetadata;
|
||||
if (hasVersion) {
|
||||
mScene->mMetaData->Add(AI_METADATA_SOURCE_FORMAT_VERSION, aiString(a.asset.version));
|
||||
@@ -1509,6 +1538,9 @@ void glTF2Importer::ImportCommonMetadata(glTF2::Asset& a) {
|
||||
if (hasCopyright) {
|
||||
mScene->mMetaData->Add(AI_METADATA_SOURCE_COPYRIGHT, aiString(a.asset.copyright));
|
||||
}
|
||||
if (hasSceneMetadata) {
|
||||
ParseExtensions(mScene->mMetaData, a.scene->customExtensions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -406,11 +406,25 @@ void SceneCombiner::MergeScenes(aiScene **_dest, aiScene *master, std::vector<At
|
||||
// Check whether this texture is an embedded texture.
|
||||
// In this case the property looks like this: *<n>,
|
||||
// where n is the index of the texture.
|
||||
aiString &s = *((aiString *)prop->mData);
|
||||
// Copy here because we overwrite the string data in-place and the buffer inside of aiString
|
||||
// will be a lie if we just reinterpret from prop->mData. The size of mData is not guaranteed to be
|
||||
// MAXLEN in size.
|
||||
aiString s(*(aiString *)prop->mData);
|
||||
if ('*' == s.data[0]) {
|
||||
// Offset the index and write it back ..
|
||||
const unsigned int idx = strtoul10(&s.data[1]) + offset[n];
|
||||
ASSIMP_itoa10(&s.data[1], sizeof(s.data) - 1, idx);
|
||||
const unsigned int oldLen = s.length;
|
||||
|
||||
s.length = 1 + ASSIMP_itoa10(&s.data[1], sizeof(s.data) - 1, idx);
|
||||
|
||||
// The string changed in size so we need to reallocate the buffer for the property.
|
||||
if (oldLen < s.length) {
|
||||
prop->mDataLength += s.length - oldLen;
|
||||
delete[] prop->mData;
|
||||
prop->mData = new char[prop->mDataLength];
|
||||
}
|
||||
|
||||
memcpy(prop->mData, static_cast<void*>(&s), prop->mDataLength);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,10 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <assimp/material.h>
|
||||
|
||||
// -------------------------------------------------------------------------------
|
||||
const char* TextureTypeToString(aiTextureType in)
|
||||
{
|
||||
switch (in)
|
||||
{
|
||||
const char *TextureTypeToString(aiTextureType in) {
|
||||
switch (in) {
|
||||
case aiTextureType_NONE:
|
||||
return "n/a";
|
||||
case aiTextureType_DIFFUSE:
|
||||
@@ -87,6 +85,12 @@ const char* TextureTypeToString(aiTextureType in)
|
||||
return "DiffuseRoughness";
|
||||
case aiTextureType_AMBIENT_OCCLUSION:
|
||||
return "AmbientOcclusion";
|
||||
case aiTextureType_SHEEN:
|
||||
return "Sheen";
|
||||
case aiTextureType_CLEARCOAT:
|
||||
return "Clearcoat";
|
||||
case aiTextureType_TRANSMISSION:
|
||||
return "Transmission";
|
||||
case aiTextureType_UNKNOWN:
|
||||
return "Unknown";
|
||||
default:
|
||||
|
||||
+11
-12
@@ -105,14 +105,13 @@ void ExportScenePbrt (
|
||||
} // end of namespace Assimp
|
||||
|
||||
// Constructor
|
||||
PbrtExporter::PbrtExporter (
|
||||
const aiScene* pScene, IOSystem* pIOSystem,
|
||||
const std::string path, const std::string file)
|
||||
: mScene(pScene),
|
||||
mIOSystem(pIOSystem),
|
||||
mPath(path),
|
||||
mFile(file)
|
||||
{
|
||||
PbrtExporter::PbrtExporter(
|
||||
const aiScene *pScene, IOSystem *pIOSystem,
|
||||
const std::string &path, const std::string &file) :
|
||||
mScene(pScene),
|
||||
mIOSystem(pIOSystem),
|
||||
mPath(path),
|
||||
mFile(file) {
|
||||
// Export embedded textures.
|
||||
if (mScene->mNumTextures > 0)
|
||||
if (!mIOSystem->CreateDirectory("textures"))
|
||||
@@ -209,12 +208,12 @@ void PbrtExporter::WriteMetaData() {
|
||||
aiString* value =
|
||||
static_cast<aiString*>(pMetaData->mValues[i].mData);
|
||||
std::string svalue = value->C_Str();
|
||||
std::size_t found = svalue.find_first_of("\n");
|
||||
std::size_t found = svalue.find_first_of('\n');
|
||||
mOutput << "\n";
|
||||
while (found != std::string::npos) {
|
||||
mOutput << "# " << svalue.substr(0, found) << "\n";
|
||||
svalue = svalue.substr(found + 1);
|
||||
found = svalue.find_first_of("\n");
|
||||
found = svalue.find_first_of('\n');
|
||||
}
|
||||
mOutput << "# " << svalue << "\n";
|
||||
break;
|
||||
@@ -595,8 +594,8 @@ void PbrtExporter::WriteMaterial(int m) {
|
||||
}
|
||||
mOutput << "\n";
|
||||
|
||||
auto White = [](aiColor3D c) { return c.r == 1 && c.g == 1 && c.b == 1; };
|
||||
auto Black = [](aiColor3D c) { return c.r == 0 && c.g == 0 && c.b == 0; };
|
||||
auto White = [](const aiColor3D &c) { return c.r == 1 && c.g == 1 && c.b == 1; };
|
||||
auto Black = [](const aiColor3D &c) { return c.r == 0 && c.g == 0 && c.b == 0; };
|
||||
|
||||
aiColor3D diffuse, specular, transparency;
|
||||
bool constantDiffuse = (material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuse) == AI_SUCCESS &&
|
||||
|
||||
@@ -74,8 +74,8 @@ class PbrtExporter
|
||||
{
|
||||
public:
|
||||
/// Constructor for a specific scene to export
|
||||
PbrtExporter(const aiScene* pScene, IOSystem* pIOSystem,
|
||||
const std::string path, const std::string file);
|
||||
PbrtExporter(const aiScene *pScene, IOSystem *pIOSystem,
|
||||
const std::string &path, const std::string &file);
|
||||
|
||||
/// Destructor
|
||||
virtual ~PbrtExporter();
|
||||
|
||||
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2021, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -41,6 +40,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "EmbedTexturesProcess.h"
|
||||
#include <assimp/IOStream.hpp>
|
||||
#include <assimp/IOSystem.hpp>
|
||||
#include <assimp/ParsingUtils.h>
|
||||
#include "ProcessHelper.h"
|
||||
|
||||
@@ -48,11 +49,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
EmbedTexturesProcess::EmbedTexturesProcess()
|
||||
: BaseProcess() {
|
||||
EmbedTexturesProcess::EmbedTexturesProcess() :
|
||||
BaseProcess() {
|
||||
// empty
|
||||
}
|
||||
|
||||
EmbedTexturesProcess::~EmbedTexturesProcess() {
|
||||
// empty
|
||||
}
|
||||
|
||||
bool EmbedTexturesProcess::IsActive(unsigned int pFlags) const {
|
||||
@@ -62,15 +65,16 @@ bool EmbedTexturesProcess::IsActive(unsigned int pFlags) const {
|
||||
void EmbedTexturesProcess::SetupProperties(const Importer* pImp) {
|
||||
mRootPath = pImp->GetPropertyString("sourceFilePath");
|
||||
mRootPath = mRootPath.substr(0, mRootPath.find_last_of("\\/") + 1u);
|
||||
mIOHandler = pImp->GetIOHandler();
|
||||
}
|
||||
|
||||
void EmbedTexturesProcess::Execute(aiScene* pScene) {
|
||||
if (pScene == nullptr || pScene->mRootNode == nullptr) return;
|
||||
if (pScene == nullptr || pScene->mRootNode == nullptr || mIOHandler == nullptr){
|
||||
return;
|
||||
}
|
||||
|
||||
aiString path;
|
||||
|
||||
uint32_t embeddedTexturesCount = 0u;
|
||||
|
||||
for (auto matId = 0u; matId < pScene->mNumMaterials; ++matId) {
|
||||
auto material = pScene->mMaterials[matId];
|
||||
|
||||
@@ -96,32 +100,36 @@ void EmbedTexturesProcess::Execute(aiScene* pScene) {
|
||||
ASSIMP_LOG_INFO("EmbedTexturesProcess finished. Embedded ", embeddedTexturesCount, " textures." );
|
||||
}
|
||||
|
||||
bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
|
||||
bool EmbedTexturesProcess::addTexture(aiScene *pScene, const std::string &path) const {
|
||||
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()) == std::streampos(-1)) {
|
||||
if (!mIOHandler->Exists(imagePath)) {
|
||||
ASSIMP_LOG_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()) == std::streampos(-1)) {
|
||||
if (!mIOHandler->Exists(imagePath)) {
|
||||
// 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()) == std::streampos(-1)) {
|
||||
if (!mIOHandler->Exists(imagePath)) {
|
||||
ASSIMP_LOG_ERROR("EmbedTexturesProcess: Unable to embed texture: ", path, ".");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
IOStream* pFile = mIOHandler->Open(imagePath);
|
||||
if (pFile == nullptr) {
|
||||
ASSIMP_LOG_ERROR("EmbedTexturesProcess: Unable to embed texture: ", path, ".");
|
||||
return false;
|
||||
}
|
||||
imageSize = pFile->FileSize();
|
||||
|
||||
aiTexel* imageContent = new aiTexel[ 1ul + static_cast<unsigned long>( imageSize ) / sizeof(aiTexel)];
|
||||
file.seekg(0, std::ios::beg);
|
||||
file.read(reinterpret_cast<char*>(imageContent), imageSize);
|
||||
pFile->Seek(0, aiOrigin_SET);
|
||||
pFile->Read(reinterpret_cast<char*>(imageContent), imageSize, 1);
|
||||
mIOHandler->Close(pFile);
|
||||
|
||||
// Enlarging the textures table
|
||||
unsigned int textureId = pScene->mNumTextures++;
|
||||
|
||||
@@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
struct aiNode;
|
||||
|
||||
class IOSystem;
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
/**
|
||||
@@ -76,10 +78,11 @@ public:
|
||||
|
||||
private:
|
||||
// Resolve the path and add the file content to the scene as a texture.
|
||||
bool addTexture(aiScene* pScene, std::string path) const;
|
||||
bool addTexture(aiScene *pScene, const std::string &path) const;
|
||||
|
||||
private:
|
||||
std::string mRootPath;
|
||||
IOSystem* mIOHandler = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Assimp
|
||||
|
||||
Reference in New Issue
Block a user