DHART
Loading...
Searching...
No Matches
view_analysis.h
Go to the documentation of this file.
1
7
8#include <vector>
9#include <array>
10#include <cmath>
11#include <iostream>
12#include <assert.h>
13#include <limits>
14
15#ifndef VIEW_ANALYSIS_G
16#define VIEW_ANALYSIS_G
17
18// Forward Declares
19namespace HF {
20 namespace SpatialStructures {
21 struct Node;
22 }
23 namespace RayTracer {
24 class EmbreeRayTracer;
25 struct RayRequest;
26 }
27}
28
45namespace HF::ViewAnalysis {
49 enum class AGGREGATE_TYPE {
51 COUNT = 0,
53 SUM = 1,
55 AVERAGE = 2,
57 MAX = 3,
59 MIN = 4
60 };
61
66
68
116 std::vector<std::array<float, 3>> FibbonacciDistributePoints(
117 int num_points,
118 float upwards_fov = 50.0f,
119 float downward_fov = 70.0f
120 );
129
194 inline void Aggregate(float& out_total, float new_value, const AGGREGATE_TYPE agg_type, int count = 0) {
195 switch (agg_type) {
197 if (new_value > 0) out_total += 1;
198 break;
200 out_total += new_value;
201 break;
203 int n = count - 1;
204 out_total = (n * (out_total)+new_value) / count;
205 break;
206 }
207 case AGGREGATE_TYPE::MAX: {
208 out_total = std::max<float>(out_total, new_value);
209 break;
210 }
211 case AGGREGATE_TYPE::MIN: {
212 out_total = std::min<float>(out_total, new_value);
213 break;
214 }
215 default:
216 throw std::out_of_range("Unimplemented aggregation type");
217 break;
218 } // End Switch
219 assert(out_total == 0 || isnormal(out_total));
220 return;
221 }
222
233
334 template <typename RES, typename RT, typename N>
335 std::vector<RES> SphericalViewAnalysis(
336 RT& ray_tracer,
337 const std::vector<N>& Nodes,
338 int num_rays,
339 float upward_limit = 50.0f,
340 float downward_limit = 70.0f,
341 float height = 1.7f)
342 {
343 // Calculate directions then perform a quick check to see if we can even hold this vector
344 const auto directions = FibbonacciDistributePoints(num_rays, upward_limit, downward_limit);
345 int required_vector_size = directions.size() * Nodes.size();
346 std::vector<RES> out_results;
347
348 // Throw if we can't fit the results into a single vector. This will change based on the implementation
349 // of std::vector being used.
350 if (out_results.max_size() < required_vector_size) {
351 std::cout << "The desired view analysis setting exceed the maximum vector size!" << std::endl;
352 throw std::bad_array_new_length();
353 }
354 out_results.resize(required_vector_size);
355
356 // Size of the vector is the number of rays
357 num_rays = directions.size();
358
359 #pragma omp parallel
360 {
361 // Start parallel intersections
362 #pragma omp for schedule(dynamic)
363 for (int i = 0; i < Nodes.size(); i++)
364 {
365 // Reset out values to temporarily store results. Kept private by defining here
366 float out_distance = 0;
367 int out_mid = 0;
368
369 auto node = Nodes[i];
370 node[2] += height;
371 int os = directions.size() * i;
372
373 // Iterate through every direction and cast a ray for it
374 for (int k = 0; k < directions.size(); k++)
375 {
376 int idx = os + k;
377 // Call the result's SetHit if it intersected.
378 if (ray_tracer.IntersectOutputArguments(node, directions[k], out_distance, out_mid))
379 {
380 out_results[idx].SetHit(node, directions[k], out_distance, out_mid);
381 }
382 } // End direction loop
383 } // End node loop
384 } // End omp space
385
386 return out_results;
387 }
388
389// To use numeric limits, need to undefine max
390#undef max
391
399
483 template<typename RT, typename N>
485 RT& ray_tracer,
486 const std::vector<N>& Nodes,
487 int num_rays,
488 float upward_limit = 50.0f,
489 float downward_limit = 70.0f,
490 float height = 1.7f,
491 const AGGREGATE_TYPE aggregation = AGGREGATE_TYPE::SUM)
492 {
493 // Allocate score array and calculate directions
494 std::vector<float> out_scores(Nodes.size());
495 const auto directions = FibbonacciDistributePoints(num_rays, upward_limit, downward_limit);
496
497 #pragma omp parallel
498 {
499 // Start parallel intersections
500 #pragma omp for schedule(dynamic)
501 for (int i = 0; i < Nodes.size(); i++)
502 {
503 const auto& node = Nodes[i];
504
505 // Get a reference to the value in the score array, reset score and count to zero
506 float& score = out_scores[i];
507 int count = 1;
508
509 // If the aggregation type is min, set the score to some large value
510 if (aggregation == AGGREGATE_TYPE::MIN){
511 score = std::numeric_limits<float>::max();
512 }
513 else {
514 score = 0;
515 }
516
517 // Cast a ray for every direction in directions
518 for (const auto& direction : directions)
519 {
520 // Create a copy of the node to offset.
521 auto node_copy = node;
522 node_copy[2] += height;
523 //float distance = 0;
524
525 // If the ray intersects any geometry, calculate distance to the intersection point
526 // then plug that into the aggregation method.
527 if (ray_tracer.PointIntersection(
528 node_copy[0], node_copy[1], node_copy[2],
529 direction[0], direction[1], direction[2]))
530 {
531 // Add the height back to the original node so the distance check is accurate
532 float distance = sqrtf(
533 powf((node[0] - node_copy[0]), 2)
534 + powf((node[1] - node_copy[1]), 2)
535 + powf((node[2] + height - node_copy[2]), 2));
536
537 // Based on aggregation method, check this new value against the last
538 Aggregate(score, distance, aggregation, count);
539 count++;
540 }
541 }// End FOR over directions
542 } // End FOR over Nodes
543 }// End OMP
544 return out_scores;
545 }
546}
547
548#endif
vector< std::array< float, 3 > > FibbonacciDistributePoints(int num_points, float upwards_fov, float downward_fov)
Evenly distribute a set of points around a sphere centered at the origin.
std::vector< float > SphericalRayshootWithAnyRTForDistance(RT &ray_tracer, const std::vector< N > &Nodes, int num_rays, float upward_limit=50.0f, float downward_limit=70.0f, float height=1.7f, const AGGREGATE_TYPE aggregation=AGGREGATE_TYPE::SUM)
Conduct view analysis and recieve a summarized set of results for each node.
std::vector< RES > SphericalViewAnalysis(RT &ray_tracer, const std::vector< N > &Nodes, int num_rays, float upward_limit=50.0f, float downward_limit=70.0f, float height=1.7f)
Conduct view analysis with any Raytracer in parallel.
Perform human scale analysis on 3D environments.
HF::RayTracer::MultiRT RayTracer
Type of raytracer to be used internally.
Analyze space from the perspective of observers within a 3D environment.
AGGREGATE_TYPE
The type of aggregation to use for ViewAnalysisAggregate
Definition: view_analysis.h:49
@ AVERAGE
Average distance from the origin to every intersection.
@ MAX
Maximum distance from the origin to any intersection.
@ COUNT
Total number of intersections.
@ SUM
Sum of the distance from the origin to all intersections.
@ MIN
Minimum distance from the origin to any intersection.
void Aggregate(float &out_total, float new_value, const AGGREGATE_TYPE agg_type, int count=0)