<html><head><style type="text/css"><!-- DIV {margin:0px;} --></style></head><body><div style="font-family:arial,helvetica,sans-serif;font-size:10pt"><div>Hi,<br><br>good news guys'n'gals, I found and fix the last bug! :)<br><br>I said previously that the ray entry point calculation looks correct... and this is true. What is wrong is the computation of camera position in texture space! At least it's INCOMPATIBILE with the calculation of rays entry point. The two spaces are slightly different. So, the distorsion always occurs (it's not a problem related to near clipping plane) but it's more noticeable only when you look nearly the volume (and this is a very frequent case in a fly-through navigation). Basically, look at the routine that assign texture coordinate for each vertex of the volume box:<br><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier
 New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(this-&gt;CellFlag) <span style="color: rgb(127, 127, 0);">// texcoords between 0 and 1. More complex</span></span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif; color: rgb(127, 127, 0);"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif; color: rgb(127, 127, 0);">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // depends on the loaded texture</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier
 New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tcoord[j] = spacingSign[j]*(vert[j] - loadedBounds[j*2]) /</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (loadedBounds[j*2+1] - loadedBounds[j*2]);</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else // texcoords between 1/2N and 1-1/2N.</span><br style="font-family: Courier
 New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double tmp; <span style="color: rgb(127, 127, 0);">// between 0 and 1</span></span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tmp = spacingSign[j]*(vert[j] - loadedBounds[j*2]) /</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier
 New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (loadedBounds[j*2+1] - loadedBounds[j*2]);</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; double delta=static_cast&lt;double&gt;(</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; loadedExtent[j*2+1]-loadedExtent[j*2]+1);</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier
 New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tcoord[j]=(tmp*(delta-1)+0.5)/delta;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }</span><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><br><br></span>We have 2 way of doing so: one when cellFlag is true and one when cellFlag is false. When you transform the camera position from world space to texture space you have to do the SAME job. And this is not the case! Look at the current code used for this:<br><br><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">cameraPosTexture[0] = (cameraPosDataset[0]-bounds[0])/dx;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier
 New,courier,monaco,monospace,sans-serif;">cameraPosTexture[1] = (cameraPosDataset[1]-bounds[2])/dy;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">cameraPosTexture[2] = (cameraPosDataset[2]-bounds[4])/dz;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><br><br>This match the case when CellFlag is true!&nbsp; (point coordinate minus bounds, divided by the bounds range). BUT, what happen (and this is my case) if CellFlag is false?&nbsp; The formulas that map a vertex from world space to texture space are differents! The fix? Easy! Replace the previous three lines in the method vtkOpenGLGPUVolumeRayCastMapper::LoadProjectionParameters, with:<br><br>&nbsp; &nbsp; &nbsp;<span style="font-family: Courier New,courier,monaco,monospace,sans-serif;"> <span style="color: rgb(127, 127, 0);">// AGPX MODIFIED</span></span><br
 style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; if (this-&gt;CellFlag)</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; {</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cameraPosTexture[0] = (cameraPosDataset[0]-bounds[0])/dx;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cameraPosTexture[1] = (cameraPosDataset[1]-bounds[2])/dy;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span
 style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cameraPosTexture[2] = (cameraPosDataset[2]-bounds[4])/dz;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; }</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; else</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; {</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; double delta, tmp;</span><br style="font-family: Courier
 New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; delta = static_cast&lt;double&gt;(extents[1]-extents[0]+1);</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tmp = (cameraPosDataset[0]-bounds[0])/dx;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cameraPosTexture[0] = (tmp * (delta - 1) + 0.5) / delta;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp;
 &nbsp;&nbsp;&nbsp; delta = static_cast&lt;double&gt;(extents[3]-extents[2]+1);</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tmp = (cameraPosDataset[1]-bounds[2])/dy;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cameraPosTexture[1] = (tmp * (delta - 1) + 0.5) / delta;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; delta = static_cast&lt;double&gt;(extents[5]-extents[4]+1);</span><br style="font-family: Courier
 New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tmp = (cameraPosDataset[2]-bounds[4])/dz;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; cameraPosTexture[2] = (tmp * (delta - 1) + 0.5) / delta;</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; }</span><br style="font-family: Courier New,courier,monaco,monospace,sans-serif;"><span style="font-family: Courier New,courier,monaco,monospace,sans-serif;">&nbsp;&nbsp;&nbsp; <span style="color: rgb(127, 127, 0);">// AGPX MODIFIED</span></span><br><br>This resolve the problem. There still another difference: the term <span
 style="font-family: Courier New,courier,monaco,monospace,sans-serif;">spacingSign</span> is missing and surely must be introduced or it could produce wrong result when spacing is negative. I leave it for you as an exercise :)<br><br>That's all my friends! The malefic bug triad was defeat! :) Please update VTK!!! :)<br><br>Ok, thank you for your attentions and keep the very good works!<br><br>- Gianluca Arcidiacono (a.k.a. AGPX)<br></div>
</div><br>



      </body></html>