Merge remote-tracking branch 'origin/master' into HEAD

pull/3985/head
Rahul Sheth 2021-07-07 16:35:29 -04:00
commit 0a5e49252d
78 changed files with 2740 additions and 696 deletions

View File

@ -269,6 +269,8 @@ ELSEIF(MSVC)
ADD_COMPILE_OPTIONS(/wd4351)
ENDIF()
SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /D_DEBUG /Zi /Od")
SET(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Zi")
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FULL /PDBALTPATH:%_PDB% /OPT:REF /OPT:ICF")
ELSEIF (CMAKE_CXX_COMPILER_ID MATCHES "Clang" )
IF(NOT ASSIMP_HUNTER_ENABLED)
SET(CMAKE_CXX_STANDARD 11)

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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();

View File

@ -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) {

View File

@ -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));

View File

@ -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()) {

View File

@ -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,

View File

@ -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();

View File

@ -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
}

View File

@ -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;

View File

@ -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);

View File

@ -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.

View File

@ -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,

View File

@ -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,

View File

@ -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());

View File

@ -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()
{

View File

@ -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;

View File

@ -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>();

View File

@ -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

View File

@ -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)) {
}
// ------------------------------------------------------------------------------

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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));

View File

@ -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;

View File

@ -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();

View File

@ -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:

View File

@ -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;

View File

@ -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
}
};

View File

@ -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);
};
}

View File

@ -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);

View File

@ -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;

View File

@ -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) {

View File

@ -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

View File

@ -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;

View File

@ -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();

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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:

View File

@ -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 &&

View File

@ -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();

View File

@ -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++;

View File

@ -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

View File

@ -1 +0,0 @@
2.3.0

View File

@ -1,31 +0,0 @@
cache: ccache
language: cpp
matrix:
include:
- os: linux
dist: xenial
compiler: clang
- os: linux
dist: xenial
compiler: gcc
- os: osx
compiler: clang
addons:
apt:
packages:
- cmake
script:
# Output version info for compilers, cmake, and make
- ${CC} -v
- ${CXX} -v
- cmake --version
- make --version
# Clone googletest
- pushd .. && git clone https://github.com/google/googletest.git && popd
# Configure and build
- mkdir _travis_build && cd _travis_build
- cmake -G "Unix Makefiles" -DENABLE_TESTS=ON ..
- make -j10
- ./draco_tests

View File

@ -804,7 +804,7 @@ else()
draco_points_enc)
# Library targets that consume the object collections.
if(MSVC OR WIN32)
if(MSVC)
# In order to produce a DLL and import library the Windows tools require
# that the exported symbols are part of the DLL target. The unfortunate side
# effect of this is that a single configuration cannot output both the
@ -889,9 +889,6 @@ else()
# For Mac, we need to build a .bundle for the unity plugin.
if(APPLE)
set_target_properties(dracodec_unity PROPERTIES BUNDLE true)
elseif(NOT unity_decoder_lib_type STREQUAL STATIC)
set_target_properties(dracodec_unity
PROPERTIES SOVERSION ${DRACO_SOVERSION})
endif()
endif()
@ -916,9 +913,6 @@ else()
# For Mac, we need to build a .bundle for the plugin.
if(APPLE)
set_target_properties(draco_maya_wrapper PROPERTIES BUNDLE true)
else()
set_target_properties(draco_maya_wrapper
PROPERTIES SOVERSION ${DRACO_SOVERSION})
endif()
endif()

View File

