All files / engine/Source/Shaders/Voxels IntersectCylinder.js

0% Statements 0/0
0% Branches 0/0
0% Functions 0/0
0% Lines 0/0

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145                                                                                                                                                                                                                                                                                                 
//This file is automatically rebuilt by the Cesium build process.
export default "// See IntersectionUtils.glsl for the definitions of Ray, NO_HIT, Intersections,\n\
// RayShapeIntersection, setSurfaceIntersection, setShapeIntersection,\n\
// intersectIntersections\n\
// See IntersectLongitude.glsl for the definitions of intersectHalfPlane,\n\
// intersectFlippedWedge, intersectRegularWedge\n\
\n\
/* Cylinder defines (set in Scene/VoxelCylinderShape.js)\n\
#define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN\n\
#define CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT\n\
#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE\n\
#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF\n\
#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF\n\
#define CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_ZERO\n\
\n\
#define CYLINDER_INTERSECTION_INDEX_RADIUS_MAX\n\
#define CYLINDER_INTERSECTION_INDEX_RADIUS_MIN\n\
#define CYLINDER_INTERSECTION_INDEX_ANGLE\n\
*/\n\
\n\
// Cylinder uniforms\n\
uniform vec2 u_cylinderRenderRadiusMinMax;\n\
#if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE)\n\
    uniform vec2 u_cylinderRenderAngleMinMax;\n\
#endif\n\
\n\
uniform sampler2D u_renderBoundPlanesTexture;\n\
\n\
RayShapeIntersection intersectBoundPlanes(in Ray ray) {\n\
    vec4 lastEntry = vec4(ray.dir, -INF_HIT);\n\
    vec4 firstExit = vec4(-ray.dir, +INF_HIT);\n\
    for (int i = 0; i < 2; i++) {\n\
        vec4 boundPlane = getBoundPlane(u_renderBoundPlanesTexture, i);\n\
        vec4 intersection = intersectPlane(ray, boundPlane);\n\
        if (dot(ray.dir, boundPlane.xyz) < 0.0) {\n\
            lastEntry = intersection.w > lastEntry.w ? intersection : lastEntry;\n\
        } else {\n\
            firstExit = intersection.w < firstExit.w ? intersection: firstExit;\n\
        }\n\
    }\n\
\n\
    if (lastEntry.w < firstExit.w) {\n\
        return RayShapeIntersection(lastEntry, firstExit);\n\
    } else {\n\
        return RayShapeIntersection(vec4(-ray.dir, NO_HIT), vec4(ray.dir, NO_HIT));\n\
    }\n\
}\n\
\n\
/**\n\
 * Find the intersection of a ray with a right cylindrical surface of a given radius\n\
 * about the z-axis.\n\
 */\n\
RayShapeIntersection intersectCylinder(in Ray ray, in float radius, in bool convex)\n\
{\n\
    vec2 position = ray.pos.xy;\n\
    vec2 direction = ray.dir.xy;\n\
\n\
    float a = dot(direction, direction);\n\
    float b = dot(position, direction);\n\
    float c = dot(position, position) - radius * radius;\n\
    float determinant = b * b - a * c;\n\
\n\
    if (determinant < 0.0) {\n\
        vec4 miss = vec4(normalize(ray.dir), NO_HIT);\n\
        return RayShapeIntersection(miss, miss);\n\
    }\n\
\n\
    determinant = sqrt(determinant);\n\
    float t1 = (-b - determinant) / a;\n\
    float t2 = (-b + determinant) / a;\n\
    float signFlip = convex ? 1.0 : -1.0;\n\
    vec3 normal1 = vec3((position + t1 * direction) * signFlip, 0.0);\n\
    vec3 normal2 = vec3((position + t2 * direction) * signFlip, 0.0);\n\
    // Return normals in eye coordinates\n\
    vec4 intersect1 = vec4(normalize(czm_normal * normal1), t1);\n\
    vec4 intersect2 = vec4(normalize(czm_normal * normal2), t2);\n\
\n\
    return RayShapeIntersection(intersect1, intersect2);\n\
}\n\
\n\
/**\n\
 * Find the intersection of a ray with a right cylindrical solid of given\n\
 * radius and height bounds. NOTE: The shape is assumed to be convex.\n\
 */\n\
RayShapeIntersection intersectBoundedCylinder(in Ray ray, in Ray rayEC, in float radius)\n\
{\n\
    RayShapeIntersection cylinderIntersection = intersectCylinder(ray, radius, true);\n\
    RayShapeIntersection heightBoundsIntersection = intersectBoundPlanes(rayEC);\n\
    return intersectIntersections(ray, cylinderIntersection, heightBoundsIntersection);\n\
}\n\
\n\
void intersectShape(in Ray ray, in Ray rayEC, inout Intersections ix)\n\
{\n\
    RayShapeIntersection outerIntersect = intersectBoundedCylinder(ray, rayEC, u_cylinderRenderRadiusMinMax.y);\n\
\n\
    setShapeIntersection(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MAX, outerIntersect);\n\
\n\
    if (outerIntersect.entry.w == NO_HIT) {\n\
        return;\n\
    }\n\
\n\
    #if defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_FLAT)\n\
        // When the cylinder is perfectly thin it's necessary to sandwich the\n\
        // inner cylinder intersection inside the outer cylinder intersection.\n\
\n\
        // Without this special case,\n\
        // [outerMin, outerMax, innerMin, innerMax] will bubble sort to\n\
        // [outerMin, innerMin, outerMax, innerMax] which will cause the back\n\
        // side of the cylinder to be invisible because it will think the ray\n\
        // is still inside the inner (negative) cylinder after exiting the\n\
        // outer (positive) cylinder.\n\
\n\
        // With this special case,\n\
        // [outerMin, innerMin, innerMax, outerMax] will bubble sort to\n\
        // [outerMin, innerMin, innerMax, outerMax] which will work correctly.\n\
\n\
        // Note: If initializeIntersections() changes its sorting function\n\
        // from bubble sort to something else, this code may need to change.\n\
        RayShapeIntersection innerIntersect = intersectCylinder(ray, 1.0, false);\n\
        setSurfaceIntersection(ix, 0, outerIntersect.entry, true, true);  // positive, enter\n\
        setSurfaceIntersection(ix, 1, innerIntersect.entry, false, true); // negative, enter\n\
        setSurfaceIntersection(ix, 2, innerIntersect.exit, false, false); // negative, exit\n\
        setSurfaceIntersection(ix, 3, outerIntersect.exit, true, false);  // positive, exit\n\
    #elif defined(CYLINDER_HAS_RENDER_BOUNDS_RADIUS_MIN)\n\
        RayShapeIntersection innerIntersect = intersectCylinder(ray, u_cylinderRenderRadiusMinMax.x, false);\n\
        setShapeIntersection(ix, CYLINDER_INTERSECTION_INDEX_RADIUS_MIN, innerIntersect);\n\
    #endif\n\
\n\
    #if defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_UNDER_HALF)\n\
        RayShapeIntersection wedgeIntersect = intersectRegularWedge(ray, u_cylinderRenderAngleMinMax);\n\
        setShapeIntersection(ix, CYLINDER_INTERSECTION_INDEX_ANGLE, wedgeIntersect);\n\
    #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_OVER_HALF)\n\
        RayShapeIntersection wedgeIntersects[2];\n\
        intersectFlippedWedge(ray, u_cylinderRenderAngleMinMax, wedgeIntersects);\n\
        setShapeIntersection(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersects[0]);\n\
        setShapeIntersection(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersects[1]);\n\
    #elif defined(CYLINDER_HAS_RENDER_BOUNDS_ANGLE_RANGE_EQUAL_ZERO)\n\
        RayShapeIntersection wedgeIntersects[2];\n\
        intersectHalfPlane(ray, u_cylinderRenderAngleMinMax.x, wedgeIntersects);\n\
        setShapeIntersection(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 0, wedgeIntersects[0]);\n\
        setShapeIntersection(ix, CYLINDER_INTERSECTION_INDEX_ANGLE + 1, wedgeIntersects[1]);\n\
    #endif\n\
}\n\
";