1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- czm_raySegment czm_rayEllipsoidIntersectionInterval(czm_ray ray, vec3 ellipsoid_center, vec3 ellipsoid_inverseRadii)
- {
-
- vec3 q = ellipsoid_inverseRadii * (czm_inverseModelView * vec4(ray.origin, 1.0)).xyz;
- vec3 w = ellipsoid_inverseRadii * (czm_inverseModelView * vec4(ray.direction, 0.0)).xyz;
- q = q - ellipsoid_inverseRadii * (czm_inverseModelView * vec4(ellipsoid_center, 1.0)).xyz;
- float q2 = dot(q, q);
- float qw = dot(q, w);
- if (q2 > 1.0)
- {
- if (qw >= 0.0)
- {
- return czm_emptyRaySegment;
- }
- else
- {
- float qw2 = qw * qw;
- float difference = q2 - 1.0;
- float w2 = dot(w, w);
- float product = w2 * difference;
- if (qw2 < product)
- {
- return czm_emptyRaySegment;
- }
- else if (qw2 > product)
- {
- float discriminant = qw * qw - product;
- float temp = -qw + sqrt(discriminant);
- float root0 = temp / w2;
- float root1 = difference / temp;
- if (root0 < root1)
- {
- czm_raySegment i = czm_raySegment(root0, root1);
- return i;
- }
- else
- {
- czm_raySegment i = czm_raySegment(root1, root0);
- return i;
- }
- }
- else
- {
- float root = sqrt(difference / w2);
- czm_raySegment i = czm_raySegment(root, root);
- return i;
- }
- }
- }
- else if (q2 < 1.0)
- {
- float difference = q2 - 1.0;
- float w2 = dot(w, w);
- float product = w2 * difference;
- float discriminant = qw * qw - product;
- float temp = -qw + sqrt(discriminant);
- czm_raySegment i = czm_raySegment(0.0, temp / w2);
- return i;
- }
- else
- {
- if (qw < 0.0)
- {
- float w2 = dot(w, w);
- czm_raySegment i = czm_raySegment(0.0, -qw / w2);
- return i;
- }
- else
- {
- return czm_emptyRaySegment;
- }
- }
- }
|