IntersectCylinder.js 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. //This file is automatically rebuilt by the Cesium build process.
  2. export default "// See IntersectionUtils.glsl for the definitions of Ray, setIntersection,\n\
  3. // setIntersectionPair\n\
  4. \n\
  5. /* Cylinder defines (set in Scene/VoxelCylinderShape.js)\n\
  6. #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN\n\
  7. #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX\n\
  8. #define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT\n\
  9. #define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT\n\
  10. #define CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT\n\
  11. #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE\n\
  12. #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF\n\
  13. #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF\n\
  14. #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_HALF\n\
  15. #define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_ZERO\n\
  16. \n\
  17. #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS\n\
  18. #define CYLINDER_HAS_SHAPE_BOUNDS_RADIUS_FLAT\n\
  19. #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT\n\
  20. #define CYLINDER_HAS_SHAPE_BOUNDS_HEIGHT_FLAT\n\
  21. #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE\n\
  22. #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_RANGE_EQUAL_ZERO\n\
  23. #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_DISCONTINUITY\n\
  24. #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MAX_DISCONTINUITY\n\
  25. #define CYLINDER_HAS_SHAPE_BOUNDS_ANGLE_MIN_MAX_REVERSED\n\
  26. \n\
  27. #define CYLINDER_INTERSECTION_INDEX_RADIUS_MAX\n\
  28. #define CYLINDER_INTERSECTION_INDEX_RADIUS_MIN\n\
  29. #define CYLINDER_INTERSECTION_INDEX_ANGLE\n\
  30. */\n\
  31. \n\
  32. // Cylinder uniforms\n\
  33. #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT)\n\
  34. uniform vec3 u_cylinderUvToRenderBoundsScale;\n\
  35. uniform vec3 u_cylinderUvToRenderBoundsTranslate;\n\
  36. #endif\n\
  37. #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN) && !defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT)\n\
  38. uniform float u_cylinderUvToRenderRadiusMin;\n\
  39. #endif\n\
  40. #if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE)\n\
  41. uniform vec2 u_cylinderRenderAngleMinMax;\n\
  42. #endif\n\
  43. \n\
  44. vec4 intersectHalfPlane(Ray ray, float angle) {\n\
  45. vec2 o = ray.pos.xy;\n\
  46. vec2 d = ray.dir.xy;\n\
  47. vec2 planeDirection = vec2(cos(angle), sin(angle));\n\
  48. vec2 planeNormal = vec2(planeDirection.y, -planeDirection.x);\n\
  49. \n\
  50. float a = dot(o, planeNormal);\n\
  51. float b = dot(d, planeNormal);\n\
  52. float t = -a / b;\n\
  53. \n\
  54. vec2 p = o + t * d;\n\
  55. bool outside = dot(p, planeDirection) < 0.0;\n\
  56. if (outside) return vec4(-INF_HIT, +INF_HIT, NO_HIT, NO_HIT);\n\
  57. \n\
  58. return vec4(-INF_HIT, t, t, +INF_HIT);\n\
  59. }\n\
  60. \n\
  61. #define POSITIVE_HIT vec2(t, +INF_HIT);\n\
  62. #define NEGATIVE_HIT vec2(-INF_HIT, t);\n\
  63. \n\
  64. vec2 intersectHalfSpace(Ray ray, float angle)\n\
  65. {\n\
  66. vec2 o = ray.pos.xy;\n\
  67. vec2 d = ray.dir.xy;\n\
  68. vec2 n = vec2(sin(angle), -cos(angle));\n\
  69. \n\
  70. float a = dot(o, n);\n\
  71. float b = dot(d, n);\n\
  72. float t = -a / b;\n\
  73. float s = sign(a);\n\
  74. \n\
  75. // Half space cuts right through the camera, pick the side to intersect\n\
  76. if (a == 0.0) {\n\
  77. if (b >= 0.0) {\n\
  78. return POSITIVE_HIT;\n\
  79. } else {\n\
  80. return NEGATIVE_HIT;\n\
  81. }\n\
  82. }\n\
  83. \n\
  84. if (t >= 0.0 != s >= 0.0) {\n\
  85. return POSITIVE_HIT;\n\
  86. } else {\n\
  87. return NEGATIVE_HIT;\n\
  88. }\n\
  89. }\n\
  90. \n\
  91. vec2 intersectRegularWedge(Ray ray, float minAngle, float maxAngle)\n\
  92. {\n\
  93. vec2 o = ray.pos.xy;\n\
  94. vec2 d = ray.dir.xy;\n\
  95. vec2 n1 = vec2(sin(minAngle), -cos(minAngle));\n\
  96. vec2 n2 = vec2(-sin(maxAngle), cos(maxAngle));\n\
  97. \n\
  98. float a1 = dot(o, n1);\n\
  99. float a2 = dot(o, n2);\n\
  100. float b1 = dot(d, n1);\n\
  101. float b2 = dot(d, n2);\n\
  102. \n\
  103. float t1 = -a1 / b1;\n\
  104. float t2 = -a2 / b2;\n\
  105. float s1 = sign(a1);\n\
  106. float s2 = sign(a2);\n\
  107. \n\
  108. float tmin = min(t1, t2);\n\
  109. float tmax = max(t1, t2);\n\
  110. float smin = tmin == t1 ? s1 : s2;\n\
  111. float smax = tmin == t1 ? s2 : s1;\n\
  112. \n\
  113. bool e = tmin >= 0.0;\n\
  114. bool f = tmax >= 0.0;\n\
  115. bool g = smin >= 0.0;\n\
  116. bool h = smax >= 0.0;\n\
  117. \n\
  118. if (e != g && f == h) return vec2(tmin, tmax);\n\
  119. else if (e == g && f == h) return vec2(-INF_HIT, tmin);\n\
  120. else if (e != g && f != h) return vec2(tmax, +INF_HIT);\n\
  121. else return vec2(NO_HIT);\n\
  122. }\n\
  123. \n\
  124. vec4 intersectFlippedWedge(Ray ray, float minAngle, float maxAngle)\n\
  125. {\n\
  126. vec2 planeIntersectMin = intersectHalfSpace(ray, minAngle);\n\
  127. vec2 planeIntersectMax = intersectHalfSpace(ray, maxAngle + czm_pi);\n\
  128. return vec4(planeIntersectMin, planeIntersectMax);\n\
  129. }\n\
  130. \n\
  131. vec2 intersectUnitCylinder(Ray ray)\n\
  132. {\n\
  133. vec3 o = ray.pos;\n\
  134. vec3 d = ray.dir;\n\
  135. \n\
  136. float a = dot(d.xy, d.xy);\n\
  137. float b = dot(o.xy, d.xy);\n\
  138. float c = dot(o.xy, o.xy) - 1.0;\n\
  139. float det = b * b - a * c;\n\
  140. \n\
  141. if (det < 0.0) {\n\
  142. return vec2(NO_HIT);\n\
  143. }\n\
  144. \n\
  145. det = sqrt(det);\n\
  146. float ta = (-b - det) / a;\n\
  147. float tb = (-b + det) / a;\n\
  148. float t1 = min(ta, tb);\n\
  149. float t2 = max(ta, tb);\n\
  150. \n\
  151. float z1 = o.z + t1 * d.z;\n\
  152. float z2 = o.z + t2 * d.z;\n\
  153. \n\
  154. if (abs(z1) >= 1.0)\n\
  155. {\n\
  156. float tCap = (sign(z1) - o.z) / d.z;\n\
  157. t1 = abs(b + a * tCap) < det ? tCap : NO_HIT;\n\
  158. }\n\
  159. \n\
  160. if (abs(z2) >= 1.0)\n\
  161. {\n\
  162. float tCap = (sign(z2) - o.z) / d.z;\n\
  163. t2 = abs(b + a * tCap) < det ? tCap : NO_HIT;\n\
  164. }\n\
  165. \n\
  166. return vec2(t1, t2);\n\
  167. }\n\
  168. \n\
  169. vec2 intersectUnitCircle(Ray ray) {\n\
  170. vec3 o = ray.pos;\n\
  171. vec3 d = ray.dir;\n\
  172. \n\
  173. float t = -o.z / d.z;\n\
  174. vec2 zPlanePos = o.xy + d.xy * t;\n\
  175. float distSqr = dot(zPlanePos, zPlanePos);\n\
  176. \n\
  177. if (distSqr > 1.0) {\n\
  178. return vec2(NO_HIT);\n\
  179. }\n\
  180. \n\
  181. return vec2(t, t);\n\
  182. }\n\
  183. \n\
  184. vec2 intersectInfiniteUnitCylinder(Ray ray)\n\
  185. {\n\
  186. vec3 o = ray.pos;\n\
  187. vec3 d = ray.dir;\n\
  188. \n\
  189. float a = dot(d.xy, d.xy);\n\
  190. float b = dot(o.xy, d.xy);\n\
  191. float c = dot(o.xy, o.xy) - 1.0;\n\
  192. float det = b * b - a * c;\n\
  193. \n\
  194. if (det < 0.0) {\n\
  195. return vec2(NO_HIT);\n\
  196. }\n\
  197. \n\
  198. det = sqrt(det);\n\
  199. float t1 = (-b - det) / a;\n\
  200. float t2 = (-b + det) / a;\n\
  201. float tmin = min(t1, t2);\n\
  202. float tmax = max(t1, t2);\n\
  203. \n\
  204. return vec2(tmin, tmax);\n\
  205. }\n\
  206. \n\
  207. void intersectShape(Ray ray, inout Intersections ix)\n\
  208. {\n\
  209. #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MAX) || defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT)\n\
  210. ray.pos = ray.pos * u_cylinderUvToRenderBoundsScale + u_cylinderUvToRenderBoundsTranslate;\n\
  211. ray.dir *= u_cylinderUvToRenderBoundsScale;\n\
  212. #else\n\
  213. // Position is converted from [0,1] to [-1,+1] because shape intersections assume unit space is [-1,+1].\n\
  214. // Direction is scaled as well to be in sync with position.\n\
  215. ray.pos = ray.pos * 2.0 - 1.0;\n\
  216. ray.dir *= 2.0;\n\
  217. #endif\n\
  218. \n\
  219. #if defined(CYLINDER_HAS_RENDER_BOUNDS_HEIGHT_FLAT)\n\
  220. vec2 outerIntersect = intersectUnitCircle(ray);\n\
  221. #else\n\
  222. vec2 outerIntersect = intersectUnitCylinder(ray);\n\
  223. #endif\n\
  224. \n\
  225. setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MAX, outerIntersect);\n\
  226. \n\
  227. if (outerIntersect.x == NO_HIT) {\n\
  228. return;\n\
  229. }\n\
  230. \n\
  231. #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT)\n\
  232. // When the cylinder is perfectly thin it's necessary to sandwich the\n\
  233. // inner cylinder intersection inside the outer cylinder intersection.\n\
  234. \n\
  235. // Without this special case,\n\
  236. // [outerMin, outerMax, innerMin, innerMax] will bubble sort to\n\
  237. // [outerMin, innerMin, outerMax, innerMax] which will cause the back\n\
  238. // side of the cylinder to be invisible because it will think the ray\n\
  239. // is still inside the inner (negative) cylinder after exiting the\n\
  240. // outer (positive) cylinder.\n\
  241. \n\
  242. // With this special case,\n\
  243. // [outerMin, innerMin, innerMax, outerMax] will bubble sort to\n\
  244. // [outerMin, innerMin, innerMax, outerMax] which will work correctly.\n\
  245. \n\
  246. // Note: If initializeIntersections() changes its sorting function\n\
  247. // from bubble sort to something else, this code may need to change.\n\
  248. vec2 innerIntersect = intersectInfiniteUnitCylinder(ray);\n\
  249. setIntersection(ix, 0, outerIntersect.x, true, true); // positive, enter\n\
  250. setIntersection(ix, 1, innerIntersect.x, false, true); // negative, enter\n\
  251. setIntersection(ix, 2, innerIntersect.y, false, false); // negative, exit\n\
  252. setIntersection(ix, 3, outerIntersect.y, true, false); // positive, exit\n\
  253. #elif defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN)\n\
  254. Ray innerRay = Ray(ray.pos * u_cylinderUvToRenderRadiusMin, ray.dir * u_cylinderUvToRenderRadiusMin);\n\
  255. vec2 innerIntersect = intersectInfiniteUnitCylinder(innerRay);\n\
  256. setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MIN, innerIntersect);\n\
  257. #endif\n\
  258. \n\
  259. #if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF)\n\
  260. vec2 wedgeIntersect = intersectRegularWedge(ray, u_cylinderRenderAngleMinMax.x, u_cylinderRenderAngleMinMax.y);\n\
  261. setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect);\n\
  262. #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF)\n\
  263. vec4 wedgeIntersect = intersectFlippedWedge(ray, u_cylinderRenderAngleMinMax.x, u_cylinderRenderAngleMinMax.y);\n\
  264. setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy);\n\
  265. setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw);\n\
  266. #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_HALF)\n\
  267. vec2 wedgeIntersect = intersectHalfSpace(ray, u_cylinderRenderAngleMinMax.x);\n\
  268. setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect);\n\
  269. #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_ZERO)\n\
  270. vec4 wedgeIntersect = intersectHalfPlane(ray, u_cylinderRenderAngleMinMax.x);\n\
  271. setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersect.xy);\n\
  272. setIntersectionPair(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersect.zw);\n\
  273. #endif\n\
  274. }\n\
  275. ";