NDEVR
API Documentation
GravityIntersection.h
1#pragma once
2#include <NDEVR/DesignObjectLookup.h>
3#include <NDEVR/AngleDefinitions.h>
4#include <NDEVR/BinaryHeap.h>
5namespace NDEVR
6{
17 {
18 public:
39 {
40 SelectionInfo info;
41 if (m_query_points.size() < 3)
42 return Matrix<fltp08>(1.0);
43 MinHeap<fltp08, LineSegment<3, fltp08>> heap(4);
44 RLock lock(m_lookup->readLock());
45 info.model_filter = [](const Model& model)->bool
46 {
47 bool ignore = false;
48 ignore |= !model.get<NDPO::allow_interactions>();
49 //ignore |= model.get<bool>(NDPN::is_application_owned);
50 ignore |= !model.get<NDPO::spacial_visible>();
51 return !ignore;
52 };
53 Matrix<fltp08> inverted_mat = m_current_transform.invert();
54 for (uint04 i = 0; i < m_query_points.size(); i++)
55 {
58 seg[A] = reference - m_gravity_vector * m_max_fall_height;
59 seg[B] = reference + m_gravity_vector * m_max_fall_height;
60 info.clearLastSelection();
65 info.is_exact = true;
67 info.current_selection.setTransform(Matrix<fltp08>(1.0));
68 m_lookup->processSelection(info);
70 {
71 fltp08 length = seg.lengthSquared();
72 seg[A] = reference;
73 seg[B] = info.nearestScreenLocation();
74 //if (heap.size() < 3 || heap.extremeComp() > length)
75 {
76 heap.insert(length, inverted_mat * seg);
77 //if (heap.size() > 3)
78 //heap.deleteExtreme();
79 }
80 }
81 }
82 if(heap.size() < 3)
83 return Matrix<fltp08>(1.0);
84 Buffer<Vector<3, fltp08>> original_points(heap.size());
85 Buffer<Vector<3, fltp08>> intersection_points(heap.size());
86 for (uint04 i = 0; i < heap.size(); i++)
87 {
88 original_points.add(heap.getAll()[i].first[A]);
89 intersection_points.add(heap.getAll()[i].first[B]);
90 }
92 Plane<3, fltp08> p1 = Plane<3, fltp08>::CreateBestFitPlane(original_points);
93 Plane<3, fltp08> p2 = Plane<3, fltp08>::CreateBestFitPlane(intersection_points);
94 Ray<3, fltp08> n0 = p1.normal;
95 Ray<3, fltp08> n1 = p2.normal;
96 //Ray<3, fltp08> average_fall = (p2.d * p2.normal) - (p1.d * p1.normal);
97 if (IsInvalid(n0) || IsInvalid(n1))
98 return Matrix<fltp08>(1.0);
99 if (dot(n0, n1) < 0.0)
100 n1 = -n1;
101 Vector<3, fltp08> cross_product = cross(n0, n1).normalized();
102 auto cos_theta = dot(n0, n1);
103 double sin_theta = std::sqrt(1 - cos_theta * cos_theta);
104
105 Matrix<fltp08> skew(1.0);
106 skew[0][0] = 0;
107 skew[0][1] = -cross_product[2];
108 skew[0][2] = cross_product[1];
109
110 skew[1][0] = cross_product[2];
111 skew[1][1] = 0;
112 skew[1][2] = -cross_product[0];
113
114 skew[2][0] = -cross_product[1];
115 skew[2][1] = cross_product[0];
116 skew[2][2] = 0;
117
118 Matrix<fltp08> axis_matrix(1.0);
119 for (uint01 i = 0; i < 3; ++i)
120 {
121 for (uint01 j = 0; j < 3; ++j)
122 axis_matrix[i][j] = cross_product[i] * cross_product[j];
123 }
124 Matrix<fltp08> mat(1.0);
125 // Rotation matrix formula: R = I + sin(theta) * skew(axis) + (1 - cos(theta)) * (axis * axis^T)
126 for (uint01 i = 0; i < 3; ++i)
127 {
128 for (uint01 j = 0; j < 3; ++j)
129 mat[i][j] = mat[i][j] * cos_theta + sin_theta * skew[i][j] + (1 - cos_theta) * axis_matrix[i][j];
130 }
131 lib_assert(IsValid(mat), "Bad matrix");
132 mat = mat.transpose();
133 Ray<3, fltp08> average_fall(0.0);
134 for (uint04 i = 0; i < heap.size(); i++)
135 {
136 average_fall += heap.getAll()[i].first[B] - heap.getAll()[i].first[A];
137 }
138 average_fall /= cast<fltp08>(heap.size());
139 //n0 = mat.transpose() * n0;
140 return Matrix<fltp08>::OffsetMatrix(average_fall) * mat;
141 }
142
150 void setup(DesignObjectLookup* lookup, const Matrix<fltp08>& mat, const Buffer<Vertex<3, fltp08>>& points)
151 {
152 m_lookup = lookup;
154 m_query_points = points;
155 }
156
172 {
173 Set<Vertex<3, fltp08>> points;
174 SelectionInfo info;
175 info.use_interaction_flag = false;
177 Bounds<3, fltp08> bounds = mat * model.getBoundsOfVisible();
178 Matrix<fltp08> inverted_matrix = mat.invert();
179 fltp08 d = bounds.span().dimensionalValue<MAX>() * delta;
180 for (fltp08 x = bounds[MIN][X]; x < bounds[MAX][X]; x += d)
181 {
182 for (fltp08 y = bounds[MIN][Y]; y < bounds[MAX][Y]; y += d)
183 {
184 info.clearLastSelection();
189 info.is_exact = true;
190 info.current_selection = SelectionArea<3, fltp08>(LineSegment<3, fltp08>({ x, y, bounds[MIN][Z] }, { x, y, bounds[MIN][Z] + max }));
191 info.current_selection.setTransform(Matrix<fltp08>(1.0));
192 info.parseAll(model);
193 if (IsValid(info.nearestScreenLocation()))
194 points.add(info.nearestScreenLocation());
195 }
196 }
197 Buffer<Vertex<3, fltp08>> avg = FilterSamples(10 * d, points.values(), bounds.center());
198 for (uint04 i = 0; i < avg.size(); i++)
199 avg[i] = inverted_matrix * avg[i];
200 return avg;
201 }
202
211 static Vertex<3, fltp08> LowestPoint(const Buffer<Vertex<3, fltp08>>& clustered_points)
212 {
213 Vertex<3, fltp08> lowest_point(Constant<fltp08>::Max);
214 for (uint04 i = 0; i < clustered_points.size(); i++)
215 {
216 if (clustered_points[i][Z] < lowest_point[Z])
217 {
218 lowest_point = clustered_points[i];
219 }
220 }
221 return lowest_point;
222 }
223
243 static Buffer<Vertex<3, fltp08>> FilterSamples(fltp08 cluster_distance, Buffer<Vertex<3, fltp08>> clustered_points, Vertex<3, fltp08> center)
244 {
245 Buffer<Vertex<3, fltp08>> lowest_points;
246 while(clustered_points.size() > 0)
247 {
248 Vertex<3, fltp08> lowest = LowestPoint(clustered_points);
249 Vertex<3, fltp08> true_lowest = lowest;
250 fltp08 d_from_center = distanceSquared(lowest, center);
251 for (uint04 i = clustered_points.size() - 1; IsValid(i); i--)
252 {
253 if (distanceSquared(clustered_points[i], lowest) < cluster_distance)
254 {
255 if (clustered_points[i][Z] == lowest[Z] && distanceSquared(clustered_points[i], center) < d_from_center)
256 lowest = clustered_points[i];
257 clustered_points.removeIndex(i);
258 }
259 }
260 lowest_points.add(lowest);
261 }
262 return lowest_points;
263 }
264 protected:
267
271 };
272}
A specification of upper and lower bounds in N-dimensions.
Definition Bounds.hpp:54
constexpr t_vertex center() const
Returns the center of the bounds.
Definition Bounds.hpp:129
constexpr Ray< t_dims, t_type > span() const
The side lengths of these bounds.
Definition Bounds.hpp:113
The equivelent of std::vector but with a bit more control.
Definition Buffer.hpp:58
void add(t_type &&object)
Adds object to the end of the buffer.
Definition Buffer.hpp:190
A core class where all Design Objects including models, materials, and geometries are stored.
Computes gravity-based intersection transforms by casting rays along a gravity vector and finding whe...
Vector< 3, fltp08 > m_gravity_vector
The direction of gravity used for raycasting. Defaults to downward along the Z axis.
fltp08 m_max_fall_height
The maximum distance to cast rays along the gravity vector in each direction from a query point.
static Buffer< Vertex< 3, fltp08 > > FindGravityPoints(const Model &model, fltp08 delta, fltp08 max)
Generates a set of gravity sample points by casting vertical rays through a model's bounding area.
void setup(DesignObjectLookup *lookup, const Matrix< fltp08 > &mat, const Buffer< Vertex< 3, fltp08 > > &points)
Initializes the gravity intersection with the required scene context, transform, and query points.
static Buffer< Vertex< 3, fltp08 > > FilterSamples(fltp08 cluster_distance, Buffer< Vertex< 3, fltp08 > > clustered_points, Vertex< 3, fltp08 > center)
Filters a set of points by iteratively extracting the lowest-Z point and removing nearby neighbors wi...
Matrix< fltp08 > calculateIntersection() const
Calculates an intersection transform by projecting query points along the gravity vector and fitting ...
Buffer< Vertex< 3, fltp08 > > m_query_points
The set of local-space query points to project along the gravity vector.
static Vertex< 3, fltp08 > LowestPoint(const Buffer< Vertex< 3, fltp08 > > &clustered_points)
Finds the vertex with the lowest Z coordinate from a set of points.
DesignObjectLookup * m_lookup
Pointer to the scene lookup used for selection/intersection queries. Not owned by this class.
Matrix< fltp08 > m_current_transform
The transformation matrix applied to query points before performing intersection queries.
Class: LineSegment.
Definition Line.hpp:52
constexpr t_type lengthSquared() const
Definition Line.hpp:462
Templated logic for doing matrix multiplication.
Definition Matrix.hpp:182
void parseAll(const Model &model)
Parses the given model and all of its descendants.
std::function< bool(const Model &)> model_filter
Optional filter predicate for model processing. Returns true to include.
A core class that represents a node on model hierarchy.
Definition Model.h:292
Bounds< 3, fltp08 > getBoundsOfVisible() const
Returns the bounding box of all visible descendants.
Matrix< fltp08 > getCompleteTransform() const
Returns the fully composed local-to-global transform matrix for this model.
Logic for a given plane or N-dimensions.
Definition Plane.hpp:53
Used to lock a particular variable for reading.
Definition RWLock.h:157
An area of N-dimensional space that is considered selected.
fltp08 screen_distance
The screen-space distance to the nearest hit.
Definition Selector.h:83
Responsible for turning a user interaction into a selection within a DesignObjectLookup.
Definition Selector.h:52
bool is_exact
Whether exact intersection testing is used (vs. bounding-box only).
Definition Selector.h:257
ClosestModelInfo nearest_line
Closest hit info for line primitives.
Definition Selector.h:247
bool use_interaction_flag
Whether to respect the model's interaction flag when selecting.
Definition Selector.h:258
ClosestModelInfo nearest_solid
Closest hit info for solid (triangle/face) primitives.
Definition Selector.h:248
fltp08 min_screen_cutoff_distance
Minimum screen-space distance below which hits are ignored.
Definition Selector.h:250
Vertex< 3, fltp08 > nearestScreenLocation() const
Returns the screen-space location of the nearest selection hit.
void clearLastSelection()
Clears only the most recent selection data, preserving historical state.
SelectionArea< 3, fltp08 > current_selection
The current active selection area.
Definition Selector.h:239
ClosestModelInfo nearest_point
Closest hit info for point primitives.
Definition Selector.h:246
Container that stores unique elements in no particular order, and which allow for fast retrieval or i...
Definition Set.h:59
Buffer< t_value, t_memory_manager > values() const
Returns all elements in the Set as a Buffer.
Definition Set.h:131
void add(const t_value &key)
Inserts a value into the Set by const reference.
Definition Set.h:104
A fixed-size array with N dimensions used as the basis for geometric and mathematical types.
Definition Vector.hpp:62
constexpr Vector< t_dims, t_norm_type > normalized(Vector< t_dims, t_norm_type > value_if_nan=Constant< Vector< t_dims, t_norm_type > >::Invalid) const
Gets the normalized, or unit length representation of this vector.
Definition Vector.hpp:486
A point in N-dimensional space, used primarily for spatial location information.
Definition Vertex.hpp:44
The primary namespace for the NDEVR SDK.
static constexpr bool IsValid(const Angle< t_type > &value)
Checks whether the given Angle holds a valid value.
Definition Angle.h:398
t_type dot(const Vector< t_dims, t_type > &v1, const Vector< t_dims, t_type > &v2)
uint32_t uint04
-Defines an alias representing a 4 byte, unsigned integer -Can represent exact integer values 0 throu...
double fltp08
Defines an alias representing an 8 byte floating-point number.
constexpr Vector< 1, t_type > cross(const Vector< 1, t_type > &, const Vector< 1, t_type > &)
uint8_t uint01
-Defines an alias representing a 1 byte, unsigned integer -Can represent exact integer values 0 throu...
static constexpr bool IsInvalid(const Angle< t_type > &value)
Checks whether the given Angle holds an invalid value.
Definition Angle.h:388
Matrix3< g_type > skew(const Vector3< g_type > &v)
Computes the 3x3 skew-symmetric matrix from a 3D vector.
Definition se3_ops.hpp:28
@ allow_interactions
Whether user interactions with this object are allowed.
@ spacial_visible
Whether the object is visible in the 3D spatial view.
constexpr t_to cast(const Angle< t_from > &value)
Casts an Angle from one backing type to another.
Definition Angle.h:408
Options controlling which degrees of freedom are solved when computing a best-fit transform.