Compare commits
11 Commits
version/20
...
version/20
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
711cc512c5 | ||
|
|
d0dee701a9 | ||
|
|
e87a671942 | ||
|
|
234abdf85c | ||
|
|
e5bef3f97f | ||
|
|
af0f7676c4 | ||
|
|
a3bdfab17b | ||
|
|
44bae773a0 | ||
|
|
5fe527a2d1 | ||
|
|
b79f03c96c | ||
|
|
631fa62495 |
@@ -1 +1 @@
|
||||
2020.3.11
|
||||
2020.3.13
|
||||
|
||||
@@ -298,8 +298,8 @@ namespace canvas
|
||||
{
|
||||
if( camera.valid() && Canvas::getSystemAdapter() )
|
||||
Canvas::getSystemAdapter()->removeCamera(camera.get());
|
||||
camera.release();
|
||||
texture.release();
|
||||
camera = nullptr;
|
||||
texture = nullptr;
|
||||
|
||||
_flags &= ~AVAILABLE;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <simgear_config.h>
|
||||
|
||||
#include "ErrorReportingCallback.hxx"
|
||||
#include "logstream.hxx"
|
||||
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
|
||||
@@ -27,6 +28,31 @@ static ErrorReportCallback static_callback;
|
||||
static ContextCallback static_contextCallback;
|
||||
|
||||
|
||||
string_list static_errorNames = {
|
||||
"shader/effect",
|
||||
"loading texture",
|
||||
"XML/animation load",
|
||||
"3D model load",
|
||||
"loading BTG",
|
||||
"sceanrio load",
|
||||
"UI dialog load",
|
||||
"loading Audio/FX",
|
||||
"Nasal/commnad load of XML",
|
||||
"aircraft-systems",
|
||||
"loading input/joystick config",
|
||||
"load AI/traffic",
|
||||
"from TerraSync"};
|
||||
|
||||
string_list static_errorTypeNames = {
|
||||
"unknown",
|
||||
"not found",
|
||||
"out of memory",
|
||||
"bad header",
|
||||
"bad data",
|
||||
"misconfigured",
|
||||
"disk IO/permissions",
|
||||
"network IO"};
|
||||
|
||||
void setErrorReportCallback(ErrorReportCallback cb)
|
||||
{
|
||||
static_callback = cb;
|
||||
@@ -53,6 +79,7 @@ static FailureCallback static_failureCallback;
|
||||
void reportFailure(LoadFailure type, ErrorCode code, const std::string& details, sg_location loc)
|
||||
{
|
||||
if (!static_failureCallback) {
|
||||
SG_LOG(SG_GENERAL, SG_WARN, "Error:" << static_errorTypeNames.at(static_cast<int>(type)) << " from " << static_errorNames.at(static_cast<int>(code)) << "::" << details << "\n\t" << loc.asString());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -62,6 +89,9 @@ void reportFailure(LoadFailure type, ErrorCode code, const std::string& details,
|
||||
void reportFailure(LoadFailure type, ErrorCode code, const std::string& details, const SGPath& path)
|
||||
{
|
||||
if (!static_failureCallback) {
|
||||
// if no callback is registered, log here instead
|
||||
SG_LOG(SG_GENERAL, SG_WARN, "Error:" << static_errorTypeNames.at(static_cast<int>(type)) << " from " << static_errorNames.at(static_cast<int>(code)) << "::" << details << "\n\t" << path);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,6 +74,22 @@ public:
|
||||
return _value;
|
||||
}
|
||||
|
||||
const T& value_or(const T& defaultValue) const
|
||||
{
|
||||
if (!_haveValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
T& value_or(T& defaultValue) const
|
||||
{
|
||||
if (!_haveValue) {
|
||||
return defaultValue;
|
||||
}
|
||||
return _value;
|
||||
}
|
||||
|
||||
T& value()
|
||||
{
|
||||
if (!_haveValue) {
|
||||
|
||||
@@ -160,7 +160,8 @@ size_t hash_value(const Effect::Key&);
|
||||
|
||||
Effect* makeEffect(const std::string& name,
|
||||
bool realizeTechniques,
|
||||
const SGReaderWriterOptions* options);
|
||||
const SGReaderWriterOptions* options,
|
||||
const SGPath& modelPath = SGPath{});
|
||||
|
||||
Effect* makeEffect(SGPropertyNode* prop,
|
||||
bool realizeTechniques,
|
||||
|
||||
@@ -114,7 +114,8 @@ void mergePropertyTrees(SGPropertyNode* resultNode,
|
||||
|
||||
Effect* makeEffect(const string& name,
|
||||
bool realizeTechniques,
|
||||
const SGReaderWriterOptions* options)
|
||||
const SGReaderWriterOptions* options,
|
||||
const SGPath& modelPath)
|
||||
{
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::ReentrantMutex> lock(effectMutex);
|
||||
@@ -125,8 +126,7 @@ Effect* makeEffect(const string& name,
|
||||
}
|
||||
string effectFileName(name);
|
||||
effectFileName += ".eff";
|
||||
string absFileName
|
||||
= SGModelLib::findDataFile(effectFileName, options);
|
||||
string absFileName = SGModelLib::findDataFile(effectFileName, options, modelPath);
|
||||
if (absFileName.empty()) {
|
||||
simgear::reportFailure(simgear::LoadFailure::NotFound, simgear::ErrorCode::LoadEffectsShaders, "Couldn't find Effect:" + effectFileName);
|
||||
return nullptr;
|
||||
@@ -197,7 +197,7 @@ Effect* makeEffect(SGPropertyNode* prop,
|
||||
Effect* parent = 0;
|
||||
if (inheritProp) {
|
||||
//prop->removeChild("inherits-from");
|
||||
parent = makeEffect(inheritProp->getStringValue(), false, options);
|
||||
parent = makeEffect(inheritProp->getStringValue(), false, options, filePath);
|
||||
if (parent) {
|
||||
Effect::Key key;
|
||||
key.unmerged = prop;
|
||||
|
||||
@@ -83,6 +83,8 @@ bool SGMaterialLib::load( const SGPath &fg_root, const SGPath& mpath,
|
||||
options->setObjectCacheHint(osgDB::Options::CACHE_ALL);
|
||||
options->setDatabasePath(fg_root.utf8Str());
|
||||
|
||||
std::lock_guard<std::mutex> g(d->mutex);
|
||||
|
||||
simgear::PropertyList blocks = materialblocks.getChildren("region");
|
||||
simgear::PropertyList::const_iterator block_iter = blocks.begin();
|
||||
|
||||
@@ -153,14 +155,20 @@ bool SGMaterialLib::load( const SGPath &fg_root, const SGPath& mpath,
|
||||
|
||||
// find a material record by material name and tile center
|
||||
SGMaterial *SGMaterialLib::find( const string& material, const SGVec2f center ) const
|
||||
{
|
||||
std::lock_guard<std::mutex> g(d->mutex);
|
||||
return internalFind(material, center);
|
||||
}
|
||||
|
||||
SGMaterial* SGMaterialLib::internalFind(const string& material, const SGVec2f center) const
|
||||
{
|
||||
SGMaterial *result = NULL;
|
||||
const_material_map_iterator it = matlib.find( material );
|
||||
if ( it != end() ) {
|
||||
if (it != end()) {
|
||||
// We now have a list of materials that match this
|
||||
// name. Find the first one that matches.
|
||||
// We start at the end of the list, as the materials
|
||||
// list is ordered with the smallest regions at the end.
|
||||
// We start at the end of the list, as the materials
|
||||
// list is ordered with the smallest regions at the end.
|
||||
material_list::const_reverse_iterator iter = it->second.rbegin();
|
||||
while (iter != it->second.rend()) {
|
||||
result = *iter;
|
||||
@@ -184,11 +192,12 @@ SGMaterial *SGMaterialLib::find( const string& material, const SGGeod& center )
|
||||
SGMaterialCache *SGMaterialLib::generateMatCache(SGVec2f center)
|
||||
{
|
||||
SGMaterialCache* newCache = new SGMaterialCache();
|
||||
std::lock_guard<std::mutex> g(d->mutex);
|
||||
|
||||
material_map::const_reverse_iterator it = matlib.rbegin();
|
||||
for (; it != matlib.rend(); ++it) {
|
||||
newCache->insert(it->first, find(it->first, center));
|
||||
newCache->insert(it->first, internalFind(it->first, center));
|
||||
}
|
||||
|
||||
return newCache;
|
||||
}
|
||||
|
||||
|
||||
@@ -81,7 +81,10 @@ private:
|
||||
typedef material_map::const_iterator const_material_map_iterator;
|
||||
|
||||
material_map matlib;
|
||||
|
||||
|
||||
|
||||
SGMaterial* internalFind(const std::string& material, const SGVec2f center) const;
|
||||
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
|
||||
@@ -559,8 +559,8 @@ sgLoad3DModel_internal(const SGPath& path,
|
||||
// Some material animations (eventually all) are actually effects.
|
||||
makeEffectAnimations(animation_nodes, effect_nodes);
|
||||
{
|
||||
ref_ptr<Node> modelWithEffects
|
||||
= instantiateEffects(group.get(), effect_nodes, options.get());
|
||||
ref_ptr<Node> modelWithEffects = instantiateEffects(group.get(), effect_nodes, options.get(),
|
||||
path.dirPath());
|
||||
group = static_cast<Group*>(modelWithEffects.get());
|
||||
}
|
||||
|
||||
|
||||
@@ -16,23 +16,27 @@
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
//
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <simgear_config.h>
|
||||
#endif
|
||||
#include <simgear_config.h>
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include "SGText.hxx"
|
||||
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/misc/strutils.hxx>
|
||||
|
||||
#include <osg/Geode>
|
||||
#include <osg/MatrixTransform>
|
||||
#include <osgText/Text>
|
||||
#include <osgText/Font>
|
||||
|
||||
#include <simgear/misc/ResourceManager.hxx>
|
||||
#include <simgear/math/SGMath.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/misc/strutils.hxx>
|
||||
#include <simgear/scene/material/Effect.hxx>
|
||||
#include <simgear/scene/material/EffectGeode.hxx>
|
||||
#include <simgear/scene/util/SGReaderWriterOptions.hxx>
|
||||
#include <simgear/debug/ErrorReportingCallback.hxx>
|
||||
|
||||
using std::string;
|
||||
|
||||
class SGText::UpdateCallback : public osg::NodeCallback {
|
||||
@@ -95,9 +99,15 @@ osg::Node * SGText::appendText(const SGPropertyNode* configNode,
|
||||
osg::Geode * g = new osg::Geode;
|
||||
g->addDrawable( text );
|
||||
|
||||
SGPath path("Fonts" );
|
||||
path.append( configNode->getStringValue( "font", "Helvetica" ));
|
||||
text->setFont( path.utf8Str() );
|
||||
const std::string requestedFont = configNode->getStringValue("font","Helvetica");
|
||||
const SGPath fontPath = simgear::ResourceManager::instance()->findPath("Fonts/" + requestedFont);
|
||||
if ( !fontPath.isNull() ) {
|
||||
text->setFont( fontPath.utf8Str() );
|
||||
} else {
|
||||
simgear::reportFailure(simgear::LoadFailure::NotFound,
|
||||
simgear::ErrorCode::LoadingTexture,
|
||||
"SGText: couldn;t find font:" + requestedFont);
|
||||
}
|
||||
|
||||
text->setCharacterSize(configNode->getDoubleValue("character-size", 1.0 ),
|
||||
configNode->getDoubleValue("character-aspect-ratio", 1.0 ));
|
||||
|
||||
@@ -234,7 +234,7 @@ public:
|
||||
typedef std::map<string, SGPropertyNode_ptr> EffectMap;
|
||||
using SplicingVisitor::apply;
|
||||
MakeEffectVisitor(const SGReaderWriterOptions* options = 0)
|
||||
: _options(options)
|
||||
: _options(options), _modelPath(SGPath{})
|
||||
{
|
||||
}
|
||||
virtual void apply(osg::Group& node);
|
||||
@@ -246,10 +246,17 @@ public:
|
||||
_currentEffectParent = effect;
|
||||
}
|
||||
SGPropertyNode* getDefaultEffect() { return _currentEffectParent; }
|
||||
|
||||
void setModelPath(const SGPath& p)
|
||||
{
|
||||
_modelPath = p;
|
||||
}
|
||||
|
||||
protected:
|
||||
EffectMap _effectMap;
|
||||
SGPropertyNode_ptr _currentEffectParent;
|
||||
osg::ref_ptr<const SGReaderWriterOptions> _options;
|
||||
SGPath _modelPath;
|
||||
};
|
||||
|
||||
void MakeEffectVisitor::apply(osg::Group& node)
|
||||
@@ -287,7 +294,7 @@ void MakeEffectVisitor::apply(osg::Geode& geode)
|
||||
makeParametersFromStateSet(ssRoot, ss);
|
||||
SGPropertyNode_ptr effectRoot = new SGPropertyNode;
|
||||
effect::mergePropertyTrees(effectRoot, ssRoot, _currentEffectParent);
|
||||
Effect* effect = makeEffect(effectRoot, true, _options.get());
|
||||
Effect* effect = makeEffect(effectRoot, true, _options.get(), _modelPath);
|
||||
EffectGeode* eg = dynamic_cast<EffectGeode*>(&geode);
|
||||
if (eg) {
|
||||
eg->setEffect(effect);
|
||||
@@ -332,7 +339,8 @@ protected:
|
||||
|
||||
ref_ptr<Node> instantiateEffects(osg::Node* modelGroup,
|
||||
PropertyList& effectProps,
|
||||
const SGReaderWriterOptions* options)
|
||||
const SGReaderWriterOptions* options,
|
||||
const SGPath& modelPath)
|
||||
{
|
||||
SGPropertyNode_ptr defaultEffectPropRoot;
|
||||
MakeEffectVisitor visitor(options);
|
||||
@@ -357,13 +365,15 @@ ref_ptr<Node> instantiateEffects(osg::Node* modelGroup,
|
||||
if (!defaultEffectPropRoot)
|
||||
defaultEffectPropRoot = DefaultEffect::instance()->getEffect();
|
||||
visitor.setDefaultEffect(defaultEffectPropRoot.ptr());
|
||||
visitor.setModelPath(modelPath);
|
||||
modelGroup->accept(visitor);
|
||||
osg::NodeList& result = visitor.getResults();
|
||||
return ref_ptr<Node>(result[0].get());
|
||||
}
|
||||
|
||||
ref_ptr<Node> instantiateMaterialEffects(osg::Node* modelGroup,
|
||||
const SGReaderWriterOptions* options)
|
||||
const SGReaderWriterOptions* options,
|
||||
const SGPath& modelPath)
|
||||
{
|
||||
|
||||
SGPropertyNode_ptr effect;
|
||||
@@ -390,7 +400,7 @@ ref_ptr<Node> instantiateMaterialEffects(osg::Node* modelGroup,
|
||||
|
||||
effect->addChild("default")->setBoolValue(true);
|
||||
effectProps.push_back(effect);
|
||||
return instantiateEffects(modelGroup, effectProps, options);
|
||||
return instantiateEffects(modelGroup, effectProps, options, modelPath);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -102,7 +102,8 @@ public:
|
||||
osg::ref_ptr<osg::Node>
|
||||
instantiateEffects(osg::Node* model,
|
||||
PropertyList& effectProps,
|
||||
const SGReaderWriterOptions* options);
|
||||
const SGReaderWriterOptions* options,
|
||||
const SGPath& currentDir = SGPath{});
|
||||
|
||||
/**
|
||||
* Apply a set of material-defined effects to a model
|
||||
@@ -112,9 +113,10 @@ instantiateEffects(osg::Node* model,
|
||||
*
|
||||
* returns a copy if any nodes are changed
|
||||
*/
|
||||
osg::ref_ptr<osg::Node>
|
||||
instantiateMaterialEffects(osg::Node* model,
|
||||
const SGReaderWriterOptions* options);
|
||||
osg::ref_ptr<osg::Node>
|
||||
instantiateMaterialEffects(osg::Node* model,
|
||||
const SGReaderWriterOptions* options,
|
||||
const SGPath& modelPath = SGPath{});
|
||||
|
||||
/**
|
||||
* Transform an OSG subgraph by substituting the Effects and
|
||||
@@ -127,10 +129,11 @@ instantiateEffects(osg::Node* model,
|
||||
|
||||
inline osg::ref_ptr<osg::Node>
|
||||
instantiateEffects(osg::Node* model,
|
||||
const SGReaderWriterOptions* options)
|
||||
const SGReaderWriterOptions* options,
|
||||
const SGPath& currentDir = SGPath{})
|
||||
{
|
||||
PropertyList effectProps;
|
||||
return instantiateEffects(model, effectProps, options);
|
||||
return instantiateEffects(model, effectProps, options, currentDir);
|
||||
}
|
||||
}
|
||||
#endif // __MODEL_HXX
|
||||
|
||||
@@ -512,6 +512,14 @@ void Particles::setupStaticColorComponent(float r1, float g1, float b1, float a1
|
||||
staticColorComponents[7] = a2;
|
||||
}
|
||||
|
||||
ParticlesGlobalManager::~ParticlesGlobalManager()
|
||||
{
|
||||
// break a ref-counting cycle
|
||||
if (d->_commonRoot) {
|
||||
d->_commonRoot->removeUpdateCallback(d.get());
|
||||
}
|
||||
}
|
||||
|
||||
void ParticlesGlobalManager::setWindVector(const osg::Vec3& wind)
|
||||
{
|
||||
std::lock_guard<std::mutex> g(d->_lock);
|
||||
|
||||
@@ -150,7 +150,7 @@ protected:
|
||||
class ParticlesGlobalManager
|
||||
{
|
||||
public:
|
||||
~ParticlesGlobalManager() = default;
|
||||
~ParticlesGlobalManager();
|
||||
|
||||
static ParticlesGlobalManager* instance();
|
||||
static void clear();
|
||||
|
||||
@@ -267,12 +267,12 @@ public:
|
||||
SGVec2f texCoord = a*t0 + b*t1 + c*t2;
|
||||
|
||||
// Check this random point against the object mask
|
||||
// red channel.
|
||||
// blue channel.
|
||||
osg::Image* img = object_mask->getImage();
|
||||
unsigned int x = (int) (img->s() * texCoord.x()) % img->s();
|
||||
unsigned int y = (int) (img->t() * texCoord.y()) % img->t();
|
||||
|
||||
if (mt_rand(&seed) < img->getColor(x, y).r()) {
|
||||
if (mt_rand(&seed) < img->getColor(x, y).b()) {
|
||||
points.push_back(randomPoint);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -192,12 +192,12 @@ public:
|
||||
SGVec2f texCoord = a*t0 + b*t1 + c*t2;
|
||||
|
||||
// Check this random point against the object mask
|
||||
// red channel.
|
||||
// blue channel.
|
||||
osg::Image* img = object_mask->getImage();
|
||||
unsigned int x = (int) (img->s() * texCoord.x()) % img->s();
|
||||
unsigned int y = (int) (img->t() * texCoord.y()) % img->t();
|
||||
|
||||
if (mt_rand(&seed) < img->getColor(x, y).r()) {
|
||||
if (mt_rand(&seed) < img->getColor(x, y).b()) {
|
||||
points.push_back(randomPoint);
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -343,7 +343,7 @@ public:
|
||||
* Schedule this audio sample to stop (or start) playing.
|
||||
*/
|
||||
inline void set_out_of_range(bool oor = true) {
|
||||
_out_of_range = oor; _playing = (!oor && _loop); _changed = true;
|
||||
_out_of_range = oor; _changed = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -347,7 +347,9 @@ SGXmlSound::update (double dt)
|
||||
// else
|
||||
// if a property is defined then test if it's value is FALSE
|
||||
// or if the mode is IN_TRANSIT then
|
||||
// test whether the current value matches the previous value.
|
||||
// test whether the current value matches the previous value,
|
||||
// else
|
||||
// check if out of range.
|
||||
if ( // Lisp, anyone?
|
||||
(_condition && !_condition->test()) ||
|
||||
(!_condition && _property &&
|
||||
@@ -355,7 +357,8 @@ SGXmlSound::update (double dt)
|
||||
!curr_value ||
|
||||
( (_mode == SGXmlSound::IN_TRANSIT) && (curr_value == _prev_value) )
|
||||
)
|
||||
)
|
||||
) ||
|
||||
_sample->test_out_of_range()
|
||||
)
|
||||
{
|
||||
if ((_mode != SGXmlSound::IN_TRANSIT) || (_stopping > MAX_TRANSIT_TIME))
|
||||
|
||||
Reference in New Issue
Block a user