Merge branch 'master' into safe
This commit is contained in:
@@ -2203,7 +2203,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
|
||||
@@ -2607,10 +2665,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
|
||||
|
||||
@@ -63,6 +63,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
struct aiScene;
|
||||
struct aiNode;
|
||||
struct aiLight;
|
||||
//struct aiMaterial;
|
||||
|
||||
namespace Assimp
|
||||
@@ -95,6 +96,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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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];
|
||||
|
||||
@@ -101,27 +105,31 @@ bool EmbedTexturesProcess::addTexture(aiScene* pScene, std::string path) const {
|
||||
std::string imagePath = path;
|
||||
|
||||
// Test path directly
|
||||
std::ifstream file(imagePath, std::ios::binary | std::ios::ate);
|
||||
if ((imageSize = file.tellg()) == std::streampos(-1)) {
|
||||
if (!mIOHandler->Exists(imagePath)) {
|
||||
ASSIMP_LOG_WARN("EmbedTexturesProcess: Cannot find image: ", imagePath, ". Will try to find it in root folder.");
|
||||
|
||||
// Test path in root path
|
||||
imagePath = mRootPath + path;
|
||||
file.open(imagePath, std::ios::binary | std::ios::ate);
|
||||
if ((imageSize = file.tellg()) == std::streampos(-1)) {
|
||||
if (!mIOHandler->Exists(imagePath)) {
|
||||
// Test path basename in root path
|
||||
imagePath = mRootPath + path.substr(path.find_last_of("\\/") + 1u);
|
||||
file.open(imagePath, std::ios::binary | std::ios::ate);
|
||||
if ((imageSize = file.tellg()) == std::streampos(-1)) {
|
||||
if (!mIOHandler->Exists(imagePath)) {
|
||||
ASSIMP_LOG_ERROR("EmbedTexturesProcess: Unable to embed texture: ", path, ".");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
IOStream* pFile = mIOHandler->Open(imagePath);
|
||||
if (pFile == nullptr) {
|
||||
ASSIMP_LOG_ERROR("EmbedTexturesProcess: Unable to embed texture: ", path, ".");
|
||||
return false;
|
||||
}
|
||||
imageSize = pFile->FileSize();
|
||||
|
||||
aiTexel* imageContent = new aiTexel[ 1ul + static_cast<unsigned long>( imageSize ) / sizeof(aiTexel)];
|
||||
file.seekg(0, std::ios::beg);
|
||||
file.read(reinterpret_cast<char*>(imageContent), imageSize);
|
||||
pFile->Seek(0, aiOrigin_SET);
|
||||
pFile->Read(reinterpret_cast<char*>(imageContent), imageSize, 1);
|
||||
mIOHandler->Close(pFile);
|
||||
|
||||
// Enlarging the textures table
|
||||
unsigned int textureId = pScene->mNumTextures++;
|
||||
|
||||
@@ -48,6 +48,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
struct aiNode;
|
||||
|
||||
class IOSystem;
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
/**
|
||||
@@ -80,6 +82,7 @@ private:
|
||||
|
||||
private:
|
||||
std::string mRootPath;
|
||||
IOSystem* mIOHandler = nullptr;
|
||||
};
|
||||
|
||||
} // namespace Assimp
|
||||
|
||||
Reference in New Issue
Block a user