|
From: <fli...@li...> - 2023-10-30 20:03:46
|
stuartbuchanan pushed a commit to branch next
in repository simgear.
The following commit(s) were added to refs/heads/next by this push:
new 5480ae83 WS30 - Ground mesh materialo lookup
5480ae83 is described below
SF URL: http://sourceforge.net/p/flightgear/simgear/ci/5480ae8389a2ec9594641df33d7132989d52178f/
Commit: 5480ae8389a2ec9594641df33d7132989d52178f
Author: Stuart Buchanan
Committer: Stuart Buchanan
AuthorDate: Mon Oct 30 18:33:42 2023 +0000
WS30 - Ground mesh materialo lookup
Squashed commit of the following:
commit 6ac3ae74fbebb74748df5f5c7ff02e7513012d06
Author: Stuart Buchanan <stu...@ya...>
AuthorDate: Fri Oct 27 13:48:29 2023 +0100
WS30 - VPBTechnique cleanup
commit 24cb4b03a0180dee0a8b3ca8a694fc8e81bcbb11
Author: Stuart Buchanan <stu...@ya...>
AuthorDate: Fri Oct 27 12:27:35 2023 +0100
WS30 - VPBTechnique cleanup
commit 7baec1a8bcea1cd482e0414af72236517cc9ae8d
Author: Stuart Buchanan <stu...@ya...>
AuthorDate: Thu Oct 26 20:32:27 2023 +0100
WS30 - Ground mesh material lookup
commit aafbf3e2e33a2fbdf6be241e77f424d54716866a
Author: Stuart Buchanan <stu...@ya...>
AuthorDate: Thu Oct 26 20:30:38 2023 +0100
WS30 - Ground mesh material lookup
---
simgear/CMakeLists.txt | 2 +-
simgear/bvh/BVHBoundingBoxVisitor.hxx | 3 +
simgear/bvh/BVHLineSegmentVisitor.cxx | 19 ++-
simgear/bvh/BVHLineSegmentVisitor.hxx | 11 +-
simgear/bvh/BVHMaterial.hxx | 5 +-
simgear/bvh/BVHNearestPointVisitor.hxx | 9 +-
simgear/bvh/BVHStaticTriangle.cxx | 3 +-
simgear/bvh/BVHSubTreeCollector.cxx | 10 ++
simgear/bvh/BVHSubTreeCollector.hxx | 2 +
simgear/bvh/BVHTerrainTile.cxx | 70 +++++++++++
simgear/bvh/BVHTerrainTile.hxx | 43 +++++++
simgear/bvh/BVHVisitor.hxx | 4 +-
simgear/bvh/CMakeLists.txt | 6 +-
simgear/scene/material/Atlas.cxx | 5 +-
simgear/scene/material/Atlas.hxx | 8 +-
simgear/scene/material/matlib.cxx | 4 +-
simgear/scene/model/BVHDebugCollectVisitor.hxx | 7 ++
simgear/scene/model/BVHPageNodeOSG.cxx | 21 +++-
simgear/scene/model/BoundingVolumeBuildVisitor.hxx | 42 ++++++-
simgear/scene/tgdb/VPBTechnique.cxx | 130 +++++++++++++--------
simgear/scene/tgdb/VPBTechnique.hxx | 29 +++--
21 files changed, 352 insertions(+), 81 deletions(-)
diff --git a/simgear/CMakeLists.txt b/simgear/CMakeLists.txt
index b4020867..18685c38 100644
--- a/simgear/CMakeLists.txt
+++ b/simgear/CMakeLists.txt
@@ -3,7 +3,6 @@ file(WRITE ${PROJECT_BINARY_DIR}/simgear/version.h "#define SIMGEAR_VERSION ${SI
foreach( mylibfolder
bucket
- bvh
debug
embedded_resources
emesary
@@ -29,6 +28,7 @@ foreach( mylibfolder
endforeach( mylibfolder )
if(NOT SIMGEAR_HEADLESS)
+ add_subdirectory(bvh)
add_subdirectory(canvas)
add_subdirectory(environment)
add_subdirectory(screen)
diff --git a/simgear/bvh/BVHBoundingBoxVisitor.hxx b/simgear/bvh/BVHBoundingBoxVisitor.hxx
index c14ff9c2..6e69d143 100644
--- a/simgear/bvh/BVHBoundingBoxVisitor.hxx
+++ b/simgear/bvh/BVHBoundingBoxVisitor.hxx
@@ -27,6 +27,7 @@
#include "BVHTransform.hxx"
#include "BVHMotionTransform.hxx"
#include "BVHLineGeometry.hxx"
+#include "BVHTerrainTile.hxx"
#include "BVHStaticData.hxx"
@@ -56,6 +57,8 @@ public:
{ expandBy(node.getBoundingSphere()); }
virtual void apply(BVHStaticGeometry& node)
{ expandBy(node.getBoundingSphere()); }
+ virtual void apply(BVHTerrainTile& node)
+ { expandBy(node.getBoundingSphere()); }
virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data)
{ expandBy(node.getBoundingBox()); }
diff --git a/simgear/bvh/BVHLineSegmentVisitor.cxx b/simgear/bvh/BVHLineSegmentVisitor.cxx
index 86fdd659..001b1cb6 100644
--- a/simgear/bvh/BVHLineSegmentVisitor.cxx
+++ b/simgear/bvh/BVHLineSegmentVisitor.cxx
@@ -32,6 +32,7 @@
#include "BVHMotionTransform.hxx"
#include "BVHLineGeometry.hxx"
#include "BVHStaticGeometry.hxx"
+#include "BVHTerrainTile.hxx"
#include "BVHStaticData.hxx"
@@ -90,7 +91,7 @@ BVHLineSegmentVisitor::apply(BVHMotionTransform& transform)
if (!intersects(_lineSegment, transform.getBoundingSphere()))
return;
- bool haveHit = _haveHit;
+ bool haveHit = _haveHit;
_haveHit = false;
// Push the line segment
@@ -131,6 +132,22 @@ BVHLineSegmentVisitor::apply(BVHStaticGeometry& node)
node.traverse(*this);
}
+void
+BVHLineSegmentVisitor::apply(BVHTerrainTile& node)
+{
+ if (!intersects(_lineSegment, node.getBoundingSphere()))
+ return;
+
+ node.traverse(*this);
+
+ if (_haveHit && (_material == NULL)) {
+ // Any hit within a BVHTerrainTile won't have a material associated, as that
+ // information is not available within the BVH for a Terrain tile. So
+ // get it from the tile itself now.
+ _material = node.getMaterial(this);
+ }
+}
+
void
BVHLineSegmentVisitor::apply(const BVHStaticBinary& node,
const BVHStaticData& data)
diff --git a/simgear/bvh/BVHLineSegmentVisitor.hxx b/simgear/bvh/BVHLineSegmentVisitor.hxx
index 87883fb1..c0040e82 100644
--- a/simgear/bvh/BVHLineSegmentVisitor.hxx
+++ b/simgear/bvh/BVHLineSegmentVisitor.hxx
@@ -57,6 +57,8 @@ public:
{ return _angularVelocity; }
const BVHMaterial* getMaterial() const
{ return _material; }
+ void setMaterial(BVHMaterial* material) { _material = material; }
+
BVHNode::Id getId() const
{ return _id; }
@@ -66,10 +68,13 @@ public:
virtual void apply(BVHMotionTransform& transform);
virtual void apply(BVHLineGeometry&);
virtual void apply(BVHStaticGeometry& node);
-
+ virtual void apply(BVHTerrainTile& tile);
+
virtual void apply(const BVHStaticBinary&, const BVHStaticData&);
virtual void apply(const BVHStaticTriangle&, const BVHStaticData&);
-
+
+ void setHit(bool hit) { _haveHit = hit; }
+
protected:
void setLineSegmentEnd(const SGVec3d& end)
{
@@ -80,7 +85,7 @@ protected:
#endif
_lineSegment.set(_lineSegment.getStart(), end);
}
-
+
private:
SGLineSegmentd _lineSegment;
double _time;
diff --git a/simgear/bvh/BVHMaterial.hxx b/simgear/bvh/BVHMaterial.hxx
index 995970c5..a682cd9a 100644
--- a/simgear/bvh/BVHMaterial.hxx
+++ b/simgear/bvh/BVHMaterial.hxx
@@ -27,9 +27,12 @@ namespace simgear {
class BVHMaterial : public SGReferenced {
public:
- BVHMaterial() = default;
virtual ~BVHMaterial() = default;
+ BVHMaterial(bool solid=true, double friction_factor=1.0, double rolling_friction=0.02, double bumpiness=0.0, double load_resistance=1e30) :
+ _solid(solid), _friction_factor(friction_factor), _rolling_friction(rolling_friction), _bumpiness(bumpiness), _load_resistance(load_resistance)
+ { }
+
/**
* Return if the surface material is solid, if it is not solid, a fluid
* can be assumed, that is usually water.
diff --git a/simgear/bvh/BVHNearestPointVisitor.hxx b/simgear/bvh/BVHNearestPointVisitor.hxx
index 7b3a5bbf..950118fb 100644
--- a/simgear/bvh/BVHNearestPointVisitor.hxx
+++ b/simgear/bvh/BVHNearestPointVisitor.hxx
@@ -28,6 +28,7 @@
#include "BVHTransform.hxx"
#include "BVHLineGeometry.hxx"
#include "BVHStaticGeometry.hxx"
+#include "BVHTerrainTile.hxx"
#include "BVHStaticData.hxx"
@@ -113,7 +114,13 @@ public:
return;
node.traverse(*this);
}
-
+ virtual void apply(BVHTerrainTile& leaf)
+ {
+ if (!intersects(_sphere, leaf.getBoundingSphere()))
+ return;
+ leaf.traverse(*this);
+ }
+
virtual void apply(const BVHStaticBinary& node, const BVHStaticData& data)
{
if (!intersects(_sphere, node.getBoundingBox()))
diff --git a/simgear/bvh/BVHStaticTriangle.cxx b/simgear/bvh/BVHStaticTriangle.cxx
index 53572060..d60c98d0 100644
--- a/simgear/bvh/BVHStaticTriangle.cxx
+++ b/simgear/bvh/BVHStaticTriangle.cxx
@@ -21,8 +21,7 @@
namespace simgear {
-BVHStaticTriangle::BVHStaticTriangle(unsigned material,
- const unsigned indices[3]) :
+BVHStaticTriangle::BVHStaticTriangle(unsigned material, const unsigned indices[3]) :
_material(material)
{
for (unsigned i = 0; i < 3; ++i)
diff --git a/simgear/bvh/BVHSubTreeCollector.cxx b/simgear/bvh/BVHSubTreeCollector.cxx
index 6928dc7b..317dfaed 100644
--- a/simgear/bvh/BVHSubTreeCollector.cxx
+++ b/simgear/bvh/BVHSubTreeCollector.cxx
@@ -23,6 +23,7 @@
#include "BVHNode.hxx"
#include "BVHGroup.hxx"
#include "BVHTransform.hxx"
+#include "BVHTerrainTile.hxx"
#include "BVHStaticData.hxx"
@@ -151,6 +152,15 @@ BVHSubTreeCollector::apply(BVHStaticGeometry& node)
_staticNode = 0;
}
+void
+BVHSubTreeCollector::apply(BVHTerrainTile& node)
+{
+ if (!intersects(_sphere, node.getBoundingSphere()))
+ return;
+
+ addNode(&node);
+}
+
void
BVHSubTreeCollector::apply(const BVHStaticBinary& node,
const BVHStaticData& data)
diff --git a/simgear/bvh/BVHSubTreeCollector.hxx b/simgear/bvh/BVHSubTreeCollector.hxx
index 72f64ace..66933b45 100644
--- a/simgear/bvh/BVHSubTreeCollector.hxx
+++ b/simgear/bvh/BVHSubTreeCollector.hxx
@@ -24,6 +24,7 @@
#include "BVHNode.hxx"
#include "BVHGroup.hxx"
#include "BVHStaticNode.hxx"
+#include "BVHTerrainTile.hxx"
namespace simgear {
@@ -48,6 +49,7 @@ public:
virtual void apply(BVHMotionTransform&);
virtual void apply(BVHLineGeometry&);
virtual void apply(BVHStaticGeometry&);
+ virtual void apply(BVHTerrainTile&);
virtual void apply(const BVHStaticBinary&, const BVHStaticData&);
virtual void apply(const BVHStaticTriangle&, const BVHStaticData&);
diff --git a/simgear/bvh/BVHTerrainTile.cxx b/simgear/bvh/BVHTerrainTile.cxx
new file mode 100644
index 00000000..9010459e
--- /dev/null
+++ b/simgear/bvh/BVHTerrainTile.cxx
@@ -0,0 +1,70 @@
+// Copyright (C) 2023 Stuart Buchanan - stu...@gm...
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifdef HAVE_CONFIG_H
+# include <simgear_config.h>
+#endif
+
+#include "BVHTerrainTile.hxx"
+#include "BVHLineSegmentVisitor.hxx"
+#include "BVHSubTreeCollector.hxx"
+#include "simgear/scene/tgdb/VPBTechnique.hxx"
+
+#include <algorithm>
+
+namespace simgear {
+
+BVHTerrainTile::BVHTerrainTile(osgTerrain::TerrainTile *tile)
+{
+ _tile = tile;
+}
+
+BVHTerrainTile::~BVHTerrainTile()
+{
+ _tile = 0;
+}
+
+BVHMaterial* BVHTerrainTile::getMaterial(simgear::BVHLineSegmentVisitor* lsv) {
+ BVHMaterial* material;
+ if (! lsv->empty()) {
+ // LSV contains the uv coordinates of the intersection u*(v1-v0) + v*(v2-v0) and the origin indices on the drawable they refer to.
+ // However it does not have any information on the actual material as this is part of the TerrainTile texture.
+ simgear::VPBTechnique* technique = dynamic_cast<simgear::VPBTechnique*>(_tile->getTerrainTechnique());
+ if (technique) {
+ material = technique->getMaterial(toOsg(lsv->getPoint()));
+ } else {
+ SG_LOG(SG_TERRAIN, SG_ALERT, "BVHTerrainTile::getMaterial unable to get technique");
+ }
+ } else {
+ SG_LOG(SG_TERRAIN, SG_ALERT, "BVHTerrainTile::getMaterial but no LSV hit");
+ }
+
+ return material;
+}
+
+void BVHTerrainTile::accept(BVHVisitor& visitor)
+{
+ visitor.apply(*this);
+}
+
+SGSphered BVHTerrainTile::computeBoundingSphere() const {
+ simgear::VPBTechnique* technique = dynamic_cast<simgear::VPBTechnique*>(_tile->getTerrainTechnique());
+ return technique->computeBoundingSphere();
+}
+
+
+}
diff --git a/simgear/bvh/BVHTerrainTile.hxx b/simgear/bvh/BVHTerrainTile.hxx
new file mode 100644
index 00000000..7830251b
--- /dev/null
+++ b/simgear/bvh/BVHTerrainTile.hxx
@@ -0,0 +1,43 @@
+// Copyright (C) 2023 Stuart Buchanan - stu...@gm...
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Library General Public
+// License as published by the Free Software Foundation; either
+// version 2 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Library General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+
+#ifndef BVHTerrainTile_hxx
+#define BVHTerrainTile_hxx
+
+#include <simgear/structure/SGSharedPtr.hxx>
+#include "BVHGroup.hxx"
+#include "BVHLineSegmentVisitor.hxx"
+#include "BVHMaterial.hxx"
+#include "BVHVisitor.hxx"
+#include <osgTerrain/TerrainTile>
+
+namespace simgear {
+
+class BVHTerrainTile : public BVHGroup {
+public:
+ BVHTerrainTile(osgTerrain::TerrainTile *tile);
+ virtual ~BVHTerrainTile();
+ virtual void accept(BVHVisitor& visitor);
+ virtual SGSphered computeBoundingSphere() const;
+ BVHMaterial* getMaterial(BVHLineSegmentVisitor* lsv);
+private:
+ osg::ref_ptr<osgTerrain::TerrainTile> _tile;
+};
+
+}
+
+#endif
diff --git a/simgear/bvh/BVHVisitor.hxx b/simgear/bvh/BVHVisitor.hxx
index b8a5c3bb..e6196444 100644
--- a/simgear/bvh/BVHVisitor.hxx
+++ b/simgear/bvh/BVHVisitor.hxx
@@ -28,6 +28,7 @@ class BVHTransform;
class BVHMotionTransform;
class BVHStaticGeometry;
class BVHLineGeometry;
+class BVHTerrainTile;
class BVHStaticBinary;
class BVHStaticTriangle;
@@ -47,7 +48,8 @@ public:
virtual void apply(BVHMotionTransform&) = 0;
virtual void apply(BVHLineGeometry&) = 0;
virtual void apply(BVHStaticGeometry&) = 0;
-
+ virtual void apply(BVHTerrainTile&) = 0;
+
// Static tree nodes to handle
virtual void apply(const BVHStaticBinary&, const BVHStaticData&) = 0;
virtual void apply(const BVHStaticTriangle&, const BVHStaticData&) = 0;
diff --git a/simgear/bvh/CMakeLists.txt b/simgear/bvh/CMakeLists.txt
index 96157bd9..a754c50c 100644
--- a/simgear/bvh/CMakeLists.txt
+++ b/simgear/bvh/CMakeLists.txt
@@ -21,6 +21,7 @@ set(HEADERS
BVHSubTreeCollector.hxx
BVHMaterial.hxx
BVHTransform.hxx
+ BVHTerrainTile.hxx
BVHVisitor.hxx
)
@@ -39,11 +40,12 @@ set(SOURCES
BVHStaticNode.cxx
BVHStaticTriangle.cxx
BVHSubTreeCollector.cxx
+ BVHTerrainTile.cxx
BVHTransform.cxx
)
-simgear_component(bvh bvh "${SOURCES}" "${HEADERS}")
+simgear_scene_component(bvh bvh "${SOURCES}" "${HEADERS}")
if(ENABLE_TESTS)
- add_simgear_autotest(bvhtest bvhtest.cxx)
+ add_simgear_scene_autotest(bvhtest bvhtest.cxx)
endif(ENABLE_TESTS)
diff --git a/simgear/scene/material/Atlas.cxx b/simgear/scene/material/Atlas.cxx
index aa286215..4e247077 100644
--- a/simgear/scene/material/Atlas.cxx
+++ b/simgear/scene/material/Atlas.cxx
@@ -79,7 +79,7 @@ Atlas::Atlas(osg::ref_ptr<const SGReaderWriterOptions> options) {
}
}
-void Atlas::addMaterial(int landclass, bool isWater, bool isSea, SGMaterial* mat) {
+void Atlas::addMaterial(int landclass, bool isWater, bool isSea, SGSharedPtr<SGMaterial> mat) {
SG_LOG(SG_TERRAIN, SG_DEBUG, "Atlas Landclass mapping: " << landclass << " : " << mat->get_names()[0]);
_index[landclass] = _materialLookupIndex;
@@ -185,6 +185,9 @@ void Atlas::addMaterial(int landclass, bool isWater, bool isSea, SGMaterial* mat
// 11-15th textures for the various overlay textures for terrain-default.eff, we do the same for ws30.eff
_textureLookup1->setElement(_materialLookupIndex, osg::Vec4f( (float) (textureList[0] / 255.0), (float) (textureList[11] / 255.0), (float) (textureList[12] / 255.0), (float) (textureList[13] / 255.0)));
_textureLookup2->setElement(_materialLookupIndex, osg::Vec4f( (float) (textureList[14] / 255.0), (float) (textureList[15] / 255.0), (float) (textureList[20] / 255.0), (float) (textureList[21] / 255.0)));
+ _bvhMaterialMap[_materialLookupIndex] = mat;
+ } else {
+ SG_LOG(SG_TERRAIN, SG_ALERT, "Attempt to add undefined material to Material Atlas: " << landclass);
}
++_materialLookupIndex;
diff --git a/simgear/scene/material/Atlas.hxx b/simgear/scene/material/Atlas.hxx
index 3e092b05..ff325c7c 100644
--- a/simgear/scene/material/Atlas.hxx
+++ b/simgear/scene/material/Atlas.hxx
@@ -21,6 +21,7 @@
#include <simgear/compiler.h>
+#include <simgear/bvh/BVHMaterial.hxx>
#include <simgear/math/SGMath.hxx>
#include <simgear/structure/SGReferenced.hxx>
#include <simgear/structure/SGSharedPtr.hxx>
@@ -47,6 +48,7 @@ public:
// Mapping of landclass numbers to indexes within the atlas
// materialLookup
typedef std::map<int, int> AtlasIndex;
+ typedef std::map<unsigned, SGSharedPtr<SGMaterial> > AtlasMap;
// Mapping of texture filenames to their index in the Atlas image itself.
typedef std::map<std::string, unsigned int> TextureMap;
@@ -56,7 +58,7 @@ public:
typedef std::map<int, bool> WaterAtlas;
void addUniforms(osg::StateSet* stateset);
- void addMaterial(int landclass, bool water, bool sea, SGMaterial* mat);
+ void addMaterial(int landclass, bool water, bool sea, SGSharedPtr<SGMaterial> mat);
// Maximum number of material entries in the atlas
static const unsigned int MAX_MATERIALS = 64;
@@ -66,6 +68,7 @@ public:
bool isSea(int landclass) { return _seaAtlas[landclass];}
int getIndex(int landclass) { return _index[landclass]; };
+ AtlasMap getBVHMaterialMap() { return _bvhMaterialMap; };
AtlasImage getImage() { return _image; };
private:
@@ -85,13 +88,14 @@ private:
osg::ref_ptr<osg::Uniform> _materialParams1;
osg::ref_ptr<osg::Uniform> _materialParams2;
osg::ref_ptr<osg::Uniform> _materialParams3;
-
+
unsigned int _imageIndex; // Index into the image
unsigned int _materialLookupIndex; // Index into the material lookup
WaterAtlas _waterAtlas;
WaterAtlas _seaAtlas;
TextureMap _textureMap;
+ AtlasMap _bvhMaterialMap;
// Maximum number of textures per texture-set for the Atlas.
static const unsigned int MAX_TEXTURES = 22;
diff --git a/simgear/scene/material/matlib.cxx b/simgear/scene/material/matlib.cxx
index dcd229ae..90d78e0a 100644
--- a/simgear/scene/material/matlib.cxx
+++ b/simgear/scene/material/matlib.cxx
@@ -368,8 +368,8 @@ osg::ref_ptr<Atlas> SGMaterialLib::getOrCreateAtlas(SGMaterialLib::landclass_map
int landclass = lc_iter->first;
bool water = lc_iter->second._water;
bool sea = lc_iter->second._sea;
- SGMaterial* mat = find(lc_iter->second._mat, center);
- atlas->addMaterial(landclass, water, sea, mat);
+ SGSharedPtr<SGMaterial> mat = find(lc_iter->second._mat, center);
+ if (mat != NULL ) atlas->addMaterial(landclass, water, sea, mat);
}
SGMaterialLib::_atlasCache[id] = atlas;
diff --git a/simgear/scene/model/BVHDebugCollectVisitor.hxx b/simgear/scene/model/BVHDebugCollectVisitor.hxx
index 8e7be665..5ec278c9 100644
--- a/simgear/scene/model/BVHDebugCollectVisitor.hxx
+++ b/simgear/scene/model/BVHDebugCollectVisitor.hxx
@@ -83,6 +83,13 @@ public:
node.traverse(*this);
--_currentLevel;
}
+ virtual void apply(BVHTerrainTile& node)
+ {
+ addNodeSphere(node);
+ ++_currentLevel;
+ node.traverse(*this);
+ --_currentLevel;
+ }
virtual void apply(BVHTransform& node)
{
addNodeSphere(node);
diff --git a/simgear/scene/model/BVHPageNodeOSG.cxx b/simgear/scene/model/BVHPageNodeOSG.cxx
index d38f8ee1..44f1ba09 100644
--- a/simgear/scene/model/BVHPageNodeOSG.cxx
+++ b/simgear/scene/model/BVHPageNodeOSG.cxx
@@ -34,6 +34,7 @@
#include <osg/ProxyNode>
#include <osg/Transform>
#include <osgDB/ReadFile>
+#include <osgTerrain/TerrainTile>
#include <simgear/scene/material/mat.hxx>
#include <simgear/scene/material/matlib.hxx>
@@ -43,6 +44,7 @@
#include <simgear/math/SGGeometry.hxx>
#include <simgear/bvh/BVHStaticGeometryBuilder.hxx>
+#include <simgear/bvh/BVHTerrainTile.hxx>
#include "PrimitiveCollector.hxx"
@@ -190,7 +192,7 @@ public:
if (!transform.computeLocalToWorldMatrix(localToWorldMatrix, this))
return;
- // evaluate the loca to world matrix here in this group node.
+ // evaluate the local to world matrix here in this group node.
_NodeVisitor nodeVisitor(_flatten);
nodeVisitor.traverse(transform);
_nodeBin.addNode(nodeVisitor.getNode(localToWorldMatrix));
@@ -269,6 +271,21 @@ public:
apply(static_cast<osg::Group&>(proxyNode));
}
+ virtual void apply(osg::Group& group)
+ {
+ osgTerrain::TerrainTile* tile = dynamic_cast<osgTerrain::TerrainTile*>(&group);
+
+ if (tile) {
+ SGSceneUserData* userData = SGSceneUserData::getOrCreateSceneUserData(tile);
+ if (userData) {
+ BVHTerrainTile* bvhTerrainTile = new BVHTerrainTile(tile);
+ userData->setBVHNode(bvhTerrainTile);
+ }
+ } else {
+ apply(static_cast<osg::Node&>(group));
+ }
+ }
+
static osg::ref_ptr<const osgDB::Options>
getOptions(const osg::Referenced* referenced, const std::string& databasePath)
{
@@ -288,7 +305,7 @@ public:
SGSharedPtr<BVHNode> getNode(const osg::Matrix& matrix = osg::Matrix())
{
- // Flush any pendig leaf nodes
+ // Flush any pending leaf nodes
if (_geometryBuilder.valid()) {
_nodeBin.addNode(_geometryBuilder->buildTree());
_geometryBuilder.clear();
diff --git a/simgear/scene/model/BoundingVolumeBuildVisitor.hxx b/simgear/scene/model/BoundingVolumeBuildVisitor.hxx
index d9271917..0b8b4470 100644
--- a/simgear/scene/model/BoundingVolumeBuildVisitor.hxx
+++ b/simgear/scene/model/BoundingVolumeBuildVisitor.hxx
@@ -20,12 +20,15 @@
#define SimGear_BoundingVolumeBuildVisitor_hxx
#include <osg/Camera>
+#include <osg/CoordinateSystemNode>
#include <osg/Drawable>
#include <osg/Geode>
#include <osg/Group>
#include <osg/PagedLOD>
#include <osg/Transform>
#include <osg/TriangleFunctor>
+#include <osgTerrain/TerrainTile>
+#include <osgTerrain/Terrain>
#include <simgear/scene/material/mat.hxx>
#include <simgear/scene/material/matlib.hxx>
@@ -35,6 +38,7 @@
#include <simgear/math/SGGeometry.hxx>
#include <simgear/bvh/BVHStaticGeometryBuilder.hxx>
+#include <simgear/bvh/BVHTerrainTile.hxx>
#include "PrimitiveCollector.hxx"
@@ -142,7 +146,38 @@ public:
}
virtual void apply(osg::Group& group)
- { traverseAndCollect(group); }
+ {
+ osgTerrain::TerrainTile* tile = dynamic_cast<osgTerrain::TerrainTile*>(&group);
+
+ if (tile) {
+ SGSharedPtr<BVHTerrainTile> bvhTile = new BVHTerrainTile(tile);
+
+ // push the current active primitive list
+ _PrimitiveCollector previousPrimitives;
+ _primitiveCollector.swap(previousPrimitives);
+
+ const BVHMaterial* mat = previousPrimitives.getCurrentMaterial();
+ _primitiveCollector.setCurrentMaterial(mat);
+
+ // walk the children
+ traverse(group);
+
+ // Build the flat tree and add it as a chile of this node. This way the BVHTerrain
+ // tile methods can intercept and modify any intersections.
+ BVHNode* bvNode = _primitiveCollector.buildTreeAndClear();
+ bvhTile->addChild(bvNode);
+
+ SGSceneUserData* userData;
+ userData = SGSceneUserData::getOrCreateSceneUserData(&group);
+ if (userData) {
+ userData->setBVHNode(bvhTile);
+ }
+ // pop the current active primitive list
+ _primitiveCollector.swap(previousPrimitives);
+ } else {
+ traverseAndCollect(group);
+ }
+ }
virtual void apply(osg::Transform& transform)
{ traverseAndDump(transform); }
@@ -159,6 +194,11 @@ public:
traverseAndDump(camera);
}
+ virtual void apply(osg::CoordinateSystemNode& node)
+ {
+ traverseAndCollect(node);
+ }
+
void traverseAndDump(osg::Node& node)
{
if (hasBoundingVolumeTree(node))
diff --git a/simgear/scene/tgdb/VPBTechnique.cxx b/simgear/scene/tgdb/VPBTechnique.cxx
index f1d222c8..5811199a 100644
--- a/simgear/scene/tgdb/VPBTechnique.cxx
+++ b/simgear/scene/tgdb/VPBTechnique.cxx
@@ -38,6 +38,7 @@
#include <osg/Math>
#include <osg/Timer>
+#include <simgear/bvh/BVHSubTreeCollector.hxx>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/sg_random.hxx>
#include <simgear/math/SGMath.hxx>
@@ -176,13 +177,13 @@ void VPBTechnique::init(int dirtyMask, bool assumeMultiThreaded)
osg::ref_ptr<BufferData> buffer = new BufferData;
- Locator* masterLocator = computeMasterLocator();
+ buffer->_masterLocator = computeMasterLocator();
- osg::Vec3d centerModel = computeCenterModel(*buffer, masterLocator);
+ osg::Vec3d centerModel = computeCenterModel(*buffer);
// Generate a set of material definitions for this location.
SGMaterialLibPtr matlib = _options->getMaterialLib();
- const SGGeod loc = computeCenterGeod(*buffer, masterLocator);
+ const SGGeod loc = computeCenterGeod(*buffer);
osg::ref_ptr<SGMaterialCache> matcache;
if (matlib) {
SG_LOG(SG_TERRAIN, SG_DEBUG, "Applying VPB material " << loc);
@@ -194,7 +195,7 @@ void VPBTechnique::init(int dirtyMask, bool assumeMultiThreaded)
if ((dirtyMask & TerrainTile::IMAGERY_DIRTY)==0)
{
- generateGeometry(*buffer, masterLocator, centerModel, matcache);
+ generateGeometry(*buffer, centerModel, matcache);
osg::ref_ptr<BufferData> read_buffer = _currentBufferData;
@@ -205,20 +206,20 @@ void VPBTechnique::init(int dirtyMask, bool assumeMultiThreaded)
}
else
{
- applyColorLayers(*buffer, masterLocator, matcache);
- applyLineFeatures(*buffer, masterLocator, matcache);
- applyAreaFeatures(*buffer, masterLocator, matcache);
- applyMaterials(*buffer, masterLocator, matcache);
+ applyColorLayers(*buffer, matcache);
+ applyLineFeatures(*buffer, matcache);
+ applyAreaFeatures(*buffer, matcache);
+ applyMaterials(*buffer, matcache);
}
}
else
{
- generateGeometry(*buffer, masterLocator, centerModel, matcache);
+ generateGeometry(*buffer, centerModel, matcache);
- applyColorLayers(*buffer, masterLocator, matcache);
- applyLineFeatures(*buffer, masterLocator, matcache);
- applyAreaFeatures(*buffer, masterLocator, matcache);
- applyMaterials(*buffer, masterLocator, matcache);
+ applyColorLayers(*buffer, matcache);
+ applyLineFeatures(*buffer, matcache);
+ applyAreaFeatures(*buffer, matcache);
+ applyMaterials(*buffer, matcache);
}
if (buffer->_transform.valid()) buffer->_transform->setThreadSafeRefUnref(true);
@@ -260,9 +261,9 @@ Locator* VPBTechnique::computeMasterLocator()
return masterLocator;
}
-osg::Vec3d VPBTechnique::computeCenter(BufferData& buffer, Locator* masterLocator)
+osg::Vec3d VPBTechnique::computeCenter(BufferData& buffer)
{
- if (!masterLocator) return osg::Vec3d(0.0,0.0,0.0);
+ if (!buffer._masterLocator) return osg::Vec3d(0.0,0.0,0.0);
osgTerrain::Layer* elevationLayer = _terrainTile->getElevationLayer();
osgTerrain::Layer* colorLayer = _terrainTile->getColorLayer(0);
@@ -270,17 +271,17 @@ osg::Vec3d VPBTechnique::computeCenter(BufferData& buffer, Locator* masterLocato
Locator* elevationLocator = elevationLayer ? elevationLayer->getLocator() : 0;
Locator* colorLocator = colorLayer ? colorLayer->getLocator() : 0;
- if (!elevationLocator) elevationLocator = masterLocator;
- if (!colorLocator) colorLocator = masterLocator;
+ if (!elevationLocator) elevationLocator = buffer._masterLocator;
+ if (!colorLocator) colorLocator = buffer._masterLocator;
osg::Vec3d bottomLeftNDC(DBL_MAX, DBL_MAX, 0.0);
osg::Vec3d topRightNDC(-DBL_MAX, -DBL_MAX, 0.0);
if (elevationLayer)
{
- if (elevationLocator!= masterLocator)
+ if (elevationLocator!= buffer._masterLocator)
{
- masterLocator->computeLocalBounds(*elevationLocator, bottomLeftNDC, topRightNDC);
+ buffer._masterLocator->computeLocalBounds(*elevationLocator, bottomLeftNDC, topRightNDC);
}
else
{
@@ -293,9 +294,9 @@ osg::Vec3d VPBTechnique::computeCenter(BufferData& buffer, Locator* masterLocato
if (colorLayer)
{
- if (colorLocator!= masterLocator)
+ if (colorLocator!= buffer._masterLocator)
{
- masterLocator->computeLocalBounds(*colorLocator, bottomLeftNDC, topRightNDC);
+ buffer._masterLocator->computeLocalBounds(*colorLocator, bottomLeftNDC, topRightNDC);
}
else
{
@@ -313,11 +314,11 @@ osg::Vec3d VPBTechnique::computeCenter(BufferData& buffer, Locator* masterLocato
return centerNDC;
}
-osg::Vec3d VPBTechnique::computeCenterModel(BufferData& buffer, Locator* masterLocator)
+osg::Vec3d VPBTechnique::computeCenterModel(BufferData& buffer)
{
- osg::Vec3d centerNDC = computeCenter(buffer, masterLocator);
+ osg::Vec3d centerNDC = computeCenter(buffer);
osg::Vec3d centerModel = centerNDC;
- masterLocator->convertLocalToModel(centerNDC, centerModel);
+ buffer._masterLocator->convertLocalToModel(centerNDC, centerModel);
buffer._transform = new osg::MatrixTransform;
buffer._transform->setMatrix(osg::Matrix::translate(centerModel));
@@ -325,7 +326,7 @@ osg::Vec3d VPBTechnique::computeCenterModel(BufferData& buffer, Locator* masterL
return centerModel;
}
-const SGGeod VPBTechnique::computeCenterGeod(BufferData& buffer, Locator* masterLocator)
+const SGGeod VPBTechnique::computeCenterGeod(BufferData& buffer)
{
const osg::Vec3d world = buffer._transform->getMatrix().getTrans();
return SGGeod::fromCart(toSG(world));
@@ -850,7 +851,7 @@ void VertexNormalGenerator::computeNormals()
}
}
-void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator, const osg::Vec3d& centerModel, osg::ref_ptr<SGMaterialCache> matcache)
+void VPBTechnique::generateGeometry(BufferData& buffer, const osg::Vec3d& centerModel, osg::ref_ptr<SGMaterialCache> matcache)
{
osg::ref_ptr<Atlas> atlas;
@@ -925,7 +926,7 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
bool createSkirt = skirtHeight != 0.0f;
// construct the VertexNormalGenerator which will manage the generation and the vertices and normals
- VertexNormalGenerator VNG(masterLocator, centerModel, numRows, numColumns, scaleHeight, constraint_gap, createSkirt);
+ VertexNormalGenerator VNG(buffer._masterLocator, centerModel, numRows, numColumns, scaleHeight, constraint_gap, createSkirt);
unsigned int numVertices = VNG.capacity();
@@ -1014,7 +1015,7 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
//
// populate the primitive data
//
- bool swapOrientation = !(masterLocator->orientationOpenGL());
+ bool swapOrientation = !(buffer._masterLocator->orientationOpenGL());
bool smallTile = numVertices < 65536;
// OSG_NOTICE<<"smallTile = "<<smallTile<<std::endl;
@@ -1249,6 +1250,7 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
buffer._landGeometry->setUseDisplayList(false);
buffer._landGeometry->setUseVertexBufferObjects(true);
+ buffer._landGeometry->computeBoundingBox();
buffer._landGeode->runGenerators(buffer._landGeometry);
// Tile-specific information for the shaders
@@ -1297,10 +1299,12 @@ void VPBTechnique::generateGeometry(BufferData& buffer, Locator* masterLocator,
}
}
-void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator, osg::ref_ptr<SGMaterialCache> matcache)
+void VPBTechnique::applyColorLayers(BufferData& buffer, osg::ref_ptr<SGMaterialCache> matcache)
{
const SGPropertyNode* propertyNode = _options->getPropertyNode().get();
Atlas* atlas = matcache->getAtlas();
+ buffer._BVHMaterialMap = atlas->getBVHMaterialMap();
+
auto tileID = _terrainTile->getTileID();
bool photoScenery = false;
@@ -1360,7 +1364,7 @@ void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator,
stateset->setTextureAttributeAndModes(7, waterTexture);
stateset->addUniform(new osg::Uniform(VPBTechnique::PHOTO_SCENERY, true));
- stateset->addUniform(new osg::Uniform(VPBTechnique::Z_UP_TRANSFORM, osg::Matrixf(osg::Matrix::inverse(makeZUpFrameRelative(computeCenterGeod(buffer, masterLocator))))));
+ stateset->addUniform(new osg::Uniform(VPBTechnique::Z_UP_TRANSFORM, osg::Matrixf(osg::Matrix::inverse(makeZUpFrameRelative(computeCenterGeod(buffer))))));
stateset->addUniform(new osg::Uniform(VPBTechnique::MODEL_OFFSET, (osg::Vec3f) buffer._transform->getMatrix().getTrans()));
atlas->addUniforms(stateset);
@@ -1424,7 +1428,7 @@ void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator,
texture2D->setWrap(osg::Texture::WRAP_T,osg::Texture::CLAMP_TO_EDGE);
osg::ref_ptr<osg::Texture2D> coastTexture = new osg::Texture2D;
- coastTexture->setImage(generateCoastTexture(buffer, masterLocator));
+ coastTexture->setImage(generateCoastTexture(buffer));
coastTexture->setMaxAnisotropy(16.0f);
coastTexture->setResizeNonPowerOfTwoHint(false);
coastTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST_MIPMAP_NEAREST);
@@ -1437,7 +1441,7 @@ void VPBTechnique::applyColorLayers(BufferData& buffer, Locator* masterLocator,
stateset->setTextureAttributeAndModes(1, atlas->getImage(), osg::StateAttribute::ON);
stateset->setTextureAttributeAndModes(7, coastTexture, osg::StateAttribute::ON);
stateset->addUniform(new osg::Uniform(VPBTechnique::PHOTO_SCENERY, false));
- stateset->addUniform(new osg::Uniform(VPBTechnique::Z_UP_TRANSFORM, osg::Matrixf(osg::Matrix::inverse(makeZUpFrameRelative(computeCenterGeod(buffer, masterLocator))))));
+ stateset->addUniform(new osg::Uniform(VPBTechnique::Z_UP_TRANSFORM, osg::Matrixf(osg::Matrix::inverse(makeZUpFrameRelative(computeCenterGeod(buffer))))));
stateset->addUniform(new osg::Uniform(VPBTechnique::MODEL_OFFSET, (osg::Vec3f) buffer._transform->getMatrix().getTrans()));
atlas->addUniforms(stateset);
//SG_LOG(SG_TERRAIN, SG_ALERT, "modeOffset:" << buffer._transform->getMatrix().getTrans().length() << " " << buffer._transform->getMatrix().getTrans());
@@ -1449,7 +1453,7 @@ double VPBTechnique::det2(const osg::Vec2d a, const osg::Vec2d b)
return a.x() * b.y() - b.x() * a.y();
}
-void VPBTechnique::applyMaterials(BufferData& buffer, Locator* masterLocator, osg::ref_ptr<SGMaterialCache> matcache)
+void VPBTechnique::applyMaterials(BufferData& buffer, osg::ref_ptr<SGMaterialCache> matcache)
{
if (!matcache) return;
pc_init(2718281);
@@ -1475,7 +1479,7 @@ void VPBTechnique::applyMaterials(BufferData& buffer, Locator* masterLocator, os
SGMaterial* mat = 0;
- const SGGeod loc = computeCenterGeod(buffer, masterLocator);
+ const SGGeod loc = computeCenterGeod(buffer);
osg::Vec3d up = buffer._transform->getMatrix().getTrans();
up.normalize();
@@ -1716,7 +1720,7 @@ void VPBTechnique::applyMaterials(BufferData& buffer, Locator* masterLocator, os
}
}
-void VPBTechnique::applyLineFeatures(BufferData& buffer, Locator* masterLocator, osg::ref_ptr<SGMaterialCache> matcache)
+void VPBTechnique::applyLineFeatures(BufferData& buffer, osg::ref_ptr<SGMaterialCache> matcache)
{
if (! matcache) {
SG_LOG(SG_TERRAIN, SG_ALERT, "Unable to get materials library to generate roads");
@@ -1791,7 +1795,7 @@ void VPBTechnique::applyLineFeatures(BufferData& buffer, Locator* masterLocator,
auto lineFeatures = (*rb)->getLineFeatures();
for (auto r = lineFeatures.begin(); r != lineFeatures.end(); ++r) {
- if (r->_width > minWidth) generateLineFeature(buffer, masterLocator, *r, world, v, t, n, lights, x0, x1, ysize, light_edge_spacing, light_edge_height, light_edge_offset, elevation_offset_m);
+ if (r->_width > minWidth) generateLineFeature(buffer, *r, world, v, t, n, lights, x0, x1, ysize, light_edge_spacing, light_edge_height, light_edge_offset, elevation_offset_m);
}
if (v->size() == 0) {
@@ -1857,12 +1861,12 @@ void VPBTechnique::applyLineFeatures(BufferData& buffer, Locator* masterLocator,
if (lightbin.getNumLights() > 0) buffer._transform->addChild(createLights(lightbin, osg::Matrix::identity(), _options));
}
-void VPBTechnique::generateLineFeature(BufferData& buffer, Locator* masterLocator, LineFeatureBin::LineFeature road, osg::Vec3d modelCenter, osg::Vec3Array* v, osg::Vec2Array* t, osg::Vec3Array* n, osg::Vec3Array* lights, double x0, double x1, unsigned int ysize, double light_edge_spacing, double light_edge_height, bool light_edge_offset, double elevation_offset_m)
+void VPBTechnique::generateLineFeature(BufferData& buffer, LineFeatureBin::LineFeature road, osg::Vec3d modelCenter, osg::Vec3Array* v, osg::Vec2Array* t, osg::Vec3Array* n, osg::Vec3Array* lights, double x0, double x1, unsigned int ysize, double light_edge_spacing, double light_edge_height, bool light_edge_offset, double elevation_offset_m)
{
// We're in Earth-centered coordinates, so "up" is simply directly away from (0,0,0)
osg::Vec3d up = modelCenter;
up.normalize();
- TileBounds tileBounds(masterLocator, up);
+ TileBounds tileBounds(buffer._masterLocator, up);
std::list<osg::Vec3d> nodes = tileBounds.clipToTile(road._nodes);
@@ -1873,11 +1877,11 @@ void VPBTechnique::generateLineFeature(BufferData& buffer, Locator* masterLocato
std::list<osg::Vec3d> roadPoints;
auto road_iter = nodes.begin();
- ma = getMeshIntersection(buffer, masterLocator, *road_iter - modelCenter, up);
+ ma = getMeshIntersection(buffer, *road_iter - modelCenter, up);
road_iter++;
for (; road_iter != nodes.end(); road_iter++) {
- mb = getMeshIntersection(buffer, masterLocator, *road_iter - modelCenter, up);
+ mb = getMeshIntersection(buffer, *road_iter - modelCenter, up);
auto esl = VPBElevationSlice::computeVPBElevationSlice(buffer._landGeometry, ma, mb, up);
for(auto eslitr = esl.begin(); eslitr != esl.end(); ++eslitr) {
@@ -1982,7 +1986,7 @@ void VPBTechnique::generateLineFeature(BufferData& buffer, Locator* masterLocato
}
}
-void VPBTechnique::applyAreaFeatures(BufferData& buffer, Locator* masterLocator, osg::ref_ptr<SGMaterialCache> matcache)
+void VPBTechnique::applyAreaFeatures(BufferData& buffer, osg::ref_ptr<SGMaterialCache> matcache)
{
if (! matcache) {
SG_LOG(SG_TERRAIN, SG_ALERT, "Unable to get materials library to generate areas");
@@ -2050,7 +2054,7 @@ void VPBTechnique::applyAreaFeatures(BufferData& buffer, Locator* masterLocator,
auto areaFeatures = (*rb)->getAreaFeatures();
for (auto r = areaFeatures.begin(); r != areaFeatures.end(); ++r) {
- if (r->_area > minArea) generateAreaFeature(buffer, masterLocator, *r, world, geometry, v, t, n, xsize, ysize);
+ if (r->_area > minArea) generateAreaFeature(buffer, *r, world, geometry, v, t, n, xsize, ysize);
}
if (v->size() == 0) continue;
@@ -2069,7 +2073,7 @@ void VPBTechnique::applyAreaFeatures(BufferData& buffer, Locator* masterLocator,
}
}
-void VPBTechnique::generateAreaFeature(BufferData& buffer, Locator* masterLocator, AreaFeatureBin::AreaFeature area, osg::Vec3d modelCenter, osg::Geometry* geometry, osg::Vec3Array* v, osg::Vec2Array* t, osg::Vec3Array* n, unsigned int xsize, unsigned int ysize)
+void VPBTechnique::generateAreaFeature(BufferData& buffer, AreaFeatureBin::AreaFeature area, osg::Vec3d modelCenter, osg::Geometry* geometry, osg::Vec3Array* v, osg::Vec2Array* t, osg::Vec3Array* n, unsigned int xsize, unsigned int ysize)
{
if (area._nodes.size() < 3) {
SG_LOG(SG_TERRAIN, SG_ALERT, "Coding error - AreaFeatureBin::LineFeature with fewer than three nodes");
@@ -2095,7 +2099,7 @@ void VPBTechnique::generateAreaFeature(BufferData& buffer, Locator* masterLocato
auto area_iter = area._nodes.begin();
osg::Vec3d pt = *area_iter - modelCenter;
- ma = getMeshIntersection(buffer, masterLocator, pt, up);
+ ma = getMeshIntersection(buffer, pt, up);
// Only build this area if the first vertex is on the mesh. This ensures that the
// area is only generated once, no matter how many tiles it spans.
@@ -2107,7 +2111,7 @@ void VPBTechnique::generateAreaFeature(BufferData& buffer, Locator* masterLocato
// Ignore small segments - we really don't need resolution less than 10m
if ((pt - last_pt).length2() < 100.0) continue;
- ma = getMeshIntersection(buffer, masterLocator, pt, up);
+ ma = getMeshIntersection(buffer, pt, up);
if (ma !=pt) {
elev += up*ma;
elev_count++;
@@ -2168,7 +2172,7 @@ osg::Image* VPBTechnique::generateWaterTexture(Atlas* atlas) {
}
-osg::Image* VPBTechnique::generateCoastTexture(BufferData& buffer, Locator* masterLocator) {
+osg::Image* VPBTechnique::generateCoastTexture(BufferData& buffer) {
unsigned int coast_features_lod_range = 4;
unsigned int waterTextureSize = 2048;
@@ -2197,7 +2201,7 @@ osg::Image* VPBTechnique::generateCoastTexture(BufferData& buffer, Locator* mast
osg::Vec3d up = world;
up.normalize();
- TileBounds tileBounds(masterLocator, up);
+ TileBounds tileBounds(buffer._masterLocator, up);
bool coastsFound = false;
@@ -2244,7 +2248,7 @@ osg::Image* VPBTechnique::generateCoastTexture(BufferData& buffer, Locator* mast
if (clipped.size() > 1) {
// We need at least two points to render a line.
LineFeatureBin::LineFeature line = LineFeatureBin::LineFeature(clipped, coastWidth);
- addCoastline(masterLocator, coastTexture, line, waterTextureSize, tileSize, coastWidth);
+ addCoastline(buffer._masterLocator, coastTexture, line, waterTextureSize, tileSize, coastWidth);
}
}
}
@@ -2376,7 +2380,7 @@ void VPBTechnique::addCoastline(Locator* masterLocator, osg::Image* waterTexture
}
// Find the intersection of a given SGGeod with the terrain mesh
-osg::Vec3d VPBTechnique::getMeshIntersection(BufferData& buffer, Locator* masterLocator, osg::Vec3d pt, osg::Vec3d up)
+osg::Vec3d VPBTechnique::getMeshIntersection(BufferData& buffer, osg::Vec3d pt, osg::Vec3d up)
{
osg::ref_ptr<osgUtil::LineSegmentIntersector> intersector;
intersector = new osgUtil::LineSegmentIntersector(pt - up*100.0, pt + up*8000.0);
@@ -2633,4 +2637,32 @@ float VPBTechnique::getMeanLoadTime(int tileLevel) {
if (_loadStats.find(tileLevel) == _loadStats.end()) return 0.0;
return _loadStats[tileLevel].second / _loadStats[tileLevel].first;
+}
+
+BVHMaterial* VPBTechnique::getMaterial(osg::Vec3d point) {
+ osg::Vec3d local;
+ _currentBufferData->_masterLocator->convertModelToLocal(point, local);
+
+ auto image = _terrainTile->getColorLayer(0)->getImage();
+ // Blue channel indicates if this is water, green channel is an index into the landclass data
+ unsigned int tx = (unsigned int) (image->s() * local.x()) % image->s();
+ unsigned int ty = (unsigned int) (image->t() * local.y()) % image->t();
+ auto c = image->getColor(tx, ty);
+ unsigned int lc = (unsigned int) std::abs(std::round(c.g() * 255.0));
+ SGSharedPtr<SGMaterial> mat = _currentBufferData->_BVHMaterialMap[lc];
+ if (mat) {
+ //SG_LOG(SG_TERRAIN, SG_ALERT, "Material: " << mat->get_names()[0]);
+ return mat;
+ } else {
+ SG_LOG(SG_TERRAIN, SG_ALERT, "Unexpected Landclass index in landclass texture: " << lc << " original texture value: " << c.g() << " at point " << local);
+ return new BVHMaterial();
+ }
+}
+
+SGSphered VPBTechnique::computeBoundingSphere() const {
+ SGSphered bs;
+ osg::Vec3d center = _currentBufferData->_transform->getBound().center();
+ bs.setCenter(SGVec3d(center.x(), center.y(), center.z()));
+ bs.setRadius(_currentBufferData->_transform->getBound().radius());
+ return bs;
}
\ No newline at end of file
diff --git a/simgear/scene/tgdb/VPBTechnique.hxx b/simgear/scene/tgdb/VPBTechnique.hxx
index 89d0d674..78f59800 100644
--- a/simgear/scene/tgdb/VPBTechnique.hxx
+++ b/simgear/scene/tgdb/VPBTechnique.hxx
@@ -29,6 +29,8 @@
#include <osgTerrain/Locator>
#include <simgear/bucket/newbucket.hxx>
+#include <simgear/bvh/BVHMaterial.hxx>
+#include <simgear/math/SGGeometry.hxx>
#include <simgear/scene/material/EffectGeode.hxx>
#include <simgear/scene/material/matlib.hxx>
#include <simgear/scene/tgdb/AreaFeatureBin.hxx>
@@ -64,6 +66,9 @@ class VPBTechnique : public TerrainTechnique
/** Traverse the terain subgraph.*/
virtual void traverse(osg::NodeVisitor& nv);
+ virtual BVHMaterial* getMaterial(osg::Vec3d point);
+ virtual SGSphered computeBoundingSphere() const;
+
virtual void cleanSceneGraph();
void setFilterBias(float filterBias);
@@ -123,26 +128,27 @@ class VPBTechnique : public TerrainTechnique
osg::ref_ptr<osg::Group> _lineFeatures;
float _width;
float _height;
+ Atlas::AtlasMap _BVHMaterialMap;
+ osg::ref_ptr<Locator> _masterLocator;
protected:
~BufferData() {}
};
- virtual osg::Vec3d computeCenter(BufferData& buffer, Locator* masterLocator);
- virtual osg::Vec3d computeCenterModel(BufferData& buffer, Locator* masterLocator);
- const virtual SGGeod computeCenterGeod(BufferData& buffer, Locator* masterLocator);
+ virtual osg::Vec3d computeCenter(BufferData& buffer);
+ virtual osg::Vec3d computeCenterModel(BufferData& buffer);
+ const virtual SGGeod computeCenterGeod(BufferData& buffer);
- virtual void generateGeometry(BufferData& buffer, Locator* masterLocator, const osg::Vec3d& centerModel, osg::ref_ptr<SGMaterialCache> matcache);
+ virtual void generateGeometry(BufferData& buffer, const osg::Vec3d& centerModel, osg::ref_ptr<SGMaterialCache> matcache);
- virtual void applyColorLayers(BufferData& buffer, Locator* masterLocator, osg::ref_ptr<SGMaterialCache> matcache);
+ virtual void applyColorLayers(BufferData& buffer, osg::ref_ptr<SGMaterialCache> matcache);
virtual double det2(const osg::Vec2d a, const osg::Vec2d b);
- virtual void applyMaterials(BufferData& buffer, Locator* masterLocator, osg::ref_ptr<SGMaterialCache> matcache);
+ virtual void applyMaterials(BufferData& buffer, osg::ref_ptr<SGMaterialCache> matcache);
- virtual void applyLineFeatures(BufferData& buffer, Locator* masterLocator, osg::ref_ptr<SGMaterialCache> matcache);
+ virtual void applyLineFeatures(BufferData& buffer, osg::ref_ptr<SGMaterialCache> matcache);
virtual void generateLineFeature(BufferData& buffer,
- Locator* masterLocator,
LineFeatureBin::LineFeature road,
osg::Vec3d modelCenter,
osg::Vec3Array* v,
@@ -157,9 +163,8 @@ class VPBTechnique : public TerrainTechnique
bool light_edge_offset,
double elevation_offset_m);
- virtual void applyAreaFeatures(BufferData& buffer, Locator* masterLocator, osg::ref_ptr<SGMaterialCache> matcache);
+ virtual void applyAreaFeatures(BufferData& buffer, osg::ref_ptr<SGMaterialCache> matcache);
virtual void generateAreaFeature(BufferData& buffer,
- Locator* masterLocator,
AreaFeatureBin::AreaFeature area,
osg::Vec3d modelCenter,
osg::Geometry* geometry,
@@ -169,13 +174,13 @@ class VPBTechnique : public TerrainTechnique
unsigned int xsize,
unsigned int ysize);
- virtual osg::Image* generateCoastTexture(BufferData& buffer, Locator* masterLocator);
+ virtual osg::Image* generateCoastTexture(BufferData& buffer);
virtual osg::Image* generateWaterTexture(Atlas* atlas);
virtual void addCoastline(Locator* masterLocator, osg::Image* waterTexture, LineFeatureBin::LineFeature line, unsigned int waterTextureSize, float tileSize, float coastWidth);
virtual void updateWaterTexture(osg::Image* waterTexture, unsigned int waterTextureSize, osg::Vec4 color, float x, float y);
virtual void writeShoreStripe(osg::Image* waterTexture, unsigned int waterTextureSize, float tileSize, float coastWidth, float x, float y, int dx, int dy);
- virtual osg::Vec3d getMeshIntersection(BufferData& buffer, Locator* masterLocator, osg::Vec3d pt, osg::Vec3d up);
+ virtual osg::Vec3d getMeshIntersection(BufferData& buffer, osg::Vec3d pt, osg::Vec3d up);
static void updateStats(int tileLevel, float loadTime);
static float getMeanLoadTime(int tileLevel);
|