Skip to content

Commit

Permalink
Merge commit '122a87a54' from orbweaver/master
Browse files Browse the repository at this point in the history
  • Loading branch information
codereader committed Dec 19, 2021
2 parents 748fc55 + 122a87a commit b3bf3d7
Show file tree
Hide file tree
Showing 60 changed files with 736 additions and 727 deletions.
12 changes: 12 additions & 0 deletions debian/changelog
@@ -1,3 +1,15 @@
darkradiant (2.14.0~focal2) focal; urgency=medium

* New major release on all platforms.
* Multi-selection support in Entity Inspector.
* New model importer with ability to import FBX models.
* Improved copy-paste of textures on angled faces.
* Improved scaling functionality in Surface Inspector.
* Redesigned Game Connection UI to enable hot reload in The Dark Mod.
* Numerous smaller fixes and improvements.

-- Matthew Mott <orbweaver3d@gmail.com> Sun, 28 Nov 2021 18:52:23 +0000

darkradiant (2.13.0~focal4) focal; urgency=medium

* Fix for incorrect entity/brush colours in canvas windows.
Expand Down
2 changes: 1 addition & 1 deletion debian/control
Expand Up @@ -2,7 +2,7 @@ Source: darkradiant
Section: editors
Priority: optional
Maintainer: Matthew Mott <orbweaver3d@gmail.com>
Build-Depends: debhelper (>= 10), cmake (>= 3.12), pkg-config, libxml2-dev, libglew-dev, python-dev, libvorbis-dev, libopenal-dev, libalut-dev, libjpeg-dev, libftgl-dev, libwxbase3.0-dev, libwxgtk3.0-gtk3-dev, libsigc++-2.0-dev, libglib2.0-dev, libeigen3-dev, libgit2-dev
Build-Depends: debhelper (>= 10), cmake (>= 3.12), pkg-config, asciidoctor, libxml2-dev, libglew-dev, python-dev, libvorbis-dev, libopenal-dev, libalut-dev, libjpeg-dev, libftgl-dev, libwxbase3.0-dev, libwxgtk3.0-gtk3-dev, libsigc++-2.0-dev, libglib2.0-dev, libeigen3-dev, libgit2-dev
Standards-Version: 4.5.1

Package: darkradiant
Expand Down
39 changes: 2 additions & 37 deletions include/ientity.h
Expand Up @@ -16,7 +16,7 @@ typedef std::shared_ptr<IEntityClass> IEntityClassPtr;
typedef std::shared_ptr<const IEntityClass> IEntityClassConstPtr;

// Observes a single entity key value and gets notified on change
class KeyObserver
class KeyObserver: public sigc::trackable
{
public:
using Ptr = std::shared_ptr<KeyObserver>;
Expand Down Expand Up @@ -286,7 +286,7 @@ class Entity
};

/// Callback for an entity key value change
using KeyObserverFunc = std::function<void(const std::string&)>;
using KeyObserverFunc = sigc::slot<void(const std::string&)>;

/**
* \brief Interface for a node which represents an entity.
Expand All @@ -306,30 +306,6 @@ class IEntityNode : public IRenderEntity,
/// Get a modifiable reference to the contained Entity
virtual Entity& getEntity() = 0;

/**
* @brief Attach a KeyObserver to observe a key's value changes.
*
* This is similar to attaching the KeyObserver directly to the
* EntityKeyValue, except that it is not required that the key value
* currently exist.
*
* If the key already exists, the KeyObserver will be immediately invoked
* with the current value; otherwise the observer will be invoked with an
* empty value. If the key is subsequently created or changed, the observer
* will be invoked with the new value. Likewise, if the key is deleted, the
* KeyObserver will be invoked with an empty value.
*
* It is the responsibility of the calling code to ensure that the
* KeyObserver remains alive as long as it is attached.
*
* @param key
* The key to observe.
*
* @param observer
* Observer to attach.
*/
virtual void addKeyObserver(const std::string& key, KeyObserver& observer) = 0;

