|
|
|||
File indexing completed on 2026-08-12 08:27:03
0001 #pragma once 0002 0003 /** 0004 * @file csg_intersect_leaf_phi_wedge.h 0005 * 0006 * Shared angular clipping helpers for centred CSG leaf primitives. 0007 * 0008 * Partial-phi spheres and cylinders store their angular interval directly in the 0009 * leaf parameter quad: 0010 * 0011 * q0.f.x = startPhi 0012 * q0.f.y = deltaPhi 0013 * 0014 * Angles are in radians and describe a counter-clockwise sweep about the positive 0015 * z axis, starting at `startPhi`. The interval includes both radial boundary 0016 * half-planes and the z axis. A wedge is active only for 0017 * `0 < deltaPhi < 2*pi`; values outside that range preserve the legacy unclipped 0018 * primitive. 0019 * 0020 * These `LEAF_FUNC` helpers are shared by host and device intersection and 0021 * signed-distance implementations. They provide angular classification for 0022 * curved surfaces and caps, a signed field for combining the angular constraint 0023 * with the leaf distance, and intersections with the two radial walls. Wall 0024 * intersections are clipped only to the outward radial half-plane here; callers 0025 * must additionally apply the primitive's radial, axial, and `t_min` constraints. 0026 */ 0027 0028 /** 0029 * Reports whether an angular interval clips a full primitive. 0030 * 0031 * @param deltaPhi Counter-clockwise angular sweep in radians. 0032 * @return `true` only for a positive sweep strictly smaller than a full circle. 0033 * Non-positive and at-least-full-circle sweeps are treated as unclipped. 0034 */ 0035 LEAF_FUNC 0036 bool csg_has_phi_wedge(const float deltaPhi) 0037 { 0038 return deltaPhi > 0.f && deltaPhi < 2.f * CUDART_PI_F; 0039 } 0040 0041 /** 0042 * Computes the counter-clockwise azimuthal displacement from `startPhi`. 0043 * 0044 * The result is normalized to the half-open interval `[0, 2*pi)`, which also 0045 * makes intervals whose end angle crosses phi zero straightforward to test. 0046 * Callers that need special handling at the z axis should do so before invoking 0047 * this helper because azimuth is undefined there. 0048 * 0049 * @param x Point x coordinate relative to the primitive centre. 0050 * @param y Point y coordinate relative to the primitive centre. 0051 * @param startPhi Angular origin of the wedge in radians. 0052 * @return Normalized counter-clockwise displacement from `startPhi`, in radians. 0053 */ 0054 LEAF_FUNC 0055 float csg_phi_delta(const float x, const float y, const float startPhi) 0056 { 0057 const float twoPi = 2.f * CUDART_PI_F; 0058 float dphi = atan2f(y, x) - startPhi; 0059 while (dphi < 0.f) dphi += twoPi; 0060 while (dphi >= twoPi) dphi -= twoPi; 0061 return dphi; 0062 } 0063 0064 /** 0065 * Tests whether an xy point lies within an inclusive phi interval. 0066 * 0067 * Inactive wedges accept every point. Points sufficiently close to the z axis 0068 * are also accepted because they belong to both radial boundary half-planes. 0069 * A small angular tolerance includes points lying numerically on the end wall. 0070 * 0071 * @param x Point x coordinate relative to the primitive centre. 0072 * @param y Point y coordinate relative to the primitive centre. 0073 * @param startPhi Start angle of the counter-clockwise interval, in radians. 0074 * @param deltaPhi Angular sweep of the interval, in radians. 0075 * @return `true` when the point is inside or on the wedge, or when no wedge is 0076 * active. 0077 */ 0078 LEAF_FUNC 0079 bool csg_in_phi_wedge(const float x, const float y, const float startPhi, const float deltaPhi) 0080 { 0081 if (!csg_has_phi_wedge(deltaPhi)) 0082 return true; 0083 0084 const float radial2 = x * x + y * y; 0085 if (radial2 < 1.e-12f) 0086 return true; 0087 0088 return csg_phi_delta(x, y, startPhi) <= deltaPhi + 1.e-6f; 0089 } 0090 0091 /** 0092 * Evaluates a signed field for the angular wedge constraint. 0093 * 0094 * Negative values classify points inside the wedge, positive values classify 0095 * points outside, and zero identifies either radial wall. For sweeps no larger 0096 * than pi the wedge is the intersection of the two inward half-spaces, so their 0097 * signed plane fields are combined with `max`. For larger "pacman" sweeps the 0098 * wedge is their union and `min` is used instead. 0099 * 0100 * This helper assumes an active wedge (`0 < deltaPhi < 2*pi`). It is intended as 0101 * a classification-compatible field to combine with another leaf distance, not 0102 * as a general Euclidean distance to every feature of the finite primitive. 0103 * 0104 * @param x Point x coordinate relative to the primitive centre. 0105 * @param y Point y coordinate relative to the primitive centre. 0106 * @param startPhi Start angle of the counter-clockwise interval, in radians. 0107 * @param deltaPhi Angular sweep of the interval, in radians. 0108 * @return Signed angular-wedge field: negative inside, positive outside. 0109 */ 0110 LEAF_FUNC 0111 float csg_distance_phi_wedge(const float x, const float y, const float startPhi, const float deltaPhi) 0112 { 0113 const float endPhi = startPhi + deltaPhi; 0114 const float sinStart = sinf(startPhi); 0115 const float cosStart = cosf(startPhi); 0116 const float sinEnd = sinf(endPhi); 0117 const float cosEnd = cosf(endPhi); 0118 0119 const float sdStart = x * sinStart - y * cosStart; 0120 const float sdEnd = -x * sinEnd + y * cosEnd; 0121 0122 return deltaPhi <= CUDART_PI_F ? fmaxf(sdStart, sdEnd) : fminf(sdStart, sdEnd); 0123 } 0124 0125 /** 0126 * Intersects a ray with one radial boundary half-plane of a phi wedge. 0127 * 0128 * The boundary is the half of the vertical plane extending from the z axis in 0129 * the direction `boundaryPhi`. Intersections on the opposite radial half-plane 0130 * are rejected. On success, `(nx, ny)` is the outward unit normal for either the 0131 * start or end wall of a counter-clockwise wedge. 0132 * 0133 * This helper does not reject intersections behind the ray origin and does not 0134 * clip against a primitive radius or z extent. The caller must validate `t` 0135 * against `t_min` and its own finite surface bounds. Output values are meaningful 0136 * only when the function returns `true`. 0137 * 0138 * @param[out] t Ray parameter at the wall intersection. 0139 * @param[out] nx Outward wall-normal x component. 0140 * @param[out] ny Outward wall-normal y component. 0141 * @param boundaryPhi Azimuth of the radial boundary half-plane, in radians. 0142 * @param startWall `true` for the interval's start wall, `false` for its end wall. 0143 * @param ox Ray-origin x coordinate relative to the primitive centre. 0144 * @param oy Ray-origin y coordinate relative to the primitive centre. 0145 * @param vx Ray-direction x component. 0146 * @param vy Ray-direction y component. 0147 * @return `true` when the ray is not parallel to the boundary plane and its 0148 * intersection lies on the outward radial half-plane. 0149 */ 0150 LEAF_FUNC 0151 bool csg_intersect_phi_wall(float& t, float& nx, float& ny, const float boundaryPhi, const bool startWall, const float ox, const float oy, const float vx, const float vy) 0152 { 0153 const float sinPhi = sinf(boundaryPhi); 0154 const float cosPhi = cosf(boundaryPhi); 0155 const float denom = vx * sinPhi - vy * cosPhi; 0156 0157 if (fabsf(denom) <= 1.e-12f) 0158 return false; 0159 0160 t = -(ox * sinPhi - oy * cosPhi) / denom; 0161 0162 const float x = ox + t * vx; 0163 const float y = oy + t * vy; 0164 0165 if (x * cosPhi + y * sinPhi < -1.e-6f) 0166 return false; 0167 0168 nx = startWall ? sinPhi : -sinPhi; 0169 ny = startWall ? -cosPhi : cosPhi; 0170 return true; 0171 }
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|