Add the ability to add multiple ModelGeometry's for a RenderableModel to show models with multiple OBJ files without needing to create multiple scene graph nodes

This commit is contained in:
Alexander Bock
2020-08-18 16:34:54 +02:00
parent d4291163ba
commit 7603edf906
7 changed files with 213 additions and 93 deletions

View File

@@ -57,6 +57,167 @@ local initializeAndAddNodes = function()
YAxis = transforms.EarthInertial.Identifier
}
},
Renderable = {
Type = "RenderableModel",
Geometry = {
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/0.obj",
ColorTexture = models .. "/0.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/1.obj",
ColorTexture = models .. "/1.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/2.obj",
ColorTexture = models .. "/2.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/3.obj",
ColorTexture = models .. "/3.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/4.obj",
ColorTexture = models .. "/4.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/5.obj",
ColorTexture = models .. "/5.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/6.obj",
ColorTexture = models .. "/6.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/7.obj",
ColorTexture = models .. "/7.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/8.obj",
ColorTexture = models .. "/8.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/10.obj",
ColorTexture = models .. "/10.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/11.obj",
ColorTexture = models .. "/11.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/13.obj",
ColorTexture = models .. "/13.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/14.obj",
ColorTexture = models .. "/14.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/15.obj",
ColorTexture = models .. "/15.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/16.obj",
ColorTexture = models .. "/16.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/17.obj",
ColorTexture = models .. "/17.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/19.obj",
ColorTexture = models .. "/19.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/21.obj",
ColorTexture = models .. "/21.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/22.obj",
ColorTexture = models .. "/22.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/23.obj",
ColorTexture = models .. "/23.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/24.obj",
ColorTexture = models .. "/24.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/25.obj",
ColorTexture = models .. "/25.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/foilsilver.obj",
ColorTexture = models .. "/foilsilver.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/olive.obj",
ColorTexture = models .. "/olive.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/basemetal.obj",
ColorTexture = models .. "/basemetal.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/white_20.obj",
ColorTexture = models .. "/white_20.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/plasticblack.obj",
ColorTexture = models .. "/plasticblack.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/ecostresswhite.obj",
ColorTexture = models .. "/ecostresswhite.png"
},
{
Type = "MultiModelGeometry",
GeometryFile = models .. "/plain.obj",
ColorTexture = models .. "/plain.png"
},
},
LightSources = {
{
Type = "SceneGraphLightSource",
Identifier = "Sun",
Node = sunTransforms.SolarSystemBarycenter.Identifier,
Intensity = 1.0
}
},
PerformShading = true,
DisableFaceCulling = true
},
GUI = {
Name = "ISSparentNode",
Path = "/Solar System/Planets/Earth/Satellites/ISS",
@@ -64,24 +225,6 @@ local initializeAndAddNodes = function()
}
}
local list = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "10", "11",
"13", "14", "15", "16", "17", "19", "21", "22", "23", "24", "25",
"foilsilver", "olive", "basemetal", "white_20", "plasticblack", "ecostresswhite",
"plain"}
local nodes = { iss, parentNode }
for i, info in ipairs(list) do
n = assetHelper.createModelPart(
parentNode.Identifier,
sunTransforms.SolarSystemBarycenter.Identifier,
models,
info,
info .. ".png",
true
)
table.insert(nodes, n)
end
local issTrail = {
Identifier = identifier .. "_trail",
Parent = transforms.EarthInertial.Identifier,
@@ -108,7 +251,7 @@ local initializeAndAddNodes = function()
}
table.insert(nodes, issTrail)
return nodes
return { iss, parentNode, issTrail }
end
asset.onInitialize(function ()

View File

@@ -43,14 +43,8 @@ namespace {
constexpr const char* KeyType = "Type";
constexpr const char* KeyGeomModelFile = "GeometryFile";
constexpr const char* KeyColorTexture = "ColorTexture";
constexpr const int8_t CurrentCacheVersion = 3;
constexpr openspace::properties::Property::PropertyInfo TextureInfo = {
"ColorTexture",
"Color Texture",
"This value points to a color texture file that is applied to the geometry "
"rendered in this object."
};
} // namespace
namespace openspace::modelgeometry {
@@ -76,10 +70,11 @@ documentation:: Documentation ModelGeometry::Documentation() {
"location of the .mod file."
},
{
TextureInfo.identifier,
KeyColorTexture,
new StringVerifier,
Optional::Yes,
TextureInfo.description
"This value points to a color texture file that is applied to the "
"geometry rendered in this object."
}
}
};
@@ -99,10 +94,7 @@ std::unique_ptr<ModelGeometry> ModelGeometry::createFromDictionary(
return std::unique_ptr<ModelGeometry>(geometry);
}
ModelGeometry::ModelGeometry(const ghoul::Dictionary& dictionary)
: properties::PropertyOwner({ "ModelGeometry" })
, _colorTexturePath(TextureInfo)
{
ModelGeometry::ModelGeometry(const ghoul::Dictionary& dictionary) {
documentation::testSpecificationAndThrow(
Documentation(),
dictionary,
@@ -111,13 +103,8 @@ ModelGeometry::ModelGeometry(const ghoul::Dictionary& dictionary)
_file = absPath(dictionary.value<std::string>(KeyGeomModelFile));
_colorTexturePath.onChange([this]() { _colorTextureDirty = true; });
addProperty(_colorTexturePath);
if (dictionary.hasKey(TextureInfo.identifier)) {
_colorTexturePath = absPath(dictionary.value<std::string>(
TextureInfo.identifier
));
if (dictionary.hasKey(KeyColorTexture)) {
_colorTexturePath = absPath(dictionary.value<std::string>(KeyColorTexture));
}
}
@@ -131,28 +118,6 @@ void ModelGeometry::bindTexture() {
}
}
void ModelGeometry::update() {
if (_colorTextureDirty) {
_texture = nullptr;
if (!_colorTexturePath.value().empty()) {
_texture = ghoul::io::TextureReader::ref().loadTexture(
absPath(_colorTexturePath)
);
if (_texture) {
LDEBUGC(
"RenderableModel",
fmt::format("Loaded texture from '{}'", absPath(_colorTexturePath))
);
_texture->uploadTexture();
_texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
_texture->purgeFromRAM();
}
}
_colorTextureDirty = false;
}
}
void ModelGeometry::render() {
glBindVertexArray(_vaoID);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _ibo);
@@ -230,6 +195,21 @@ bool ModelGeometry::initialize(Renderable* parent) {
glBindVertexArray(0);
if (!_colorTexturePath.empty()) {
_texture = ghoul::io::TextureReader::ref().loadTexture(
absPath(_colorTexturePath)
);
if (_texture) {
LDEBUGC(
"RenderableModel",
fmt::format("Loaded texture from '{}'", absPath(_colorTexturePath))
);
_texture->uploadTexture();
_texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
_texture->purgeFromRAM();
}
}
return true;
}

View File

@@ -25,9 +25,6 @@
#ifndef __OPENSPACE_MODULE_BASE___MODELGEOMETRY___H__
#define __OPENSPACE_MODULE_BASE___MODELGEOMETRY___H__
#include <openspace/properties/propertyowner.h>
#include <openspace/properties/stringproperty.h>
#include <ghoul/opengl/ghoul_gl.h>
#include <ghoul/opengl/texture.h>
#include <memory>
@@ -40,7 +37,7 @@ namespace openspace::documentation { struct Documentation; }
namespace openspace::modelgeometry {
class ModelGeometry : public properties::PropertyOwner {
class ModelGeometry {
public:
struct Vertex {
GLfloat location[4];
@@ -58,7 +55,6 @@ public:
virtual bool initialize(Renderable* parent);
virtual void deinitialize();
void bindTexture();
void update();
void render();
virtual bool loadModel(const std::string& filename) = 0;
@@ -77,15 +73,13 @@ protected:
bool loadCachedFile(const std::string& filename);
bool saveCachedFile(const std::string& filename);
properties::StringProperty _colorTexturePath;
bool _colorTextureDirty = false;
GLuint _vaoID = 0;
GLuint _vbo = 0;
GLuint _ibo = 0 ;
GLenum _mode = GL_TRIANGLES;
double _boundingRadius = 0.0;
std::string _colorTexturePath;
std::unique_ptr<ghoul::opengl::Texture> _texture;
std::vector<Vertex> _vertices;

View File

@@ -114,7 +114,13 @@ documentation::Documentation RenderableModel::Documentation() {
{
{
KeyGeometry,
new ReferencingVerifier("base_geometry_model"),
new TableVerifier({
{
"*",
new ReferencingVerifier("base_geometry_model"),
Optional::Yes
}
}),
Optional::No,
"This specifies the model that is rendered by the Renderable."
},
@@ -204,7 +210,11 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
if (dictionary.hasKey(KeyGeometry)) {
ghoul::Dictionary dict = dictionary.value<ghoul::Dictionary>(KeyGeometry);
_geometry = modelgeometry::ModelGeometry::createFromDictionary(dict);
for (int i = 1; i <= dict.size(); ++i) {
std::string key = std::to_string(i);
ghoul::Dictionary geom = dict.value<ghoul::Dictionary>(key);
_geometry.push_back(modelgeometry::ModelGeometry::createFromDictionary(geom));
}
}
if (dictionary.hasKey(ModelTransformInfo.identifier)) {
@@ -244,7 +254,6 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
addPropertySubOwner(_lightSourcePropertyOwner);
addPropertySubOwner(_geometry.get());
addProperty(_ambientIntensity);
addProperty(_diffuseIntensity);
@@ -292,14 +301,16 @@ void RenderableModel::initializeGL() {
ghoul::opengl::updateUniformLocations(*_program, _uniformCache, UniformNames);
_geometry->initialize(this);
for (const std::unique_ptr<modelgeometry::ModelGeometry>& geom : _geometry) {
geom->initialize(this);
}
}
void RenderableModel::deinitializeGL() {
if (_geometry) {
_geometry->deinitialize();
_geometry = nullptr;
for (const std::unique_ptr<modelgeometry::ModelGeometry>& geom : _geometry) {
geom->deinitialize();
}
_geometry.clear();
BaseModule::ProgramObjectManager.release(
ProgramName,
@@ -388,20 +399,18 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) {
_performShading
);
_geometry->setUniforms(*_program);
// Bind texture
ghoul::opengl::TextureUnit unit;
unit.activate();
_geometry->bindTexture();
_program->setUniform(_uniformCache.texture, unit);
if (_disableFaceCulling) {
glDisable(GL_CULL_FACE);
}
_geometry->render();
ghoul::opengl::TextureUnit unit;
unit.activate();
_program->setUniform(_uniformCache.texture, unit);
for (const std::unique_ptr<modelgeometry::ModelGeometry>& geom : _geometry) {
geom->setUniforms(*_program);
geom->bindTexture();
geom->render();
}
if (_disableFaceCulling) {
glEnable(GL_CULL_FACE);
}
@@ -414,7 +423,6 @@ void RenderableModel::update(const UpdateData&) {
_program->rebuildFromFile();
ghoul::opengl::updateUniformLocations(*_program, _uniformCache, UniformNames);
}
_geometry->update();
}
} // namespace openspace

View File

@@ -66,7 +66,7 @@ public:
static documentation::Documentation Documentation();
private:
std::unique_ptr<modelgeometry::ModelGeometry> _geometry;
std::vector<std::unique_ptr<modelgeometry::ModelGeometry>> _geometry;
properties::FloatProperty _ambientIntensity;

View File

@@ -132,7 +132,6 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di
Dictionary geometryDictionary = dictionary.value<Dictionary>(keyGeometry);
_geometry = modelgeometry::ModelGeometry::createFromDictionary(geometryDictionary);
addPropertySubOwner(_geometry.get());
addPropertySubOwner(_projectionComponent);
_projectionComponent.initialize(
@@ -198,7 +197,6 @@ void RenderableModelProjection::initializeGL() {
DepthFboUniformNames
);
loadTextures();
_projectionComponent.initializeGL();
float bs = boundingSphere();
@@ -355,8 +353,6 @@ void RenderableModelProjection::update(const UpdateData& data) {
data.modelTransform.translation;
_sunPosition = static_cast<glm::vec3>(p);
_geometry->update();
}
void RenderableModelProjection::imageProjectGPU(

View File

@@ -65,7 +65,6 @@ public:
static documentation::Documentation Documentation();
private:
bool loadTextures();
void attitudeParameters(double time);
void imageProjectGPU(const ghoul::opengl::Texture& projectionTexture);