/**
* @brief Observe key value changes using a callback function.
*
Expand All @@ -345,17 +321,6 @@ class IEntityNode : public IRenderEntity,
*/
virtual void observeKey(const std::string& key, KeyObserverFunc func) = 0;

/**
* @brief Remove a key observer attached with addKeyObserver.
*
* @param key
* Key being observed.
*
* @param observer
* Observer to remove.
*/
virtual void removeKeyObserver(const std::string& key, KeyObserver& observer) = 0;

/**
* greebo: Tells the entity to reload the child model. This usually
* includes removal of the child model node and triggering
Expand Down
7 changes: 7 additions & 0 deletions include/inode.h
Expand Up @@ -261,4 +261,11 @@ class INode :
virtual void transformChangedLocal() = 0;
};

/// Cast an INode to a particular interface
template<typename Interface>
std::shared_ptr<Interface> node_cast(INodePtr nodeP)
{
return std::dynamic_pointer_cast<Interface>(nodeP);
}

} // namespace scene
9 changes: 2 additions & 7 deletions include/iselectable.h
Expand Up @@ -26,14 +26,9 @@ namespace scene
typedef std::shared_ptr<INode> INodePtr;
}

inline ISelectablePtr Node_getSelectable(const scene::INodePtr& node)
{
return std::dynamic_pointer_cast<ISelectable>(node);
}

inline void Node_setSelected(const scene::INodePtr& node, bool selected)
{
ISelectablePtr selectable = Node_getSelectable(node);
ISelectablePtr selectable = scene::node_cast<ISelectable>(node);

if (selectable)
{
Expand All @@ -43,7 +38,7 @@ inline void Node_setSelected(const scene::INodePtr& node, bool selected)

inline bool Node_isSelected(const scene::INodePtr& node)
{
ISelectablePtr selectable = Node_getSelectable(node);
ISelectablePtr selectable = scene::node_cast<ISelectable>(node);

if (selectable)
{
Expand Down
24 changes: 12 additions & 12 deletions include/itransformable.h
Expand Up @@ -16,6 +16,17 @@ typedef BasicVector4<double> Vector4;
class Quaternion;
class Matrix4;

/**
* @brief Interface for a node which can be transformed via GUI operations.
*
* This interface is designed for nodes which can be translated, rotated and
* scaled via manipulators or other mouse operations. A number of incremental
* transforms can be accumulated, which are then "committed" via
* freezeTransform() or abandoned via revertTransform(). Typically the
* uncommitted live transform will affect rendering (so the user can see the
* effect of the manipulation), but will not be saved into entity spawnargs
* until the transform is frozen.
*/
class ITransformable
{
public:
Expand All @@ -37,15 +48,4 @@ class ITransformable
// before the operation started.
virtual const Vector3& getUntransformedOrigin() = 0;
};
typedef std::shared_ptr<ITransformable> ITransformablePtr;

namespace scene
{
class INode;
typedef std::shared_ptr<INode> INodePtr;
}

inline ITransformablePtr Node_getTransformable(const scene::INodePtr& node)
{
return std::dynamic_pointer_cast<ITransformable>(node);
}
typedef std::shared_ptr<ITransformable> ITransformablePtr;
5 changes: 0 additions & 5 deletions include/itransformnode.h
Expand Up @@ -15,11 +15,6 @@ class ITransformNode
};
typedef std::shared_ptr<ITransformNode> ITransformNodePtr;

inline ITransformNodePtr Node_getTransformNode(const scene::INodePtr& node)
{
return std::dynamic_pointer_cast<ITransformNode>(node);
}

/// An ITransformNode which can provide non-const access to its transform matrix
class IMatrixTransform: public ITransformNode
{
Expand Down
5 changes: 5 additions & 0 deletions libs/scene/Node.cpp
Expand Up @@ -479,6 +479,11 @@ void Node::setRenderSystem(const RenderSystemPtr& renderSystem)
_children.setRenderSystem(renderSystem);
}

bool Node::intersectsLight(const RendererLight& light) const
{
return light.lightAABB().intersects(worldAABB());
}

