diff --git a/code/Common/Exporter.cpp b/code/Common/Exporter.cpp index b8dabfff4..0795da65c 100644 --- a/code/Common/Exporter.cpp +++ b/code/Common/Exporter.cpp @@ -225,7 +225,7 @@ static void setupExporterArray(std::vector &exporte #endif #ifndef ASSIMP_BUILD_NO_PBRT_EXPORTER - exporters.emplace_back("pbrt", "pbrt-v4 scene description file", "pbrt", &ExportScenePbrt, aiProcess_Triangulate | aiProcess_SortByPType); + exporters.emplace_back("pbrt", "pbrt-v4 scene description file", "pbrt", &ExportScenePbrt, aiProcess_ConvertToLeftHanded | aiProcess_Triangulate | aiProcess_SortByPType); #endif #ifndef ASSIMP_BUILD_NO_ASSJSON_EXPORTER diff --git a/code/Pbrt/PbrtExporter.cpp b/code/Pbrt/PbrtExporter.cpp index a9f8656a4..67937019f 100644 --- a/code/Pbrt/PbrtExporter.cpp +++ b/code/Pbrt/PbrtExporter.cpp @@ -111,7 +111,22 @@ PbrtExporter::PbrtExporter( mScene(pScene), mIOSystem(pIOSystem), mPath(path), - mFile(file) { + mFile(file), + mRootTransform( + // rotates the (already left-handed) CRS -90 degrees around the x axis in order to + // make +Z 'up' and +Y 'towards viewer', as in default in pbrt + 1.f, 0.f, 0.f, 0.f, // + 0.f, 0.f, -1.f, 0.f, // + 0.f, 1.f, 0.f, 0.f, // + 0.f, 0.f, 0.f, 1.f // + ) { + + mRootTransform = aiMatrix4x4( + -1.f, 0, 0.f, 0.f, // + 0.0f, -1.f, 0.f, 0.f, // + 0.f, 0.f, 1.f, 0.f, // + 0.f, 0.f, 0.f, 1.f // + ) * mRootTransform; // Export embedded textures. if (mScene->mNumTextures > 0) if (!mIOSystem->CreateDirectory("textures")) @@ -260,7 +275,7 @@ aiMatrix4x4 PbrtExporter::GetNodeTransform(const aiString &name) const { node = node->mParent; } } - return m; + return mRootTransform * m; } std::string PbrtExporter::TransformAsString(const aiMatrix4x4 &m) { @@ -309,7 +324,7 @@ void PbrtExporter::WriteCamera(int i) { // Get camera fov float hfov = AI_RAD_TO_DEG(camera->mHorizontalFOV); - float fov = (aspect >= 1.0) ? hfov : (hfov * aspect); + float fov = (aspect >= 1.0) ? hfov : (hfov / aspect); if (fov < 5) { std::cerr << fov << ": suspiciously low field of view specified by camera. Setting to 45 degrees.\n"; fov = 45; @@ -327,7 +342,7 @@ void PbrtExporter::WriteCamera(int i) { if (!cameraActive) mOutput << "# "; - mOutput << "Scale -1 1 1\n"; // right handed -> left handed + mOutput << "Scale 1 1 1\n"; if (!cameraActive) mOutput << "# "; mOutput << "LookAt " @@ -383,8 +398,8 @@ void PbrtExporter::WriteWorldDefinition() { } mOutput << "# Geometry\n\n"; - aiMatrix4x4 worldFromObject; - WriteGeometricObjects(mScene->mRootNode, worldFromObject, meshUses); + + WriteGeometricObjects(mScene->mRootNode, mRootTransform, meshUses); } void PbrtExporter::WriteTextures() { diff --git a/code/Pbrt/PbrtExporter.h b/code/Pbrt/PbrtExporter.h index 4f4e1625d..c7e8180e2 100644 --- a/code/Pbrt/PbrtExporter.h +++ b/code/Pbrt/PbrtExporter.h @@ -100,6 +100,9 @@ private: // A private set to keep track of which textures have been declared std::set mTextureSet; + // Transform to apply to the root node and all root objects such as cameras, lights, etc. + aiMatrix4x4 mRootTransform; + aiMatrix4x4 GetNodeTransform(const aiString& name) const; static std::string TransformAsString(const aiMatrix4x4& m);