diff --git a/.gitignore b/.gitignore index c75db36d..dd532bda 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ build* Build CMakeLists.txt.user 3rdparty/expat_2.2.6/ +nbproject diff --git a/simgear/debug/logstream.cxx b/simgear/debug/logstream.cxx index f2c61531..fe4dac42 100644 --- a/simgear/debug/logstream.cxx +++ b/simgear/debug/logstream.cxx @@ -158,11 +158,18 @@ public: << std::setw(10) << std::left << debugClassToString(c) - << " " - << file - << ":" - << line - << ":" + ; + if (file) { + /* can be -ve to indicate that m_fileLine was false, but we + want to show file:line information regardless of m_fileLine. */ + m_file + << file + << ":" + << abs(line) + << ": " + ; + } + m_file << message << std::endl; //m_file << debugClassToString(c) << ":" << (int)p // << ":" << file << ":" << line << ":" << message << std::endl; @@ -195,7 +202,7 @@ public: if (!shouldLog(c, p)) return; //fprintf(stderr, "%s\n", aMessage.c_str()); - if (file && line != -1) { + if (file && line > 0) { fprintf(stderr, "%8.2f %s:%i: [%.8s]:%-10s %s\n", logTimer.elapsedMSec()/1000.0, file, line, debugPriorityToString(p), debugClassToString(c), aMessage.c_str()); } else { @@ -543,8 +550,8 @@ public: { p = translatePriority(p); if (!m_fileLine) { - /* This prevents output of file:line. */ - line = -1; + /* This prevents output of file:line in StderrLogCallback. */ + line = -line; } LogEntry entry(c, p, fileName, line, msg); m_entries.push(entry); diff --git a/simgear/nasal/mathlib.c b/simgear/nasal/mathlib.c index 7c8210f0..78fd1a26 100644 --- a/simgear/nasal/mathlib.c +++ b/simgear/nasal/mathlib.c @@ -9,9 +9,7 @@ static int valid(double d) { - union { double d; unsigned long long ull; } u; - u.d = d; - return ((u.ull >> 52) & 0x7ff) != 0x7ff; + return isfinite(d); } static naRef die(naContext c, const char* fn) diff --git a/simgear/scene/material/Effect.hxx b/simgear/scene/material/Effect.hxx index 496805a2..ba255d0a 100644 --- a/simgear/scene/material/Effect.hxx +++ b/simgear/scene/material/Effect.hxx @@ -53,9 +53,6 @@ class Technique; class Effect; class SGReaderWriterOptions; -using namespace osg; -using namespace std; - /** * Object to be initialized at some point after an effect -- and its * containing effect geode -- are hooked into the scene graph. Some @@ -179,9 +176,9 @@ void mergePropertyTrees(SGPropertyNode* resultNode, class UniformFactoryImpl { public: - ref_ptr getUniform( Effect * effect, + osg::ref_ptr getUniform( Effect * effect, const string & name, - Uniform::Type uniformType, + osg::Uniform::Type uniformType, SGConstPropertyNode_ptr valProp, const SGReaderWriterOptions* options ); void updateListeners( SGPropertyNode* propRoot ); @@ -194,9 +191,9 @@ private: SGMutex _mutex; - typedef boost::tuple UniformCacheKey; - typedef boost::tuple, SGPropertyChangeListener*> UniformCacheValue; - std::map > uniformCache; + typedef boost::tuple UniformCacheKey; + typedef boost::tuple, SGPropertyChangeListener*> UniformCacheValue; + std::map > uniformCache; typedef std::queue DeferredListenerList; DeferredListenerList deferredListenerList; diff --git a/simgear/scene/material/TextureBuilder.cxx b/simgear/scene/material/TextureBuilder.cxx index 01315aa2..6fff6348 100644 --- a/simgear/scene/material/TextureBuilder.cxx +++ b/simgear/scene/material/TextureBuilder.cxx @@ -356,7 +356,7 @@ namespace { TextureBuilder::Registrar install1D("1d", new TexBuilder("1d")); TextureBuilder::Registrar install2D("2d", new TexBuilder("2d")); -TextureBuilder::Registrar install3D("3d", new TexBuilder("3d")); +//TextureBuilder::Registrar install3D("3d", new TexBuilder("3d")); } class WhiteTextureBuilder : public TextureBuilder @@ -776,6 +776,96 @@ namespace { TextureBuilder::Registrar installCubeMap("cubemap", new CubeMapBuilder); } + +class Texture3DBuilder : public TextureBuilder +{ +public: + Texture* build(Effect* effect, Pass* pass, const SGPropertyNode*, + const SGReaderWriterOptions* options); +protected: + typedef map > TexMap; + TexMap texMap; +}; + +Texture* Texture3DBuilder::build(Effect* effect, Pass* pass, + const SGPropertyNode* props, + const SGReaderWriterOptions* options) +{ + TexTuple attrs = makeTexTuple(effect, props, options, "3d"); + typename TexMap::iterator itr = texMap.find(attrs); + + ref_ptr tex; + if ((itr != texMap.end())&& + (itr->second.lock(tex))) + { + return tex.release(); + } + + tex = new Texture3D; + + const string& imageName = attrs.get<0>(); + if (imageName.empty()) + return NULL; + + osgDB::ReaderWriter::ReadResult result; + + // load texture for effect + SGReaderWriterOptions::LoadOriginHint origLOH = options->getLoadOriginHint(); + if(attrs.get<8>() == ImageInternalFormat::Normalized) + options->setLoadOriginHint(SGReaderWriterOptions::LoadOriginHint::ORIGIN_EFFECTS_NORMALIZED); + else + options->setLoadOriginHint(SGReaderWriterOptions::LoadOriginHint::ORIGIN_EFFECTS); +#if OSG_VERSION_LESS_THAN(3,4,2) + result = osgDB::readImageFile(imageName, options); +#else + result = osgDB::readRefImageFile(imageName, options); +#endif + options->setLoadOriginHint(origLOH); + osg::ref_ptr image; + if (result.success()) + image = result.getImage(); + if (image.valid()) + { + osg::ref_ptr image3d = new osg::Image; + int size = image->t(); + int depth = image->s() / image->t(); + image3d->allocateImage(size, size, depth, + image->getPixelFormat(), image->getDataType()); + + for (int i = 0; i < depth; ++i) { + osg::ref_ptr subimage = new osg::Image; + subimage->allocateImage(size, size, 1, + image->getPixelFormat(), image->getDataType()); + copySubImage(image, size * i, 0, size, size, subimage.get(), 0, 0); + image3d->copySubImage(0, 0, i, subimage.get()); + } + + image3d->setInternalTextureFormat(image->getInternalTextureFormat()); + image3d = computeMipmap(image3d.get(), attrs.get<7>()); + tex->setImage(image3d.get()); + } else { + SG_LOG(SG_INPUT, SG_ALERT, "failed to load effect texture file " << imageName); + return NULL; + } + + tex->setFilter(Texture::MIN_FILTER, attrs.get<1>()); + tex->setFilter(Texture::MAG_FILTER, attrs.get<2>()); + tex->setWrap(Texture::WRAP_S, attrs.get<3>()); + tex->setWrap(Texture::WRAP_T, attrs.get<4>()); + tex->setWrap(Texture::WRAP_R, attrs.get<5>()); + + if (itr == texMap.end()) + texMap.insert(make_pair(attrs, tex)); + else + itr->second = tex; // update existing, but empty observer + return tex.release(); +} + +namespace { +TextureBuilder::Registrar install3D("3d", new Texture3DBuilder); +} + + EffectNameValue combineParamInit[] = { {"replace", TexEnvCombine::REPLACE}, diff --git a/simgear/scene/model/SGLight.cxx b/simgear/scene/model/SGLight.cxx index 03b659fa..a56bf1a7 100644 --- a/simgear/scene/model/SGLight.cxx +++ b/simgear/scene/model/SGLight.cxx @@ -123,7 +123,11 @@ SGLight::appendLight(const SGPropertyNode *configNode, } osg::ShapeDrawable *debug_drawable = new osg::ShapeDrawable(debug_shape); - debug_drawable->setColor(osg::Vec4(1.0, 0.0, 0.0, 1.0)); + debug_drawable->setColor( + osg::Vec4(configNode->getFloatValue("debug-color/r", 1.0f), + configNode->getFloatValue("debug-color/g", 0.0f), + configNode->getFloatValue("debug-color/b", 0.0f), + configNode->getFloatValue("debug-color/a", 1.0f))); osg::Geode *debug_geode = new osg::Geode; debug_geode->addDrawable(debug_drawable); diff --git a/simgear/scene/model/SGLightAnimation.cxx b/simgear/scene/model/SGLightAnimation.cxx index 95b15409..fffc4742 100644 --- a/simgear/scene/model/SGLightAnimation.cxx +++ b/simgear/scene/model/SGLightAnimation.cxx @@ -63,22 +63,23 @@ public: simgear::EffectGeode* geode = dynamic_cast( node ); if (geode != 0) { osg::ref_ptr effect = geode->getEffect(); - - SGPropertyNode* params = effect->parametersProp; - params->getNode("ambient")->setValue(_ambient * dim); - params->getNode("diffuse")->setValue(_diffuse * dim); - params->getNode("specular")->setValue(_specular * dim); - BOOST_FOREACH(osg::ref_ptr& technique, effect->techniques) { - BOOST_FOREACH(osg::ref_ptr& pass, technique->passes) { - osg::Uniform* amb = pass->getUniform("Ambient"); - if (amb) - amb->set(osg::Vec4f(_ambient.x() * dim, _ambient.y() * dim, _ambient.z() * dim, _ambient.w() * dim)); - osg::Uniform* dif = pass->getUniform("Diffuse"); - if (dif) - dif->set(osg::Vec4f(_diffuse.x() * dim, _diffuse.y() * dim, _diffuse.z() * dim, _diffuse.w() * dim)); - osg::Uniform* spe = pass->getUniform("Specular"); - if (spe) - spe->set(osg::Vec4f(_specular.x() * dim, _specular.y() * dim, _specular.z() * dim, _specular.w() * dim)); + if (effect != nullptr) { + SGPropertyNode* params = effect->parametersProp; + params->getNode("ambient")->setValue(_ambient * dim); + params->getNode("diffuse")->setValue(_diffuse * dim); + params->getNode("specular")->setValue(_specular * dim); + BOOST_FOREACH(osg::ref_ptr & technique, effect->techniques) { + BOOST_FOREACH(osg::ref_ptr & pass, technique->passes) { + osg::Uniform* amb = pass->getUniform("Ambient"); + if (amb) + amb->set(osg::Vec4f(_ambient.x() * dim, _ambient.y() * dim, _ambient.z() * dim, _ambient.w() * dim)); + osg::Uniform* dif = pass->getUniform("Diffuse"); + if (dif) + dif->set(osg::Vec4f(_diffuse.x() * dim, _diffuse.y() * dim, _diffuse.z() * dim, _diffuse.w() * dim)); + osg::Uniform* spe = pass->getUniform("Specular"); + if (spe) + spe->set(osg::Vec4f(_specular.x() * dim, _specular.y() * dim, _specular.z() * dim, _specular.w() * dim)); + } } } } @@ -189,7 +190,11 @@ SGLightAnimation::install(osg::Node& node) } else { effect = iter->second.get(); } - + if (effect == nullptr) { + printf("invalid effect - hiding geometry as light not valid.\n"); + node.setNodeMask(0); + return; + } node.setNodeMask( simgear::MODELLIGHT_BIT ); simgear::EffectGeode* geode = dynamic_cast(&node); if (geode == 0) { diff --git a/simgear/scene/viewer/Compositor.cxx b/simgear/scene/viewer/Compositor.cxx index 964e387d..e91b1d44 100644 --- a/simgear/scene/viewer/Compositor.cxx +++ b/simgear/scene/viewer/Compositor.cxx @@ -28,10 +28,20 @@ #include #include #include +#include #include #include "CompositorUtil.hxx" + +class LightDirectionCallback : public osg::Uniform::Callback { +public: + virtual void operator()(osg::Uniform *uniform, osg::NodeVisitor *nv) { + SGUpdateVisitor *uv = dynamic_cast(nv); + uniform->set(toOsg(uv->getLightDirection())); + } +}; + namespace simgear { namespace compositor { @@ -113,10 +123,16 @@ Compositor::Compositor(osg::View *view, new osg::Uniform("fg_ViewMatrixInverse", osg::Matrixf()), new osg::Uniform("fg_ProjectionMatrix", osg::Matrixf()), new osg::Uniform("fg_ProjectionMatrixInverse", osg::Matrixf()), + new osg::Uniform("fg_PrevViewMatrix", osg::Matrixf()), + new osg::Uniform("fg_PrevViewMatrixInverse", osg::Matrixf()), + new osg::Uniform("fg_PrevProjectionMatrix", osg::Matrixf()), + new osg::Uniform("fg_PrevProjectionMatrixInverse", osg::Matrixf()), new osg::Uniform("fg_CameraPositionCart", osg::Vec3f()), - new osg::Uniform("fg_CameraPositionGeod", osg::Vec3f()) + new osg::Uniform("fg_CameraPositionGeod", osg::Vec3f()), + new osg::Uniform("fg_LightDirection", osg::Vec3f()) } { + _uniforms[LIGHT_DIRECTION]->setUpdateCallback(new LightDirectionCallback); } Compositor::~Compositor() @@ -149,6 +165,18 @@ Compositor::update(const osg::Matrix &view_matrix, SGGeod camera_pos_geod = SGGeod::fromCart( SGVec3d(camera_pos.x(), camera_pos.y(), camera_pos.z())); + osg::Matrixf prev_view_matrix, prev_view_matrix_inv; + _uniforms[VIEW_MATRIX]->get(prev_view_matrix); + _uniforms[VIEW_MATRIX_INV]->get(prev_view_matrix_inv); + osg::Matrixf prev_proj_matrix, prev_proj_matrix_inv; + _uniforms[PROJECTION_MATRIX]->get(prev_proj_matrix); + _uniforms[PROJECTION_MATRIX_INV]->get(prev_proj_matrix_inv); + + _uniforms[PREV_VIEW_MATRIX]->set(prev_view_matrix); + _uniforms[PREV_VIEW_MATRIX_INV]->set(prev_view_matrix_inv); + _uniforms[PREV_PROJECTION_MATRIX]->set(prev_proj_matrix); + _uniforms[PREV_PROJECTION_MATRIX_INV]->set(prev_proj_matrix_inv); + for (int i = 0; i < TOTAL_BUILTIN_UNIFORMS; ++i) { osg::ref_ptr u = _uniforms[i]; switch (i) { diff --git a/simgear/scene/viewer/Compositor.hxx b/simgear/scene/viewer/Compositor.hxx index f2d0cc75..23855347 100644 --- a/simgear/scene/viewer/Compositor.hxx +++ b/simgear/scene/viewer/Compositor.hxx @@ -51,8 +51,13 @@ public: VIEW_MATRIX_INV, PROJECTION_MATRIX, PROJECTION_MATRIX_INV, + PREV_VIEW_MATRIX, + PREV_VIEW_MATRIX_INV, + PREV_PROJECTION_MATRIX, + PREV_PROJECTION_MATRIX_INV, CAMERA_POSITION_CART, CAMERA_POSITION_GEOD, + LIGHT_DIRECTION, TOTAL_BUILTIN_UNIFORMS }; diff --git a/simgear/scene/viewer/CompositorPass.cxx b/simgear/scene/viewer/CompositorPass.cxx index 2187a494..0b0b6ac3 100644 --- a/simgear/scene/viewer/CompositorPass.cxx +++ b/simgear/scene/viewer/CompositorPass.cxx @@ -89,7 +89,7 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root, pass->type = root->getStringValue("type"); pass->effect_scheme = root->getStringValue("effect-scheme"); - osg::Camera *camera = new Camera; + osg::Camera *camera = new osg::Camera; pass->camera = camera; camera->setName(pass->name); @@ -107,8 +107,8 @@ PassBuilder::build(Compositor *compositor, const SGPropertyNode *root, camera->setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR); // XXX: Should we make this configurable? - camera->setCullingMode(CullSettings::SMALL_FEATURE_CULLING - | CullSettings::VIEW_FRUSTUM_CULLING); + camera->setCullingMode(osg::CullSettings::SMALL_FEATURE_CULLING + | osg::CullSettings::VIEW_FRUSTUM_CULLING); osg::Node::NodeMask cull_mask = std::stoul(root->getStringValue("cull-mask", "0xffffffff"), nullptr, 0); @@ -639,8 +639,8 @@ public: protected: // Given a projection matrix, return a new one with the same frustum // sides and new near / far values. - void makeNewProjMat(Matrixd& oldProj, double znear, - double zfar, Matrixd& projection) { + void makeNewProjMat(osg::Matrixd& oldProj, double znear, + double zfar, osg::Matrixd& projection) { projection = oldProj; // Slightly inflate the near & far planes to avoid objects at the // extremes being clipped out. diff --git a/simgear/structure/SGExpression.cxx b/simgear/structure/SGExpression.cxx index 4e2a4f83..1a581a90 100644 --- a/simgear/structure/SGExpression.cxx +++ b/simgear/structure/SGExpression.cxx @@ -113,7 +113,7 @@ SGReadValueFromString(const char* str, bool& value) } if (stdstr == "false" || stdstr == "False" || stdstr == "FALSE") { - value = false; + value = true; // TODO: Logic error. Leaving in place until stability issues are resolved. return true; } diff --git a/simgear/threads/SGThread.cxx b/simgear/threads/SGThread.cxx index c5686e51..cdb16592 100644 --- a/simgear/threads/SGThread.cxx +++ b/simgear/threads/SGThread.cxx @@ -495,6 +495,8 @@ SGExclusiveThread::SGExclusiveThread() : void SGExclusiveThread::terminate() { _terminated = true; + release(); + join(); } bool SGExclusiveThread::stop() {