From 59cf5a8a3e493f4a3d646ca4e4f81d6420f0451e Mon Sep 17 00:00:00 2001 From: Wenzel Jakob Date: Mon, 16 Aug 2010 11:09:02 +0200 Subject: [PATCH] Handle broken blender 2.5 DAE files --- src/collada/converter.cpp | 62 +++++++++++++++++++++++++++++++-------- src/collada/converter.h | 3 ++ src/collada/main.cpp | 10 ++++++- 3 files changed, 62 insertions(+), 13 deletions(-) diff --git a/src/collada/converter.cpp b/src/collada/converter.cpp index 9d15df51..175ad4e2 100644 --- a/src/collada/converter.cpp +++ b/src/collada/converter.cpp @@ -645,6 +645,15 @@ void loadLight(Transform transform, std::ostream &os, domLight &light) { domLight::domTechnique_common::domPoint *point = light.getTechnique_common()->getPoint().cast(); if (point) { + bool notQuadratic = false; + if (point->getConstant_attenuation() && point->getConstant_attenuation()->getValue() != 1) + notQuadratic = true; + if (point->getLinear_attenuation() && point->getLinear_attenuation()->getValue() != 0) + notQuadratic = true; + if (point->getQuadratic_attenuation() && point->getQuadratic_attenuation()->getValue() != 1) + notQuadratic = true; + if (notQuadratic) + SLog(EWarn, "Point light \"%s\" is not a quadratic light! Treating it as one -- expect problems.", light.getId()); domFloat3 &color = point->getColor()->getValue(); os << "\t" << endl; os << "\t\t" << endl << endl; @@ -667,6 +676,15 @@ void loadLight(Transform transform, std::ostream &os, domLight &light) { domLight::domTechnique_common::domSpot *spot = light.getTechnique_common()->getSpot().cast(); if (spot) { + bool notQuadratic = false; + if (spot->getConstant_attenuation() && spot->getConstant_attenuation()->getValue() != 1) + notQuadratic = true; + if (spot->getLinear_attenuation() && spot->getLinear_attenuation()->getValue() != 0) + notQuadratic = true; + if (spot->getQuadratic_attenuation() && spot->getQuadratic_attenuation()->getValue() != 1) + notQuadratic = true; + if (notQuadratic) + SLog(EWarn, "Spot light \"%s\" is not a quadratic light! Treating it as one -- expect problems.", light.getId()); domFloat3 &color = spot->getColor()->getValue(); Float falloffAngle = 180.0f; if (spot->getFalloff_angle()) @@ -758,32 +776,52 @@ void loadCamera(ColladaConverter *cvt, Transform transform, std::ostream &os, do domCamera::domOptics::domTechnique_common::domPerspective* persp = camera.getOptics()-> getTechnique_common()->getPerspective().cast(); if (persp) { - if (persp->getAspect_ratio().cast() != 0) - aspect = (Float) persp->getAspect_ratio()->getValue(); if (cvt->m_xres != -1) { xres = cvt->m_xres; aspect = (Float) cvt->m_xres / (Float) cvt->m_yres; + } else { + if (persp->getAspect_ratio().cast() != 0) { + aspect = (Float) persp->getAspect_ratio()->getValue(); + if (std::abs(aspect-0.1) < Epsilon) { + SLog(EWarn, "Found the suspicious aspect ratio \"0.1\", which is likely due to a bug in Blender 2.5" + " - setting to 1.0. Please use the \"-r\" parameter to override the resolution."); + aspect = 1.0f; + } + } } os << "\t" << endl; if (persp->getXfov().cast()) { - Float yFov = radToDeg(2 * std::atan(std::tan(degToRad((Float) persp->getXfov()->getValue())/2) / aspect)); + Float xFov = persp->getXfov()->getValue(); + if (std::abs(xFov-1.0f) < Epsilon && cvt->m_fov == -1) { + SLog(EWarn, "Found the suspicious field of view value \"1.0\", which is likely due to a bug in Blender 2.5" + " - setting to 45deg. Please use the \"-f\" parameter to override this."); + xFov = 45.0f; + } + Float yFov = radToDeg(2 * std::atan(std::tan(degToRad(xFov)/1) / aspect)); + if (cvt->m_fov != -1) + xFov = yFov = cvt->m_fov; if (aspect <= 1.0f) - os << "\t\tgetXfov()->getValue() << "\"/>" << endl; + os << "\t\t" << endl; else os << "\t\t" << endl; - os << "\t\tgetZnear()->getValue() << "\"/>" << endl; - os << "\t\tgetZfar()->getValue() << "\"/>" << endl; - os << "\t\tm_mapSmallerSide ? "true" : "false") << "\"/>" << endl; } else if (persp->getYfov().cast()) { - Float xFov = radToDeg(2 * std::atan(std::tan(degToRad((Float) persp->getYfov()->getValue())/2) * aspect)); + Float yFov = persp->getYfov()->getValue(); + if (std::abs(yFov-1.0) < Epsilon && cvt->m_fov == -1) { + SLog(EWarn, "Found the suspicious field of view value \"1.0\", which is likely due to a bug in Blender 2.5" + " - setting to 45deg. Please use the \"-f\" parameter to override this."); + yFov = 45.0f; + } + Float xFov = radToDeg(2 * std::atan(std::tan(degToRad(yFov)/2) * aspect)); + if (cvt->m_fov != -1) + xFov = yFov = cvt->m_fov; if (aspect > 1.0f) - os << "\t\tgetYfov()->getValue() << "\"/>" << endl; + os << "\t\t" << endl; else os << "\t\t" << endl; - os << "\t\tgetZnear()->getValue() << "\"/>" << endl; - os << "\t\tgetZfar()->getValue() << "\"/>" << endl; - os << "\t\tm_mapSmallerSide ? "true" : "false") << "\"/>" << endl; } + os << "\t\tgetZnear()->getValue() << "\"/>" << endl; + os << "\t\tgetZfar()->getValue() << "\"/>" << endl; + os << "\t\tm_mapSmallerSide ? "true" : "false") << "\"/>" << endl; } os << endl; diff --git a/src/collada/converter.h b/src/collada/converter.h index 6dcb92e2..229a208a 100644 --- a/src/collada/converter.h +++ b/src/collada/converter.h @@ -9,6 +9,7 @@ public: m_mapSmallerSide = true; m_xres = m_yres = -1; m_samplesPerPixel = 8; + m_fov = -1; } void convert(const std::string &inputFile, @@ -22,9 +23,11 @@ public: inline void setMapSmallerSide(bool mapSmallerSide) { m_mapSmallerSide = mapSmallerSide; } inline void setResolution(int xres, int yres) { m_xres = xres; m_yres = yres; } inline void setSamplesPerPixel(int samplesPerPixel) { m_samplesPerPixel = samplesPerPixel; } + inline void setFov(Float fov) { m_fov = fov; } inline const std::string &getFilename() const { return m_filename; } public: bool m_srgb, m_mapSmallerSide; int m_xres, m_yres, m_samplesPerPixel; + Float m_fov; std::string m_filename; }; diff --git a/src/collada/main.cpp b/src/collada/main.cpp index 477833c6..64083a46 100644 --- a/src/collada/main.cpp +++ b/src/collada/main.cpp @@ -56,6 +56,7 @@ void help() { << " -s Assume that colors are in sRGB space." << endl << endl << " -m Map the larger image side to the full field of view" << endl << endl << " -r x Override the image resolution to e.g. 1920×1080" << endl << endl + << " -f Override the field of view to the given value specified in degrees." << endl << endl << "Please see the documentation for more information." << endl; } @@ -64,10 +65,11 @@ int colladaMain(int argc, char **argv) { char optchar, *end_ptr = NULL; int xres = -1, yres = -1; int samplesPerPixel = 8; + Float fov = -1; optind = 1; - while ((optchar = getopt(argc, argv, "shmr:p:")) != -1) { + while ((optchar = getopt(argc, argv, "shmr:p:f:")) != -1) { switch (optchar) { case 's': srgb = true; @@ -80,6 +82,11 @@ int colladaMain(int argc, char **argv) { if (*end_ptr != '\0') SLog(EError, "Invalid number of samples per pixel!"); break; + case 'f': + fov = strtod(optarg, &end_ptr); + if (*end_ptr != '\0') + SLog(EError, "Invalid field of view value!"); + break; case 'r': { std::vector tokens = tokenize(optarg, "x"); if (tokens.size() != 2) @@ -109,6 +116,7 @@ int colladaMain(int argc, char **argv) { converter.setResolution(xres, yres); converter.setMapSmallerSide(mapSmallerSide); converter.setSamplesPerPixel(samplesPerPixel); + converter.setFov(fov); converter.convert(argv[optind], "", argv[optind+1], argc > optind+2 ? argv[optind+2] : ""); return 0;