Merge branch 'master' into patch-1

pull/3954/head
ihsinme 2021-06-15 09:42:05 +03:00 committed by GitHub
commit 6a78ef5652
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 90 additions and 7 deletions

View File

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

View File

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

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