The Persistence of Vision Raytracer (POV-Ray).
This is the Bug Tracking System for the POV-Ray project. Before opening a new task, please read How to make a Bug Report
Please do not issue bugs reports against versions earlier than 3.6.
FS#59 - Cone intersection test broken
Attached to Project:
POV-Ray
Opened by Christoph Lipka (clipka) - Wednesday, 16 September 2009, 19:00 GMT
Last edited by Chris Cason (chrisc) - Thursday, 31 December 2009, 14:14 GMT
Opened by Christoph Lipka (clipka) - Wednesday, 16 September 2009, 19:00 GMT
Last edited by Chris Cason (chrisc) - Thursday, 31 December 2009, 14:14 GMT
|
DetailsThe following scene, showing an almost cylindrical cone floating above a plane, renders fine in POV 3.6.2, but is obviously broken in 3.7.0.beta.34:
camera {
right x
up y*image_height/image_width
location <80,50,40>
look_at <0,0,0>
}
light_source { <500,500,500> color rgb 1 }
cone {
<0,0,30>, 11.303000, <0,0,-30>, 11.302999
texture { pigment { color rgb 1 } }
}
plane { y, -20 texture { pigment { color rgb 0.3 } } }
The error occurs even with the -MB option, indicating that the problem has nothing to do with bounding, but is in the cone intersection testing code. |
This task depends upon
Closed by Chris Cason (chrisc)
Thursday, 31 December 2009, 14:14 GMT
Reason for closing: Fixed
Additional comments about closing: Thanks for the fix!
Thursday, 31 December 2009, 14:14 GMT
Reason for closing: Fixed
Additional comments about closing: Thanks for the fix!
Confirmed, beta 34, from source on linux amd64.
While reading the source of cones.cpp, it seems that a few typo/copy-paste are present since a long time.
Could someone check that the following change would make better sense ?
(does not solve the issue, but it seems to me to be better from the understanding point)
@@ -253,7 +253,7 @@ z = P[Z] + t2 * D[Z]; - if ((t2 > Cone_Tolerance) && (t1 < MAX_DISTANCE) && (z >= 0.0) && (z <= 1.0)) + if ((t2 > Cone_Tolerance) && (t2 < MAX_DISTANCE) && (z >= 0.0) && (z <= 1.0)) { Intersection[i].d = t2 / len; Intersection[i++].t = SIDE_HIT; @@ -311,7 +311,7 @@ z = P[Z] + t2 * D[Z]; - if ((t2 > Cone_Tolerance) && (t1 < MAX_DISTANCE) && (z >= dist) && (z <= 1.0)) + if ((t2 > Cone_Tolerance) && (t2 < MAX_DISTANCE) && (z >= dist) && (z <= 1.0)) { Intersection[i].d = t2 / len; Intersection[i++].t = SIDE_HIT;For the reported bug, the code between 3.6 and 3.7 for cones is very similar.
So similar that it does not explain the issue.
MAX_DISTANCE & EPSILON are assumed to be the same (looks so here)
The issue is due to the equation solving for a cone: such nearly identical apex & base gives a huge transformation matrix
(the cone object is always in a basic box, apex = 1.0, base = 0.0, base at origin, apex 1 unit away and dist is the distance useful from apex.)
Huge transform, very small dist.
But code is the same (excepted the compilation option ??? do they play a role ?)
Cone_Tolerance moved from 1e-6 to 1e-9, did that matter at such scale/transform ?
(testing in progress)
Cone_Tolerance 1e-6, nor 1e-19 did NOT fix the issue.
BTW, the reported max trace level is reported as 0.
Re the code change suggested by Jerome, I agree: The existing code looks suspiciously like a copy&paste blunder.
In fact, despite the OP's statement, 3.6.1 is also bugged, when the view is adjusted.
camera { right x up y*image_height/image_width location <80,50,40> look_at <0,0,-30> angle 78 } light_source { <500,500,500> color rgb 1 } cone { <0,0,30>, 11.303000, <0,0,-30>, 11.302999 texture { pigment { color rgb 1 } } } plane { y, -20 texture { pigment { color rgb 2.3 } } } sphere { <0,0,34>,5 texture { pigment { color green 1 } } }for the cone (in both versions) Internal data
tlen : 678179999.30286061763763427734
dist: 0.99999991152791289917
base_r: 11.30299899999999979627
apex_r: 11.30300000000000082423
tmpf: 678179939.30286061763763427734
len: 60.00000000000000000000
Now, given the delta of radius/length, I would change the cylinder detector in Compute_Cone_Data from fabs(apex_radius-base_radius) < EPSILON
to
fabs(apex_radius-base_radius)*len/tlen < EPSILON
OP's scene would evaluate to .000000000000088472087238424866928698649637995230318792561639
which is 88.4e-15, far under our current epsilon (1.0e-10).
Problem solved!
(Yes, we are pushing that cone as a cylinder, but could you really see the difference ?)
P.S: as the computation of tlen & len is required beforehand, a reorganisation of the function Compute_Cone_Data is required.
Here a suggestion (tested) for replacement of cones.cpp