void Node::setForcedVisibility(bool forceVisible, bool includeChildren)
{
_forceVisible = forceVisible;
Expand Down
12 changes: 8 additions & 4 deletions libs/scene/Node.h
Expand Up @@ -18,9 +18,7 @@ class Graph;
typedef std::weak_ptr<Graph> GraphWeakPtr;

/// Main implementation of INode
class Node :
public virtual INode,
public std::enable_shared_from_this<Node>
class Node: public LitObject, public virtual INode, public std::enable_shared_from_this<Node>
{
public:
enum {
Expand Down Expand Up @@ -192,7 +190,13 @@ class Node :

// Base renderable implementation
virtual RenderSystemPtr getRenderSystem() const;
virtual void setRenderSystem(const RenderSystemPtr& renderSystem) override;
void setRenderSystem(const RenderSystemPtr& renderSystem) override;

// Default LitObject::intersectsLight implementation, does a simple
// intersection check between this node's worldAABB and the light's
// lightAABB. Subclasses may override to provide more precise intersection
// tests if appropriate.
bool intersectsLight(const RendererLight& light) const override;

protected:
// Set the "forced visible" flag, only to be used internally by subclasses
Expand Down
32 changes: 32 additions & 0 deletions libs/scene/TransformedCopy.h
@@ -0,0 +1,32 @@
#pragma once

namespace scene
{

/**
* @brief Storage for a value which exists in both a base and a
* temporarily-transformed state.
*
* The base state is typically stored in spawnargs (e.g. the "origin" key),
* whereas the transformed state is rendered during an ongoing mouse
* manipulation.
*
* @tparam T
* A copyable value (usually a Vector3 or an angle).
*/
template <typename T> struct TransformedCopy
{
/// Untransformed value
T base;

/// Temporarily-transformed value
T transformed;

/// Reset all transformed values to the base values
void revertTransform()
{
transformed = base;
}
};

} // namespace scene
2 changes: 1 addition & 1 deletion libs/transformlib.h
Expand Up @@ -38,7 +38,7 @@ void forEachTransformable(const INode& node, Func functor)
node.foreachNode(
[&](const scene::INodePtr& child) -> bool
{
ITransformablePtr transformable = Node_getTransformable(child);
ITransformablePtr transformable = scene::node_cast<ITransformable>(child);
if (transformable)
functor(*transformable);

Expand Down
26 changes: 13 additions & 13 deletions plugins/script/interfaces/SceneGraphInterface.cpp
Expand Up @@ -10,7 +10,7 @@
#include "EntityInterface.h"
#include "PatchInterface.h"

namespace script
namespace script
{

ScriptSceneNode::ScriptSceneNode(const scene::INodePtr& node) :
Expand All @@ -33,26 +33,26 @@ void ScriptSceneNode::removeFromParent()
}
}

void ScriptSceneNode::addToContainer(const ScriptSceneNode& container)
void ScriptSceneNode::addToContainer(const ScriptSceneNode& container)
{
scene::INodePtr node = _node.lock();
if (node != NULL) {
scene::addNodeToContainer(node, container);
}
}

const AABB& ScriptSceneNode::getWorldAABB() const
const AABB& ScriptSceneNode::getWorldAABB() const
{
scene::INodePtr node = _node.lock();
return node != NULL ? node->worldAABB() : _emptyAABB;
}

bool ScriptSceneNode::isNull() const
bool ScriptSceneNode::isNull() const
{
return _node.lock() == NULL;
}

ScriptSceneNode ScriptSceneNode::getParent()
ScriptSceneNode ScriptSceneNode::getParent()
{
scene::INodePtr node = _node.lock();
return node != NULL ? ScriptSceneNode(node->getParent()) : ScriptSceneNode(scene::INodePtr());
Expand All @@ -64,28 +64,28 @@ std::string ScriptSceneNode::getNodeType()
return node != NULL ? getNameForNodeType(node->getNodeType()) : "null";
}

void ScriptSceneNode::traverse(scene::NodeVisitor& visitor)
void ScriptSceneNode::traverse(scene::NodeVisitor& visitor)
{
scene::INodePtr node = _node.lock();
if (node != NULL) {
node->traverse(visitor);
}
}

void ScriptSceneNode::traverseChildren(scene::NodeVisitor& visitor)
void ScriptSceneNode::traverseChildren(scene::NodeVisitor& visitor)
{
scene::INodePtr node = _node.lock();
if (node != NULL) {
node->traverseChildren(visitor);
}
}

bool ScriptSceneNode::isSelected()
bool ScriptSceneNode::isSelected()
{
scene::INodePtr node = _node.lock();
if (node == NULL) return false;

ISelectablePtr selectable = Node_getSelectable(node);
ISelectablePtr selectable = scene::node_cast<ISelectable>(node);

return (selectable != NULL) ? selectable->isSelected() : false;
}
Expand All @@ -95,19 +95,19 @@ void ScriptSceneNode::setSelected(int selected)
scene::INodePtr node = _node.lock();
if (node == NULL) return;

ISelectablePtr selectable = Node_getSelectable(node);
ISelectablePtr selectable = scene::node_cast<ISelectable>(node);

if (selectable != NULL) {
selectable->setSelected(static_cast<bool>(selected));
}
}

void ScriptSceneNode::invertSelected()
void ScriptSceneNode::invertSelected()
{
scene::INodePtr node = _node.lock();
if (node == NULL) return;

ISelectablePtr selectable = Node_getSelectable(node);
ISelectablePtr selectable = scene::node_cast<ISelectable>(node);

if (selectable != NULL) {
selectable->setSelected(!selectable->isSelected());
Expand Down Expand Up @@ -161,7 +161,7 @@ void SceneGraphInterface::registerInterface(py::module& scope, py::dict& globals
// Add the module declaration to the given python namespace
py::class_<SceneGraphInterface> sceneGraphInterface(scope, "SceneGraph");
sceneGraphInterface.def("root", &SceneGraphInterface::root);

// Now point the Python variable "GlobalSceneGraph" to this instance
globals["GlobalSceneGraph"] = this;
}
Expand Down
2 changes: 1 addition & 1 deletion radiantcore/CMakeLists.txt
Expand Up @@ -33,7 +33,7 @@ add_library(radiantcore MODULE
entity/curve/CurveEditInstance.cpp
entity/curve/CurveNURBS.cpp
entity/SpawnArgs.cpp
entity/doom3group/Doom3GroupNode.cpp
entity/doom3group/StaticGeometryNode.cpp
entity/eclassmodel/EclassModelNode.cpp
entity/EntityModule.cpp
entity/EntityNode.cpp
Expand Down
7 changes: 1 addition & 6 deletions radiantcore/brush/BrushNode.cpp
Expand Up @@ -39,7 +39,6 @@ BrushNode::BrushNode(const BrushNode& other) :
ComponentEditable(other),
ComponentSnappable(other),
PlaneSelectable(other),
LitObject(other),
Transformable(other),
m_brush(*this, other.m_brush),
_selectedPoints(GL_POINTS),
Expand Down Expand Up @@ -75,7 +74,7 @@ std::string BrushNode::getFingerprint()
}

math::Hash hash;

hash.addSizet(static_cast<std::size_t>(m_brush.getDetailFlag() + 1));

hash.addSizet(m_brush.getNumFaces());
Expand Down Expand Up @@ -343,10 +342,6 @@ void BrushNode::DEBUG_verify() {
ASSERT_MESSAGE(m_faceInstances.size() == m_brush.DEBUG_size(), "FATAL: mismatch");
}

bool BrushNode::intersectsLight(const RendererLight& light) const {
return light.lightAABB().intersects(worldAABB());
}

void BrushNode::renderComponents(RenderableCollector& collector, const VolumeTest& volume) const
{
m_brush.evaluateBRep();
Expand Down

0 comments on commit b3bf3d7

Please sign in to comment.