From ac38f73faa445e0cf8564d048cf32af4b4462125 Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Sat, 3 May 2014 19:53:12 +0200 Subject: [PATCH] More property work Add StringProperty Add possibility for callbacks Switch RenderablePlanet to use Properties --- include/openspace/properties/property.h | 16 +++- include/openspace/properties/stringproperty.h | 54 ++++++++++++ .../openspace/properties/templateproperty.h | 3 + .../openspace/properties/templateproperty.inl | 15 +++- include/openspace/rendering/renderable.h | 1 + .../openspace/rendering/renderableplanet.h | 41 +++++---- src/properties/property.cpp | 20 ++++- src/properties/propertyowner.cpp | 5 +- src/properties/stringproperty.cpp | 61 ++++++++++++++ src/rendering/renderableplanet.cpp | 83 ++++++++++++------- 10 files changed, 246 insertions(+), 53 deletions(-) create mode 100644 include/openspace/properties/stringproperty.h create mode 100644 src/properties/stringproperty.cpp diff --git a/include/openspace/properties/property.h b/include/openspace/properties/property.h index e6c412de46..ad95481496 100644 --- a/include/openspace/properties/property.h +++ b/include/openspace/properties/property.h @@ -29,11 +29,14 @@ #include #include +#include #include namespace openspace { namespace properties { +class PropertyOwner; + class Property { public: Property(std::string identifier, std::string guiName); @@ -46,9 +49,14 @@ public: virtual void set(boost::any value); virtual const std::type_info& type() const; + virtual void onChange(std::function callback); + const std::string& identifier() const; const std::string& guiName() const; + PropertyOwner* owner() const; + void setPropertyOwner(PropertyOwner* owner); + void setGroupIdentifier(std::string groupId); std::string groupIdentifier() const; @@ -62,16 +70,22 @@ public: bool viewOption(const std::string& option) const; struct ViewOptions { - static const std::string LightPosition; static const std::string Color; + static const std::string LightPosition; + static const std::string PowerScaledScalar; + static const std::string PowerScaledCoordinate; }; const ghoul::Dictionary& metaData() const; protected: + PropertyOwner* _owner; + std::string _identifier; std::string _guiName; ghoul::Dictionary _metaData; + + std::vector> _onChangeCallbacks; }; } // namespace properties diff --git a/include/openspace/properties/stringproperty.h b/include/openspace/properties/stringproperty.h new file mode 100644 index 0000000000..c1dc995c86 --- /dev/null +++ b/include/openspace/properties/stringproperty.h @@ -0,0 +1,54 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014 * +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy of this * +* software and associated documentation files (the "Software"), to deal in the Software * +* without restriction, including without limitation the rights to use, copy, modify, * +* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * +* permit persons to whom the Software is furnished to do so, subject to the following * +* conditions: * +* * +* The above copyright notice and this permission notice shall be included in all copies * +* or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * +* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * +* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * +* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * +* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +****************************************************************************************/ + +#ifndef __STRINGPROPERTY_H__ +#define __STRINGPROPERTY_H__ + +#include + +namespace openspace { +namespace properties { + +class StringProperty : public TemplateProperty { +public: + StringProperty(std::string identifier, std::string guiName); + StringProperty(std::string identifier, std::string guiName, std::string value); + + using TemplateProperty::operator=; +}; + +template <> +std::string PropertyDelegate>::className(); + +template <> +template <> +std::string PropertyDelegate>::defaultValue(); + +//REGISTER_TEMPLATEPROPERTY_HEADER(StringProperty, std::string); + + +} // namespace properties +} // namespace openspace + +#endif // __STRINGPROPERTY_H__ \ No newline at end of file diff --git a/include/openspace/properties/templateproperty.h b/include/openspace/properties/templateproperty.h index f5fdc8fbc5..5bc1ac7777 100644 --- a/include/openspace/properties/templateproperty.h +++ b/include/openspace/properties/templateproperty.h @@ -44,6 +44,9 @@ public: operator T(); TemplateProperty& operator=(T val); + void setValue(T val); + T value() const; + protected: T _value; }; diff --git a/include/openspace/properties/templateproperty.inl b/include/openspace/properties/templateproperty.inl index 1adbe27c9a..5f746918c9 100644 --- a/include/openspace/properties/templateproperty.inl +++ b/include/openspace/properties/templateproperty.inl @@ -75,10 +75,23 @@ TemplateProperty::operator T() { template TemplateProperty& TemplateProperty::operator=(T val) { - _value = val; + setValue(val); return *this; } +template +T openspace::properties::TemplateProperty::value() const +{ + return _value; +} + +template +void openspace::properties::TemplateProperty::setValue(T val) +{ + _value = val; +} + + template boost::any TemplateProperty::get() const { return boost::any(_value); diff --git a/include/openspace/rendering/renderable.h b/include/openspace/rendering/renderable.h index d92e017ee6..5c3e883933 100644 --- a/include/openspace/rendering/renderable.h +++ b/include/openspace/rendering/renderable.h @@ -51,6 +51,7 @@ public: virtual void render(const Camera *camera, const psc &thisPosition) = 0; virtual void update(); + protected: //Renderable(); private: diff --git a/include/openspace/rendering/renderableplanet.h b/include/openspace/rendering/renderableplanet.h index 05bb64dee3..b1d59efc52 100644 --- a/include/openspace/rendering/renderableplanet.h +++ b/include/openspace/rendering/renderableplanet.h @@ -28,41 +28,46 @@ // open space includes #include #include +#include +#include +#include // ghoul includes #include #include + namespace openspace { -class RenderablePlanet: public Renderable { +class RenderablePlanet : public Renderable { public: + // constructors & destructor + RenderablePlanet(const ghoul::Dictionary& dictionary); + ~RenderablePlanet(); - // constructors & destructor - RenderablePlanet(const ghoul::Dictionary& dictionary); - ~RenderablePlanet(); + bool initialize() override; + bool deinitialize() override; - bool initialize(); - bool deinitialize(); + void setProgramObject(ghoul::opengl::ProgramObject* programObject = nullptr); + void setTexture(ghoul::opengl::Texture* texture); - void setProgramObject(ghoul::opengl::ProgramObject *programObject = nullptr); - void setTexture(ghoul::opengl::Texture *texture); + void render(const Camera* camera, const psc& thisPosition) override; + void update() override; - virtual void render(const Camera *camera, const psc &thisPosition); - virtual void update(); +protected: + void createSphere(); + void loadTexture(); private: - // shader + properties::Vec2Property _radius; + properties::IntProperty _segments; + properties::StringProperty _colorTexturePath; + ghoul::opengl::ProgramObject* _programObject; - - // texture - std::string _texturePath; ghoul::opengl::Texture* _texture; - - // Object PowerScaledSphere* _planet; }; -} // namespace openspace +} // namespace openspace -#endif // __RENDERABLEPLANET_H__ \ No newline at end of file +#endif // __RENDERABLEPLANET_H__ \ No newline at end of file diff --git a/src/properties/property.cpp b/src/properties/property.cpp index 9ae7aa9820..7268388b67 100644 --- a/src/properties/property.cpp +++ b/src/properties/property.cpp @@ -33,8 +33,11 @@ namespace { const std::string _metaDataKeyReadOnly = "isReadOnly"; } -const std::string Property::ViewOptions::LightPosition = "lightPosition"; const std::string Property::ViewOptions::Color = "color"; +const std::string Property::ViewOptions::LightPosition = "lightPosition"; +const std::string Property::ViewOptions::PowerScaledCoordinate = "powerScaledCoordinate"; +const std::string Property::ViewOptions::PowerScaledScalar = "powerScaledScalar"; + Property::Property(std::string identifier, std::string guiName) : _identifier(std::move(identifier)) @@ -107,5 +110,20 @@ const ghoul::Dictionary& Property::metaData() const { return _metaData; } +void Property::onChange(std::function callback) { + _onChangeCallbacks.emplace_back(std::move(callback)); + +} + +PropertyOwner* Property::owner() const +{ + return _owner; +} + +void Property::setPropertyOwner(PropertyOwner* owner) +{ + _owner = owner; +} + } // namespace properties } // namespace openspace diff --git a/src/properties/propertyowner.cpp b/src/properties/propertyowner.cpp index a940f7bc5a..e2af6ebc19 100644 --- a/src/properties/propertyowner.cpp +++ b/src/properties/propertyowner.cpp @@ -93,9 +93,11 @@ void PropertyOwner::addProperty(Property* prop) { << "' already present in PropertyOwner"); return; } - else + else { // Otherwise we have found the correct position to add it in _properties.insert(it, prop); + prop->setPropertyOwner(this); + } } void PropertyOwner::addProperty(Property& prop) { @@ -114,6 +116,7 @@ void PropertyOwner::removeProperty(Property* prop) { // If we found the property identifier, we can delete it if (it != _properties.end() && (*it)->identifier() == prop->identifier()) { + (*it)->setPropertyOwner(nullptr); _properties.erase(it); } else diff --git a/src/properties/stringproperty.cpp b/src/properties/stringproperty.cpp new file mode 100644 index 0000000000..a60115cd29 --- /dev/null +++ b/src/properties/stringproperty.cpp @@ -0,0 +1,61 @@ +/***************************************************************************************** +* * +* OpenSpace * +* * +* Copyright (c) 2014 * +* * +* Permission is hereby granted, free of charge, to any person obtaining a copy of this * +* software and associated documentation files (the "Software"), to deal in the Software * +* without restriction, including without limitation the rights to use, copy, modify, * +* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * +* permit persons to whom the Software is furnished to do so, subject to the following * +* conditions: * +* * +* The above copyright notice and this permission notice shall be included in all copies * +* or substantial portions of the Software. * +* * +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * +* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * +* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * +* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * +* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * +* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * +****************************************************************************************/ + +#include + +namespace openspace { +namespace properties { + +StringProperty::StringProperty(std::string identifier, std::string guiName) + : StringProperty( + std::move(identifier), std::move(guiName), + PropertyDelegate>::defaultValue()) +{ +} + +StringProperty::StringProperty(std::string identifier, std::string guiName, + std::string value) + : TemplateProperty(std::move(identifier), std::move(guiName), std::move(value)) +{} + +template <> +std::string PropertyDelegate>::className() { + return "StringProperty"; +} + +template <> +template <> +std::string PropertyDelegate>::defaultValue() { + return ""; +} + + +//REGISTER_TEMPLATEPROPERTY_SOURCE(StringProperty, std::string, ""); +// +//std::string openspace::properties::StringProperty::className() const { +// return "StringProperty"; +//} + +} // namespace properties +} // namespace openspace diff --git a/src/rendering/renderableplanet.cpp b/src/rendering/renderableplanet.cpp index 6861dbf454..7ac6618a4e 100644 --- a/src/rendering/renderableplanet.cpp +++ b/src/rendering/renderableplanet.cpp @@ -39,13 +39,16 @@ namespace openspace { RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) : Renderable(dictionary) + , _radius("radius", "Radius", glm::vec2(1.f, 0.f), glm::vec2(-10.f, -20.f), + glm::vec2(10.f, 20.f)) + , _segments("segments", "Segments", 20, 1, 1000) + , _colorTexturePath("colorTexture", "Color Texture") , _programObject(nullptr) - , _texturePath("") , _texture(nullptr) , _planet(nullptr) { double value = 1.0f, exponent = 0.0f; - double segments = 20.0; + int segments = 20; if (dictionary.hasKey("Geometry.Radius.1")) dictionary.getValue("Geometry.Radius.1", value); @@ -53,12 +56,12 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) if (dictionary.hasKey("Geometry.Radius.2")) dictionary.getValue("Geometry.Radius.2", exponent); + _radius = glm::vec2(value, exponent); + if (dictionary.hasKey("Geometry.Segments")) dictionary.getValue("Geometry.Segments", segments); - // create the power scaled scalar - pss planetSize(value, exponent); - setBoundingSphere(planetSize); + _segments = segments; // get path if available std::string path = ""; @@ -67,13 +70,22 @@ RenderablePlanet::RenderablePlanet(const ghoul::Dictionary& dictionary) path += "/"; } - if (dictionary.hasKey("Textures.Color")) { - std::string texturePath; + std::string texturePath = ""; + if (dictionary.hasKey("Textures.Color")) dictionary.getValue("Textures.Color", texturePath); - _texturePath = path + texturePath; - } - _planet = new PowerScaledSphere(pss(value, exponent), static_cast(segments)); + _colorTexturePath = path + texturePath; + + + addProperty(_radius); + _radius.onChange(std::bind(&RenderablePlanet::createSphere, this)); + addProperty(_segments); + _segments.onChange(std::bind(&RenderablePlanet::createSphere, this)); + + addProperty(_colorTexturePath); + _colorTexturePath.onChange(std::bind(&RenderablePlanet::loadTexture, this)); + + createSphere(); } RenderablePlanet::~RenderablePlanet() { @@ -81,35 +93,21 @@ RenderablePlanet::~RenderablePlanet() { } bool RenderablePlanet::initialize() { - bool completeSuccess = true; - if (_programObject == nullptr) { - completeSuccess = OsEng.ref().configurationManager().getValue("pscShader", _programObject); - } + if (_programObject == nullptr) + completeSuccess &= OsEng.ref().configurationManager().getValue("pscShader", _programObject); - if(_texturePath != "") { - _texture = ghoul::opengl::loadTexture(_texturePath); - if (_texture) { - LDEBUG("Loaded texture from '" << _texturePath <<"'"); - _texture->uploadTexture(); - } else { - completeSuccess = false; - } - } + loadTexture(); + completeSuccess &= (_texture != nullptr); + _planet->initialize(); return completeSuccess; } - - bool RenderablePlanet::deinitialize() { - if(_planet) - delete _planet; - - if(_texture) - delete _texture; - + delete _planet; + delete _texture; return true; } @@ -167,4 +165,27 @@ void RenderablePlanet::update() { } +void RenderablePlanet::createSphere() { + // create the power scaled scalar + + pss planetSize(_radius); + setBoundingSphere(planetSize); + + delete _planet; + _planet = new PowerScaledSphere(planetSize, _segments); + _planet->initialize(); +} + +void RenderablePlanet::loadTexture() { + delete _texture; + _texture = nullptr; + if (_colorTexturePath.value() != "") { + _texture = ghoul::opengl::loadTexture(_colorTexturePath); + if (_texture) { + LDEBUG("Loaded texture from '" << _colorTexturePath.value() << "'"); + _texture->uploadTexture(); + } + } +} + } // namespace openspace