Merge branch 'master' into windows-external-zlib-fix
commit
785ceaf58a
|
@ -64,13 +64,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
using namespace Assimp;
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
namespace Assimp {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Worker function for exporting a scene to Collada. Prototyped and registered in Exporter.cpp
|
||||
void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
|
||||
{
|
||||
void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/) {
|
||||
std::string path = DefaultIOSystem::absolutePath(std::string(pFile));
|
||||
std::string file = DefaultIOSystem::completeBaseName(std::string(pFile));
|
||||
|
||||
|
@ -93,12 +91,12 @@ void ExportSceneCollada(const char* pFile, IOSystem* pIOSystem, const aiScene* p
|
|||
|
||||
} // end of namespace Assimp
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor for a specific scene to export
|
||||
ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file) : mIOSystem(pIOSystem), mPath(path), mFile(file)
|
||||
{
|
||||
ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, const std::string& path, const std::string& file)
|
||||
: mIOSystem(pIOSystem)
|
||||
, mPath(path)
|
||||
, mFile(file) {
|
||||
// make sure that all formatting happens using the standard, C locale and not the user's current locale
|
||||
mOutput.imbue( std::locale("C") );
|
||||
mOutput.precision(16);
|
||||
|
@ -115,17 +113,15 @@ ColladaExporter::ColladaExporter( const aiScene* pScene, IOSystem* pIOSystem, co
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor
|
||||
ColladaExporter::~ColladaExporter()
|
||||
{
|
||||
if(mSceneOwned) {
|
||||
ColladaExporter::~ColladaExporter() {
|
||||
if ( mSceneOwned ) {
|
||||
delete mScene;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Starts writing the contents
|
||||
void ColladaExporter::WriteFile()
|
||||
{
|
||||
void ColladaExporter::WriteFile() {
|
||||
// write the DTD
|
||||
mOutput << "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>" << endstr;
|
||||
// COLLADA element start
|
||||
|
@ -158,8 +154,7 @@ void ColladaExporter::WriteFile()
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Writes the asset header
|
||||
void ColladaExporter::WriteHeader()
|
||||
{
|
||||
void ColladaExporter::WriteHeader() {
|
||||
static const ai_real epsilon = ai_real( 0.00001 );
|
||||
static const aiQuaternion x_rot(aiMatrix3x3(
|
||||
0, -1, 0,
|
||||
|
@ -240,51 +235,60 @@ void ColladaExporter::WriteHeader()
|
|||
|
||||
// If no Scene metadata, use root node metadata
|
||||
aiMetadata* meta = mScene->mMetaData;
|
||||
if (!meta)
|
||||
if (nullptr == meta) {
|
||||
meta = mScene->mRootNode->mMetaData;
|
||||
}
|
||||
|
||||
aiString value;
|
||||
if (!meta || !meta->Get("Author", value))
|
||||
if (!meta || !meta->Get("Author", value)) {
|
||||
mOutput << startstr << "<author>" << "Assimp" << "</author>" << endstr;
|
||||
else
|
||||
} else {
|
||||
mOutput << startstr << "<author>" << XMLEscape(value.C_Str()) << "</author>" << endstr;
|
||||
}
|
||||
|
||||
if (!meta || !meta->Get("AuthoringTool", value))
|
||||
if (nullptr == meta || !meta->Get("AuthoringTool", value)) {
|
||||
mOutput << startstr << "<authoring_tool>" << "Assimp Exporter" << "</authoring_tool>" << endstr;
|
||||
else
|
||||
} else {
|
||||
mOutput << startstr << "<authoring_tool>" << XMLEscape(value.C_Str()) << "</authoring_tool>" << endstr;
|
||||
}
|
||||
|
||||
if (meta)
|
||||
{
|
||||
if (meta->Get("Comments", value))
|
||||
if (meta) {
|
||||
if (meta->Get("Comments", value)) {
|
||||
mOutput << startstr << "<comments>" << XMLEscape(value.C_Str()) << "</comments>" << endstr;
|
||||
if (meta->Get("Copyright", value))
|
||||
}
|
||||
if (meta->Get("Copyright", value)) {
|
||||
mOutput << startstr << "<copyright>" << XMLEscape(value.C_Str()) << "</copyright>" << endstr;
|
||||
if (meta->Get("SourceData", value))
|
||||
}
|
||||
if (meta->Get("SourceData", value)) {
|
||||
mOutput << startstr << "<source_data>" << XMLEscape(value.C_Str()) << "</source_data>" << endstr;
|
||||
}
|
||||
}
|
||||
|
||||
PopTag();
|
||||
mOutput << startstr << "</contributor>" << endstr;
|
||||
|
||||
if (!meta || !meta->Get("Created", value))
|
||||
if (nullptr == meta || !meta->Get("Created", value)) {
|
||||
mOutput << startstr << "<created>" << date_str << "</created>" << endstr;
|
||||
else
|
||||
} else {
|
||||
mOutput << startstr << "<created>" << XMLEscape(value.C_Str()) << "</created>" << endstr;
|
||||
}
|
||||
|
||||
// Modified date is always the date saved
|
||||
mOutput << startstr << "<modified>" << date_str << "</modified>" << endstr;
|
||||
|
||||
if (meta)
|
||||
{
|
||||
if (meta->Get("Keywords", value))
|
||||
if (meta) {
|
||||
if (meta->Get("Keywords", value)) {
|
||||
mOutput << startstr << "<keywords>" << XMLEscape(value.C_Str()) << "</keywords>" << endstr;
|
||||
if (meta->Get("Revision", value))
|
||||
}
|
||||
if (meta->Get("Revision", value)) {
|
||||
mOutput << startstr << "<revision>" << XMLEscape(value.C_Str()) << "</revision>" << endstr;
|
||||
if (meta->Get("Subject", value))
|
||||
}
|
||||
if (meta->Get("Subject", value)) {
|
||||
mOutput << startstr << "<subject>" << XMLEscape(value.C_Str()) << "</subject>" << endstr;
|
||||
if (meta->Get("Title", value))
|
||||
}
|
||||
if (meta->Get("Title", value)) {
|
||||
mOutput << startstr << "<title>" << XMLEscape(value.C_Str()) << "</title>" << endstr;
|
||||
}
|
||||
}
|
||||
|
||||
mOutput << startstr << "<unit name=\"meter\" meter=\"" << scale << "\" />" << endstr;
|
||||
|
@ -299,12 +303,15 @@ void ColladaExporter::WriteTextures() {
|
|||
static const unsigned int buffer_size = 1024;
|
||||
char str[buffer_size];
|
||||
|
||||
if(mScene->HasTextures()) {
|
||||
if (mScene->HasTextures()) {
|
||||
for(unsigned int i = 0; i < mScene->mNumTextures; i++) {
|
||||
// It would be great to be able to create a directory in portable standard C++, but it's not the case,
|
||||
// so we just write the textures in the current directory.
|
||||
|
||||
aiTexture* texture = mScene->mTextures[i];
|
||||
if ( nullptr == texture ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
ASSIMP_itoa10(str, buffer_size, i + 1);
|
||||
|
||||
|
@ -458,6 +465,7 @@ void ColladaExporter::WritePointLight(const aiLight *const light){
|
|||
mOutput << startstr << "</point>" << endstr;
|
||||
|
||||
}
|
||||
|
||||
void ColladaExporter::WriteDirectionalLight(const aiLight *const light){
|
||||
const aiColor3D &color= light->mColorDiffuse;
|
||||
mOutput << startstr << "<directional>" << endstr;
|
||||
|
@ -470,6 +478,7 @@ void ColladaExporter::WriteDirectionalLight(const aiLight *const light){
|
|||
mOutput << startstr << "</directional>" << endstr;
|
||||
|
||||
}
|
||||
|
||||
void ColladaExporter::WriteSpotLight(const aiLight *const light){
|
||||
|
||||
const aiColor3D &color= light->mColorDiffuse;
|
||||
|
@ -526,18 +535,16 @@ void ColladaExporter::WriteAmbienttLight(const aiLight *const light){
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reads a single surface entry from the given material keys
|
||||
void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat, aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex)
|
||||
{
|
||||
if( pSrcMat->GetTextureCount( pTexture) > 0 )
|
||||
{
|
||||
void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial* pSrcMat,
|
||||
aiTextureType pTexture, const char* pKey, size_t pType, size_t pIndex) {
|
||||
if( pSrcMat->GetTextureCount( pTexture) > 0 ) {
|
||||
aiString texfile;
|
||||
unsigned int uvChannel = 0;
|
||||
pSrcMat->GetTexture( pTexture, 0, &texfile, NULL, &uvChannel);
|
||||
|
||||
std::string index_str(texfile.C_Str());
|
||||
|
||||
if(index_str.size() != 0 && index_str[0] == '*')
|
||||
{
|
||||
if(index_str.size() != 0 && index_str[0] == '*') {
|
||||
unsigned int index;
|
||||
|
||||
index_str = index_str.substr(1, std::string::npos);
|
||||
|
@ -555,15 +562,13 @@ void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial*
|
|||
} else {
|
||||
throw DeadlyExportError("could not find embedded texture at index " + index_str);
|
||||
}
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
poSurface.texture = texfile.C_Str();
|
||||
}
|
||||
|
||||
poSurface.channel = uvChannel;
|
||||
poSurface.exist = true;
|
||||
} else
|
||||
{
|
||||
} else {
|
||||
if( pKey )
|
||||
poSurface.exist = pSrcMat->Get( pKey, static_cast<unsigned int>(pType), static_cast<unsigned int>(pIndex), poSurface.color) == aiReturn_SUCCESS;
|
||||
}
|
||||
|
@ -571,15 +576,13 @@ void ColladaExporter::ReadMaterialSurface( Surface& poSurface, const aiMaterial*
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Reimplementation of isalnum(,C locale), because AppVeyor does not see standard version.
|
||||
static bool isalnum_C(char c)
|
||||
{
|
||||
static bool isalnum_C(char c) {
|
||||
return ( nullptr != strchr("0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",c) );
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Writes an image entry for the given surface
|
||||
void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd)
|
||||
{
|
||||
void ColladaExporter::WriteImageEntry( const Surface& pSurface, const std::string& pNameAdd) {
|
||||
if( !pSurface.texture.empty() )
|
||||
{
|
||||
mOutput << startstr << "<image id=\"" << XMLEscape(pNameAdd) << "\">" << endstr;
|
||||
|
@ -833,8 +836,9 @@ void ColladaExporter::WriteControllerLibrary()
|
|||
mOutput << startstr << "<library_controllers>" << endstr;
|
||||
PushTag();
|
||||
|
||||
for( size_t a = 0; a < mScene->mNumMeshes; ++a)
|
||||
for( size_t a = 0; a < mScene->mNumMeshes; ++a) {
|
||||
WriteController( a);
|
||||
}
|
||||
|
||||
PopTag();
|
||||
mOutput << startstr << "</library_controllers>" << endstr;
|
||||
|
|
|
@ -59,12 +59,11 @@ namespace FBX {
|
|||
class Node;
|
||||
}
|
||||
|
||||
class FBX::Node
|
||||
{
|
||||
public: // public data members
|
||||
class FBX::Node {
|
||||
public:
|
||||
// TODO: accessors
|
||||
std::string name; // node name
|
||||
std::vector<FBX::Property> properties; // node properties
|
||||
std::vector<FBX::FBXExportProperty> properties; // node properties
|
||||
std::vector<FBX::Node> children; // child nodes
|
||||
|
||||
// some nodes always pretend they have children...
|
||||
|
@ -215,7 +214,7 @@ public: // static member functions
|
|||
Assimp::StreamWriterLE& s,
|
||||
bool binary, int indent
|
||||
) {
|
||||
FBX::Property p(value);
|
||||
FBX::FBXExportProperty p(value);
|
||||
FBX::Node node(name, p);
|
||||
node.Dump(s, binary, indent);
|
||||
}
|
||||
|
|
|
@ -53,186 +53,209 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <sstream> // ostringstream
|
||||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
|
||||
// constructors for single element properties
|
||||
|
||||
FBX::Property::Property(bool v)
|
||||
: type('C'), data(1)
|
||||
{
|
||||
data = {uint8_t(v)};
|
||||
FBXExportProperty::FBXExportProperty(bool v)
|
||||
: type('C')
|
||||
, data(1) {
|
||||
data = {
|
||||
uint8_t(v)
|
||||
};
|
||||
}
|
||||
|
||||
FBX::Property::Property(int16_t v) : type('Y'), data(2)
|
||||
{
|
||||
FBXExportProperty::FBXExportProperty(int16_t v)
|
||||
: type('Y')
|
||||
, data(2) {
|
||||
uint8_t* d = data.data();
|
||||
(reinterpret_cast<int16_t*>(d))[0] = v;
|
||||
}
|
||||
|
||||
FBX::Property::Property(int32_t v) : type('I'), data(4)
|
||||
{
|
||||
FBXExportProperty::FBXExportProperty(int32_t v)
|
||||
: type('I')
|
||||
, data(4) {
|
||||
uint8_t* d = data.data();
|
||||
(reinterpret_cast<int32_t*>(d))[0] = v;
|
||||
}
|
||||
|
||||
FBX::Property::Property(float v) : type('F'), data(4)
|
||||
{
|
||||
FBXExportProperty::FBXExportProperty(float v)
|
||||
: type('F')
|
||||
, data(4) {
|
||||
uint8_t* d = data.data();
|
||||
(reinterpret_cast<float*>(d))[0] = v;
|
||||
}
|
||||
|
||||
FBX::Property::Property(double v) : type('D'), data(8)
|
||||
{
|
||||
FBXExportProperty::FBXExportProperty(double v)
|
||||
: type('D')
|
||||
, data(8) {
|
||||
uint8_t* d = data.data();
|
||||
(reinterpret_cast<double*>(d))[0] = v;
|
||||
}
|
||||
|
||||
FBX::Property::Property(int64_t v) : type('L'), data(8)
|
||||
{
|
||||
FBXExportProperty::FBXExportProperty(int64_t v)
|
||||
: type('L')
|
||||
, data(8) {
|
||||
uint8_t* d = data.data();
|
||||
(reinterpret_cast<int64_t*>(d))[0] = v;
|
||||
}
|
||||
|
||||
|
||||
// constructors for array-type properties
|
||||
|
||||
FBX::Property::Property(const char* c, bool raw)
|
||||
: Property(std::string(c), raw)
|
||||
{}
|
||||
FBXExportProperty::FBXExportProperty(const char* c, bool raw)
|
||||
: FBXExportProperty(std::string(c), raw) {
|
||||
// empty
|
||||
}
|
||||
|
||||
// strings can either be saved as "raw" (R) data, or "string" (S) data
|
||||
FBX::Property::Property(const std::string& s, bool raw)
|
||||
: type(raw ? 'R' : 'S'), data(s.size())
|
||||
{
|
||||
FBXExportProperty::FBXExportProperty(const std::string& s, bool raw)
|
||||
: type(raw ? 'R' : 'S')
|
||||
, data(s.size()) {
|
||||
for (size_t i = 0; i < s.size(); ++i) {
|
||||
data[i] = uint8_t(s[i]);
|
||||
}
|
||||
}
|
||||
|
||||
FBX::Property::Property(const std::vector<uint8_t>& r)
|
||||
: type('R'), data(r)
|
||||
{}
|
||||
FBXExportProperty::FBXExportProperty(const std::vector<uint8_t>& r)
|
||||
: type('R')
|
||||
, data(r) {
|
||||
// empty
|
||||
}
|
||||
|
||||
FBX::Property::Property(const std::vector<int32_t>& va)
|
||||
: type('i'), data(4*va.size())
|
||||
{
|
||||
FBXExportProperty::FBXExportProperty(const std::vector<int32_t>& va)
|
||||
: type('i')
|
||||
, data(4 * va.size() ) {
|
||||
int32_t* d = reinterpret_cast<int32_t*>(data.data());
|
||||
for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
|
||||
for (size_t i = 0; i < va.size(); ++i) {
|
||||
d[i] = va[i];
|
||||
}
|
||||
}
|
||||
|
||||
FBX::Property::Property(const std::vector<int64_t>& va)
|
||||
: type('l'), data(8*va.size())
|
||||
{
|
||||
FBXExportProperty::FBXExportProperty(const std::vector<int64_t>& va)
|
||||
: type('l')
|
||||
, data(8 * va.size()) {
|
||||
int64_t* d = reinterpret_cast<int64_t*>(data.data());
|
||||
for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
|
||||
for (size_t i = 0; i < va.size(); ++i) {
|
||||
d[i] = va[i];
|
||||
}
|
||||
}
|
||||
|
||||
FBX::Property::Property(const std::vector<float>& va)
|
||||
: type('f'), data(4*va.size())
|
||||
{
|
||||
FBXExportProperty::FBXExportProperty(const std::vector<float>& va)
|
||||
: type('f')
|
||||
, data(4 * va.size()) {
|
||||
float* d = reinterpret_cast<float*>(data.data());
|
||||
for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
|
||||
for (size_t i = 0; i < va.size(); ++i) {
|
||||
d[i] = va[i];
|
||||
}
|
||||
}
|
||||
|
||||
FBX::Property::Property(const std::vector<double>& va)
|
||||
: type('d'), data(8*va.size())
|
||||
{
|
||||
FBXExportProperty::FBXExportProperty(const std::vector<double>& va)
|
||||
: type('d')
|
||||
, data(8 * va.size()) {
|
||||
double* d = reinterpret_cast<double*>(data.data());
|
||||
for (size_t i = 0; i < va.size(); ++i) { d[i] = va[i]; }
|
||||
for (size_t i = 0; i < va.size(); ++i) {
|
||||
d[i] = va[i];
|
||||
}
|
||||
}
|
||||
|
||||
FBX::Property::Property(const aiMatrix4x4& vm)
|
||||
: type('d'), data(8*16)
|
||||
{
|
||||
FBXExportProperty::FBXExportProperty(const aiMatrix4x4& vm)
|
||||
: type('d')
|
||||
, data(8 * 16) {
|
||||
double* d = reinterpret_cast<double*>(data.data());
|
||||
for (unsigned int c = 0; c < 4; ++c) {
|
||||
for (unsigned int r = 0; r < 4; ++r) {
|
||||
d[4*c+r] = vm[r][c];
|
||||
d[4 * c + r] = vm[r][c];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// public member functions
|
||||
|
||||
size_t FBX::Property::size()
|
||||
{
|
||||
size_t FBXExportProperty::size() {
|
||||
switch (type) {
|
||||
case 'C': case 'Y': case 'I': case 'F': case 'D': case 'L':
|
||||
return data.size() + 1;
|
||||
case 'S': case 'R':
|
||||
return data.size() + 5;
|
||||
case 'i': case 'd':
|
||||
return data.size() + 13;
|
||||
default:
|
||||
throw DeadlyExportError("Requested size on property of unknown type");
|
||||
case 'C':
|
||||
case 'Y':
|
||||
case 'I':
|
||||
case 'F':
|
||||
case 'D':
|
||||
case 'L':
|
||||
return data.size() + 1;
|
||||
case 'S':
|
||||
case 'R':
|
||||
return data.size() + 5;
|
||||
case 'i':
|
||||
case 'd':
|
||||
return data.size() + 13;
|
||||
default:
|
||||
throw DeadlyExportError("Requested size on property of unknown type");
|
||||
}
|
||||
}
|
||||
|
||||
void FBX::Property::DumpBinary(Assimp::StreamWriterLE &s)
|
||||
{
|
||||
void FBXExportProperty::DumpBinary(Assimp::StreamWriterLE& s) {
|
||||
s.PutU1(type);
|
||||
uint8_t* d = data.data();
|
||||
size_t N;
|
||||
switch (type) {
|
||||
case 'C': s.PutU1(*(reinterpret_cast<uint8_t*>(d))); return;
|
||||
case 'Y': s.PutI2(*(reinterpret_cast<int16_t*>(d))); return;
|
||||
case 'I': s.PutI4(*(reinterpret_cast<int32_t*>(d))); return;
|
||||
case 'F': s.PutF4(*(reinterpret_cast<float*>(d))); return;
|
||||
case 'D': s.PutF8(*(reinterpret_cast<double*>(d))); return;
|
||||
case 'L': s.PutI8(*(reinterpret_cast<int64_t*>(d))); return;
|
||||
case 'S':
|
||||
case 'R':
|
||||
s.PutU4(uint32_t(data.size()));
|
||||
for (size_t i = 0; i < data.size(); ++i) { s.PutU1(data[i]); }
|
||||
return;
|
||||
case 'i':
|
||||
N = data.size() / 4;
|
||||
s.PutU4(uint32_t(N)); // number of elements
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutI4((reinterpret_cast<int32_t*>(d))[i]);
|
||||
}
|
||||
return;
|
||||
case 'l':
|
||||
N = data.size() / 8;
|
||||
s.PutU4(uint32_t(N)); // number of elements
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutI8((reinterpret_cast<int64_t*>(d))[i]);
|
||||
}
|
||||
return;
|
||||
case 'f':
|
||||
N = data.size() / 4;
|
||||
s.PutU4(uint32_t(N)); // number of elements
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutF4((reinterpret_cast<float*>(d))[i]);
|
||||
}
|
||||
return;
|
||||
case 'd':
|
||||
N = data.size() / 8;
|
||||
s.PutU4(uint32_t(N)); // number of elements
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutF8((reinterpret_cast<double*>(d))[i]);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
std::ostringstream err;
|
||||
err << "Tried to dump property with invalid type '";
|
||||
err << type << "'!";
|
||||
throw DeadlyExportError(err.str());
|
||||
case 'C': s.PutU1(*(reinterpret_cast<uint8_t*>(d))); return;
|
||||
case 'Y': s.PutI2(*(reinterpret_cast<int16_t*>(d))); return;
|
||||
case 'I': s.PutI4(*(reinterpret_cast<int32_t*>(d))); return;
|
||||
case 'F': s.PutF4(*(reinterpret_cast<float*>(d))); return;
|
||||
case 'D': s.PutF8(*(reinterpret_cast<double*>(d))); return;
|
||||
case 'L': s.PutI8(*(reinterpret_cast<int64_t*>(d))); return;
|
||||
case 'S':
|
||||
case 'R':
|
||||
s.PutU4(uint32_t(data.size()));
|
||||
for (size_t i = 0; i < data.size(); ++i) { s.PutU1(data[i]); }
|
||||
return;
|
||||
case 'i':
|
||||
N = data.size() / 4;
|
||||
s.PutU4(uint32_t(N)); // number of elements
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutI4((reinterpret_cast<int32_t*>(d))[i]);
|
||||
}
|
||||
return;
|
||||
case 'l':
|
||||
N = data.size() / 8;
|
||||
s.PutU4(uint32_t(N)); // number of elements
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutI8((reinterpret_cast<int64_t*>(d))[i]);
|
||||
}
|
||||
return;
|
||||
case 'f':
|
||||
N = data.size() / 4;
|
||||
s.PutU4(uint32_t(N)); // number of elements
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutF4((reinterpret_cast<float*>(d))[i]);
|
||||
}
|
||||
return;
|
||||
case 'd':
|
||||
N = data.size() / 8;
|
||||
s.PutU4(uint32_t(N)); // number of elements
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutF8((reinterpret_cast<double*>(d))[i]);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
std::ostringstream err;
|
||||
err << "Tried to dump property with invalid type '";
|
||||
err << type << "'!";
|
||||
throw DeadlyExportError(err.str());
|
||||
}
|
||||
}
|
||||
|
||||
void FBX::Property::DumpAscii(Assimp::StreamWriterLE &outstream, int indent)
|
||||
{
|
||||
void FBXExportProperty::DumpAscii(Assimp::StreamWriterLE& outstream, int indent) {
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss.precision(15); // this seems to match official FBX SDK exports
|
||||
|
@ -240,8 +263,7 @@ void FBX::Property::DumpAscii(Assimp::StreamWriterLE &outstream, int indent)
|
|||
outstream.PutString(ss.str());
|
||||
}
|
||||
|
||||
void FBX::Property::DumpAscii(std::ostream& s, int indent)
|
||||
{
|
||||
void FBXExportProperty::DumpAscii(std::ostream& s, int indent) {
|
||||
// no writing type... or anything. just shove it into the stream.
|
||||
uint8_t* d = data.data();
|
||||
size_t N;
|
||||
|
@ -359,6 +381,9 @@ void FBX::Property::DumpAscii(std::ostream& s, int indent)
|
|||
throw runtime_error(err.str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // Namespace FBX
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
|
||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||
|
|
|
@ -47,7 +47,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#ifndef ASSIMP_BUILD_NO_FBX_EXPORTER
|
||||
|
||||
|
||||
#include <assimp/types.h> // aiMatrix4x4
|
||||
#include <assimp/StreamWriter.h> // StreamWriterLE
|
||||
|
||||
|
@ -58,10 +57,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
namespace Assimp {
|
||||
namespace FBX {
|
||||
class Property;
|
||||
}
|
||||
|
||||
/** FBX::Property
|
||||
/** @brief FBX::Property
|
||||
*
|
||||
* Holds a value of any of FBX's recognized types,
|
||||
* each represented by a particular one-character code.
|
||||
|
@ -79,35 +76,34 @@ namespace FBX {
|
|||
* S : string (array of 1-byte char)
|
||||
* R : raw data (array of bytes)
|
||||
*/
|
||||
class FBX::Property
|
||||
{
|
||||
class FBXExportProperty {
|
||||
public:
|
||||
// constructors for basic types.
|
||||
// all explicit to avoid accidental typecasting
|
||||
explicit Property(bool v);
|
||||
explicit FBXExportProperty(bool v);
|
||||
// TODO: determine if there is actually a byte type,
|
||||
// or if this always means <bool>. 'C' seems to imply <char>,
|
||||
// so possibly the above was intended to represent both.
|
||||
explicit Property(int16_t v);
|
||||
explicit Property(int32_t v);
|
||||
explicit Property(float v);
|
||||
explicit Property(double v);
|
||||
explicit Property(int64_t v);
|
||||
explicit FBXExportProperty(int16_t v);
|
||||
explicit FBXExportProperty(int32_t v);
|
||||
explicit FBXExportProperty(float v);
|
||||
explicit FBXExportProperty(double v);
|
||||
explicit FBXExportProperty(int64_t v);
|
||||
// strings can either be stored as 'R' (raw) or 'S' (string) type
|
||||
explicit Property(const char* c, bool raw=false);
|
||||
explicit Property(const std::string& s, bool raw=false);
|
||||
explicit Property(const std::vector<uint8_t>& r);
|
||||
explicit Property(const std::vector<int32_t>& va);
|
||||
explicit Property(const std::vector<int64_t>& va);
|
||||
explicit Property(const std::vector<double>& va);
|
||||
explicit Property(const std::vector<float>& va);
|
||||
explicit Property(const aiMatrix4x4& vm);
|
||||
explicit FBXExportProperty(const char* c, bool raw = false);
|
||||
explicit FBXExportProperty(const std::string& s, bool raw = false);
|
||||
explicit FBXExportProperty(const std::vector<uint8_t>& r);
|
||||
explicit FBXExportProperty(const std::vector<int32_t>& va);
|
||||
explicit FBXExportProperty(const std::vector<int64_t>& va);
|
||||
explicit FBXExportProperty(const std::vector<double>& va);
|
||||
explicit FBXExportProperty(const std::vector<float>& va);
|
||||
explicit FBXExportProperty(const aiMatrix4x4& vm);
|
||||
|
||||
// this will catch any type not defined above,
|
||||
// so that we don't accidentally convert something we don't want.
|
||||
// for example (const char*) --> (bool)... seriously wtf C++
|
||||
template <class T>
|
||||
explicit Property(T v) : type('X') {
|
||||
explicit FBXExportProperty(T v) : type('X') {
|
||||
static_assert(std::is_void<T>::value, "TRIED TO CREATE FBX PROPERTY WITH UNSUPPORTED TYPE, CHECK YOUR PROPERTY INSTANTIATION");
|
||||
} // note: no line wrap so it appears verbatim on the compiler error
|
||||
|
||||
|
@ -115,16 +111,19 @@ public:
|
|||
size_t size();
|
||||
|
||||
// write this property node as binary data to the given stream
|
||||
void DumpBinary(Assimp::StreamWriterLE &s);
|
||||
void DumpAscii(Assimp::StreamWriterLE &s, int indent=0);
|
||||
void DumpAscii(std::ostream &s, int indent=0);
|
||||
void DumpBinary(Assimp::StreamWriterLE& s);
|
||||
void DumpAscii(Assimp::StreamWriterLE& s, int indent = 0);
|
||||
void DumpAscii(std::ostream& s, int indent = 0);
|
||||
// note: make sure the ostream is in classic "C" locale
|
||||
|
||||
private:
|
||||
char type;
|
||||
std::vector<uint8_t> data;
|
||||
};
|
||||
}
|
||||
|
||||
} // Namespace FBX
|
||||
} // Namespace Assimp
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
|
||||
|
||||
#endif // AI_FBXEXPORTPROPERTY_H_INC
|
||||
|
|
|
@ -2271,8 +2271,8 @@ void FBXExporter::WriteModelNode(
|
|||
|
||||
// not sure what these are for,
|
||||
// but they seem to be omnipresent
|
||||
m.AddChild("Shading", Property(true));
|
||||
m.AddChild("Culling", Property("CullingOff"));
|
||||
m.AddChild("Shading", FBXExportProperty(true));
|
||||
m.AddChild("Culling", FBXExportProperty("CullingOff"));
|
||||
|
||||
m.Dump(outstream, binary, 1);
|
||||
}
|
||||
|
@ -2385,7 +2385,7 @@ void FBXExporter::WriteModelNodes(
|
|||
na.AddProperties(
|
||||
node_attribute_uid, FBX::SEPARATOR + "NodeAttribute", "LimbNode"
|
||||
);
|
||||
na.AddChild("TypeFlags", Property("Skeleton"));
|
||||
na.AddChild("TypeFlags", FBXExportProperty("Skeleton"));
|
||||
na.Dump(outstream, binary, 1);
|
||||
// and connect them
|
||||
connections.emplace_back("C", "OO", node_attribute_uid, node_uid);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
ply
|
||||
format ascii 1.0
|
||||
comment Created by Open Asset Import Library - http://assimp.sf.net (v4.1.412856994)
|
||||
comment Created by Open Asset Import Library - http://assimp.sf.net (v4.1.3297435427)
|
||||
element vertex 8
|
||||
property float x
|
||||
property float y
|
||||
|
|
Loading…
Reference in New Issue