Skip to content

Commit

Permalink
#5622: Implement fingerprinting of patch nodes (layer or grouping inf…
Browse files Browse the repository at this point in the history
…ormation are disregarded)
  • Loading branch information
codereader committed May 22, 2021
1 parent f27c073 commit c33d883
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 2 deletions.
3 changes: 3 additions & 0 deletions include/icomparablenode.h
Expand Up @@ -21,4 +21,7 @@ class IComparableNode :
virtual std::size_t getFingerprint() = 0;
};

// The number of digits that are considered when hashing floating point values in fingerprinting
constexpr std::size_t SignificantFingerprintDoubleDigits = 6;

}
2 changes: 1 addition & 1 deletion radiantcore/brush/BrushNode.cpp
Expand Up @@ -63,7 +63,7 @@ const AABB& BrushNode::localAABB() const {

std::size_t BrushNode::getFingerprint()
{
constexpr std::size_t SignificantDigits = 6;
constexpr std::size_t SignificantDigits = scene::SignificantFingerprintDoubleDigits;

if (m_brush.getNumFaces() == 0)
{
Expand Down
35 changes: 35 additions & 0 deletions radiantcore/patch/PatchNode.cpp
Expand Up @@ -5,6 +5,7 @@
#include "iradiant.h"
#include "icounter.h"
#include "math/Frustum.h"
#include "math/Hash.h"

// Construct a PatchNode with no arguments
PatchNode::PatchNode(patch::PatchDefType type) :
Expand Down Expand Up @@ -45,6 +46,40 @@ scene::INode::Type PatchNode::getNodeType() const
return Type::Patch;
}

std::size_t PatchNode::getFingerprint()
{
constexpr std::size_t SignificantDigits = scene::SignificantFingerprintDoubleDigits;

if (m_patch.getHeight() * m_patch.getWidth() == 0)
{
return 0; // empty patches produce a zero fingerprint
}

// Width & Height
auto hash = m_patch.getHeight();
math::combineHash(hash, m_patch.getWidth());

// Subdivision Settings
if (m_patch.subdivisionsFixed())
{
math::combineHash(hash, static_cast<std::size_t>(m_patch.getSubdivisions().x()));
math::combineHash(hash, static_cast<std::size_t>(m_patch.getSubdivisions().y()));
}

// Material Name
math::combineHash(hash, std::hash<std::string>()(m_patch.getShader()));

// Combine all control point data
for (const auto& ctrl : m_patch.getControlPoints())
{
math::combineHash(hash, math::hashVector3(ctrl.vertex, SignificantDigits));
math::combineHash(hash, math::hashDouble(ctrl.texcoord.x(), SignificantDigits));
math::combineHash(hash, math::hashDouble(ctrl.texcoord.y(), SignificantDigits));
}

return hash;
}

void PatchNode::allocate(std::size_t size) {
// Clear the control instance vector and reserve <size> memory
m_ctrl_instances.clear();
Expand Down
7 changes: 6 additions & 1 deletion radiantcore/patch/PatchNode.h
@@ -1,6 +1,7 @@
#pragma once

#include "irenderable.h"
#include "icomparablenode.h"
#include "iscenegraph.h"
#include "itraceable.h"
#include "imap.h"
Expand All @@ -22,7 +23,8 @@ class PatchNode :
public PlaneSelectable,
public LitObject,
public Transformable,
public ITraceable
public ITraceable,
public scene::IComparableNode
{
selection::DragPlanes m_dragPlanes;

Expand Down Expand Up @@ -60,6 +62,9 @@ class PatchNode :
std::string name() const override;
Type getNodeType() const override;

// IComparableNode implementation
std::size_t getFingerprint() override;

// Bounded implementation
const AABB& localAABB() const override;

Expand Down

0 comments on commit c33d883

Please sign in to comment.