Extracts subfeatures from `sourceObject` and writes them out `outputPoints` and `outputLines`. `sourceObject` must point to a temporary object of the desired type, with identity xf.
| 38 | // Extracts subfeatures from `sourceObject` and writes them out `outputPoints` and `outputLines`. |
| 39 | // `sourceObject` must point to a temporary object of the desired type, with identity xf. |
| 40 | static void addSubfeatures( const VisualObject& sourceObject, ObjectLines* outputLines, ObjectPoints* outputPoints ) |
| 41 | { |
| 42 | // Actually add the subfeatures: |
| 43 | |
| 44 | auto parentFeature = Features::primitiveFromObjectWithWorldXf( sourceObject ); |
| 45 | assert( parentFeature && "Can't convert this object to a feature" ); |
| 46 | if ( !parentFeature ) |
| 47 | return; |
| 48 | |
| 49 | Features::forEachVisualSubfeature( *parentFeature, [&]( const Features::SubfeatureInfo& params ) -> void |
| 50 | { |
| 51 | // It's a bit jank to utilize `primitiveToObject()` just to switch over the subfeature types, but it's very convenient. |
| 52 | |
| 53 | if ( params.isInfinite ) |
| 54 | return; |
| 55 | |
| 56 | const auto subFeature = params.create( *parentFeature ); |
| 57 | |
| 58 | constexpr float infiniteExtent = 10; // Whatever, we shouldn't receive any infinite features anyway. |
| 59 | auto subObject = Features::primitiveToObject( subFeature, infiniteExtent ); |
| 60 | if ( !subObject ) |
| 61 | { |
| 62 | assert( false && "Unknown subfeature type." ); |
| 63 | return; |
| 64 | } |
| 65 | |
| 66 | if ( auto point = dynamic_cast<PointObject *>( subObject.get() ) ) |
| 67 | { |
| 68 | outputPoints->varPointCloud()->addPoint( point->getPoint() ); |
| 69 | return; |
| 70 | } |
| 71 | if ( auto line = dynamic_cast<LineObject *>( subObject.get() ) ) |
| 72 | { |
| 73 | outputLines->varPolyline()->addFromPoints( std::array{ line->getPointA(), line->getPointB() }.data(), 2, false ); |
| 74 | return; |
| 75 | } |
| 76 | if ( auto circle = dynamic_cast<CircleObject *>( subObject.get() ) ) |
| 77 | { |
| 78 | std::array<Vector3f, numCircleSegments> points; |
| 79 | for ( int i = 0; i < numCircleSegments; ++i ) |
| 80 | { |
| 81 | float angle = i * 2 * PI_F / numCircleSegments; |
| 82 | points[i].x = cosf( angle ); |
| 83 | points[i].y = sinf( angle ); |
| 84 | points[i] = circle->xf()( points[i] ); |
| 85 | } |
| 86 | outputLines->varPolyline()->addFromPoints( points.data(), numCircleSegments, true ); |
| 87 | return; |
| 88 | } |
| 89 | |
| 90 | assert( false && "The subfeature uses an unknown object type." ); |
| 91 | } ); |
| 92 | } |
| 93 | |
| 94 | |
| 95 | RenderPlaneNormalComponent::RenderPlaneNormalComponent( const VisualObject& object ) |
no test coverage detected