Merge branch 'master' into master
This commit is contained in:
@@ -74,6 +74,8 @@ namespace XmlTag {
|
||||
const char* const pid = "pid";
|
||||
const char* const pindex = "pindex";
|
||||
const char* const p1 = "p1";
|
||||
const char *const p2 = "p2";
|
||||
const char *const p3 = "p3";
|
||||
const char* const name = "name";
|
||||
const char* const type = "type";
|
||||
const char* const build = "build";
|
||||
|
||||
@@ -64,7 +64,7 @@ bool validateColorString(const char *color) {
|
||||
return true;
|
||||
}
|
||||
|
||||
aiFace ReadTriangle(XmlNode &node) {
|
||||
aiFace ReadTriangle(XmlNode &node, int &texId0, int &texId1, int &texId2) {
|
||||
aiFace face;
|
||||
|
||||
face.mNumIndices = 3;
|
||||
@@ -73,6 +73,11 @@ aiFace ReadTriangle(XmlNode &node) {
|
||||
face.mIndices[1] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v2).as_string()));
|
||||
face.mIndices[2] = static_cast<unsigned int>(std::atoi(node.attribute(XmlTag::v3).as_string()));
|
||||
|
||||
texId0 = texId1 = texId2 = -1;
|
||||
XmlParser::getIntAttribute(node, XmlTag::p1, texId0);
|
||||
XmlParser::getIntAttribute(node, XmlTag::p2, texId1);
|
||||
XmlParser::getIntAttribute(node, XmlTag::p3, texId2);
|
||||
|
||||
return face;
|
||||
}
|
||||
|
||||
@@ -412,6 +417,9 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
|
||||
bool hasPid = getNodeAttribute(currentNode, D3MF::XmlTag::pid, pid);
|
||||
bool hasP1 = getNodeAttribute(currentNode, D3MF::XmlTag::p1, p1);
|
||||
|
||||
int texId[3];
|
||||
Texture2DGroup *group = nullptr;
|
||||
aiFace face = ReadTriangle(currentNode, texId[0], texId[1], texId[2]);
|
||||
if (hasPid && hasP1) {
|
||||
auto it = mResourcesDictionnary.find(pid);
|
||||
if (it != mResourcesDictionnary.end()) {
|
||||
@@ -420,23 +428,34 @@ void XmlSerializer::ImportTriangles(XmlNode &node, aiMesh *mesh) {
|
||||
mesh->mMaterialIndex = baseMaterials->mMaterialIndex[p1];
|
||||
} else if (it->second->getType() == ResourceType::RT_Texture2DGroup) {
|
||||
if (mesh->mTextureCoords[0] == nullptr) {
|
||||
Texture2DGroup *group = static_cast<Texture2DGroup *>(it->second);
|
||||
mesh->mNumUVComponents[0] = 2;
|
||||
for (unsigned int i = 1; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
||||
mesh->mNumUVComponents[i] = 0;
|
||||
}
|
||||
|
||||
group = static_cast<Texture2DGroup *>(it->second);
|
||||
const std::string name = ai_to_string(group->mTexId);
|
||||
for (size_t i = 0; i < mMaterials.size(); ++i) {
|
||||
if (name == mMaterials[i]->GetName().C_Str()) {
|
||||
mesh->mMaterialIndex = static_cast<unsigned int>(i);
|
||||
}
|
||||
}
|
||||
mesh->mTextureCoords[0] = new aiVector3D[group->mTex2dCoords.size()];
|
||||
for (unsigned int i = 0; i < group->mTex2dCoords.size(); ++i) {
|
||||
mesh->mTextureCoords[0][i] = aiVector3D(group->mTex2dCoords[i].x, group->mTex2dCoords[i].y, 0);
|
||||
}
|
||||
mesh->mTextureCoords[0] = new aiVector3D[mesh->mNumVertices];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aiFace face = ReadTriangle(currentNode);
|
||||
// Load texture coordinates into mesh, when any
|
||||
if (group != nullptr) {
|
||||
size_t i0 = face.mIndices[0];
|
||||
size_t i1 = face.mIndices[1];
|
||||
size_t i2 = face.mIndices[2];
|
||||
mesh->mTextureCoords[0][i0] = aiVector3D(group->mTex2dCoords[texId[0]].x, group->mTex2dCoords[texId[0]].y, 0.0f);
|
||||
mesh->mTextureCoords[0][i1] = aiVector3D(group->mTex2dCoords[texId[1]].x, group->mTex2dCoords[texId[1]].y, 0.0f);
|
||||
mesh->mTextureCoords[0][i2] = aiVector3D(group->mTex2dCoords[texId[2]].x, group->mTex2dCoords[texId[2]].y, 0.0f);
|
||||
}
|
||||
|
||||
faces.push_back(face);
|
||||
}
|
||||
}
|
||||
@@ -578,11 +597,15 @@ aiMaterial *XmlSerializer::readMaterialDef(XmlNode &node, unsigned int basemater
|
||||
}
|
||||
|
||||
void XmlSerializer::StoreMaterialsInScene(aiScene *scene) {
|
||||
if (nullptr == scene || mMaterials.empty()) {
|
||||
if (nullptr == scene) {
|
||||
return;
|
||||
}
|
||||
|
||||
scene->mNumMaterials = static_cast<unsigned int>(mMaterials.size());
|
||||
if (scene->mNumMaterials == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
scene->mMaterials = new aiMaterial *[scene->mNumMaterials];
|
||||
for (size_t i = 0; i < mMaterials.size(); ++i) {
|
||||
scene->mMaterials[i] = mMaterials[i];
|
||||
|
||||
@@ -621,6 +621,11 @@ struct Animation {
|
||||
|
||||
for (std::vector<Animation *>::iterator it = pParent->mSubAnims.begin(); it != pParent->mSubAnims.end();) {
|
||||
Animation *anim = *it;
|
||||
// Assign the first animation name to the parent if empty.
|
||||
// This prevents the animation name from being lost when animations are combined
|
||||
if (mName.empty()) {
|
||||
mName = anim->mName;
|
||||
}
|
||||
CombineSingleChannelAnimationsRecursively(anim);
|
||||
|
||||
if (childrenAnimationsHaveDifferentChannels && anim->mChannels.size() == 1 &&
|
||||
|
||||
@@ -102,6 +102,7 @@ ColladaLoader::ColladaLoader() :
|
||||
mTextures(),
|
||||
mAnims(),
|
||||
noSkeletonMesh(false),
|
||||
removeEmptyBones(false),
|
||||
ignoreUpDirection(false),
|
||||
useColladaName(false),
|
||||
mNodeNameCounter(0) {
|
||||
@@ -130,6 +131,7 @@ bool ColladaLoader::CanRead(const std::string &pFile, IOSystem *pIOHandler, bool
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ColladaLoader::SetupProperties(const Importer *pImp) {
|
||||
noSkeletonMesh = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_NO_SKELETON_MESHES, 0) != 0;
|
||||
removeEmptyBones = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true) != 0;
|
||||
ignoreUpDirection = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_IGNORE_UP_DIRECTION, 0) != 0;
|
||||
useColladaName = pImp->GetPropertyInteger(AI_CONFIG_IMPORT_COLLADA_USE_COLLADA_NAMES, 0) != 0;
|
||||
}
|
||||
@@ -798,9 +800,10 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
|
||||
// count the number of bones which influence vertices of the current submesh
|
||||
size_t numRemainingBones = 0;
|
||||
for (const auto & dstBone : dstBones) {
|
||||
if (!dstBone.empty()) {
|
||||
++numRemainingBones;
|
||||
if (dstBone.empty() && removeEmptyBones) {
|
||||
continue;
|
||||
}
|
||||
++numRemainingBones;
|
||||
}
|
||||
|
||||
// create bone array and copy bone weights one by one
|
||||
@@ -809,7 +812,7 @@ aiMesh *ColladaLoader::CreateMesh(const ColladaParser &pParser, const Mesh *pSrc
|
||||
size_t boneCount = 0;
|
||||
for (size_t a = 0; a < numBones; ++a) {
|
||||
// omit bones without weights
|
||||
if (dstBones[a].empty()) {
|
||||
if (dstBones[a].empty() && removeEmptyBones) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -237,6 +237,7 @@ protected:
|
||||
std::vector<aiAnimation *> mAnims;
|
||||
|
||||
bool noSkeletonMesh;
|
||||
bool removeEmptyBones;
|
||||
bool ignoreUpDirection;
|
||||
bool useColladaName;
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -87,11 +86,6 @@ AnimationCurve::AnimationCurve(uint64_t id, const Element &element, const std::s
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurve::~AnimationCurve() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element &element, const std::string &name,
|
||||
const Document &doc, const char *const *target_prop_whitelist /*= nullptr*/,
|
||||
@@ -147,11 +141,6 @@ AnimationCurveNode::AnimationCurveNode(uint64_t id, const Element &element, cons
|
||||
props = GetPropertyTable(doc, "AnimationCurveNode.FbxAnimCurveNode", element, sc, false);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurveNode::~AnimationCurveNode() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const AnimationCurveMap &AnimationCurveNode::Curves() const {
|
||||
if (curves.empty()) {
|
||||
@@ -193,11 +182,6 @@ AnimationLayer::AnimationLayer(uint64_t id, const Element &element, const std::s
|
||||
props = GetPropertyTable(doc, "AnimationLayer.FbxAnimLayer", element, sc, true);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationLayer::~AnimationLayer() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationCurveNodeList AnimationLayer::Nodes(const char *const *target_prop_whitelist /*= nullptr*/,
|
||||
size_t whitelist_size /*= 0*/) const {
|
||||
@@ -279,11 +263,6 @@ AnimationStack::AnimationStack(uint64_t id, const Element &element, const std::s
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
AnimationStack::~AnimationStack() {
|
||||
// empty
|
||||
}
|
||||
|
||||
} // namespace FBX
|
||||
} // namespace Assimp
|
||||
|
||||
|
||||
@@ -50,7 +50,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
||||
const std::string NULL_RECORD = { // 25 null bytes in 64-bit and 13 null bytes in 32-bit
|
||||
static constexpr size_t NumNullRecords = 25;
|
||||
const char NULL_RECORD[NumNullRecords] = { // 25 null bytes in 64-bit and 13 null bytes in 32-bit
|
||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0',
|
||||
'\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0', '\0'
|
||||
}; // who knows why, it looks like two integers 32/64 bit (compressed and uncompressed sizes?) + 1 byte (might be compression type?)
|
||||
|
||||
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
|
||||
@@ -65,12 +65,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include <stdlib.h>
|
||||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
@@ -187,8 +184,7 @@ std::string FBXConverter::MakeUniqueNodeName(const Model *const model, const aiN
|
||||
|
||||
/// This struct manages nodes which may or may not end up in the node hierarchy.
|
||||
/// When a node becomes a child of another node, that node becomes its owner and mOwnership should be released.
|
||||
struct FBXConverter::PotentialNode
|
||||
{
|
||||
struct FBXConverter::PotentialNode {
|
||||
PotentialNode() : mOwnership(new aiNode), mNode(mOwnership.get()) {}
|
||||
PotentialNode(const std::string& name) : mOwnership(new aiNode(name)), mNode(mOwnership.get()) {}
|
||||
aiNode* operator->() { return mNode; }
|
||||
@@ -231,7 +227,7 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
|
||||
if (nullptr != model) {
|
||||
nodes_chain.clear();
|
||||
post_nodes_chain.clear();
|
||||
|
||||
aiMatrix4x4 new_abs_transform = parent->mTransformation;
|
||||
std::string node_name = FixNodeName(model->Name());
|
||||
// even though there is only a single input node, the design of
|
||||
// assimp (or rather: the complicated transformation chain that
|
||||
@@ -268,7 +264,7 @@ void FBXConverter::ConvertNodes(uint64_t id, aiNode *parent, aiNode *root_node)
|
||||
}
|
||||
|
||||
// attach geometry
|
||||
ConvertModel(*model, nodes_chain.back().mNode, root_node);
|
||||
ConvertModel(*model, nodes_chain.back().mNode, root_node, new_abs_transform);
|
||||
|
||||
// check if there will be any child nodes
|
||||
const std::vector<const Connection *> &child_conns = doc.GetConnectionsByDestinationSequenced(model->ID(), "Model");
|
||||
@@ -447,7 +443,7 @@ void FBXConverter::GetUniqueName(const std::string &name, std::string &uniqueNam
|
||||
auto it_pair = mNodeNames.insert({ name, 0 }); // duplicate node name instance count
|
||||
unsigned int &i = it_pair.first->second;
|
||||
while (!it_pair.second) {
|
||||
i++;
|
||||
++i;
|
||||
std::ostringstream ext;
|
||||
ext << name << std::setfill('0') << std::setw(3) << i;
|
||||
uniqueName = ext.str();
|
||||
@@ -646,9 +642,8 @@ void FBXConverter::GetRotationMatrix(Model::RotOrder mode, const aiVector3D &rot
|
||||
|
||||
bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
|
||||
const PropertyTable &props = model.Props();
|
||||
bool ok;
|
||||
|
||||
const float zero_epsilon = ai_epsilon;
|
||||
const auto zero_epsilon = ai_epsilon;
|
||||
const aiVector3D all_ones(1.0f, 1.0f, 1.0f);
|
||||
for (size_t i = 0; i < TransformationComp_MAXIMUM; ++i) {
|
||||
const TransformationComp comp = static_cast<TransformationComp>(i);
|
||||
@@ -660,6 +655,7 @@ bool FBXConverter::NeedsComplexTransformationChain(const Model &model) {
|
||||
|
||||
bool scale_compare = (comp == TransformationComp_GeometricScaling || comp == TransformationComp_Scaling);
|
||||
|
||||
bool ok = true;
|
||||
const aiVector3D &v = PropertyGet<aiVector3D>(props, NameTransformationCompProperty(comp), ok);
|
||||
if (ok && scale_compare) {
|
||||
if ((v - all_ones).SquareLength() > zero_epsilon) {
|
||||
@@ -894,18 +890,17 @@ void FBXConverter::SetupNodeMetadata(const Model &model, aiNode &nd) {
|
||||
}
|
||||
}
|
||||
|
||||
void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node) {
|
||||
void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform) {
|
||||
const std::vector<const Geometry *> &geos = model.GetGeometry();
|
||||
|
||||
std::vector<unsigned int> meshes;
|
||||
meshes.reserve(geos.size());
|
||||
|
||||
for (const Geometry *geo : geos) {
|
||||
|
||||
const MeshGeometry *const mesh = dynamic_cast<const MeshGeometry *>(geo);
|
||||
const LineGeometry *const line = dynamic_cast<const LineGeometry *>(geo);
|
||||
if (mesh) {
|
||||
const std::vector<unsigned int> &indices = ConvertMesh(*mesh, model, parent, root_node);
|
||||
const std::vector<unsigned int> &indices = ConvertMesh(*mesh, model, parent, root_node, absolute_transform);
|
||||
std::copy(indices.begin(), indices.end(), std::back_inserter(meshes));
|
||||
} else if (line) {
|
||||
const std::vector<unsigned int> &indices = ConvertLine(*line, root_node);
|
||||
@@ -926,7 +921,7 @@ void FBXConverter::ConvertModel(const Model &model, aiNode *parent, aiNode *root
|
||||
}
|
||||
|
||||
std::vector<unsigned int>
|
||||
FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node) {
|
||||
FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform) {
|
||||
std::vector<unsigned int> temp;
|
||||
|
||||
MeshMap::const_iterator it = meshes_converted.find(&mesh);
|
||||
@@ -949,13 +944,13 @@ FBXConverter::ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *
|
||||
const MatIndexArray::value_type base = mindices[0];
|
||||
for (MatIndexArray::value_type index : mindices) {
|
||||
if (index != base) {
|
||||
return ConvertMeshMultiMaterial(mesh, model, parent, root_node);
|
||||
return ConvertMeshMultiMaterial(mesh, model, absolute_transform, parent, root_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// faster code-path, just copy the data
|
||||
temp.push_back(ConvertMeshSingleMaterial(mesh, model, parent, root_node));
|
||||
temp.push_back(ConvertMeshSingleMaterial(mesh, model, absolute_transform, parent, root_node));
|
||||
return temp;
|
||||
}
|
||||
|
||||
@@ -1023,7 +1018,35 @@ aiMesh *FBXConverter::SetupEmptyMesh(const Geometry &mesh, aiNode *parent) {
|
||||
return out_mesh;
|
||||
}
|
||||
|
||||
unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
|
||||
static aiSkeleton *createAiSkeleton(SkeletonBoneContainer &sbc) {
|
||||
if (sbc.MeshArray.empty() || sbc.SkeletonBoneToMeshLookup.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
aiSkeleton *skeleton = new aiSkeleton;
|
||||
for (auto *mesh : sbc.MeshArray) {
|
||||
auto it = sbc.SkeletonBoneToMeshLookup.find(mesh);
|
||||
if (it == sbc.SkeletonBoneToMeshLookup.end()) {
|
||||
continue;
|
||||
}
|
||||
SkeletonBoneArray *ba = it->second;
|
||||
if (ba == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
skeleton->mNumBones = static_cast<unsigned int>(ba->size());
|
||||
skeleton->mBones = new aiSkeletonBone*[skeleton->mNumBones];
|
||||
size_t index = 0;
|
||||
for (auto bone : (* ba)) {
|
||||
skeleton->mBones[index] = bone;
|
||||
++index;
|
||||
}
|
||||
}
|
||||
|
||||
return skeleton;
|
||||
}
|
||||
|
||||
unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform,
|
||||
aiNode *parent, aiNode *) {
|
||||
const MatIndexArray &mindices = mesh.GetMaterialIndices();
|
||||
aiMesh *const out_mesh = SetupEmptyMesh(mesh, parent);
|
||||
@@ -1142,8 +1165,15 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
|
||||
ConvertMaterialForMesh(out_mesh, model, mesh, mindices[0]);
|
||||
}
|
||||
|
||||
if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr) {
|
||||
ConvertWeights(out_mesh, mesh, parent, NO_MATERIAL_SEPARATION, nullptr);
|
||||
if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr && !doc.Settings().useSkeleton) {
|
||||
ConvertWeights(out_mesh, mesh, absolute_transform, parent, NO_MATERIAL_SEPARATION, nullptr);
|
||||
} else if (doc.Settings().readWeights && mesh.DeformerSkin() != nullptr && doc.Settings().useSkeleton) {
|
||||
SkeletonBoneContainer sbc;
|
||||
ConvertWeightsToSkeleton(out_mesh, mesh, absolute_transform, parent, NO_MATERIAL_SEPARATION, nullptr, sbc);
|
||||
aiSkeleton *skeleton = createAiSkeleton(sbc);
|
||||
if (skeleton != nullptr) {
|
||||
mSkeletons.emplace_back(skeleton);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<aiAnimMesh *> animMeshes;
|
||||
@@ -1190,7 +1220,7 @@ unsigned int FBXConverter::ConvertMeshSingleMaterial(const MeshGeometry &mesh, c
|
||||
}
|
||||
|
||||
std::vector<unsigned int>
|
||||
FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent,
|
||||
FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform, aiNode *parent,
|
||||
aiNode *root_node) {
|
||||
const MatIndexArray &mindices = mesh.GetMaterialIndices();
|
||||
ai_assert(mindices.size());
|
||||
@@ -1201,7 +1231,7 @@ FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &mo
|
||||
for (MatIndexArray::value_type index : mindices) {
|
||||
if (had.find(index) == had.end()) {
|
||||
|
||||
indices.push_back(ConvertMeshMultiMaterial(mesh, model, index, parent, root_node));
|
||||
indices.push_back(ConvertMeshMultiMaterial(mesh, model, absolute_transform, index, parent, root_node));
|
||||
had.insert(index);
|
||||
}
|
||||
}
|
||||
@@ -1209,9 +1239,8 @@ FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &mo
|
||||
return indices;
|
||||
}
|
||||
|
||||
unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model,
|
||||
MatIndexArray::value_type index,
|
||||
aiNode *parent, aiNode *) {
|
||||
unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform,
|
||||
MatIndexArray::value_type index, aiNode *parent, aiNode *) {
|
||||
aiMesh *const out_mesh = SetupEmptyMesh(mesh, parent);
|
||||
|
||||
const MatIndexArray &mindices = mesh.GetMaterialIndices();
|
||||
@@ -1374,7 +1403,7 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
|
||||
ConvertMaterialForMesh(out_mesh, model, mesh, index);
|
||||
|
||||
if (process_weights) {
|
||||
ConvertWeights(out_mesh, mesh, parent, index, &reverseMapping);
|
||||
ConvertWeights(out_mesh, mesh, absolute_transform, parent, index, &reverseMapping);
|
||||
}
|
||||
|
||||
std::vector<aiAnimMesh *> animMeshes;
|
||||
@@ -1424,19 +1453,47 @@ unsigned int FBXConverter::ConvertMeshMultiMaterial(const MeshGeometry &mesh, co
|
||||
return static_cast<unsigned int>(mMeshes.size() - 1);
|
||||
}
|
||||
|
||||
void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo,
|
||||
static void copyBoneToSkeletonBone(aiMesh *mesh, aiBone *bone, aiSkeletonBone *skeletonBone ) {
|
||||
skeletonBone->mNumnWeights = bone->mNumWeights;
|
||||
skeletonBone->mWeights = bone->mWeights;
|
||||
skeletonBone->mOffsetMatrix = bone->mOffsetMatrix;
|
||||
skeletonBone->mMeshId = mesh;
|
||||
skeletonBone->mNode = bone->mNode;
|
||||
skeletonBone->mParent = -1;
|
||||
}
|
||||
|
||||
void FBXConverter::ConvertWeightsToSkeleton(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform, aiNode *parent, unsigned int materialIndex,
|
||||
std::vector<unsigned int> *outputVertStartIndices, SkeletonBoneContainer &skeletonContainer) {
|
||||
|
||||
if (skeletonContainer.SkeletonBoneToMeshLookup.find(out) != skeletonContainer.SkeletonBoneToMeshLookup.end()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ConvertWeights(out, geo, absolute_transform, parent, materialIndex, outputVertStartIndices);
|
||||
skeletonContainer.MeshArray.emplace_back(out);
|
||||
SkeletonBoneArray *ba = new SkeletonBoneArray;
|
||||
for (size_t i = 0; i < out->mNumBones; ++i) {
|
||||
aiBone *bone = out->mBones[i];
|
||||
if (bone == nullptr) {
|
||||
continue;
|
||||
}
|
||||
aiSkeletonBone *skeletonBone = new aiSkeletonBone;
|
||||
copyBoneToSkeletonBone(out, bone, skeletonBone);
|
||||
ba->emplace_back(skeletonBone);
|
||||
}
|
||||
skeletonContainer.SkeletonBoneToMeshLookup[out] = ba;
|
||||
}
|
||||
|
||||
void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
|
||||
aiNode *parent, unsigned int materialIndex,
|
||||
std::vector<unsigned int> *outputVertStartIndices) {
|
||||
ai_assert(geo.DeformerSkin());
|
||||
|
||||
std::vector<size_t> out_indices;
|
||||
std::vector<size_t> index_out_indices;
|
||||
std::vector<size_t> count_out_indices;
|
||||
std::vector<size_t> out_indices, index_out_indices, count_out_indices;
|
||||
|
||||
const Skin &sk = *geo.DeformerSkin();
|
||||
|
||||
std::vector<aiBone *> bones;
|
||||
|
||||
std::vector<aiBone*> bones;
|
||||
const bool no_mat_check = materialIndex == NO_MATERIAL_SEPARATION;
|
||||
ai_assert(no_mat_check || outputVertStartIndices);
|
||||
|
||||
@@ -1496,7 +1553,7 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo,
|
||||
// XXX this could be heavily simplified by collecting the bone
|
||||
// data in a single step.
|
||||
ConvertCluster(bones, cluster, out_indices, index_out_indices,
|
||||
count_out_indices, parent);
|
||||
count_out_indices, absolute_transform, parent);
|
||||
}
|
||||
|
||||
bone_map.clear();
|
||||
@@ -1509,25 +1566,20 @@ void FBXConverter::ConvertWeights(aiMesh *out, const MeshGeometry &geo,
|
||||
out->mBones = nullptr;
|
||||
out->mNumBones = 0;
|
||||
return;
|
||||
} else {
|
||||
out->mBones = new aiBone *[bones.size()]();
|
||||
out->mNumBones = static_cast<unsigned int>(bones.size());
|
||||
}
|
||||
|
||||
std::swap_ranges(bones.begin(), bones.end(), out->mBones);
|
||||
}
|
||||
out->mBones = new aiBone *[bones.size()]();
|
||||
out->mNumBones = static_cast<unsigned int>(bones.size());
|
||||
std::swap_ranges(bones.begin(), bones.end(), out->mBones);
|
||||
}
|
||||
|
||||
const aiNode *GetNodeByName(aiNode *current_node) {
|
||||
aiNode *iter = current_node;
|
||||
//printf("Child count: %d", iter->mNumChildren);
|
||||
return iter;
|
||||
}
|
||||
|
||||
void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
|
||||
void FBXConverter::ConvertCluster(std::vector<aiBone*> &local_mesh_bones, const Cluster *cluster,
|
||||
std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
|
||||
std::vector<size_t> &count_out_indices, aiNode *) {
|
||||
ai_assert(cl); // make sure cluster valid
|
||||
std::string deformer_name = cl->TargetNode()->Name();
|
||||
std::vector<size_t> &count_out_indices, const aiMatrix4x4 & /* absolute_transform*/,
|
||||
aiNode *) {
|
||||
ai_assert(cluster != nullptr); // make sure cluster valid
|
||||
|
||||
std::string deformer_name = cluster->TargetNode()->Name();
|
||||
aiString bone_name = aiString(FixNodeName(deformer_name));
|
||||
|
||||
aiBone *bone = nullptr;
|
||||
@@ -1540,10 +1592,10 @@ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const
|
||||
bone = new aiBone();
|
||||
bone->mName = bone_name;
|
||||
|
||||
bone->mOffsetMatrix = cl->Transform();
|
||||
bone->mOffsetMatrix = cluster->Transform();
|
||||
// store local transform link for post processing
|
||||
/*
|
||||
bone->mOffsetMatrix = cl->TransformLink();
|
||||
bone->mOffsetMatrix = cluster->TransformLink();
|
||||
bone->mOffsetMatrix.Inverse();
|
||||
|
||||
aiMatrix4x4 matrix = (aiMatrix4x4)absolute_transform;
|
||||
@@ -1560,7 +1612,7 @@ void FBXConverter::ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const
|
||||
cursor = bone->mWeights = new aiVertexWeight[out_indices.size()];
|
||||
|
||||
const size_t no_index_sentinel = std::numeric_limits<size_t>::max();
|
||||
const WeightArray &weights = cl->GetWeights();
|
||||
const WeightArray &weights = cluster->GetWeights();
|
||||
|
||||
const size_t c = index_out_indices.size();
|
||||
for (size_t i = 0; i < c; ++i) {
|
||||
@@ -2151,7 +2203,7 @@ void FBXConverter::SetShadingPropertiesCommon(aiMaterial *out_mat, const Propert
|
||||
if (ok) {
|
||||
out_mat->AddProperty(&ShininessExponent, 1, AI_MATKEY_SHININESS);
|
||||
// Match Blender behavior to extract roughness when only shininess is present
|
||||
const float roughness = 1.0 - (sqrt(ShininessExponent) / 10.0);
|
||||
const float roughness = 1.0f - (sqrt(ShininessExponent) / 10.0f);
|
||||
out_mat->AddProperty(&roughness, 1, AI_MATKEY_ROUGHNESS_FACTOR);
|
||||
}
|
||||
|
||||
@@ -2605,7 +2657,7 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) {
|
||||
meshMorphAnim->mNumKeys = numKeys;
|
||||
meshMorphAnim->mKeys = new aiMeshMorphKey[numKeys];
|
||||
unsigned int j = 0;
|
||||
for (auto animIt : *animData) {
|
||||
for (auto &animIt : *animData) {
|
||||
morphKeyData *keyData = animIt.second;
|
||||
unsigned int numValuesAndWeights = static_cast<unsigned int>(keyData->values.size());
|
||||
meshMorphAnim->mKeys[j].mNumValuesAndWeights = numValuesAndWeights;
|
||||
@@ -3180,7 +3232,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name,
|
||||
|
||||
bool ok = false;
|
||||
|
||||
const float zero_epsilon = ai_epsilon;
|
||||
const auto zero_epsilon = ai_epsilon;
|
||||
|
||||
const aiVector3D& preRotation = PropertyGet<aiVector3D>(props, "PreRotation", ok);
|
||||
if (ok && preRotation.SquareLength() > zero_epsilon) {
|
||||
@@ -3318,13 +3370,17 @@ FBXConverter::KeyFrameListList FBXConverter::GetRotationKeyframeList(const std::
|
||||
float vc = curve->GetValues().at(1);
|
||||
for (size_t n = 1; n < count; n++) {
|
||||
while (std::abs(vc - vp) >= 180.0f) {
|
||||
float step = std::floor(float(tc - tp) / (vc - vp) * 179.0f);
|
||||
double step = std::floor(double(tc - tp) / std::abs(vc - vp) * 179.0f);
|
||||
int64_t tnew = tp + int64_t(step);
|
||||
float vnew = vp + (vc - vp) * step / float(tc - tp);
|
||||
float vnew = vp + (vc - vp) * float(step / (tc - tp));
|
||||
if (tnew >= adj_start && tnew <= adj_stop) {
|
||||
Keys->push_back(tnew);
|
||||
Values->push_back(vnew);
|
||||
}
|
||||
else {
|
||||
// Something broke
|
||||
break;
|
||||
}
|
||||
tp = tnew;
|
||||
vp = vnew;
|
||||
}
|
||||
@@ -3625,6 +3681,12 @@ void FBXConverter::TransferDataToScene() {
|
||||
|
||||
std::swap_ranges(textures.begin(), textures.end(), mSceneOut->mTextures);
|
||||
}
|
||||
|
||||
if (!mSkeletons.empty()) {
|
||||
mSceneOut->mSkeletons = new aiSkeleton *[mSkeletons.size()];
|
||||
mSceneOut->mNumSkeletons = static_cast<unsigned int>(mSkeletons.size());
|
||||
std::swap_ranges(mSkeletons.begin(), mSkeletons.end(), mSceneOut->mSkeletons);
|
||||
}
|
||||
}
|
||||
|
||||
void FBXConverter::ConvertOrphanedEmbeddedTextures() {
|
||||
|
||||
@@ -75,7 +75,18 @@ typedef std::map<int64_t, morphKeyData*> morphAnimData;
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
||||
class MeshGeometry;
|
||||
|
||||
using SkeletonBoneArray = std::vector<aiSkeletonBone *>;
|
||||
using SkeletonBoneToMesh = std::map<aiMesh*, SkeletonBoneArray*>;
|
||||
|
||||
struct SkeletonBoneContainer {
|
||||
std::vector<aiMesh *> MeshArray;
|
||||
SkeletonBoneToMesh SkeletonBoneToMeshLookup;
|
||||
};
|
||||
|
||||
class Document;
|
||||
|
||||
/**
|
||||
* Convert a FBX #Document to #aiScene
|
||||
* @param out Empty scene to be populated
|
||||
@@ -180,12 +191,12 @@ private:
|
||||
void SetupNodeMetadata(const Model& model, aiNode& nd);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertModel(const Model &model, aiNode *parent, aiNode *root_node);
|
||||
void ConvertModel(const Model &model, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// MeshGeometry -> aiMesh, return mesh index + 1 or 0 if the conversion failed
|
||||
std::vector<unsigned int>
|
||||
ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node);
|
||||
ConvertMesh(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node, const aiMatrix4x4 &absolute_transform);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<unsigned int> ConvertLine(const LineGeometry& line, aiNode *root_node);
|
||||
@@ -194,15 +205,15 @@ private:
|
||||
aiMesh* SetupEmptyMesh(const Geometry& mesh, aiNode *parent);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
unsigned int ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model,
|
||||
unsigned int ConvertMeshSingleMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform,
|
||||
aiNode *parent, aiNode *root_node);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
std::vector<unsigned int>
|
||||
ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, aiNode *parent, aiNode *root_node);
|
||||
ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform, aiNode *parent, aiNode *root_node);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
unsigned int ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, MatIndexArray::value_type index,
|
||||
unsigned int ConvertMeshMultiMaterial(const MeshGeometry &mesh, const Model &model, const aiMatrix4x4 &absolute_transform, MatIndexArray::value_type index,
|
||||
aiNode *parent, aiNode *root_node);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -216,14 +227,19 @@ private:
|
||||
* - outputVertStartIndices is only used when a material index is specified, it gives for
|
||||
* each output vertex the DOM index it maps to.
|
||||
*/
|
||||
void ConvertWeights(aiMesh *out, const MeshGeometry &geo, aiNode *parent = nullptr,
|
||||
void ConvertWeights(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform, aiNode *parent = nullptr,
|
||||
unsigned int materialIndex = NO_MATERIAL_SEPARATION,
|
||||
std::vector<unsigned int> *outputVertStartIndices = nullptr);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertWeightsToSkeleton(aiMesh *out, const MeshGeometry &geo, const aiMatrix4x4 &absolute_transform,
|
||||
aiNode *parent, unsigned int materialIndex, std::vector<unsigned int> *outputVertStartIndices,
|
||||
SkeletonBoneContainer &skeletonContainer);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertCluster(std::vector<aiBone *> &local_mesh_bones, const Cluster *cl,
|
||||
std::vector<size_t> &out_indices, std::vector<size_t> &index_out_indices,
|
||||
std::vector<size_t> &count_out_indices, aiNode *parent );
|
||||
std::vector<size_t> &count_out_indices, const aiMatrix4x4 &absolute_transform, aiNode *parent);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ConvertMaterialForMesh(aiMesh* out, const Model& model, const MeshGeometry& geo,
|
||||
@@ -296,7 +312,8 @@ private:
|
||||
void ConvertAnimationStack(const AnimationStack& st);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void ProcessMorphAnimDatas(std::map<std::string, morphAnimData*>* morphAnimDatas, const BlendShapeChannel* bsc, const AnimationCurveNode* node);
|
||||
void ProcessMorphAnimDatas(std::map<std::string, morphAnimData*>* morphAnimDatas,
|
||||
const BlendShapeChannel* bsc, const AnimationCurveNode* node);
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void GenerateNodeAnimations(std::vector<aiNodeAnim*>& node_anims,
|
||||
@@ -445,6 +462,7 @@ private:
|
||||
|
||||
double anim_fps;
|
||||
|
||||
std::vector<aiSkeleton *> mSkeletons;
|
||||
aiScene* const mSceneOut;
|
||||
const FBX::Document& doc;
|
||||
bool mRemoveEmptyBones;
|
||||
|
||||
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -58,16 +57,14 @@ namespace FBX {
|
||||
using namespace Util;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Deformer::Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: Object(id,element,name)
|
||||
{
|
||||
Deformer::Deformer(uint64_t id, const Element& element, const Document& doc, const std::string& name) :
|
||||
Object(id,element,name) {
|
||||
const Scope& sc = GetRequiredScope(element);
|
||||
|
||||
const std::string& classname = ParseTokenAsString(GetRequiredToken(element,2));
|
||||
props = GetPropertyTable(doc,"Deformer.Fbx" + classname,element,sc,true);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Deformer::~Deformer()
|
||||
{
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace FBX {
|
||||
using namespace Util;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LazyObject::LazyObject(uint64_t id, const Element& element, const Document& doc) :
|
||||
LazyObject::LazyObject(uint64_t id, const Element& element, const Document& doc) :
|
||||
doc(doc), element(element), id(id), flags() {
|
||||
// empty
|
||||
}
|
||||
@@ -544,7 +544,7 @@ std::vector<const Connection*> Document::GetConnectionsSequenced(uint64_t id, bo
|
||||
ai_assert( count != 0 );
|
||||
ai_assert( count <= MAX_CLASSNAMES);
|
||||
|
||||
size_t lengths[MAX_CLASSNAMES];
|
||||
size_t lengths[MAX_CLASSNAMES] = {};
|
||||
|
||||
const size_t c = count;
|
||||
for (size_t i = 0; i < c; ++i) {
|
||||
|
||||
@@ -164,7 +164,7 @@ class NodeAttribute : public Object {
|
||||
public:
|
||||
NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~NodeAttribute();
|
||||
virtual ~NodeAttribute() = default;
|
||||
|
||||
const PropertyTable& Props() const {
|
||||
ai_assert(props.get());
|
||||
@@ -180,7 +180,7 @@ class CameraSwitcher : public NodeAttribute {
|
||||
public:
|
||||
CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~CameraSwitcher();
|
||||
virtual ~CameraSwitcher() = default;
|
||||
|
||||
int CameraID() const {
|
||||
return cameraId;
|
||||
@@ -225,7 +225,7 @@ class Camera : public NodeAttribute {
|
||||
public:
|
||||
Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
|
||||
virtual ~Camera();
|
||||
virtual ~Camera() = default;
|
||||
|
||||
fbx_simple_property(Position, aiVector3D, aiVector3D(0,0,0))
|
||||
fbx_simple_property(UpVector, aiVector3D, aiVector3D(0,1,0))
|
||||
@@ -250,21 +250,21 @@ public:
|
||||
class Null : public NodeAttribute {
|
||||
public:
|
||||
Null(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
virtual ~Null();
|
||||
virtual ~Null() = default;
|
||||
};
|
||||
|
||||
/** DOM base class for FBX limb node markers attached to a node */
|
||||
class LimbNode : public NodeAttribute {
|
||||
public:
|
||||
LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
virtual ~LimbNode();
|
||||
virtual ~LimbNode() = default;
|
||||
};
|
||||
|
||||
/** DOM base class for FBX lights attached to a node */
|
||||
class Light : public NodeAttribute {
|
||||
public:
|
||||
Light(uint64_t id, const Element& element, const Document& doc, const std::string& name);
|
||||
virtual ~Light();
|
||||
virtual ~Light() = default;
|
||||
|
||||
enum Type {
|
||||
Type_Point,
|
||||
@@ -690,7 +690,7 @@ using KeyValueList = std::vector<float>;
|
||||
class AnimationCurve : public Object {
|
||||
public:
|
||||
AnimationCurve(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||
virtual ~AnimationCurve();
|
||||
virtual ~AnimationCurve() = default;
|
||||
|
||||
/** get list of keyframe positions (time).
|
||||
* Invariant: |GetKeys()| > 0 */
|
||||
@@ -731,7 +731,7 @@ public:
|
||||
AnimationCurveNode(uint64_t id, const Element& element, const std::string& name, const Document& doc,
|
||||
const char *const *target_prop_whitelist = nullptr, size_t whitelist_size = 0);
|
||||
|
||||
virtual ~AnimationCurveNode();
|
||||
virtual ~AnimationCurveNode() = default;
|
||||
|
||||
const PropertyTable& Props() const {
|
||||
ai_assert(props.get());
|
||||
@@ -776,7 +776,7 @@ using AnimationCurveNodeList = std::vector<const AnimationCurveNode*>;
|
||||
class AnimationLayer : public Object {
|
||||
public:
|
||||
AnimationLayer(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||
virtual ~AnimationLayer();
|
||||
virtual ~AnimationLayer() = default;
|
||||
|
||||
const PropertyTable& Props() const {
|
||||
ai_assert(props.get());
|
||||
@@ -799,7 +799,7 @@ using AnimationLayerList = std::vector<const AnimationLayer*>;
|
||||
class AnimationStack : public Object {
|
||||
public:
|
||||
AnimationStack(uint64_t id, const Element& element, const std::string& name, const Document& doc);
|
||||
virtual ~AnimationStack();
|
||||
virtual ~AnimationStack() = default;
|
||||
|
||||
fbx_simple_property(LocalStart, int64_t, 0L)
|
||||
fbx_simple_property(LocalStop, int64_t, 0L)
|
||||
|
||||
@@ -59,14 +59,12 @@ namespace Util {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// signal DOM construction error, this is always unrecoverable. Throws DeadlyImportError.
|
||||
void DOMError(const std::string& message, const Token& token)
|
||||
{
|
||||
void DOMError(const std::string& message, const Token& token) {
|
||||
throw DeadlyImportError("FBX-DOM", Util::GetTokenText(&token), message);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void DOMError(const std::string& message, const Element* element /*= nullptr*/)
|
||||
{
|
||||
void DOMError(const std::string& message, const Element* element /*= nullptr*/) {
|
||||
if(element) {
|
||||
DOMError(message,element->KeyToken());
|
||||
}
|
||||
@@ -76,8 +74,7 @@ void DOMError(const std::string& message, const Element* element /*= nullptr*/)
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// print warning, do return
|
||||
void DOMWarning(const std::string& message, const Token& token)
|
||||
{
|
||||
void DOMWarning(const std::string& message, const Token& token) {
|
||||
if(DefaultLogger::get()) {
|
||||
ASSIMP_LOG_WARN("FBX-DOM", Util::GetTokenText(&token), message);
|
||||
}
|
||||
|
||||
@@ -74,13 +74,11 @@ std::shared_ptr<const PropertyTable> GetPropertyTable(const Document& doc,
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <typename T>
|
||||
inline
|
||||
const T* ProcessSimpleConnection(const Connection& con,
|
||||
bool is_object_property_conn,
|
||||
const char* name,
|
||||
const Element& element,
|
||||
const char** propNameOut = nullptr)
|
||||
{
|
||||
inline const T* ProcessSimpleConnection(const Connection& con,
|
||||
bool is_object_property_conn,
|
||||
const char* name,
|
||||
const Element& element,
|
||||
const char** propNameOut = nullptr) {
|
||||
if (is_object_property_conn && !con.PropertyName().length()) {
|
||||
DOMWarning("expected incoming " + std::string(name) +
|
||||
" link to be an object-object connection, ignoring",
|
||||
|
||||
@@ -255,7 +255,7 @@ void FBXExporter::WriteBinaryHeader()
|
||||
|
||||
void FBXExporter::WriteBinaryFooter()
|
||||
{
|
||||
outfile->Write(NULL_RECORD.c_str(), NULL_RECORD.size(), 1);
|
||||
outfile->Write(NULL_RECORD, NumNullRecords, 1);
|
||||
|
||||
outfile->Write(GENERIC_FOOTID.c_str(), GENERIC_FOOTID.size(), 1);
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ struct ImportSettings {
|
||||
readLights(true),
|
||||
readAnimations(true),
|
||||
readWeights(true),
|
||||
useSkeleton(false),
|
||||
preservePivots(true),
|
||||
optimizeEmptyAnimationCurves(true),
|
||||
useLegacyEmbeddedTextureNaming(false),
|
||||
@@ -112,6 +113,11 @@ struct ImportSettings {
|
||||
* Default value is true. */
|
||||
bool readWeights;
|
||||
|
||||
/** will convert all animation data into a skeleton (experimental)
|
||||
* Default value is false.
|
||||
*/
|
||||
bool useSkeleton;
|
||||
|
||||
/** preserve transformation pivots and offsets. Since these can
|
||||
* not directly be represented in assimp, additional dummy
|
||||
* nodes will be generated. Note that settings this to false
|
||||
|
||||
@@ -90,12 +90,9 @@ static const aiImporterDesc desc = {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by #Importer
|
||||
FBXImporter::FBXImporter() {
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor, private as well
|
||||
FBXImporter::~FBXImporter() {
|
||||
FBXImporter::FBXImporter() :
|
||||
mSettings() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -115,20 +112,21 @@ const aiImporterDesc *FBXImporter::GetInfo() const {
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Setup configuration properties for the loader
|
||||
void FBXImporter::SetupProperties(const Importer *pImp) {
|
||||
settings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
|
||||
settings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
|
||||
settings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
|
||||
settings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true);
|
||||
settings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
|
||||
settings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
|
||||
settings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);
|
||||
settings.readWeights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_WEIGHTS, true);
|
||||
settings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
|
||||
settings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
|
||||
settings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
|
||||
settings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
|
||||
settings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
|
||||
settings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
|
||||
mSettings.readAllLayers = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_GEOMETRY_LAYERS, true);
|
||||
mSettings.readAllMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ALL_MATERIALS, false);
|
||||
mSettings.readMaterials = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_MATERIALS, true);
|
||||
mSettings.readTextures = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_TEXTURES, true);
|
||||
mSettings.readCameras = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_CAMERAS, true);
|
||||
mSettings.readLights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_LIGHTS, true);
|
||||
mSettings.readAnimations = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_ANIMATIONS, true);
|
||||
mSettings.readWeights = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_READ_WEIGHTS, true);
|
||||
mSettings.strictMode = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_STRICT_MODE, false);
|
||||
mSettings.preservePivots = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_PRESERVE_PIVOTS, true);
|
||||
mSettings.optimizeEmptyAnimationCurves = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_OPTIMIZE_EMPTY_ANIMATION_CURVES, true);
|
||||
mSettings.useLegacyEmbeddedTextureNaming = pImp->GetPropertyBool(AI_CONFIG_IMPORT_FBX_EMBEDDED_TEXTURES_LEGACY_NAMING, false);
|
||||
mSettings.removeEmptyBones = pImp->GetPropertyBool(AI_CONFIG_IMPORT_REMOVE_EMPTY_BONES, true);
|
||||
mSettings.convertToMeters = pImp->GetPropertyBool(AI_CONFIG_FBX_CONVERT_TO_M, false);
|
||||
mSettings.useSkeleton = pImp->GetPropertyBool(AI_CONFIG_FBX_USE_SKELETON_BONE_CONTAINER, false);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
@@ -155,7 +153,7 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||
contents[contents.size() - 1] = 0;
|
||||
const char *const begin = &*contents.begin();
|
||||
|
||||
// broadphase tokenizing pass in which we identify the core
|
||||
// broad-phase tokenized pass in which we identify the core
|
||||
// syntax elements of FBX (brackets, commas, key:value mappings)
|
||||
TokenList tokens;
|
||||
try {
|
||||
@@ -173,15 +171,14 @@ void FBXImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||
Parser parser(tokens, is_binary);
|
||||
|
||||
// take the raw parse-tree and convert it to a FBX DOM
|
||||
Document doc(parser, settings);
|
||||
Document doc(parser, mSettings);
|
||||
|
||||
// convert the FBX DOM to aiScene
|
||||
ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
|
||||
ConvertToAssimpScene(pScene, doc, mSettings.removeEmptyBones);
|
||||
|
||||
// size relative to cm
|
||||
float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();
|
||||
if (size_relative_to_cm == 0.0)
|
||||
{
|
||||
if (size_relative_to_cm == 0.0) {
|
||||
// BaseImporter later asserts that fileScale is non-zero.
|
||||
ThrowException("The UnitScaleFactor must be non-zero");
|
||||
}
|
||||
|
||||
@@ -69,13 +69,14 @@ typedef class basic_formatter<char, std::char_traits<char>, std::allocator<char>
|
||||
// -------------------------------------------------------------------------------------------
|
||||
class FBXImporter : public BaseImporter, public LogFunctions<FBXImporter> {
|
||||
public:
|
||||
/// @brief The class constructor.
|
||||
FBXImporter();
|
||||
~FBXImporter() override;
|
||||
|
||||
// --------------------
|
||||
bool CanRead(const std::string &pFile,
|
||||
IOSystem *pIOHandler,
|
||||
bool checkSig) const override;
|
||||
/// @brief The class destructor, default implementation.
|
||||
~FBXImporter() override = default;
|
||||
|
||||
/// @brief Will check the file for readability.
|
||||
bool CanRead(const std::string &pFile, IOSystem *pIOHandler, bool checkSig) const override;
|
||||
|
||||
protected:
|
||||
// --------------------
|
||||
@@ -90,7 +91,7 @@ protected:
|
||||
IOSystem *pIOHandler) override;
|
||||
|
||||
private:
|
||||
FBX::ImportSettings settings;
|
||||
FBX::ImportSettings mSettings;
|
||||
}; // !class FBXImporter
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
||||
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -54,18 +53,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#include "FBXImportSettings.h"
|
||||
#include "FBXDocumentUtil.h"
|
||||
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
||||
using namespace Util;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc)
|
||||
: Object(id, element, name)
|
||||
, skin()
|
||||
{
|
||||
const std::vector<const Connection*>& conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer");
|
||||
Geometry::Geometry(uint64_t id, const Element& element, const std::string& name, const Document& doc) :
|
||||
Object(id, element, name), skin() {
|
||||
const std::vector<const Connection*> &conns = doc.GetConnectionsByDestinationSequenced(ID(),"Deformer");
|
||||
for(const Connection* con : conns) {
|
||||
const Skin* const sk = ProcessSimpleConnection<Skin>(*con, false, "Skin -> Geometry", element);
|
||||
if(sk) {
|
||||
@@ -78,12 +74,6 @@ Geometry::Geometry(uint64_t id, const Element& element, const std::string& name,
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Geometry::~Geometry()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const std::vector<const BlendShape*>& Geometry::GetBlendShapes() const {
|
||||
return blendShapes;
|
||||
@@ -183,18 +173,12 @@ MeshGeometry::MeshGeometry(uint64_t id, const Element& element, const std::strin
|
||||
if(doc.Settings().readAllLayers || index == 0) {
|
||||
const Scope& layer = GetRequiredScope(*(*it).second);
|
||||
ReadLayer(layer);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
FBXImporter::LogWarn("ignoring additional geometry layers");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
MeshGeometry::~MeshGeometry() {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
const std::vector<aiVector3D>& MeshGeometry::GetVertices() const {
|
||||
return m_vertices;
|
||||
|
||||
@@ -55,22 +55,25 @@ namespace FBX {
|
||||
/**
|
||||
* DOM base class for all kinds of FBX geometry
|
||||
*/
|
||||
class Geometry : public Object
|
||||
{
|
||||
class Geometry : public Object {
|
||||
public:
|
||||
/// @brief The class constructor with all parameters.
|
||||
/// @param id The id.
|
||||
/// @param element
|
||||
/// @param name
|
||||
/// @param doc
|
||||
Geometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
|
||||
virtual ~Geometry();
|
||||
virtual ~Geometry() = default;
|
||||
|
||||
/** Get the Skin attached to this geometry or nullptr */
|
||||
/// Get the Skin attached to this geometry or nullptr
|
||||
const Skin* DeformerSkin() const;
|
||||
|
||||
/** Get the BlendShape attached to this geometry or nullptr */
|
||||
/// Get the BlendShape attached to this geometry or nullptr
|
||||
const std::vector<const BlendShape*>& GetBlendShapes() const;
|
||||
|
||||
private:
|
||||
const Skin* skin;
|
||||
std::vector<const BlendShape*> blendShapes;
|
||||
|
||||
};
|
||||
|
||||
typedef std::vector<int> MatIndexArray;
|
||||
@@ -79,14 +82,13 @@ typedef std::vector<int> MatIndexArray;
|
||||
/**
|
||||
* DOM class for FBX geometry of type "Mesh"
|
||||
*/
|
||||
class MeshGeometry : public Geometry
|
||||
{
|
||||
class MeshGeometry : public Geometry {
|
||||
public:
|
||||
/** The class constructor */
|
||||
MeshGeometry( uint64_t id, const Element& element, const std::string& name, const Document& doc );
|
||||
|
||||
/** The class destructor */
|
||||
virtual ~MeshGeometry();
|
||||
virtual ~MeshGeometry() = default;
|
||||
|
||||
/** Get a list of all vertex points, non-unique*/
|
||||
const std::vector<aiVector3D>& GetVertices() const;
|
||||
@@ -130,6 +132,7 @@ public:
|
||||
/** Determine the face to which a particular output vertex index belongs.
|
||||
* This mapping is always unique. */
|
||||
unsigned int FaceForVertexIndex( unsigned int in_index ) const;
|
||||
|
||||
private:
|
||||
void ReadLayer( const Scope& layer );
|
||||
void ReadLayerElement( const Scope& layerElement );
|
||||
|
||||
@@ -57,114 +57,65 @@ namespace FBX {
|
||||
using namespace Util;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
NodeAttribute::NodeAttribute(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: Object(id,element,name)
|
||||
, props()
|
||||
{
|
||||
const Scope& sc = GetRequiredScope(element);
|
||||
NodeAttribute::NodeAttribute(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
|
||||
Object(id, element, name), props() {
|
||||
const Scope &sc = GetRequiredScope(element);
|
||||
|
||||
const std::string& classname = ParseTokenAsString(GetRequiredToken(element,2));
|
||||
const std::string &classname = ParseTokenAsString(GetRequiredToken(element, 2));
|
||||
|
||||
// hack on the deriving type but Null/LimbNode attributes are the only case in which
|
||||
// the property table is by design absent and no warning should be generated
|
||||
// for it.
|
||||
const bool is_null_or_limb = !strcmp(classname.c_str(), "Null") || !strcmp(classname.c_str(), "LimbNode");
|
||||
props = GetPropertyTable(doc,"NodeAttribute.Fbx" + classname,element,sc, is_null_or_limb);
|
||||
props = GetPropertyTable(doc, "NodeAttribute.Fbx" + classname, element, sc, is_null_or_limb);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
NodeAttribute::~NodeAttribute()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
CameraSwitcher::CameraSwitcher(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
|
||||
NodeAttribute(id, element, doc, name) {
|
||||
const Scope &sc = GetRequiredScope(element);
|
||||
const Element *const CameraId = sc["CameraId"];
|
||||
const Element *const CameraName = sc["CameraName"];
|
||||
const Element *const CameraIndexName = sc["CameraIndexName"];
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CameraSwitcher::CameraSwitcher(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: NodeAttribute(id,element,doc,name)
|
||||
{
|
||||
const Scope& sc = GetRequiredScope(element);
|
||||
const Element* const CameraId = sc["CameraId"];
|
||||
const Element* const CameraName = sc["CameraName"];
|
||||
const Element* const CameraIndexName = sc["CameraIndexName"];
|
||||
|
||||
if(CameraId) {
|
||||
cameraId = ParseTokenAsInt(GetRequiredToken(*CameraId,0));
|
||||
if (CameraId) {
|
||||
cameraId = ParseTokenAsInt(GetRequiredToken(*CameraId, 0));
|
||||
}
|
||||
|
||||
if(CameraName) {
|
||||
cameraName = GetRequiredToken(*CameraName,0).StringContents();
|
||||
if (CameraName) {
|
||||
cameraName = GetRequiredToken(*CameraName, 0).StringContents();
|
||||
}
|
||||
|
||||
if(CameraIndexName && CameraIndexName->Tokens().size()) {
|
||||
cameraIndexName = GetRequiredToken(*CameraIndexName,0).StringContents();
|
||||
if (CameraIndexName && CameraIndexName->Tokens().size()) {
|
||||
cameraIndexName = GetRequiredToken(*CameraIndexName, 0).StringContents();
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
CameraSwitcher::~CameraSwitcher()
|
||||
{
|
||||
Camera::Camera(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
|
||||
NodeAttribute(id, element, doc, name) {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Camera::Camera(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: NodeAttribute(id,element,doc,name)
|
||||
{
|
||||
Light::Light(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
|
||||
NodeAttribute(id, element, doc, name) {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Camera::~Camera()
|
||||
{
|
||||
Null::Null(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
|
||||
NodeAttribute(id, element, doc, name) {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Light::Light(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: NodeAttribute(id,element,doc,name)
|
||||
{
|
||||
LimbNode::LimbNode(uint64_t id, const Element &element, const Document &doc, const std::string &name) :
|
||||
NodeAttribute(id, element, doc, name) {
|
||||
// empty
|
||||
}
|
||||
|
||||
} // namespace FBX
|
||||
} // namespace Assimp
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Light::~Light()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Null::Null(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: NodeAttribute(id,element,doc,name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Null::~Null()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LimbNode::LimbNode(uint64_t id, const Element& element, const Document& doc, const std::string& name)
|
||||
: NodeAttribute(id,element,doc,name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
LimbNode::~LimbNode()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // ASSIMP_BUILD_NO_FBX_IMPORTER
|
||||
|
||||
@@ -162,12 +162,6 @@ Element::Element(const Token& key_token, Parser& parser) : key_token(key_token)
|
||||
while(n->Type() != TokenType_KEY && n->Type() != TokenType_CLOSE_BRACKET);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Element::~Element()
|
||||
{
|
||||
// no need to delete tokens, they are owned by the parser
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Scope::Scope(Parser& parser,bool topLevel)
|
||||
{
|
||||
@@ -226,12 +220,6 @@ Parser::Parser (const TokenList& tokens, bool is_binary)
|
||||
root.reset(new Scope(*this,true));
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
Parser::~Parser()
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
TokenPtr Parser::AdvanceToNextToken()
|
||||
{
|
||||
@@ -961,8 +949,7 @@ void ParseVectorDataArray(std::vector<float>& out, const Element& el)
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// read an array of uints
|
||||
void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el)
|
||||
{
|
||||
void ParseVectorDataArray(std::vector<unsigned int>& out, const Element& el) {
|
||||
out.resize( 0 );
|
||||
const TokenList& tok = el.Tokens();
|
||||
if(tok.empty()) {
|
||||
@@ -1186,7 +1173,6 @@ aiMatrix4x4 ReadMatrix(const Element& element)
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// wrapper around ParseTokenAsString() with ParseError handling
|
||||
std::string ParseTokenAsString(const Token& t)
|
||||
|
||||
@@ -87,7 +87,7 @@ class Element
|
||||
{
|
||||
public:
|
||||
Element(const Token& key_token, Parser& parser);
|
||||
~Element();
|
||||
~Element() = default;
|
||||
|
||||
const Scope* Compound() const {
|
||||
return compound.get();
|
||||
@@ -160,7 +160,7 @@ public:
|
||||
/** Parse given a token list. Does not take ownership of the tokens -
|
||||
* the objects must persist during the entire parser lifetime */
|
||||
Parser (const TokenList& tokens,bool is_binary);
|
||||
~Parser();
|
||||
~Parser() = default;
|
||||
|
||||
const Scope& GetRootScope() const {
|
||||
return *root.get();
|
||||
|
||||
@@ -874,7 +874,7 @@ void IRRImporter::InternReadFile(const std::string &pFile, aiScene *pScene, IOSy
|
||||
|
||||
// Batch loader used to load external models
|
||||
BatchLoader batch(pIOHandler);
|
||||
// batch.SetBasePath(pFile);
|
||||
//batch.SetBasePath(pFile);
|
||||
|
||||
cameras.reserve(5);
|
||||
lights.reserve(5);
|
||||
|
||||
@@ -287,7 +287,7 @@ void LWOImporter::InternReadFile(const std::string &pFile,
|
||||
if (UINT_MAX == iDefaultSurface) {
|
||||
pSorted.erase(pSorted.end() - 1);
|
||||
}
|
||||
for (unsigned int p = 0, j = 0; j < mSurfaces->size(); ++j) {
|
||||
for (unsigned int j = 0; j < mSurfaces->size(); ++j) {
|
||||
SortedRep &sorted = pSorted[j];
|
||||
if (sorted.empty())
|
||||
continue;
|
||||
@@ -425,7 +425,6 @@ void LWOImporter::InternReadFile(const std::string &pFile,
|
||||
} else {
|
||||
ASSIMP_LOG_VERBOSE_DEBUG("LWO2: No need to compute normals, they're already there");
|
||||
}
|
||||
++p;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,9 +57,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
// Assimp specific M3D configuration. Comment out these defines to remove functionality
|
||||
//#define ASSIMP_USE_M3D_READFILECB
|
||||
|
||||
// Share stb_image's PNG loader with other importers/exporters instead of bringing our own copy.
|
||||
#define STBI_ONLY_PNG
|
||||
#include <stb/stb_image.h>
|
||||
#include "Common/StbCommon.h"
|
||||
|
||||
#include "m3d.h"
|
||||
|
||||
|
||||
@@ -449,6 +449,9 @@ void MDLImporter::ParseSkinLump_3DGS_MDL7(
|
||||
unsigned int iWidth,
|
||||
unsigned int iHeight) {
|
||||
std::unique_ptr<aiTexture> pcNew;
|
||||
if (szCurrent == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get the type of the skin
|
||||
unsigned int iMasked = (unsigned int)(iType & 0xF);
|
||||
|
||||
@@ -151,45 +151,46 @@ namespace Grammar {
|
||||
}
|
||||
|
||||
static TokenType matchTokenType(const char *tokenType) {
|
||||
if (MetricType == tokenType) {
|
||||
const size_t len = std::strlen(tokenType);
|
||||
if (0 == strncmp(MetricType, tokenType, len)) {
|
||||
return MetricToken;
|
||||
} else if (NameType == tokenType) {
|
||||
} else if (0 == strncmp(NameType, tokenType, len)) {
|
||||
return NameToken;
|
||||
} else if (ObjectRefType == tokenType) {
|
||||
} else if (0 == strncmp(ObjectRefType, tokenType, len)) {
|
||||
return ObjectRefToken;
|
||||
} else if (MaterialRefType == tokenType) {
|
||||
} else if (0 == strncmp(MaterialRefType, tokenType, len)) {
|
||||
return MaterialRefToken;
|
||||
} else if (MetricKeyType == tokenType) {
|
||||
} else if (0 == strncmp(MetricKeyType, tokenType, len)) {
|
||||
return MetricKeyToken;
|
||||
} else if (GeometryNodeType == tokenType) {
|
||||
} else if (0 == strncmp(GeometryNodeType, tokenType, len)) {
|
||||
return GeometryNodeToken;
|
||||
} else if (CameraNodeType == tokenType) {
|
||||
} else if (0 == strncmp(CameraNodeType, tokenType, len)) {
|
||||
return CameraNodeToken;
|
||||
} else if (LightNodeType == tokenType) {
|
||||
} else if (0 == strncmp(LightNodeType, tokenType, len)) {
|
||||
return LightNodeToken;
|
||||
} else if (GeometryObjectType == tokenType) {
|
||||
} else if (0 == strncmp(GeometryObjectType, tokenType, len)) {
|
||||
return GeometryObjectToken;
|
||||
} else if (CameraObjectType == tokenType) {
|
||||
} else if (0 == strncmp(CameraObjectType, tokenType, len)) {
|
||||
return CameraObjectToken;
|
||||
} else if (LightObjectType == tokenType) {
|
||||
} else if (0 == strncmp(LightObjectType, tokenType, len)) {
|
||||
return LightObjectToken;
|
||||
} else if (TransformType == tokenType) {
|
||||
} else if (0 == strncmp(TransformType, tokenType, len)) {
|
||||
return TransformToken;
|
||||
} else if (MeshType == tokenType) {
|
||||
} else if (0 == strncmp(MeshType, tokenType, len)) {
|
||||
return MeshToken;
|
||||
} else if (VertexArrayType == tokenType) {
|
||||
} else if (0 == strncmp(VertexArrayType, tokenType, len)) {
|
||||
return VertexArrayToken;
|
||||
} else if (IndexArrayType == tokenType) {
|
||||
} else if (0 == strncmp(IndexArrayType, tokenType, len)) {
|
||||
return IndexArrayToken;
|
||||
} else if (MaterialType == tokenType) {
|
||||
} else if (0 == strncmp(MaterialType, tokenType, len)) {
|
||||
return MaterialToken;
|
||||
} else if (ColorType == tokenType) {
|
||||
} else if (0 == strncmp(ColorType, tokenType, len)) {
|
||||
return ColorToken;
|
||||
} else if (ParamType == tokenType) {
|
||||
} else if (0 == strncmp(ParamType, tokenType, len)) {
|
||||
return ParamToken;
|
||||
} else if (TextureType == tokenType) {
|
||||
} else if (0 == strncmp(TextureType, tokenType, len)) {
|
||||
return TextureToken;
|
||||
} else if (AttenType == tokenType) {
|
||||
} else if (0 == strncmp(AttenType, tokenType, len)) {
|
||||
return AttenToken;
|
||||
}
|
||||
|
||||
@@ -256,11 +257,6 @@ OpenGEXImporter::RefInfo::RefInfo(aiNode *node, Type type, std::vector<std::stri
|
||||
// empty
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
OpenGEXImporter::RefInfo::~RefInfo() {
|
||||
// empty
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
OpenGEXImporter::OpenGEXImporter() :
|
||||
m_root(nullptr),
|
||||
@@ -285,10 +281,6 @@ OpenGEXImporter::OpenGEXImporter() :
|
||||
// empty
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
OpenGEXImporter::~OpenGEXImporter() {
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
bool OpenGEXImporter::CanRead(const std::string &file, IOSystem *pIOHandler, bool /*checkSig*/) const {
|
||||
static const char *tokens[] = { "Metric", "GeometryNode", "VertexArray (attrib", "IndexArray" };
|
||||
|
||||
@@ -79,12 +79,7 @@ struct MetricInfo {
|
||||
float m_floatValue;
|
||||
int m_intValue;
|
||||
|
||||
MetricInfo()
|
||||
: m_stringValue( )
|
||||
, m_floatValue( 0.0f )
|
||||
, m_intValue( -1 ) {
|
||||
// empty
|
||||
}
|
||||
MetricInfo(): m_stringValue( ), m_floatValue( 0.0f ), m_intValue( -1 ) {}
|
||||
};
|
||||
|
||||
/** @brief This class is used to implement the OpenGEX importer
|
||||
@@ -97,7 +92,7 @@ public:
|
||||
OpenGEXImporter();
|
||||
|
||||
/// The class destructor.
|
||||
~OpenGEXImporter() override;
|
||||
~OpenGEXImporter() override = default;
|
||||
|
||||
/// BaseImporter override.
|
||||
bool CanRead( const std::string &file, IOSystem *pIOHandler, bool checkSig ) const override;
|
||||
@@ -170,7 +165,7 @@ private:
|
||||
std::vector<std::string> m_Names;
|
||||
|
||||
RefInfo( aiNode *node, Type type, std::vector<std::string> &names );
|
||||
~RefInfo();
|
||||
~RefInfo() = default;
|
||||
|
||||
RefInfo( const RefInfo & ) = delete;
|
||||
RefInfo &operator = ( const RefInfo & ) = delete;
|
||||
|
||||
@@ -129,10 +129,20 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
|
||||
unsigned int numTextures = (unsigned int)stream.GetI4();
|
||||
|
||||
std::vector<Material> materials;
|
||||
materials.reserve(numMats);
|
||||
try {
|
||||
materials.reserve(numMats);
|
||||
} catch(const std::bad_alloc&) {
|
||||
ASSIMP_LOG_ERROR("Invalid alloc for materials.");
|
||||
throw DeadlyImportError("Invalid Quick3D-file, material allocation failed.");
|
||||
}
|
||||
|
||||
std::vector<Mesh> meshes;
|
||||
meshes.reserve(numMeshes);
|
||||
try {
|
||||
meshes.reserve(numMeshes);
|
||||
} catch(const std::bad_alloc&) {
|
||||
ASSIMP_LOG_ERROR("Invalid alloc for meshes.");
|
||||
throw DeadlyImportError("Invalid Quick3D-file, mesh allocation failed.");
|
||||
}
|
||||
|
||||
// Allocate the scene root node
|
||||
pScene->mRootNode = new aiNode();
|
||||
|
||||
@@ -683,7 +683,7 @@ bool glTF2Exporter::GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &she
|
||||
}
|
||||
|
||||
// Default Sheen color factor {0,0,0} disables Sheen, so do not export
|
||||
if (sheen.sheenColorFactor == defaultSheenFactor) {
|
||||
if (sheen.sheenColorFactor[0] == defaultSheenFactor[0] && sheen.sheenColorFactor[1] == defaultSheenFactor[1] && sheen.sheenColorFactor[2] == defaultSheenFactor[2]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -908,7 +908,7 @@ Ref<Node> FindSkeletonRootJoint(Ref<Skin> &skinRef) {
|
||||
do {
|
||||
startNodeRef = parentNodeRef;
|
||||
parentNodeRef = startNodeRef->parent;
|
||||
} while (!parentNodeRef->jointName.empty());
|
||||
} while (parentNodeRef && !parentNodeRef->jointName.empty());
|
||||
|
||||
return parentNodeRef;
|
||||
}
|
||||
|
||||
+8
-2
@@ -167,6 +167,7 @@ SET( Logging_SRCS
|
||||
SOURCE_GROUP(Logging FILES ${Logging_SRCS})
|
||||
|
||||
SET( Common_SRCS
|
||||
Common/StbCommon.h
|
||||
Common/Compression.cpp
|
||||
Common/Compression.h
|
||||
Common/BaseImporter.cpp
|
||||
@@ -1099,8 +1100,6 @@ if(MSVC10)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
ADD_DEFINITIONS( -DASSIMP_BUILD_DLL_EXPORT )
|
||||
|
||||
IF( MSVC OR "${CMAKE_CXX_SIMULATE_ID}" MATCHES "MSVC") # clang with MSVC ABI
|
||||
ADD_DEFINITIONS( -D_SCL_SECURE_NO_WARNINGS )
|
||||
ADD_DEFINITIONS( -D_CRT_SECURE_NO_WARNINGS )
|
||||
@@ -1177,6 +1176,13 @@ ENDIF()
|
||||
ADD_LIBRARY( assimp ${assimp_src} )
|
||||
ADD_LIBRARY(assimp::assimp ALIAS assimp)
|
||||
|
||||
# Add or remove dllexport tags depending on the library type.
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
TARGET_COMPILE_DEFINITIONS(assimp PRIVATE ASSIMP_BUILD_DLL_EXPORT)
|
||||
ELSE ()
|
||||
TARGET_COMPILE_DEFINITIONS(assimp PRIVATE OPENDDL_STATIC_LIBARY)
|
||||
ENDIF ()
|
||||
|
||||
TARGET_USE_COMMON_OUTPUT_DIRECTORY(assimp)
|
||||
|
||||
IF (ASSIMP_WARNINGS_AS_ERRORS)
|
||||
|
||||
+6
-13
@@ -5,8 +5,6 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -1282,18 +1280,13 @@ ASSIMP_API void aiQuaternionInterpolate(
|
||||
# define STBI_ONLY_PNG
|
||||
#endif
|
||||
|
||||
// Ensure all symbols are linked correctly
|
||||
#if ASSIMP_NEEDS_STB_IMAGE
|
||||
|
||||
# if _MSC_VER // "unreferenced function has been removed" (SSE2 detection routine in x64 builds)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable: 4505)
|
||||
// Share stb_image's PNG loader with other importers/exporters instead of bringing our own copy.
|
||||
# define STBI_ONLY_PNG
|
||||
# ifdef ASSIMP_USE_STB_IMAGE_STATIC
|
||||
# define STB_IMAGE_STATIC
|
||||
# endif
|
||||
|
||||
# define STB_IMAGE_IMPLEMENTATION
|
||||
# include "stb/stb_image.h"
|
||||
|
||||
# if _MSC_VER
|
||||
# pragma warning(pop)
|
||||
# endif
|
||||
|
||||
# include "Common/StbCommon.h"
|
||||
#endif
|
||||
|
||||
@@ -63,7 +63,7 @@ inline int select_fseek(FILE *file, int64_t offset, int origin) {
|
||||
|
||||
|
||||
|
||||
#if defined _WIN64 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
|
||||
#if defined _WIN32 && (!defined __GNUC__ || !defined __CLANG__ && __MSVCRT_VERSION__ >= 0x0601)
|
||||
template <>
|
||||
inline size_t select_ftell<8>(FILE *file) {
|
||||
return (size_t)::_ftelli64(file);
|
||||
@@ -74,7 +74,7 @@ inline int select_fseek<8>(FILE *file, int64_t offset, int origin) {
|
||||
return ::_fseeki64(file, offset, origin);
|
||||
}
|
||||
|
||||
#endif // #if defined _WIN32 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
|
||||
@@ -149,13 +149,20 @@ size_t DefaultIOStream::FileSize() const {
|
||||
//
|
||||
// See here for details:
|
||||
// https://www.securecoding.cert.org/confluence/display/seccode/FIO19-C.+Do+not+use+fseek()+and+ftell()+to+compute+the+size+of+a+regular+file
|
||||
#if defined _WIN64 && (!defined __GNUC__ || __MSVCRT_VERSION__ >= 0x0601)
|
||||
#if defined _WIN32 && (!defined __GNUC__ || !defined __CLANG__ && __MSVCRT_VERSION__ >= 0x0601)
|
||||
struct __stat64 fileStat;
|
||||
//using fileno + fstat avoids having to handle the filename
|
||||
int err = _fstat64(_fileno(mFile), &fileStat);
|
||||
if (0 != err)
|
||||
return 0;
|
||||
mCachedSize = (size_t)(fileStat.st_size);
|
||||
#elif defined _WIN32
|
||||
struct _stat32 fileStat;
|
||||
//using fileno + fstat avoids having to handle the filename
|
||||
int err = _fstat32(_fileno(mFile), &fileStat);
|
||||
if (0 != err)
|
||||
return 0;
|
||||
mCachedSize = (size_t)(fileStat.st_size);
|
||||
#elif defined __GNUC__ || defined __APPLE__ || defined __MACH__ || defined __FreeBSD__
|
||||
struct stat fileStat;
|
||||
int err = stat(mFilename.c_str(), &fileStat);
|
||||
|
||||
@@ -300,10 +300,10 @@ private:
|
||||
|
||||
const char separator = getOsSeparator();
|
||||
for (it = in.begin(); it != in.end(); ++it) {
|
||||
int remaining = std::distance(in.end(), it);
|
||||
const size_t remaining = std::distance(in.end(), it);
|
||||
// Exclude :// and \\, which remain untouched.
|
||||
// https://sourceforge.net/tracker/?func=detail&aid=3031725&group_id=226462&atid=1067632
|
||||
if (remaining >= 3 && !strncmp(&*it, "://", 3 )) {
|
||||
if (remaining >= 3u && !strncmp(&*it, "://", 3 )) {
|
||||
it += 3;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -105,36 +105,39 @@ void ScenePreprocessor::ProcessMesh(aiMesh *mesh) {
|
||||
for (unsigned int i = 0; i < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++i) {
|
||||
if (!mesh->mTextureCoords[i]) {
|
||||
mesh->mNumUVComponents[i] = 0;
|
||||
} else {
|
||||
if (!mesh->mNumUVComponents[i]) {
|
||||
mesh->mNumUVComponents[i] = 2;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!mesh->mNumUVComponents[i]) {
|
||||
mesh->mNumUVComponents[i] = 2;
|
||||
}
|
||||
|
||||
aiVector3D *p = mesh->mTextureCoords[i], *end = p + mesh->mNumVertices;
|
||||
|
||||
// Ensure unused components are zeroed. This will make 1D texture channels work
|
||||
// as if they were 2D channels .. just in case an application doesn't handle
|
||||
// this case
|
||||
if (2 == mesh->mNumUVComponents[i]) {
|
||||
size_t num = 0;
|
||||
for (; p != end; ++p) {
|
||||
p->z = 0.f;
|
||||
num++;
|
||||
}
|
||||
|
||||
aiVector3D *p = mesh->mTextureCoords[i], *end = p + mesh->mNumVertices;
|
||||
|
||||
// Ensure unused components are zeroed. This will make 1D texture channels work
|
||||
// as if they were 2D channels .. just in case an application doesn't handle
|
||||
// this case
|
||||
if (2 == mesh->mNumUVComponents[i]) {
|
||||
for (; p != end; ++p) {
|
||||
p->z = 0.f;
|
||||
}
|
||||
} else if (1 == mesh->mNumUVComponents[i]) {
|
||||
for (; p != end; ++p) {
|
||||
p->z = p->y = 0.f;
|
||||
}
|
||||
} else if (3 == mesh->mNumUVComponents[i]) {
|
||||
// Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element
|
||||
for (; p != end; ++p) {
|
||||
if (p->z != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p == end) {
|
||||
ASSIMP_LOG_WARN("ScenePreprocessor: UVs are declared to be 3D but they're obviously not. Reverting to 2D.");
|
||||
mesh->mNumUVComponents[i] = 2;
|
||||
} else if (1 == mesh->mNumUVComponents[i]) {
|
||||
for (; p != end; ++p) {
|
||||
p->z = p->y = 0.f;
|
||||
}
|
||||
} else if (3 == mesh->mNumUVComponents[i]) {
|
||||
// Really 3D coordinates? Check whether the third coordinate is != 0 for at least one element
|
||||
for (; p != end; ++p) {
|
||||
if (p->z != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (p == end) {
|
||||
ASSIMP_LOG_WARN("ScenePreprocessor: UVs are declared to be 3D but they're obviously not. Reverting to 2D.");
|
||||
mesh->mNumUVComponents[i] = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ Open Asset Import Library (assimp)
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
@@ -97,13 +96,14 @@ void SkeletonMeshBuilder::CreateGeometry(const aiNode *pNode) {
|
||||
const aiMatrix4x4 &childTransform = pNode->mChildren[a]->mTransformation;
|
||||
aiVector3D childpos(childTransform.a4, childTransform.b4, childTransform.c4);
|
||||
ai_real distanceToChild = childpos.Length();
|
||||
if (distanceToChild < 0.0001)
|
||||
if (distanceToChild < ai_epsilon) {
|
||||
continue;
|
||||
}
|
||||
aiVector3D up = aiVector3D(childpos).Normalize();
|
||||
|
||||
aiVector3D orth(1.0, 0.0, 0.0);
|
||||
if (std::fabs(orth * up) > 0.99)
|
||||
if (std::fabs(orth * up) > 0.99) {
|
||||
orth.Set(0.0, 1.0, 0.0);
|
||||
}
|
||||
|
||||
aiVector3D front = (up ^ orth).Normalize();
|
||||
aiVector3D side = (front ^ up).Normalize();
|
||||
@@ -183,8 +183,9 @@ void SkeletonMeshBuilder::CreateGeometry(const aiNode *pNode) {
|
||||
// add all the vertices to the bone's influences
|
||||
bone->mNumWeights = numVertices;
|
||||
bone->mWeights = new aiVertexWeight[numVertices];
|
||||
for (unsigned int a = 0; a < numVertices; a++)
|
||||
for (unsigned int a = 0; a < numVertices; ++a) {
|
||||
bone->mWeights[a] = aiVertexWeight(vertexStartIndex + a, 1.0);
|
||||
}
|
||||
|
||||
// HACK: (thom) transform all vertices to the bone's local space. Should be done before adding
|
||||
// them to the array, but I'm tired now and I'm annoyed.
|
||||
@@ -194,8 +195,9 @@ void SkeletonMeshBuilder::CreateGeometry(const aiNode *pNode) {
|
||||
}
|
||||
|
||||
// and finally recurse into the children list
|
||||
for (unsigned int a = 0; a < pNode->mNumChildren; a++)
|
||||
for (unsigned int a = 0; a < pNode->mNumChildren; ++a) {
|
||||
CreateGeometry(pNode->mChildren[a]);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Open Asset Import Library (assimp)
|
||||
----------------------------------------------------------------------
|
||||
|
||||
Copyright (c) 2006-2022, assimp team
|
||||
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use of this software in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
|
||||
* Redistributions of source code must retain the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer.
|
||||
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the
|
||||
following disclaimer in the documentation and/or other
|
||||
materials provided with the distribution.
|
||||
|
||||
* Neither the name of the assimp team, nor the names of its
|
||||
contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior
|
||||
written permission of the assimp team.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
----------------------------------------------------------------------
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#if _MSC_VER // "unreferenced function has been removed" (SSE2 detection routine in x64 builds)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4505)
|
||||
#else
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wunused-function"
|
||||
#endif
|
||||
|
||||
#include "stb/stb_image.h"
|
||||
|
||||
#if _MSC_VER
|
||||
#pragma warning(pop)
|
||||
#else
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
@@ -135,6 +135,9 @@ ASSIMP_API aiScene::aiScene() :
|
||||
mNumCameras(0),
|
||||
mCameras(nullptr),
|
||||
mMetaData(nullptr),
|
||||
mName(),
|
||||
mNumSkeletons(0),
|
||||
mSkeletons(nullptr),
|
||||
mPrivate(new Assimp::ScenePrivateData()) {
|
||||
// empty
|
||||
}
|
||||
@@ -180,7 +183,8 @@ ASSIMP_API aiScene::~aiScene() {
|
||||
delete[] mCameras;
|
||||
|
||||
aiMetadata::Dealloc(mMetaData);
|
||||
mMetaData = nullptr;
|
||||
|
||||
delete[] mSkeletons;
|
||||
|
||||
delete static_cast<Assimp::ScenePrivateData *>(mPrivate);
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@ Other:
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "stb/stb_image.h"
|
||||
#include "Common/StbCommon.h"
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ bool EmbedTexturesProcess::addTexture(aiScene *pScene, const std::string &path)
|
||||
|
||||
aiTexel* imageContent = new aiTexel[ 1ul + static_cast<unsigned long>( imageSize ) / sizeof(aiTexel)];
|
||||
pFile->Seek(0, aiOrigin_SET);
|
||||
pFile->Read(reinterpret_cast<char*>(imageContent), imageSize, 1);
|
||||
pFile->Read(reinterpret_cast<char*>(imageContent), static_cast<size_t>(imageSize), 1);
|
||||
mIOHandler->Close(pFile);
|
||||
|
||||
// Enlarging the textures table
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
#include "revision.h"
|
||||
#ifdef __GNUC__
|
||||
#include "winresrc.h"
|
||||
#else
|
||||
#include "winres.h"
|
||||
#endif
|
||||
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
#pragma code_page(1252)
|
||||
|
||||
Reference in New Issue
Block a user