Skip to content

Commit 7391cd2

Browse files
authored
Consider incident angle when calculating intensity (#317)
* Consider incident angle when calculating intensity * Add API call for setting default intensity * Review changes
1 parent a1a6c55 commit 7391cd2

File tree

10 files changed

+112
-10
lines changed

10 files changed

+112
-10
lines changed

include/rgl/api/core.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -775,6 +775,16 @@ RGL_API rgl_status_t rgl_node_raytrace_configure_mask(rgl_node_t node, const int
775775
RGL_API rgl_status_t rgl_node_raytrace_configure_beam_divergence(rgl_node_t node, float horizontal_beam_divergence,
776776
float vertical_beam_divergence);
777777

778+
/**
779+
* Modifies RaytraceNode to set default intensity.
780+
* This value will be considered when hitting entities with no intensity texture set (`rgl_entity_set_intensity_texture`)
781+
* Defaulted default intensity is set to zero.
782+
* When accessing `RGL_FIELD_INTENSITY_U8` float is cast to uint8_t type with clamping at uint8_t max value (255).
783+
* @param node RaytraceNode to modify.
784+
* @param default_intensity Default intensity to set (cannot be a negative number).
785+
*/
786+
RGL_API rgl_status_t rgl_node_raytrace_configure_default_intensity(rgl_node_t node, float default_intensity);
787+
778788
/**
779789
* Creates or modifies FormatPointsNode.
780790
* The Node converts internal representation into a binary format defined by the `fields` array.

src/api/apiCore.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -962,8 +962,8 @@ RGL_API rgl_status_t rgl_node_raytrace_configure_beam_divergence(rgl_node_t node
962962
float vertical_beam_divergence)
963963
{
964964
auto status = rglSafeCall([&]() {
965-
RGL_API_LOG("rgl_node_raytrace_configure_beam_divergence(node={}, horizontal_divergence={}, vertical_divergence={})", repr(node),
966-
horizontal_beam_divergence, vertical_beam_divergence);
965+
RGL_API_LOG("rgl_node_raytrace_configure_beam_divergence(node={}, horizontal_divergence={}, vertical_divergence={})",
966+
repr(node), horizontal_beam_divergence, vertical_beam_divergence);
967967
CHECK_ARG(node != nullptr);
968968
CHECK_ARG((horizontal_beam_divergence > 0.0f && vertical_beam_divergence > 0.0f) ||
969969
(horizontal_beam_divergence == 0.0f && vertical_beam_divergence == 0.0f));
@@ -981,6 +981,27 @@ void TapeCore::tape_node_raytrace_configure_beam_divergence(const YAML::Node& ya
981981
rgl_node_raytrace_configure_beam_divergence(node, yamlNode[1].as<float>(), yamlNode[2].as<float>());
982982
}
983983

984+
RGL_API rgl_status_t rgl_node_raytrace_configure_default_intensity(rgl_node_t node, float default_intensity)
985+
{
986+
auto status = rglSafeCall([&]() {
987+
RGL_API_LOG("rgl_node_raytrace_configure_default_intensity(node={}, default_intensity={})", repr(node),
988+
default_intensity);
989+
CHECK_ARG(node != nullptr);
990+
CHECK_ARG(default_intensity >= 0.0f);
991+
RaytraceNode::Ptr raytraceNode = Node::validatePtr<RaytraceNode>(node);
992+
raytraceNode->setDefaultIntensity(default_intensity);
993+
});
994+
TAPE_HOOK(node, default_intensity);
995+
return status;
996+
}
997+
998+
void TapeCore::tape_node_raytrace_configure_default_intensity(const YAML::Node& yamlNode, PlaybackState& state)
999+
{
1000+
auto nodeId = yamlNode[0].as<TapeAPIObjectID>();
1001+
rgl_node_t node = state.nodes.at(nodeId);
1002+
rgl_node_raytrace_configure_default_intensity(node, yamlNode[1].as<float>());
1003+
}
1004+
9841005
RGL_API rgl_status_t rgl_node_points_format(rgl_node_t* node, const rgl_field_t* fields, int32_t field_count)
9851006
{
9861007
auto status = rglSafeCall([&]() {

src/gpu/RaytraceRequestContext.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ struct RaytraceRequestContext
2828
float nearNonHitDistance;
2929
float farNonHitDistance;
3030

31+
float defaultIntensity;
32+
3133
const Mat3x4f* raysWorld;
3234
size_t rayCount;
3335

src/gpu/optixPrograms.cu

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -178,17 +178,20 @@ extern "C" __global__ void __closesthit__()
178178
return;
179179
}
180180

181-
// Normal vector and incident angle
181+
// Normal vector
182182
Vec3f rayDir = optixGetWorldRayDirection();
183183
const Vec3f wA = optixTransformPointFromObjectToWorldSpace(A);
184184
const Vec3f wB = optixTransformPointFromObjectToWorldSpace(B);
185185
const Vec3f wC = optixTransformPointFromObjectToWorldSpace(C);
186186
const Vec3f wAB = wB - wA;
187187
const Vec3f wCA = wC - wA;
188188
const Vec3f wNormal = wAB.cross(wCA).normalized();
189-
const float incidentAngle = acosf(fabs(wNormal.dot(rayDir)));
190189

191-
float intensity = 0;
190+
// Incident angle
191+
const float cosIncidentAngle = fabs(wNormal.dot(rayDir));
192+
const float incidentAngle = acosf(cosIncidentAngle);
193+
194+
float intensity = ctx.defaultIntensity;
192195
bool isIntensityRequested = ctx.intensityF32 != nullptr || ctx.intensityU8 != nullptr;
193196
if (isIntensityRequested && entityData.textureCoords != nullptr && entityData.texture != 0) {
194197
assert(triangleIndices.x() < entityData.textureCoordsCount);
@@ -203,6 +206,7 @@ extern "C" __global__ void __closesthit__()
203206

204207
intensity = tex2D<TextureTexelFormat>(entityData.texture, uv[0], uv[1]);
205208
}
209+
intensity *= cosIncidentAngle;
206210

207211
// Save sub-sampling results
208212
ctx.mrSamples.isHit[mrSamplesIdx] = true;

src/graph/NodesCore.hpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,12 @@ struct RaytraceNode : IPointsNode
134134
void enableRayDistortion(bool enabled) { doApplyDistortion = enabled; }
135135
void setNonHitDistanceValues(float nearDistance, float farDistance);
136136
void setNonHitsMask(const int8_t* maskRaw, size_t maskPointCount);
137-
void setBeamDivergence(float hDivergenceRad, float vDivergenceRad) {
137+
void setBeamDivergence(float hDivergenceRad, float vDivergenceRad)
138+
{
138139
hBeamHalfDivergenceRad = hDivergenceRad / 2.0f;
139-
vBeamHalfDivergenceRad = vDivergenceRad / 2.0f;}
140+
vBeamHalfDivergenceRad = vDivergenceRad / 2.0f;
141+
}
142+
void setDefaultIntensity(float intensity) { defaultIntensity = intensity; }
140143

141144
private:
142145
IRaysNode::Ptr raysNode;
@@ -150,6 +153,7 @@ struct RaytraceNode : IPointsNode
150153
float farNonHitDistance{std::numeric_limits<float>::infinity()};
151154
float hBeamHalfDivergenceRad = 0.0f;
152155
float vBeamHalfDivergenceRad = 0.0f;
156+
float defaultIntensity = 0.0f;
153157

154158
DeviceAsyncArray<int8_t>::Ptr rayMask;
155159

@@ -747,8 +751,8 @@ struct RadarTrackObjectsNode : IPointsNodeSingleInput
747751
// In other words, how long object state can be predicted until it will be declared lost.
748752
float movementSensitivity = 0.01f; // Max velocity for an object to be qualified as MovementStatus::Stationary.
749753

750-
Mat3x4f lookAtSensorFrameTransform { Mat3x4f::identity() };
751-
decltype(Time::zero().asMilliseconds()) currentTime { Time::zero().asMilliseconds() };
754+
Mat3x4f lookAtSensorFrameTransform{Mat3x4f::identity()};
755+
decltype(Time::zero().asMilliseconds()) currentTime{Time::zero().asMilliseconds()};
752756

753757
HostPinnedArray<Field<XYZ_VEC3_F32>::type>::Ptr xyzHostPtr = HostPinnedArray<Field<XYZ_VEC3_F32>::type>::create();
754758
HostPinnedArray<Field<DISTANCE_F32>::type>::Ptr distanceHostPtr = HostPinnedArray<Field<DISTANCE_F32>::type>::create();

src/graph/RaytraceNode.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ void RaytraceNode::enqueueExecImpl()
9595
.doApplyDistortion = doApplyDistortion,
9696
.nearNonHitDistance = nearNonHitDistance,
9797
.farNonHitDistance = farNonHitDistance,
98+
.defaultIntensity = defaultIntensity,
9899
.raysWorld = raysPtr,
99100
.rayCount = raysNode->getRayCount(),
100101
.rayOriginToWorld = raysNode->getCumulativeRayTransfrom(),

src/tape/TapeCore.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ class TapeCore
5656
static void tape_node_raytrace_configure_non_hits(const YAML::Node& yamlNode, PlaybackState& state);
5757
static void tape_node_raytrace_configure_mask(const YAML::Node& yamlNode, PlaybackState& state);
5858
static void tape_node_raytrace_configure_beam_divergence(const YAML::Node& yamlNode, PlaybackState& state);
59+
static void tape_node_raytrace_configure_default_intensity(const YAML::Node& yamlNode, PlaybackState& state);
5960
static void tape_node_points_format(const YAML::Node& yamlNode, PlaybackState& state);
6061
static void tape_node_points_yield(const YAML::Node& yamlNode, PlaybackState& state);
6162
static void tape_node_points_compact(const YAML::Node& yamlNode, PlaybackState& state);
@@ -114,6 +115,8 @@ class TapeCore
114115
TAPE_CALL_MAPPING("rgl_node_raytrace_configure_mask", TapeCore::tape_node_raytrace_configure_mask),
115116
TAPE_CALL_MAPPING("rgl_node_raytrace_configure_beam_divergence",
116117
TapeCore::tape_node_raytrace_configure_beam_divergence),
118+
TAPE_CALL_MAPPING("rgl_node_raytrace_configure_default_intensity",
119+
TapeCore::tape_node_raytrace_configure_default_intensity),
117120
TAPE_CALL_MAPPING("rgl_node_points_format", TapeCore::tape_node_points_format),
118121
TAPE_CALL_MAPPING("rgl_node_points_yield", TapeCore::tape_node_points_yield),
119122
TAPE_CALL_MAPPING("rgl_node_points_compact", TapeCore::tape_node_points_compact),

test/src/TapeTest.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,9 @@ TEST_F(TapeTest, RecordPlayAllCalls)
239239
float vBeamDivergence = 0.1f;
240240
EXPECT_RGL_SUCCESS(rgl_node_raytrace_configure_beam_divergence(raytrace, hBeamDivergence, vBeamDivergence));
241241

242+
float defaultIntensity = 1.1f;
243+
EXPECT_RGL_SUCCESS(rgl_node_raytrace_configure_default_intensity(raytrace, defaultIntensity));
244+
242245
rgl_node_t format = nullptr;
243246
std::vector<rgl_field_t> fields = {RGL_FIELD_XYZ_VEC3_F32, RGL_FIELD_DISTANCE_F32};
244247
EXPECT_RGL_SUCCESS(rgl_node_points_format(&format, fields.data(), fields.size()));

test/src/graph/nodes/RaytraceNodeTest.cpp

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,3 +271,56 @@ TEST_F(RaytraceNodeTest, config_non_hit_far_distance_should_correctly_change_out
271271
EXPECT_EQ(outIsHits.at(i), 0);
272272
}
273273
}
274+
275+
TEST_F(RaytraceNodeTest, config_default_intensity_should_correctly_change_output)
276+
{
277+
spawnCubeOnScene(Mat3x4f::TRS({0, 0, 0}));
278+
279+
std::vector<rgl_mat3x4f> rays = {
280+
Mat3x4f::TRS({0, 0, 0}, {0, 0, 0}).toRGL(), // hit point
281+
Mat3x4f::TRS({CUBE_HALF_EDGE * 3, 0, 0}, {0, 0, 0}).toRGL(), // non-hit point
282+
};
283+
284+
float defaultIntensity = 100.0f;
285+
const float expectedIntensityForNonHit = 0.0f;
286+
287+
std::vector<rgl_field_t> outFields{IS_HIT_I32, INTENSITY_F32};
288+
289+
rgl_node_t raysNode = nullptr;
290+
rgl_node_t yieldNode = nullptr;
291+
292+
ASSERT_RGL_SUCCESS(rgl_node_rays_from_mat3x4f(&raysNode, rays.data(), rays.size()));
293+
ASSERT_RGL_SUCCESS(rgl_node_raytrace(&raytraceNode, nullptr));
294+
ASSERT_RGL_SUCCESS(rgl_node_raytrace_configure_default_intensity(raytraceNode, defaultIntensity));
295+
ASSERT_RGL_SUCCESS(rgl_node_points_yield(&yieldNode, outFields.data(), outFields.size()));
296+
297+
ASSERT_RGL_SUCCESS(rgl_graph_node_add_child(raysNode, raytraceNode));
298+
ASSERT_RGL_SUCCESS(rgl_graph_node_add_child(raytraceNode, yieldNode));
299+
300+
ASSERT_RGL_SUCCESS(rgl_graph_run(raysNode));
301+
302+
auto validateOutput = [&]() {
303+
TestPointCloud outPointCloud = TestPointCloud::createFromNode(yieldNode, outFields);
304+
std::vector<Field<INTENSITY_F32>::type> outIntensities = outPointCloud.getFieldValues<INTENSITY_F32>();
305+
std::vector<Field<IS_HIT_I32>::type> outIsHits = outPointCloud.getFieldValues<IS_HIT_I32>();
306+
307+
ASSERT_EQ(rays.size(), outIntensities.size());
308+
ASSERT_EQ(rays.size(), outIsHits.size());
309+
310+
// Hit point
311+
EXPECT_EQ(outIsHits[0], 1);
312+
EXPECT_EQ(outIntensities[0], defaultIntensity);
313+
314+
// Non-hit point
315+
EXPECT_EQ(outIsHits[1], 0);
316+
EXPECT_EQ(outIntensities[1], expectedIntensityForNonHit);
317+
};
318+
319+
validateOutput();
320+
321+
// Second round
322+
defaultIntensity = 25.0f;
323+
ASSERT_RGL_SUCCESS(rgl_node_raytrace_configure_default_intensity(raytraceNode, defaultIntensity));
324+
ASSERT_RGL_SUCCESS(rgl_graph_run(raysNode));
325+
validateOutput();
326+
}

test/src/scene/textureTest.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ TEST_P(TextureTest, rgl_texture_reading)
5656
// Create RGL graph pipeline.
5757
rgl_node_t useRaysNode = nullptr, raytraceNode = nullptr, compactNode = nullptr, yieldNode = nullptr;
5858

59-
std::vector<rgl_mat3x4f> rays = makeLidar3dRays(360, 360, 0.36, 0.36);
59+
std::vector<rgl_mat3x4f> rays = {// Ray must be incident perpendicular to the surface to receive all intensity
60+
Mat3x4f::TRS({0, 0, 0}, {0, 0, 0}).toRGL()};
6061

6162
std::vector<rgl_field_t> yieldFields = {INTENSITY_F32};
6263

0 commit comments

Comments
 (0)