@ -2,16 +2,16 @@
<img width="350px" src="docs/artwork/draco3d-vert.svg" />
</p>
![Build Status: master](https://travis-ci.org/google/draco.svg?branch=master)
[![Build Status](https://github.com/google/draco/workflows/Build/badge.svg)](https://github.com/google/draco/actions?query=workflow%3ABuild)
News
=======
### Version 1.4.1 release
* Using the versioned gstatic.com WASM and Javascript decoders is now
* Using the versioned www.gstatic.com WASM and Javascript decoders is now
recommended. To use v1.4.1, use this URL:
* https://www.gstatic.com/draco/versioned/decoders/1.4.1/*
* Replace the * with the files to load. E.g.
* https://gstatic.com/draco/versioned/decoders/1.4.1/draco_decoder.js
* https://www.gstatic.com/draco/versioned/decoders/1.4.1/draco_decoder.js
* This works with the v1.3.6 and v1.4.0 releases, and will work with future
Draco releases.
* Bug fixes

View File

@ -6,7 +6,7 @@ set(DRACO_CMAKE_DRACO_BUILD_DEFINITIONS_CMAKE_ 1)
# Utility for controlling the main draco library dependency. This changes in
# shared builds, and when an optional target requires a shared library build.
macro(set_draco_target)
if(MSVC OR WIN32)
if(MSVC)
set(draco_dependency draco)
set(draco_plugin_dependency ${draco_dependency})
else()
@ -63,6 +63,11 @@ macro(draco_set_build_definitions)
if(BUILD_SHARED_LIBS)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS TRUE)
endif()
else()
if(${CMAKE_SIZEOF_VOID_P} EQUAL 8)
# Ensure 64-bit platforms can support large files.
list(APPEND draco_defines "_LARGEFILE_SOURCE" "_FILE_OFFSET_BITS=64")
endif()
endif()
if(ANDROID)
@ -114,4 +119,6 @@ macro(draco_set_build_definitions)
draco_check_emscripten_environment()
draco_get_required_emscripten_flags(FLAG_LIST_VAR draco_base_cxx_flags)
endif()
draco_configure_sanitizer()
endmacro()

View File

@ -1,63 +0,0 @@
if(DRACO_CMAKE_DRACO_FEATURES_CMAKE_)
return()
endif()
set(DRACO_CMAKE_DRACO_FEATURES_CMAKE_ 1)
set(draco_features_file_name "${draco_build_dir}/draco/draco_features.h")
set(draco_features_list)
# Macro that handles tracking of Draco preprocessor symbols for the purpose of
# producing draco_features.h.
#
# draco_enable_feature(FEATURE <feature_name> [TARGETS <target_name>]) FEATURE
# is required. It should be a Draco preprocessor symbol. TARGETS is optional. It
# can be one or more draco targets.
#
# When the TARGETS argument is not present the preproc symbol is added to
# draco_features.h. When it is draco_features.h is unchanged, and
# target_compile_options() is called for each target specified.
macro(draco_enable_feature)
set(def_flags)
set(def_single_arg_opts FEATURE)
set(def_multi_arg_opts TARGETS)
cmake_parse_arguments(DEF "${def_flags}" "${def_single_arg_opts}"
"${def_multi_arg_opts}" ${ARGN})
if("${DEF_FEATURE}" STREQUAL "")
message(FATAL_ERROR "Empty FEATURE passed to draco_enable_feature().")
endif()
# Do nothing/return early if $DEF_FEATURE is already in the list.
list(FIND draco_features_list ${DEF_FEATURE} df_index)
if(NOT df_index EQUAL -1)
return()
endif()
list(LENGTH DEF_TARGETS df_targets_list_length)
if(${df_targets_list_length} EQUAL 0)
list(APPEND draco_features_list ${DEF_FEATURE})
else()
foreach(target ${DEF_TARGETS})
target_compile_definitions(${target} PRIVATE ${DEF_FEATURE})
endforeach()
endif()
endmacro()
# Function for generating draco_features.h.
function(draco_generate_features_h)
file(WRITE "${draco_features_file_name}.new"
"// GENERATED FILE -- DO NOT EDIT\n\n" "#ifndef DRACO_FEATURES_H_\n"
"#define DRACO_FEATURES_H_\n\n")
foreach(feature ${draco_features_list})
file(APPEND "${draco_features_file_name}.new" "#define ${feature}\n")
endforeach()
file(APPEND "${draco_features_file_name}.new"
"\n#endif // DRACO_FEATURES_H_")
# Will replace ${draco_features_file_name} only if the file content has
# changed. This prevents forced Draco rebuilds after CMake runs.
configure_file("${draco_features_file_name}.new"
"${draco_features_file_name}")
file(REMOVE "${draco_features_file_name}.new")
endfunction()

View File

@ -80,6 +80,12 @@ macro(draco_test_cxx_flag)
# Run the actual compile test.
unset(draco_all_cxx_flags_pass CACHE)
message("--- Running combined CXX flags test, flags: ${all_cxx_flags}")
# check_cxx_compiler_flag() requires that the flags are a string. When flags
# are passed as a list it will remove the list separators, and attempt to run
# a compile command using list entries concatenated together as a single
# argument. Avoid the problem by forcing the argument to be a string.
draco_set_and_stringify(SOURCE_VARS all_cxx_flags DEST all_cxx_flags)
check_cxx_compiler_flag("${all_cxx_flags}" draco_all_cxx_flags_pass)
if(cxx_test_FLAG_REQUIRED AND NOT draco_all_cxx_flags_pass)
@ -194,6 +200,9 @@ macro(draco_test_exe_linker_flag)
else()
unset(CMAKE_EXE_LINKER_FLAGS)
endif()
list(APPEND DRACO_EXE_LINKER_FLAGS ${${link_FLAG_LIST_VAR_NAME}})
list(REMOVE_DUPLICATES DRACO_EXE_LINKER_FLAGS)
endmacro()
# Runs the draco compiler tests. This macro builds up the list of list var(s)

View File

@ -55,7 +55,7 @@ macro(draco_setup_install_target)
install(TARGETS draco_encoder DESTINATION
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}")
if(WIN32)
if(MSVC)
install(TARGETS draco DESTINATION
"${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
else()

View File

@ -5,28 +5,28 @@ set(DRACO_CMAKE_DRACO_SANITIZER_CMAKE_ 1)
# Handles the details of enabling sanitizers.
macro(draco_configure_sanitizer)
if(DRACO_SANITIZE AND NOT MSVC)
if(DRACO_SANITIZE AND NOT EMSCRIPTEN AND NOT MSVC)
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(DRACO_SANITIZE MATCHES "cfi")
list(APPEND DRACO_CXX_FLAGS "-flto" "-fno-sanitize-trap=cfi")
list(APPEND DRACO_EXE_LINKER_FLAGS "-flto" "-fno-sanitize-trap=cfi"
list(APPEND SAN_CXX_FLAGS "-flto" "-fno-sanitize-trap=cfi")
list(APPEND SAN_LINKER_FLAGS "-flto" "-fno-sanitize-trap=cfi"
"-fuse-ld=gold")
endif()
if(${CMAKE_SIZEOF_VOID_P} EQUAL 4
AND DRACO_SANITIZE MATCHES "integer|undefined")
list(APPEND DRACO_EXE_LINKER_FLAGS "--rtlib=compiler-rt" "-lgcc_s")
list(APPEND SAN_LINKER_FLAGS "--rtlib=compiler-rt" "-lgcc_s")
endif()
endif()
list(APPEND DRACO_CXX_FLAGS "-fsanitize=${DRACO_SANITIZE}")
list(APPEND DRACO_EXE_LINKER_FLAGS "-fsanitize=${DRACO_SANITIZE}")
list(APPEND SAN_CXX_FLAGS "-fsanitize=${DRACO_SANITIZE}")
list(APPEND SAN_LINKER_FLAGS "-fsanitize=${DRACO_SANITIZE}")
# Make sanitizer callstacks accurate.
list(APPEND DRACO_CXX_FLAGS "-fno-omit-frame-pointer"
"-fno-optimize-sibling-calls")
list(APPEND SAN_CXX_FLAGS "-fno-omit-frame-pointer")
list(APPEND SAN_CXX_FLAGS "-fno-optimize-sibling-calls")
draco_test_cxx_flag(FLAG_LIST_VAR_NAMES DRACO_CXX_FLAGS FLAG_REQUIRED)
draco_test_exe_linker_flag(FLAG_LIST_VAR_NAME DRACO_EXE_LINKER_FLAGS)
draco_test_cxx_flag(FLAG_LIST_VAR_NAMES SAN_CXX_FLAGS FLAG_REQUIRED)
draco_test_exe_linker_flag(FLAG_LIST_VAR_NAME SAN_LINKER_FLAGS)
endif()
endmacro()

View File

@ -87,6 +87,7 @@ macro(draco_add_executable)
endif()
add_executable(${exe_NAME} ${exe_SOURCES})
set_target_properties(${exe_NAME} PROPERTIES VERSION ${DRACO_VERSION})
if(exe_OUTPUT_NAME)
set_target_properties(${exe_NAME} PROPERTIES OUTPUT_NAME ${exe_OUTPUT_NAME})
@ -109,10 +110,11 @@ macro(draco_add_executable)
if(exe_LINK_FLAGS OR DRACO_EXE_LINKER_FLAGS)
if(${CMAKE_VERSION} VERSION_LESS "3.13")
set(link_flags ${exe_LINK_FLAGS} ${DRACO_EXE_LINKER_FLAGS})
list(APPEND exe_LINK_FLAGS "${DRACO_EXE_LINKER_FLAGS}")
# LINK_FLAGS is managed as a string.
draco_set_and_stringify(SOURCE "${exe_LINK_FLAGS}" DEST exe_LINK_FLAGS)
set_target_properties(${exe_NAME}
PROPERTIES LINK_FLAGS ${exe_LINK_FLAGS}
${DRACO_EXE_LINKER_FLAGS})
PROPERTIES LINK_FLAGS "${exe_LINK_FLAGS}")
else()
target_link_options(${exe_NAME} PRIVATE ${exe_LINK_FLAGS}
${DRACO_EXE_LINKER_FLAGS})
@ -130,7 +132,7 @@ macro(draco_add_executable)
endif()
if(BUILD_SHARED_LIBS AND (MSVC OR WIN32))
target_compile_definitions(${lib_NAME} PRIVATE "DRACO_BUILDING_DLL=0")
target_compile_definitions(${exe_NAME} PRIVATE "DRACO_BUILDING_DLL=0")
endif()
if(exe_LIB_DEPS)
@ -163,8 +165,8 @@ endmacro()
# cmake-format: off
# - OUTPUT_NAME: Override output file basename. Target basename defaults to
# NAME. OUTPUT_NAME is ignored when BUILD_SHARED_LIBS is enabled and CMake
# is generating a build for which MSVC or WIN32 are true. This is to avoid
# output basename collisions with DLL import libraries.
# is generating a build for which MSVC is true. This is to avoid output
# basename collisions with DLL import libraries.
# - TEST: Flag. Presence means treat library as a test.
# - DEFINES: List of preprocessor macro definitions.
# - INCLUDES: list of include directories for the target.
@ -259,7 +261,7 @@ macro(draco_add_library)
endif()
if(lib_OUTPUT_NAME)
if(NOT (BUILD_SHARED_LIBS AND (MSVC OR WIN32)))
if(NOT (BUILD_SHARED_LIBS AND MSVC))
set_target_properties(${lib_NAME}
PROPERTIES OUTPUT_NAME ${lib_OUTPUT_NAME})
endif()
@ -318,8 +320,12 @@ macro(draco_add_library)
set_target_properties(${lib_NAME} PROPERTIES PREFIX "")
endif()
if(lib_TYPE STREQUAL SHARED AND NOT MSVC)
set_target_properties(${lib_NAME} PROPERTIES SOVERSION ${DRACO_SOVERSION})
# VERSION and SOVERSION as necessary
if(NOT lib_TYPE STREQUAL STATIC AND NOT lib_TYPE STREQUAL MODULE)
set_target_properties(${lib_NAME} PROPERTIES VERSION ${DRACO_VERSION})
if(NOT MSVC)
set_target_properties(${lib_NAME} PROPERTIES SOVERSION ${DRACO_SOVERSION})
endif()
endif()
if(BUILD_SHARED_LIBS AND (MSVC OR WIN32))

View File

@ -17,31 +17,31 @@
namespace draco {
void DracoTimer::Start() {
#ifdef _WIN32
QueryPerformanceCounter(&tv_start);
QueryPerformanceCounter(&tv_start_);
#else
gettimeofday(&tv_start, nullptr);
gettimeofday(&tv_start_, nullptr);
#endif
}
void DracoTimer::Stop() {
#ifdef _WIN32
QueryPerformanceCounter(&tv_end);
QueryPerformanceCounter(&tv_end_);
#else
gettimeofday(&tv_end, nullptr);
gettimeofday(&tv_end_, nullptr);
#endif
}
int64_t DracoTimer::GetInMs() {
#ifdef _WIN32
LARGE_INTEGER elapsed = {0};
elapsed.QuadPart = tv_end.QuadPart - tv_start.QuadPart;
elapsed.QuadPart = tv_end_.QuadPart - tv_start_.QuadPart;
LARGE_INTEGER frequency = {0};
QueryPerformanceFrequency(&frequency);
return elapsed.QuadPart * 1000 / frequency.QuadPart;
#else
const int64_t seconds = (tv_end.tv_sec - tv_start.tv_sec) * 1000;
const int64_t milliseconds = (tv_end.tv_usec - tv_start.tv_usec) / 1000;
const int64_t seconds = (tv_end_.tv_sec - tv_start_.tv_sec) * 1000;
const int64_t milliseconds = (tv_end_.tv_usec - tv_start_.tv_usec) / 1000;
return seconds + milliseconds;
#endif
}

View File

@ -20,9 +20,10 @@
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
typedef LARGE_INTEGER timeval;
typedef LARGE_INTEGER DracoTimeVal;
#else
#include <sys/time.h>
typedef timeval DracoTimeVal;
#endif
#include <cinttypes>
@ -39,8 +40,8 @@ class DracoTimer {
int64_t GetInMs();
private:
timeval tv_start;
timeval tv_end;
DracoTimeVal tv_start_;
DracoTimeVal tv_end_;
};
typedef DracoTimer CycleTimer;

View File

@ -18,6 +18,7 @@
#include <cctype>
#include <cmath>
#include <iterator>
#include <limits>
namespace draco {
namespace parser {
@ -252,7 +253,7 @@ DecoderBuffer ParseLineIntoDecoderBuffer(DecoderBuffer *buffer) {
std::string ToLower(const std::string &str) {
std::string out;
std::transform(str.begin(), str.end(), std::back_inserter(out), [](unsigned char c){return tolower(c);});
std::transform(str.begin(), str.end(), std::back_inserter(out), tolower);
return out;
}

View File

@ -268,14 +268,14 @@ std::vector<std::string> PlyReader::SplitWords(const std::string &line) {
while ((end = line.find_first_of(" \t\n\v\f\r", start)) !=
std::string::npos) {
const std::string word(line.substr(start, end - start));
if (!std::all_of(word.begin(), word.end(), [](unsigned char c){return isspace(c);})) {
if (!std::all_of(word.begin(), word.end(), isspace)) {
output.push_back(word);
}
start = end + 1;
}
const std::string last_word(line.substr(start));
if (!std::all_of(last_word.begin(), last_word.end(), [](unsigned char c){return isspace(c);})) {
if (!std::all_of(last_word.begin(), last_word.end(), isspace)) {
output.push_back(last_word);
}
return output;

View File

@ -87,7 +87,14 @@ size_t StdioFileReader::GetFileSize() {
return false;
}
#if _FILE_OFFSET_BITS == 64
const size_t file_size = static_cast<size_t>(ftello(file_));
#elif defined _WIN64
const size_t file_size = static_cast<size_t>(_ftelli64(file_));
#else
const size_t file_size = static_cast<size_t>(ftell(file_));
#endif
rewind(file_);
return file_size;

View File

@ -129,7 +129,7 @@ void Sweep::EdgeEvent(SweepContext& tcx, Point& ep, Point& eq, Triangle* triangl
EdgeEvent( tcx, ep, *p1, triangle, *p1 );
} else {
// ASSIMP_CHANGE (aramis_acg)
std::runtime_error("EdgeEvent - collinear points not supported");
throw std::runtime_error("EdgeEvent - collinear points not supported");
}
return;
}

View File

@ -144,7 +144,7 @@ enum aiTextureMapMode {
enum aiTextureMapping {
/** The mapping coordinates are taken from an UV channel.
*
* The #AI_MATKEY_UVWSRC key specifies from which UV channel
* #AI_MATKEY_UVWSRC property specifies from which UV channel
* the texture coordinates are to be taken from (remember,
* meshes can have more than one UV channel).
*/
@ -202,11 +202,15 @@ enum aiTextureType {
/** The texture is combined with the result of the diffuse
* lighting equation.
* OR
* PBR Specular/Glossiness
*/
aiTextureType_DIFFUSE = 1,
/** The texture is combined with the result of the specular
* lighting equation.
* OR
* PBR Specular/Glossiness
*/
aiTextureType_SPECULAR = 2,
@ -288,6 +292,32 @@ enum aiTextureType {
aiTextureType_DIFFUSE_ROUGHNESS = 16,
aiTextureType_AMBIENT_OCCLUSION = 17,
/** PBR Material Modifiers
* Some modern renderers have further PBR modifiers that may be overlaid
* on top of the 'base' PBR materials for additional realism.
* These use multiple texture maps, so only the base type is directly defined
*/
/** Sheen
* Generally used to simulate textiles that are covered in a layer of microfibers
* eg velvet
* https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_sheen
*/
aiTextureType_SHEEN = 19,
/** Clearcoat
* Simulates a layer of 'polish' or 'laquer' layered on top of a PBR substrate
* https://autodesk.github.io/standard-surface/#closures/coating
* https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
*/
aiTextureType_CLEARCOAT = 20,
/** Transmission
* Simulates transmission through the surface
* May include further information such as wall thickness
*/
aiTextureType_TRANSMISSION = 21,
/** Unknown texture
*
* A texture reference that does not match any of the definitions
@ -309,7 +339,9 @@ ASSIMP_API const char *TextureTypeToString(enum aiTextureType in);
// ---------------------------------------------------------------------------
/** @brief Defines all shading models supported by the library
*
*
* Property: #AI_MATKEY_SHADING_MODEL
*
* The list of shading modes has been taken from Blender.
* See Blender documentation for more information. The API does
* not distinguish between "specular" and "diffuse" shaders (thus the
@ -318,6 +350,7 @@ ASSIMP_API const char *TextureTypeToString(enum aiTextureType in);
* Again, this value is just a hint. Assimp tries to select the shader whose
* most common implementation matches the original rendering results of the
* 3D modeler which wrote a particular model as closely as possible.
*
*/
enum aiShadingMode {
/** Flat shading. Shading is done on per-face base,
@ -364,13 +397,28 @@ enum aiShadingMode {
aiShadingMode_CookTorrance = 0x8,
/** No shading at all. Constant light influence of 1.0.
* Also known as "Unlit"
*/
aiShadingMode_NoShading = 0x9,
aiShadingMode_Unlit = aiShadingMode_NoShading, // Alias
/** Fresnel shading
*/
aiShadingMode_Fresnel = 0xa,
/** Physically-Based Rendering (PBR) shading using
* Bidirectional scattering/reflectance distribution function (BSDF/BRDF)
* There are multiple methods under this banner, and model files may provide
* data for more than one PBR-BRDF method.
* Applications should use the set of provided properties to determine which
* of their preferred PBR rendering methods are likely to be available
* eg:
* - If AI_MATKEY_METALLIC_FACTOR is set, then a Metallic/Roughness is available
* - If AI_MATKEY_GLOSSINESS_FACTOR is set, then a Specular/Glossiness is available
* Note that some PBR methods allow layering of techniques
*/
aiShadingMode_PBR_BRDF = 0xb,
#ifndef SWIG
_aiShadingMode_Force32Bit = INT_MAX
#endif
@ -922,12 +970,66 @@ extern "C" {
// ---------------------------------------------------------------------------
// PBR material support
// --------------------
// Properties defining PBR rendering techniques
#define AI_MATKEY_USE_COLOR_MAP "$mat.useColorMap", 0, 0
// Metallic/Roughness Workflow
// ---------------------------
// Base RGBA color factor. Will be multiplied by final base color texture values if extant
// Note: Importers may choose to copy this into AI_MATKEY_COLOR_DIFFUSE for compatibility
// with renderers and formats that do not support Metallic/Roughness PBR
#define AI_MATKEY_BASE_COLOR "$clr.base", 0, 0
#define AI_MATKEY_BASE_COLOR_TEXTURE aiTextureType_BASE_COLOR, 0
#define AI_MATKEY_USE_METALLIC_MAP "$mat.useMetallicMap", 0, 0
// Metallic factor. 0.0 = Full Dielectric, 1.0 = Full Metal
#define AI_MATKEY_METALLIC_FACTOR "$mat.metallicFactor", 0, 0
#define AI_MATKEY_METALLIC_TEXTURE aiTextureType_METALNESS, 0
#define AI_MATKEY_USE_ROUGHNESS_MAP "$mat.useRoughnessMap", 0, 0
// Roughness factor. 0.0 = Perfectly Smooth, 1.0 = Completely Rough
#define AI_MATKEY_ROUGHNESS_FACTOR "$mat.roughnessFactor", 0, 0
#define AI_MATKEY_ROUGHNESS_TEXTURE aiTextureType_DIFFUSE_ROUGHNESS, 0
// Specular/Glossiness Workflow
// ---------------------------
// Diffuse/Albedo Color. Note: Pure Metals have a diffuse of {0,0,0}
// AI_MATKEY_COLOR_DIFFUSE
// Specular Color.
// Note: Metallic/Roughness may also have a Specular Color
// AI_MATKEY_COLOR_SPECULAR
#define AI_MATKEY_SPECULAR_FACTOR "$mat.specularFactor", 0, 0
// Glossiness factor. 0.0 = Completely Rough, 1.0 = Perfectly Smooth
#define AI_MATKEY_GLOSSINESS_FACTOR "$mat.glossinessFactor", 0, 0
// Sheen
// -----
// Sheen base RGB color. Default {0,0,0}
#define AI_MATKEY_SHEEN_COLOR_FACTOR "$clr.sheen.factor", 0, 0
// Sheen Roughness Factor.
#define AI_MATKEY_SHEEN_ROUGHNESS_FACTOR "$mat.sheen.roughnessFactor", 0, 0
#define AI_MATKEY_SHEEN_COLOR_TEXTURE aiTextureType_SHEEN, 0
#define AI_MATKEY_SHEEN_ROUGHNESS_TEXTURE aiTextureType_SHEEN, 1
// Clearcoat
// ---------
// Clearcoat layer intensity. 0.0 = none (disabled)
#define AI_MATKEY_CLEARCOAT_FACTOR "$mat.clearcoat.factor", 0, 0
#define AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR "$mat.clearcoat.roughnessFactor", 0, 0
#define AI_MATKEY_CLEARCOAT_TEXTURE aiTextureType_CLEARCOAT, 0
#define AI_MATKEY_CLEARCOAT_ROUGHNESS_TEXTURE aiTextureType_CLEARCOAT, 1
#define AI_MATKEY_CLEARCOAT_NORMAL_TEXTURE aiTextureType_CLEARCOAT, 2
// Transmission
// ------------
// https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission
// Base percentage of light transmitted through the surface. 0.0 = Opaque, 1.0 = Fully transparent
#define AI_MATKEY_TRANSMISSION_FACTOR "$mat.transmission.factor", 0, 0
// Texture defining percentage of light transmitted through the surface.
// Multiplied by AI_MATKEY_TRANSMISSION_FACTOR
#define AI_MATKEY_TRANSMISSION_TEXTURE aiTextureType_TRANSMISSION, 0
// Emissive
// --------
#define AI_MATKEY_USE_EMISSIVE_MAP "$mat.useEmissiveMap", 0, 0
#define AI_MATKEY_EMISSIVE_INTENSITY "$mat.emissiveIntensity", 0, 0
#define AI_MATKEY_USE_AO_MAP "$mat.useAOMap", 0, 0
@ -1397,8 +1499,6 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray(
ai_real *pOut,
unsigned int *pMax);
#ifdef __cplusplus
// ---------------------------------------------------------------------------
/** @brief Retrieve a single float property with a specific key from the material.
*
@ -1418,7 +1518,7 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialFloatArray(
* @return Specifies whether the key has been found. If not, the output
* float remains unmodified.*/
// ---------------------------------------------------------------------------
inline aiReturn aiGetMaterialFloat(const aiMaterial *pMat,
inline aiReturn aiGetMaterialFloat(const C_STRUCT aiMaterial *pMat,
const char *pKey,
unsigned int type,
unsigned int index,
@ -1426,14 +1526,6 @@ inline aiReturn aiGetMaterialFloat(const aiMaterial *pMat,
return aiGetMaterialFloatArray(pMat, pKey, type, index, pOut, (unsigned int *)0x0);
}
#else
// Use our friend, the C preprocessor
#define aiGetMaterialFloat (pMat, type, index, pKey, pOut) \
aiGetMaterialFloatArray(pMat, type, index, pKey, pOut, NULL)
#endif //!__cplusplus
// ---------------------------------------------------------------------------
/** @brief Retrieve an array of integer values with a specific key
* from a material
@ -1446,8 +1538,6 @@ ASSIMP_API C_ENUM aiReturn aiGetMaterialIntegerArray(const C_STRUCT aiMaterial *
int *pOut,
unsigned int *pMax);
#ifdef __cplusplus
// ---------------------------------------------------------------------------
/** @brief Retrieve an integer property with a specific key from a material
*
@ -1461,14 +1551,6 @@ inline aiReturn aiGetMaterialInteger(const C_STRUCT aiMaterial *pMat,
return aiGetMaterialIntegerArray(pMat, pKey, type, index, pOut, (unsigned int *)0x0);
}
#else
// use our friend, the C preprocessor
#define aiGetMaterialInteger (pMat, type, index, pKey, pOut) \
aiGetMaterialIntegerArray(pMat, type, index, pKey, pOut, NULL)
#endif //!__cplusplus
// ---------------------------------------------------------------------------
/** @brief Retrieve a color value from the material property table
*

View File

@ -432,7 +432,7 @@ struct aiMetadata {
/// Check whether there is a metadata entry for the given key.
/// \param [in] Key - the key value value to check for.
inline bool HasKey(const char *key) {
inline bool HasKey(const char *key) const {
if (nullptr == key) {
return false;
}

View File

@ -50,32 +50,32 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# pragma GCC system_header
#endif
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR "$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE aiTextureType_DIFFUSE, 1
//#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_FACTOR "$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0
//#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLIC_FACTOR "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0
//#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_ROUGHNESS_FACTOR "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0
//#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_BASE_COLOR_TEXTURE aiTextureType_DIFFUSE, 1
#define AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 0
#define AI_MATKEY_GLTF_ALPHAMODE "$mat.gltf.alphaMode", 0, 0
#define AI_MATKEY_GLTF_ALPHACUTOFF "$mat.gltf.alphaCutoff", 0, 0
#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0
#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0, 0
#define AI_MATKEY_GLTF_UNLIT "$mat.gltf.unlit", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_SHEEN "$mat.gltf.materialSheen", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR "$mat.gltf.materialSheen.sheenColorFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR "$mat.gltf.materialSheen.sheenRoughnessFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE aiTextureType_UNKNOWN, 1
#define AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 2
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT "$mat.gltf.materialClearcoat", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR "$mat.gltf.materialClearcoat.clearcoatFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR "$mat.gltf.materialClearcoat.clearcoatRoughnessFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE aiTextureType_UNKNOWN, 3
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 4
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE aiTextureType_NORMALS, 1
#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION "$mat.gltf.materialTransmission", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR "$mat.gltf.materialTransmission.transmissionFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE aiTextureType_UNKNOWN, 5
//#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0
//#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0, 0
//#define AI_MATKEY_GLTF_UNLIT "$mat.gltf.unlit", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_SHEEN "$mat.gltf.materialSheen", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR "$mat.gltf.materialSheen.sheenColorFactor", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR "$mat.gltf.materialSheen.sheenRoughnessFactor", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE aiTextureType_UNKNOWN, 1
//#define AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 2
//#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT "$mat.gltf.materialClearcoat", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR "$mat.gltf.materialClearcoat.clearcoatFactor", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR "$mat.gltf.materialClearcoat.clearcoatRoughnessFactor", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE aiTextureType_UNKNOWN, 3
//#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 4
//#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE aiTextureType_NORMALS, 1
//#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION "$mat.gltf.materialTransmission", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR "$mat.gltf.materialTransmission.transmissionFactor", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE aiTextureType_UNKNOWN, 5
#define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord"
//#define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord"
#define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname"
#define _AI_MATKEY_GLTF_MAPPINGID_BASE "$tex.mappingid"
#define _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE "$tex.mappingfiltermag"
@ -83,7 +83,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#define _AI_MATKEY_GLTF_SCALE_BASE "$tex.scale"
#define _AI_MATKEY_GLTF_STRENGTH_BASE "$tex.strength"
#define AI_MATKEY_GLTF_TEXTURE_TEXCOORD(type, N) _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, type, N
//#define AI_MATKEY_GLTF_TEXTURE_TEXCOORD(type, N) _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE, type, N
#define AI_MATKEY_GLTF_MAPPINGNAME(type, N) _AI_MATKEY_GLTF_MAPPINGNAME_BASE, type, N
#define AI_MATKEY_GLTF_MAPPINGID(type, N) _AI_MATKEY_GLTF_MAPPINGID_BASE, type, N
#define AI_MATKEY_GLTF_MAPPINGFILTER_MAG(type, N) _AI_MATKEY_GLTF_MAPPINGFILTER_MAG_BASE, type, N

View File

@ -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,
@ -397,22 +395,35 @@ struct aiScene
//! Returns an embedded texture
const aiTexture* GetEmbeddedTexture(const char* filename) const {
return GetEmbeddedTextureAndIndex(filename).first;
}
//! Returns an embedded texture and its index
std::pair<const aiTexture*, int> GetEmbeddedTextureAndIndex(const char* filename) const {
if(nullptr==filename) {
return std::make_pair(nullptr, -1);
}
// lookup using texture ID (if referenced like: "*1", "*2", etc.)
if ('*' == *filename) {
int index = std::atoi(filename + 1);
if (0 > index || mNumTextures <= static_cast<unsigned>(index))
return nullptr;
return mTextures[index];
if (0 > index || mNumTextures <= static_cast<unsigned>(index)) {
return std::make_pair(nullptr, -1);
}
return std::make_pair(mTextures[index], index);
}
// lookup using filename
const char* shortFilename = GetShortFilename(filename);
if (nullptr == shortFilename) {
return std::make_pair(nullptr, -1);
}
for (unsigned int i = 0; i < mNumTextures; i++) {
const char* shortTextureFilename = GetShortFilename(mTextures[i]->mFilename.C_Str());
if (strcmp(shortTextureFilename, shortFilename) == 0) {
return mTextures[i];
return std::make_pair(mTextures[i], i);
}
}
return nullptr;
return std::make_pair(nullptr, -1);
}
#endif // __cplusplus

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

View File

@ -53,8 +53,8 @@ class utTypes : public ::testing::Test {
TEST_F( utTypes, Color3dCpmpareOpTest ) {
aiColor3D col1( 1, 2, 3 );
aiColor3D col2( 4, 5, 6 );
aiColor3D col3( col1 );
const aiColor3D &col3(col1);
EXPECT_FALSE( col1 == col2 );
EXPECT_FALSE( col2 == col3 );
EXPECT_TRUE( col1 == col3 );

View File

@ -57,10 +57,9 @@ using namespace Assimp;
class utglTF2ImportExport : public AbstractImportExportBase {
public:
virtual bool importerTest() {
virtual bool importerMatTest(const char *file, bool spec_gloss, std::array<aiTextureMapMode, 2> exp_modes = { aiTextureMapMode_Wrap, aiTextureMapMode_Wrap }) {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured.gltf",
aiProcess_ValidateDataStructure);
const aiScene *scene = importer.ReadFile(file, aiProcess_ValidateDataStructure);
EXPECT_NE(scene, nullptr);
if (!scene) {
return false;
@ -72,13 +71,49 @@ public:
}
const aiMaterial *material = scene->mMaterials[0];
// This Material should be a PBR
aiShadingMode shadingMode;
EXPECT_EQ(aiReturn_SUCCESS, material->Get(AI_MATKEY_SHADING_MODEL, shadingMode));
EXPECT_EQ(aiShadingMode_PBR_BRDF, shadingMode);
// Should import the texture as diffuse and as base color
aiString path;
aiTextureMapMode modes[2];
std::array<aiTextureMapMode,2> modes;
EXPECT_EQ(aiReturn_SUCCESS, material->GetTexture(aiTextureType_DIFFUSE, 0, &path, nullptr, nullptr,
nullptr, nullptr, modes));
nullptr, nullptr, modes.data()));
EXPECT_STREQ(path.C_Str(), "CesiumLogoFlat.png");
EXPECT_EQ(modes[0], aiTextureMapMode_Mirror);
EXPECT_EQ(modes[1], aiTextureMapMode_Clamp);
EXPECT_EQ(exp_modes, modes);
// Also as Base Color
EXPECT_EQ(aiReturn_SUCCESS, material->GetTexture(aiTextureType_BASE_COLOR, 0, &path, nullptr, nullptr,
nullptr, nullptr, modes.data()));
EXPECT_STREQ(path.C_Str(), "CesiumLogoFlat.png");
EXPECT_EQ(exp_modes, modes);
// Should have a MetallicFactor (default is 1.0)
ai_real metal_factor = ai_real(0.5);
EXPECT_EQ(aiReturn_SUCCESS, material->Get(AI_MATKEY_METALLIC_FACTOR, metal_factor));
EXPECT_EQ(ai_real(0.0), metal_factor);
// And a roughness factor (default is 1.0)
ai_real roughness_factor = ai_real(0.5);
EXPECT_EQ(aiReturn_SUCCESS, material->Get(AI_MATKEY_ROUGHNESS_FACTOR, roughness_factor));
EXPECT_EQ(ai_real(1.0), roughness_factor);
aiColor3D spec_color = { 0, 0, 0 };
ai_real glossiness = ai_real(0.5);
if (spec_gloss) {
EXPECT_EQ(aiReturn_SUCCESS, material->Get(AI_MATKEY_COLOR_SPECULAR, spec_color));
constexpr ai_real spec_val(0.20000000298023225); // From the file
EXPECT_EQ(spec_val, spec_color.r);
EXPECT_EQ(spec_val, spec_color.g);
EXPECT_EQ(spec_val, spec_color.b);
EXPECT_EQ(aiReturn_SUCCESS, material->Get(AI_MATKEY_GLOSSINESS_FACTOR, glossiness));
EXPECT_EQ(ai_real(1.0), glossiness);
} else {
EXPECT_EQ(aiReturn_FAILURE, material->Get(AI_MATKEY_COLOR_SPECULAR, spec_color));
EXPECT_EQ(aiReturn_FAILURE, material->Get(AI_MATKEY_GLOSSINESS_FACTOR, glossiness));
}
return true;
}
@ -105,14 +140,89 @@ public:
};
TEST_F(utglTF2ImportExport, importglTF2FromFileTest) {
EXPECT_TRUE(importerTest());
EXPECT_TRUE(importerMatTest(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF/BoxTextured.gltf", false, {aiTextureMapMode_Mirror, aiTextureMapMode_Clamp}));
}
TEST_F(utglTF2ImportExport, importBinaryglTF2FromFileTest) {
EXPECT_TRUE(binaryImporterTest());
}
TEST_F(utglTF2ImportExport, importglTF2_KHR_materials_pbrSpecularGlossiness) {
EXPECT_TRUE(importerMatTest(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured.gltf", true));
}
void VerifyClearCoatScene(const aiScene *scene) {
ASSERT_NE(nullptr, scene);
ASSERT_TRUE(scene->HasMaterials());
// Find a specific Clearcoat material and check the values
const aiString partial_coated("Partial_Coated");
bool found_partial_coat = false;
for (size_t i = 0; i < scene->mNumMaterials; ++i) {
const aiMaterial *material = scene->mMaterials[i];
ASSERT_NE(nullptr, material);
if (material->GetName() == partial_coated) {
found_partial_coat = true;
ai_real clearcoat_factor(0.0f);
EXPECT_EQ(aiReturn_SUCCESS, material->Get(AI_MATKEY_CLEARCOAT_FACTOR, clearcoat_factor));
EXPECT_EQ(ai_real(1.0f), clearcoat_factor);
ai_real clearcoat_rough_factor(0.0f);
EXPECT_EQ(aiReturn_SUCCESS, material->Get(AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR, clearcoat_rough_factor));
EXPECT_EQ(ai_real(0.03f), clearcoat_rough_factor);
// Should import the texture as diffuse and as base color
aiString path;
std::array<aiTextureMapMode, 2> modes;
static const std::array<aiTextureMapMode, 2> exp_modes = { aiTextureMapMode_Wrap, aiTextureMapMode_Wrap };
EXPECT_EQ(aiReturn_SUCCESS, material->GetTexture(AI_MATKEY_CLEARCOAT_TEXTURE, &path, nullptr, nullptr,
nullptr, nullptr, modes.data()));
EXPECT_STREQ(path.C_Str(), "PartialCoating.png");
EXPECT_EQ(exp_modes, modes);
}
}
EXPECT_TRUE(found_partial_coat);
}
TEST_F(utglTF2ImportExport, importglTF2_KHR_materials_clearcoat) {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/ClearCoat-glTF/ClearCoatTest.gltf", aiProcess_ValidateDataStructure);
VerifyClearCoatScene(scene);
}
#ifndef ASSIMP_BUILD_NO_EXPORT
TEST_F(utglTF2ImportExport, importglTF2AndExport_KHR_materials_clearcoat) {
{
Assimp::Importer importer;
Assimp::Exporter exporter;
const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/ClearCoat-glTF/ClearCoatTest.gltf", aiProcess_ValidateDataStructure);
ASSERT_NE(nullptr, scene);
// Export
EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/ClearCoat-glTF/ClearCoatTest_out.glb"));
}
// And re-import
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/ClearCoat-glTF/ClearCoatTest_out.glb", aiProcess_ValidateDataStructure);
VerifyClearCoatScene(scene);
}
TEST_F(utglTF2ImportExport, importglTF2AndExport_KHR_materials_pbrSpecularGlossiness) {
Assimp::Importer importer;
Assimp::Exporter exporter;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured.gltf",
aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
// Export
EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured_out.glb"));
// And re-import
EXPECT_TRUE(importerMatTest(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured_out.glb", true));
}
TEST_F(utglTF2ImportExport, importglTF2AndExportToOBJ) {
Assimp::Importer importer;
Assimp::Exporter exporter;
@ -130,6 +240,7 @@ TEST_F(utglTF2ImportExport, importglTF2EmbeddedAndExportToOBJ) {
EXPECT_NE(nullptr, scene);
EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "obj", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-Embedded/BoxTextured_out.obj"));
}
#endif // ASSIMP_BUILD_NO_EXPORT
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModePointsWithoutIndices) {
@ -492,32 +603,58 @@ TEST_F(utglTF2ImportExport, sceneMetadata) {
}
TEST_F(utglTF2ImportExport, texcoords) {
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTexcoords-glTF/boxTexcoords.gltf",
aiProcess_ValidateDataStructure);
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTexcoords-glTF/boxTexcoords.gltf", aiProcess_ValidateDataStructure);
ASSERT_NE(scene, nullptr);
ASSERT_TRUE(scene->HasMaterials());
const aiMaterial *material = scene->mMaterials[0];
aiString path;
unsigned int uvIndex = 255;
aiTextureMapMode modes[2];
EXPECT_EQ(aiReturn_SUCCESS, material->GetTexture(AI_MATKEY_BASE_COLOR_TEXTURE, &path, nullptr, &uvIndex, nullptr, nullptr, modes));
EXPECT_STREQ(path.C_Str(), "texture.png");
EXPECT_EQ(uvIndex, 0);
uvIndex = 255;
EXPECT_EQ(aiReturn_SUCCESS, material->GetTexture(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE, &path, nullptr, &uvIndex, nullptr, nullptr, modes));
EXPECT_STREQ(path.C_Str(), "texture.png");
EXPECT_EQ(uvIndex, 1);
}
#ifndef ASSIMP_BUILD_NO_EXPORT
TEST_F(utglTF2ImportExport, texcoords_export) {
{
Assimp::Importer importer;
Assimp::Exporter exporter;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTexcoords-glTF/boxTexcoords.gltf", aiProcess_ValidateDataStructure);
ASSERT_NE(scene, nullptr);
ASSERT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTexcoords-glTF/boxTexcoords.gltf_out.glb"));
}
Assimp::Importer importer;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTexcoords-glTF/boxTexcoords.gltf", aiProcess_ValidateDataStructure);
ASSERT_NE(scene, nullptr);
ASSERT_TRUE(scene->HasMaterials());
const aiMaterial *material = scene->mMaterials[0];
aiString path;
unsigned int uvIndex = 255;
aiTextureMapMode modes[2];
EXPECT_EQ(aiReturn_SUCCESS, material->GetTexture(aiTextureType_DIFFUSE, 0, &path, nullptr, nullptr,
nullptr, nullptr, modes));
EXPECT_EQ(aiReturn_SUCCESS, material->GetTexture(AI_MATKEY_BASE_COLOR_TEXTURE, &path, nullptr, &uvIndex, nullptr, nullptr, modes));
EXPECT_STREQ(path.C_Str(), "texture.png");
int uvIndex = -1;
EXPECT_EQ(aiGetMaterialInteger(material, AI_MATKEY_GLTF_TEXTURE_TEXCOORD(aiTextureType_DIFFUSE, 0), &uvIndex), aiReturn_SUCCESS);
EXPECT_EQ(uvIndex, 0);
// Using manual macro expansion of AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE here.
// The following works with some but not all compilers:
// #define APPLY(X, Y) X(Y)
// ..., APPLY(AI_MATKEY_GLTF_TEXTURE_TEXCOORD, AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE), ...
EXPECT_EQ(aiGetMaterialInteger(material, AI_MATKEY_GLTF_TEXTURE_TEXCOORD(aiTextureType_UNKNOWN, 0), &uvIndex), aiReturn_SUCCESS);
uvIndex = 255;
EXPECT_EQ(aiReturn_SUCCESS, material->GetTexture(AI_MATKEY_GLTF_PBRMETALLICROUGHNESS_METALLICROUGHNESS_TEXTURE, &path, nullptr, &uvIndex, nullptr, nullptr, modes));
EXPECT_STREQ(path.C_Str(), "texture.png");
EXPECT_EQ(uvIndex, 1);
}
#endif // ASSIMP_BUILD_NO_EXPORT
TEST_F(utglTF2ImportExport, recursive_nodes) {
Assimp::Importer importer;
const aiScene* scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/RecursiveNodes/RecursiveNodes.gltf", aiProcess_ValidateDataStructure);

View File

@ -39,9 +39,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#include "assimp_view.h"
#include "AnimEvaluator.h"
#include <tuple>
#include <assimp/anim.h>
#include <assimp/ai_assert.h>
using namespace AssimpView;

View File

@ -1,4 +1,3 @@
/** Calculates a pose for a given time of an animation */
/*
---------------------------------------------------------------------------
Open Asset Import Library (assimp)
@ -40,11 +39,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
---------------------------------------------------------------------------
*/
#pragma once
#ifndef AV_ANIMEVALUATOR_H_INCLUDED
#define AV_ANIMEVALUATOR_H_INCLUDED
/** Calculates a pose for a given time of an animation */
#include <tuple>
#include <vector>
#include <assimp/matrix4x4.h>
struct aiAnimation;
namespace AssimpView {
@ -63,18 +68,19 @@ public:
/// @brief The class destructor.
~AnimEvaluator();
/** Evaluates the animation tracks for a given time stamp. The calculated pose can be retrieved as a
* array of transformation matrices afterwards by calling GetTransformations().
* @param pTime The time for which you want to evaluate the animation, in seconds. Will be mapped into the animation cycle, so
* it can be an arbitrary value. Best use with ever-increasing time stamps.
*/
/// @brief Evaluates the animation tracks for a given time stamp.
/// The calculated pose can be retrieved as an array of transformation
/// matrices afterwards by calling GetTransformations().
/// @param pTime The time for which you want to evaluate the animation, in seconds.
/// Will be mapped into the animation cycle, so it can get an arbitrary
/// value. Best use with ever-increasing time stamps.
void Evaluate(double pTime);
/** Returns the transform matrices calculated at the last Evaluate() call. The array matches the mChannels array of
* the aiAnimation. */
/// @brief Returns the transform matrices calculated at the last Evaluate() call.
/// The array matches the mChannels array of the aiAnimation.
const std::vector<aiMatrix4x4> &GetTransformations() const { return mTransforms; }
protected:
private:
const aiAnimation *mAnim;
double mLastTime;
std::vector<std::tuple<unsigned int, unsigned int, unsigned int>> mLastPositions;

View File

@ -489,7 +489,7 @@ int CreateAssetData() {
nidx = 3;
break;
default:
ai_assert(false);
CLogWindow::Instance().WriteLine("Unknown primitiv type");
break;
};
@ -500,8 +500,7 @@ int CreateAssetData() {
// check whether we can use 16 bit indices
if (numIndices >= 65536) {
// create 32 bit index buffer
if (FAILED(g_piDevice->CreateIndexBuffer(4 *
numIndices,
if (FAILED(g_piDevice->CreateIndexBuffer(4 * numIndices,
D3DUSAGE_WRITEONLY | dwUsage,
D3DFMT_INDEX32,
D3DPOOL_DEFAULT,
@ -523,7 +522,7 @@ int CreateAssetData() {
} else {
// create 16 bit index buffer
if (FAILED(g_piDevice->CreateIndexBuffer(2 *
numIndices,
numIndices,
D3DUSAGE_WRITEONLY | dwUsage,
D3DFMT_INDEX16,
D3DPOOL_DEFAULT,