From Aric Aumann, added options for controlling the swap of the left/right handed coordinate system

This commit is contained in:
Robert Osfield 2009-04-08 10:44:37 +00:00
parent fd5f5a71c2
commit d2a0e7884d
2 changed files with 40 additions and 14 deletions

View File

@ -52,6 +52,9 @@ public:
{
supportsExtension("x","DirectX scene format");
supportsOption("flipTexture", "flip texture upside-down");
// made hand switching an option - .x models from XSI's export are right-handed already
supportsOption("rightHanded", "prevents reader from switching handedness for right handed files");
supportsOption("leftHanded", "reader switches handedness for left handed files");
}
virtual const char* className() const {
@ -61,10 +64,10 @@ public:
virtual ReadResult readNode(const std::string& fileName, const osgDB::ReaderWriter::Options* options) const;
private:
osg::Group * convertFromDX(DX::Object & obj, bool flipTexture, float creaseAngle,
osg::Group * convertFromDX(DX::Object & obj, bool switchHands, bool flipTexture, float creaseAngle,
const osgDB::ReaderWriter::Options * options) const;
osg::Geode * convertFromDX(DX::Mesh & mesh, bool flipTexture, float creaseAngle,
osg::Geode * convertFromDX(DX::Mesh & mesh, bool switchHands, bool flipTexture, float creaseAngle,
const osgDB::ReaderWriter::Options * options) const;
};
@ -94,10 +97,17 @@ osgDB::ReaderWriter::ReadResult ReaderWriterDirectX::readNode(const std::string&
local_opt->setDatabasePath(osgDB::getFilePath(fileName));
// Options?
bool flipTexture = true;
bool flipTexture = true;
bool switchHands = true; // when true: swap y and z for incoming files
float creaseAngle = 80.0f;
if (options) {
const std::string option = options->getOptionString();
if(option.find("rightHanded") != std::string::npos) {
switchHands=false;
}
if(option.find("leftHanded") != std::string::npos) {
switchHands=true;
}
if (option.find("flipTexture") != std::string::npos) {
flipTexture = false;
}
@ -107,7 +117,7 @@ osgDB::ReaderWriter::ReadResult ReaderWriterDirectX::readNode(const std::string&
}
// Convert to osg::Group
osg::Group* group = convertFromDX(obj, flipTexture, creaseAngle, local_opt.get());
osg::Group* group = convertFromDX(obj, switchHands, flipTexture, creaseAngle, local_opt.get());
if (!group) {
return ReadResult::ERROR_IN_READING_FILE;
}
@ -116,7 +126,7 @@ osgDB::ReaderWriter::ReadResult ReaderWriterDirectX::readNode(const std::string&
}
// Convert DirectX object
osg::Group * ReaderWriterDirectX::convertFromDX(DX::Object & obj,
osg::Group * ReaderWriterDirectX::convertFromDX(DX::Object & obj, bool switchHands,
bool flipTexture, float creaseAngle,
const osgDB::ReaderWriter::Options * options) const
{
@ -125,7 +135,7 @@ osg::Group * ReaderWriterDirectX::convertFromDX(DX::Object & obj,
for (unsigned int i = 0; i < obj.getNumMeshes(); ++i) {
//std::cerr << "converting mesh " << i << std::endl;
DX::Mesh & mesh = *obj.getMesh(i);
osg::Geode * geode = convertFromDX(mesh, flipTexture, creaseAngle, options);
osg::Geode * geode = convertFromDX(mesh, switchHands, flipTexture, creaseAngle, options);
if (!geode) {
return 0;
}
@ -136,7 +146,7 @@ osg::Group * ReaderWriterDirectX::convertFromDX(DX::Object & obj,
}
// Convert DirectX mesh to osg::Geode
osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Mesh & mesh,
osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Mesh & mesh, bool switchHands,
bool flipTexture, float creaseAngle,
const osgDB::ReaderWriter::Options * options) const
{
@ -170,6 +180,10 @@ osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Mesh & mesh,
* obj_y -> osg_z
* obj_z -> osg_y
*
* - aa: Changed always change left to right hand to an option that allows
* us to read right-handed models as-is. Our modeler is using XSI, which
* exports to right-handed system.
*
* - Polys are CW oriented
*/
std::vector<osg::Geometry*> geomList;
@ -294,29 +308,38 @@ osg::Geode* ReaderWriterDirectX::convertFromDX(DX::Mesh & mesh,
// Convert CW to CCW order
unsigned int jj = (j > 0 ? np - j : j);
if(!switchHands) jj=j;
// Vertices
unsigned int vi = faces[i][jj];
if (vertexArray) {
// Transform Xleft/Yup/Zinto to Xleft/Yinto/Zup
const DX::Vector & v = mesh.getVertices()[vi];
vertexArray->push_back(osg::Vec3(v.x,v.z,v.y));
if(switchHands)// Transform Xleft/Yup/Zinto to Xleft/Yinto/Zup
vertexArray->push_back(osg::Vec3(v.x,v.z,v.y));
else
vertexArray->push_back(osg::Vec3(v.x,v.y,v.z));
}
// Normals
unsigned int ni = meshNormals->faceNormals[i][jj];
if (normalArray) {
// Transform Xleft/Yup/Zinto to Xleft/Yinto/Zup
const DX::Vector& n = meshNormals->normals[ni];
normalArray->push_back(osg::Vec3(n.x,n.z,n.y));
if(switchHands)// Transform Xleft/Yup/Zinto to Xleft/Yinto/Zup
normalArray->push_back(osg::Vec3(n.x,n.z,n.y));
else
normalArray->push_back(osg::Vec3(n.x,n.y,n.z));
}
// TexCoords
if (texCoordArray) {
const DX::Coords2d& tc = (*meshTexCoords)[vi];
osg::Vec2 uv;
if (flipTexture)
uv.set(tc.u, 1.0f - tc.v); // Image is upside down
if (flipTexture){
if(switchHands)
uv.set(tc.u, 1.0f - tc.v); // Image is upside down
else
uv.set(1.0f - tc.u, 1.0f - tc.v); // Image is 180 degrees
}
else
uv.set(tc.u, tc.v);
texCoordArray->push_back(uv);

View File

@ -131,6 +131,7 @@ void Object::parseSection(ifstream& fin)
Mesh * mesh = new Mesh(this);
_meshes.push_back(mesh);
mesh->parseMesh(fin);
osg::notify(osg::INFO) << "Mesh " << (token.size()>1?token[1]:"") << endl;
}
else if (token[0] == "Material") {
//
@ -144,9 +145,11 @@ void Object::parseSection(ifstream& fin)
}
parseMaterial(fin, mm);
_globalMaterials.push_back(mm);
osg::notify(osg::INFO) << "Material " << (token.size()>1?token[1]:"") << endl;
}
else if (token[0] == "Frame") {
parseFrame(fin);
//parseFrame(fin);
parseSection(fin);
}
else {
//cerr << "!!! Begin section " << token[0] << endl;