Skip to content

Commit f9b6a43

Browse files
authored
Compute XYZ in MR based on distance, not XYZ samples (#295)
* Add RGL_RETURN_TYPE_NOT_DIVERGENT * Compute XYZ based on raydir and distance * Fix XYZ computation, run beam sample processing conditionally
1 parent d23a43e commit f9b6a43

File tree

7 files changed

+27
-18
lines changed

7 files changed

+27
-18
lines changed

include/rgl/api/core.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,9 @@ typedef enum : int32_t
387387
*/
388388
typedef enum : int32_t
389389
{
390-
RGL_RETURN_TYPE_FIRST = 0,
391-
RGL_RETURN_TYPE_LAST = 1,
390+
RGL_RETURN_TYPE_NOT_DIVERGENT = 0,
391+
RGL_RETURN_TYPE_FIRST = 1,
392+
RGL_RETURN_TYPE_LAST = 2,
392393
} rgl_return_type_t;
393394

394395
/**

src/gpu/RaytraceRequestContext.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ struct RaytraceRequestContext
2828
float nearNonHitDistance;
2929
float farNonHitDistance;
3030

31-
const Mat3x4f* rays;
31+
const Mat3x4f* raysWorld;
3232
size_t rayCount;
3333

3434
Mat3x4f rayOriginToWorld;

src/gpu/nodeKernels.cu

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ __global__ void kFilterGroundPoints(size_t pointCount, const Vec3f sensor_up_vec
224224
}
225225

226226
__global__ void kProcessBeamSamplesFirstLast(size_t beamCount, int samplesPerBeam, MultiReturnPointers beamSamples,
227-
MultiReturnPointers first, MultiReturnPointers last)
227+
MultiReturnPointers first, MultiReturnPointers last, const Mat3x4f* beamsWorld)
228228
{
229229
LIMIT(beamCount);
230230

@@ -244,14 +244,16 @@ __global__ void kProcessBeamSamplesFirstLast(size_t beamCount, int samplesPerBea
244244
lastIdx = sampleIdx;
245245
}
246246
}
247+
Vec3f beamOrigin = beamsWorld[beamIdx] * Vec3f{0, 0, 0};
248+
Vec3f beamDir = ((beamsWorld[beamIdx] * Vec3f{0, 0, 1}) - beamOrigin).normalized();
247249
bool isHit = firstIdx >= 0; // Note that firstHit >= 0 implies lastHit >= 0
248250
first.isHit[beamIdx] = isHit;
249251
last.isHit[beamIdx] = isHit;
250252
if (isHit) {
251-
first.xyz[beamIdx] = beamSamples.xyz[beamIdx * samplesPerBeam + firstIdx];
252253
first.distance[beamIdx] = beamSamples.distance[beamIdx * samplesPerBeam + firstIdx];
253-
last.xyz[beamIdx] = beamSamples.xyz[beamIdx * samplesPerBeam + lastIdx];
254254
last.distance[beamIdx] = beamSamples.distance[beamIdx * samplesPerBeam + lastIdx];
255+
first.xyz[beamIdx] = beamOrigin + beamDir * first.distance[beamIdx];
256+
last.xyz[beamIdx] = beamOrigin + beamDir * last.distance[beamIdx];
255257
}
256258
}
257259

@@ -329,7 +331,7 @@ void gpuRadarComputeEnergy(cudaStream_t stream, size_t count, float rayAzimuthSt
329331
}
330332

331333
void gpuProcessBeamSamplesFirstLast(cudaStream_t stream, size_t beamCount, int samplesPerBeam, MultiReturnPointers beamSamples,
332-
MultiReturnPointers first, MultiReturnPointers last)
334+
MultiReturnPointers first, MultiReturnPointers last, const Mat3x4f* beamsWorld)
333335
{
334-
run(kProcessBeamSamplesFirstLast, stream, beamCount, samplesPerBeam, beamSamples, first, last);
336+
run(kProcessBeamSamplesFirstLast, stream, beamCount, samplesPerBeam, beamSamples, first, last, beamsWorld);
335337
}

src/gpu/nodeKernels.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,4 +53,4 @@ void gpuRadarComputeEnergy(cudaStream_t stream, size_t count, float rayAzimuthSt
5353
const Field<DISTANCE_F32>::type* hitDist, const Field<NORMAL_VEC3_F32>::type* hitNorm,
5454
const Field<XYZ_VEC3_F32>::type* hitPos, Vector<3, thrust::complex<float>>* outBUBRFactor);
5555
void gpuProcessBeamSamplesFirstLast(cudaStream_t stream, size_t beamCount, int samplesPerBeam, MultiReturnPointers beamSamples,
56-
MultiReturnPointers first, MultiReturnPointers last);
56+
MultiReturnPointers first, MultiReturnPointers last, const Mat3x4f* beamWorld);

src/gpu/optixPrograms.cu

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ extern "C" __global__ void __raygen__()
5555
return;
5656
}
5757

58-
Mat3x4f ray = ctx.rays[rayIdx];
58+
Mat3x4f ray = ctx.raysWorld[rayIdx];
5959
const Mat3x4f rayLocal =
6060
ctx.rayOriginToWorld.inverse() *
6161
ray; // TODO(prybicki): instead of computing inverse, we should pass rays in local CF and then transform them to world CF.
@@ -142,7 +142,9 @@ extern "C" __global__ void __closesthit__()
142142
if (!ctx.doApplyDistortion) {
143143
return hitWorldRaytraced;
144144
}
145-
Mat3x4f undistortedRay = ctx.rays[beamIdx] * makeBeamSampleRayTransform(ctx.beamHalfDivergence, circleIdx, vertexIdx);
145+
Mat3x4f sampleRayTf = beamSampleRayIdx == 0 ? Mat3x4f::identity() :
146+
makeBeamSampleRayTransform(ctx.beamHalfDivergence, circleIdx, vertexIdx);
147+
Mat3x4f undistortedRay = ctx.raysWorld[beamIdx] * sampleRayTf;
146148
Vec3f undistortedOrigin = undistortedRay * Vec3f{0, 0, 0};
147149
Vec3f undistortedDir = undistortedRay * Vec3f{0, 0, 1} - undistortedOrigin;
148150
return undistortedOrigin + undistortedDir * distance;
@@ -186,7 +188,6 @@ extern "C" __global__ void __closesthit__()
186188

187189
// Save sub-sampling results
188190
ctx.mrSamples.isHit[mrSamplesIdx] = true;
189-
ctx.mrSamples.xyz[mrSamplesIdx] = hitWorldSeenBySensor;
190191
ctx.mrSamples.distance[mrSamplesIdx] = distance;
191192
if (beamSampleRayIdx != 0) {
192193
return;
@@ -267,7 +268,7 @@ __device__ Mat3x4f makeBeamSampleRayTransform(float halfDivergenceAngleRad, unsi
267268

268269
__device__ void saveNonHitRayResult(float nonHitDistance)
269270
{
270-
Mat3x4f ray = ctx.rays[optixGetLaunchIndex().x];
271+
Mat3x4f ray = ctx.raysWorld[optixGetLaunchIndex().x];
271272
Vec3f origin = ray * Vec3f{0, 0, 0};
272273
Vec3f dir = ray * Vec3f{0, 0, 1} - origin;
273274
Vec3f displacement = dir.normalized() * nonHitDistance;

src/graph/NodesCore.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,9 @@ struct MultiReturnSwitchNode : IPointsNodeSingleInput
212212
// Data getters
213213
IAnyArray::ConstPtr getFieldData(rgl_field_t field) override
214214
{
215+
if (returnType == RGL_RETURN_TYPE_NOT_DIVERGENT) {
216+
return rtxInput->getFieldData(field);
217+
}
215218
return rtxInput->getFieldDataMultiReturn(field, returnType);
216219
}
217220

src/graph/RaytraceNode.cpp

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ void RaytraceNode::enqueueExecImpl()
9494
.doApplyDistortion = doApplyDistortion,
9595
.nearNonHitDistance = nearNonHitDistance,
9696
.farNonHitDistance = farNonHitDistance,
97-
.rays = raysPtr,
97+
.raysWorld = raysPtr,
9898
.rayCount = raysNode->getRayCount(),
9999
.rayOriginToWorld = raysNode->getCumulativeRayTransfrom(),
100100
.rayRanges = rayRanges.has_value() ? (*rayRanges)->asSubclass<DeviceAsyncArray>()->getReadPtr() :
@@ -133,8 +133,10 @@ void RaytraceNode::enqueueExecImpl()
133133
CHECK_OPTIX(optixLaunch(Optix::getOrCreate().pipeline, getStreamHandle(), pipelineArgsPtr, pipelineArgsSize, &sceneSBT,
134134
launchDims.x, launchDims.y, launchDims.y));
135135

136-
gpuProcessBeamSamplesFirstLast(getStreamHandle(), raysNode->getRayCount(), MULTI_RETURN_BEAM_SAMPLES,
137-
mrSamples.getPointers(), mrFirst.getPointers(), mrLast.getPointers());
136+
if (beamHalfDivergence > 0.0f) {
137+
gpuProcessBeamSamplesFirstLast(getStreamHandle(), raysNode->getRayCount(), MULTI_RETURN_BEAM_SAMPLES,
138+
mrSamples.getPointers(), mrFirst.getPointers(), mrLast.getPointers(), raysPtr);
139+
}
138140
}
139141

140142
IAnyArray::ConstPtr RaytraceNode::getFieldDataMultiReturn(rgl_field_t field, rgl_return_type_t type)
@@ -144,15 +146,15 @@ IAnyArray::ConstPtr RaytraceNode::getFieldDataMultiReturn(rgl_field_t field, rgl
144146
case XYZ_VEC3_F32: return mrFirst.xyz;
145147
case DISTANCE_F32: return mrFirst.distance;
146148
case IS_HIT_I32: return mrFirst.isHit;
147-
default: throw InvalidPipeline(fmt::format("Multi-Return not supported for this field ({})", toString(field)));
149+
default: return getFieldData(field);
148150
}
149151
}
150152
if (type == RGL_RETURN_TYPE_LAST) {
151153
switch (field) {
152154
case XYZ_VEC3_F32: return mrLast.xyz;
153155
case DISTANCE_F32: return mrLast.distance;
154156
case IS_HIT_I32: return mrLast.isHit;
155-
default: throw InvalidPipeline(fmt::format("Multi-Return not supported for this field ({})", toString(field)));
157+
default: return getFieldData(field);
156158
}
157159
}
158160
throw InvalidPipeline(fmt::format("Unknown multi-return type ({})", type));

0 commit comments

Comments
 (0)