RTC_GEOMETRY_TYPE_USER(3)

πŸ’– RTC_GEOMETRY_TYPE_USER β€” user geometry type πŸ’–

okay bestie, welcome to the Embree Ray Tracing Kernels 4 manual, and today's main character is RTC_GEOMETRY_TYPE_USER, the geometry type that lets you be the boss of what a primitive even is. no cap. πŸ¦‹


✨ SYNOPSIS ✨

#include <embree4/rtcore.h>

RTCGeometry geometry =
  rtcNewGeometry(device, RTC_GEOMETRY_TYPE_USER);

🌸 DESCRIPTION 🌸

so. user-defined geometries hold a whole bunch of user-defined primitives, the same way triangle meshes hold a whole bunch of triangles. that's it, that's the vibe. the shape of those user-defined primitives? you specify it through registered callback functions, which is literally how you extend Embree with whatever arbitrary types of primitives your heart desires. iconic behavior honestly. πŸ’…

you create user-defined geometries by passing RTC_GEOMETRY_TYPE_USER into the rtcNewGeometry function call. then β€” and this part is not optional, bestie β€” you have to set:

  • the number of primitives (peep rtcSetGeometryUserPrimitiveCount)
  • a user data pointer (peep rtcSetGeometryUserData)
  • a bounding function closure (peep rtcSetGeometryBoundsFunction)
  • your user-defined intersect callback (peep rtcSetGeometryIntersectFunction)
  • your user-defined occluded callback (peep rtcSetGeometryOccludedFunction)

the bounding function is what gets used to query the bounds of all time steps of a user primitive, while the intersect and occluded callback functions get called to intersect the primitive with a ray. and the user data pointer? it gets passed to every single callback invocation, and you can use it to point at your application's representation of the user geometry. so convenient. obsessed. πŸŽ€

the creation of a user geometry typically looks the following:

RTCGeometry geometry = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_USER);
rtcSetGeometryUserPrimitiveCount(geometry, numPrimitives);
rtcSetGeometryUserData(geometry, userGeometryRepresentation);
rtcSetGeometryBoundsFunction(geometry, boundsFunction);
rtcSetGeometryIntersectFunction(geometry, intersectFunction);
rtcSetGeometryOccludedFunction(geometry, occludedFunction);

please have a look at the rtcSetGeometryBoundsFunction, rtcSetGeometryIntersectFunction, and rtcSetGeometryOccludedFunction functions on the implementation of the callback functions. they're the blueprint, fr fr. πŸ“–βœ¨

⚠️ okay important one: primitives of a user geometry get ignored during rendering when their bounds are empty β€” meaning the bounds have lower>upper in at least one dimension. so if your primitive is mysteriously not showing up, check your bounds first, bestie. πŸ’€

see tutorial [User Geometry] for an example of how to use the user-defined geometries. go look, it's giving tutorial energy. 🧚


πŸ’… EXIT STATUS πŸ’…

on failure, NULL is returned and an error code is set that can be queried using rtcGetDeviceError. so like, if you get NULL back, don't just sit there β€” go ask rtcGetDeviceError what happened. 🫢


🌈 SEE ALSO 🌈

  • [rtcNewGeometry]
  • [rtcSetGeometryUserPrimitiveCount]
  • [rtcSetGeometryUserData]
  • [rtcSetGeometryBoundsFunction]
  • [rtcSetGeometryIntersectFunction]
  • [rtcSetGeometryOccludedFunction]

and that's the whole page, bestie, you ate it. πŸ’– this was RTC_GEOMETRY_TYPE_USER(3) straight out of the Embree Ray Tracing Kernels 4 docs β€” go build something cursed and beautiful with it. mwah. πŸ˜­πŸ‘‘πŸ“

πŸ“¦ where this page comes from