mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-05 11:09:37 -06:00
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:
@@ -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 ()
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -65,7 +65,6 @@ public:
|
||||
static documentation::Documentation Documentation();
|
||||
|
||||
private:
|
||||
bool loadTextures();
|
||||
void attitudeParameters(double time);
|
||||
void imageProjectGPU(const ghoul::opengl::Texture& projectionTexture);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user