Implement ascii FBX export.
It's available under the 'fbxa' format id.
This commit is contained in:
@@ -48,7 +48,9 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream> // stringstream
|
||||
#include <ostream>
|
||||
#include <locale>
|
||||
#include <sstream> // ostringstream
|
||||
|
||||
|
||||
// constructors for single element properties
|
||||
@@ -164,18 +166,18 @@ size_t FBX::Property::size()
|
||||
}
|
||||
}
|
||||
|
||||
void FBX::Property::Dump(Assimp::StreamWriterLE &s)
|
||||
void FBX::Property::DumpBinary(Assimp::StreamWriterLE &s)
|
||||
{
|
||||
s.PutU1(type);
|
||||
uint8_t* d;
|
||||
uint8_t* d = data.data();
|
||||
size_t N;
|
||||
switch (type) {
|
||||
case 'C': s.PutU1(*(reinterpret_cast<uint8_t*>(data.data()))); return;
|
||||
case 'Y': s.PutI2(*(reinterpret_cast<int16_t*>(data.data()))); return;
|
||||
case 'I': s.PutI4(*(reinterpret_cast<int32_t*>(data.data()))); return;
|
||||
case 'F': s.PutF4(*(reinterpret_cast<float*>(data.data()))); return;
|
||||
case 'D': s.PutF8(*(reinterpret_cast<double*>(data.data()))); return;
|
||||
case 'L': s.PutI8(*(reinterpret_cast<int64_t*>(data.data()))); return;
|
||||
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()));
|
||||
@@ -187,7 +189,6 @@ void FBX::Property::Dump(Assimp::StreamWriterLE &s)
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
d = data.data();
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutI4((reinterpret_cast<int32_t*>(d))[i]);
|
||||
}
|
||||
@@ -198,7 +199,6 @@ void FBX::Property::Dump(Assimp::StreamWriterLE &s)
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
d = data.data();
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutI8((reinterpret_cast<int64_t*>(d))[i]);
|
||||
}
|
||||
@@ -209,7 +209,6 @@ void FBX::Property::Dump(Assimp::StreamWriterLE &s)
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
d = data.data();
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutF4((reinterpret_cast<float*>(d))[i]);
|
||||
}
|
||||
@@ -220,18 +219,146 @@ void FBX::Property::Dump(Assimp::StreamWriterLE &s)
|
||||
s.PutU4(0); // no encoding (1 would be zip-compressed)
|
||||
// TODO: compress if large?
|
||||
s.PutU4(uint32_t(data.size())); // data size
|
||||
d = data.data();
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
s.PutF8((reinterpret_cast<double*>(d))[i]);
|
||||
}
|
||||
return;
|
||||
default:
|
||||
std::stringstream err;
|
||||
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)
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss.imbue(std::locale::classic());
|
||||
ss.precision(15); // this seems to match official FBX SDK exports
|
||||
DumpAscii(ss, indent);
|
||||
outstream.PutString(ss.str());
|
||||
}
|
||||
|
||||
void FBX::Property::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;
|
||||
size_t swap = data.size();
|
||||
size_t count = 0;
|
||||
switch (type) {
|
||||
case 'C':
|
||||
if (*(reinterpret_cast<uint8_t*>(d))) { s << 'T'; }
|
||||
else { s << 'F'; }
|
||||
return;
|
||||
case 'Y': s << *(reinterpret_cast<int16_t*>(d)); return;
|
||||
case 'I': s << *(reinterpret_cast<int32_t*>(d)); return;
|
||||
case 'F': s << *(reinterpret_cast<float*>(d)); return;
|
||||
case 'D': s << *(reinterpret_cast<double*>(d)); return;
|
||||
case 'L': s << *(reinterpret_cast<int64_t*>(d)); return;
|
||||
case 'S':
|
||||
// first search to see if it has "\x00\x01" in it -
|
||||
// which separates fields which are reversed in the ascii version.
|
||||
// yeah.
|
||||
// FBX, yeah.
|
||||
for (size_t i = 0; i < data.size(); ++i) {
|
||||
if (data[i] == '\0') {
|
||||
swap = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case 'R':
|
||||
s << '"';
|
||||
// we might as well check this now,
|
||||
// probably it will never happen
|
||||
for (size_t i = 0; i < data.size(); ++i) {
|
||||
char c = data[i];
|
||||
if (c == '"') {
|
||||
throw runtime_error("can't handle quotes in property string");
|
||||
}
|
||||
}
|
||||
// first write the SWAPPED member (if any)
|
||||
for (size_t i = swap + 2; i < data.size(); ++i) {
|
||||
char c = data[i];
|
||||
s << c;
|
||||
}
|
||||
// then a separator
|
||||
if (swap != data.size()) {
|
||||
s << "::";
|
||||
}
|
||||
// then the initial member
|
||||
for (size_t i = 0; i < swap; ++i) {
|
||||
char c = data[i];
|
||||
s << c;
|
||||
}
|
||||
s << '"';
|
||||
return;
|
||||
case 'i':
|
||||
N = data.size() / 4; // number of elements
|
||||
s << '*' << N << " {\n";
|
||||
for (int i = 0; i < indent + 1; ++i) { s << '\t'; }
|
||||
s << "a: ";
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
if (i > 0) { s << ','; }
|
||||
if (count++ > 120) { s << '\n'; count = 0; }
|
||||
s << (reinterpret_cast<int32_t*>(d))[i];
|
||||
}
|
||||
s << '\n';
|
||||
for (int i = 0; i < indent; ++i) { s << '\t'; }
|
||||
s << "} ";
|
||||
return;
|
||||
case 'l':
|
||||
N = data.size() / 8;
|
||||
s << '*' << N << " {\n";
|
||||
for (int i = 0; i < indent + 1; ++i) { s << '\t'; }
|
||||
s << "a: ";
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
if (i > 0) { s << ','; }
|
||||
if (count++ > 120) { s << '\n'; count = 0; }
|
||||
s << (reinterpret_cast<int64_t*>(d))[i];
|
||||
}
|
||||
s << '\n';
|
||||
for (int i = 0; i < indent; ++i) { s << '\t'; }
|
||||
s << "} ";
|
||||
return;
|
||||
case 'f':
|
||||
N = data.size() / 4;
|
||||
s << '*' << N << " {\n";
|
||||
for (int i = 0; i < indent + 1; ++i) { s << '\t'; }
|
||||
s << "a: ";
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
if (i > 0) { s << ','; }
|
||||
if (count++ > 120) { s << '\n'; count = 0; }
|
||||
s << (reinterpret_cast<float*>(d))[i];
|
||||
}
|
||||
s << '\n';
|
||||
for (int i = 0; i < indent; ++i) { s << '\t'; }
|
||||
s << "} ";
|
||||
return;
|
||||
case 'd':
|
||||
N = data.size() / 8;
|
||||
s << '*' << N << " {\n";
|
||||
for (int i = 0; i < indent + 1; ++i) { s << '\t'; }
|
||||
s << "a: ";
|
||||
// set precision to something that can handle doubles
|
||||
s.precision(15);
|
||||
for (size_t i = 0; i < N; ++i) {
|
||||
if (i > 0) { s << ','; }
|
||||
if (count++ > 120) { s << '\n'; count = 0; }
|
||||
s << (reinterpret_cast<double*>(d))[i];
|
||||
}
|
||||
s << '\n';
|
||||
for (int i = 0; i < indent; ++i) { s << '\t'; }
|
||||
s << "} ";
|
||||
return;
|
||||
default:
|
||||
std::ostringstream err;
|
||||
err << "Tried to dump property with invalid type '";
|
||||
err << type << "'!";
|
||||
throw runtime_error(err.str());
|
||||
}
|
||||
}
|
||||
|
||||
#endif // ASSIMP_BUILD_NO_FBX_EXPORTER
|
||||
#endif // ASSIMP_BUILD_NO_EXPORT
|
||||
|
||||
Reference in New Issue
Block a user