Horde3D
http://horde3d.org/forums/

[solved] Terrain extension / checkIntersection
http://horde3d.org/forums/viewtopic.php?f=3&t=336
Page 1 of 1

Author:  Codepoet [ 17.05.2008, 13:43 ]
Post subject:  [solved] Terrain extension / checkIntersection

TerrainNode::checkIntersection does not work for rays perpendicular to the terrain. For rays with a direction nearly perpendicular to the surface it fails most of the time, too.

Author:  Volker [ 28.05.2008, 13:35 ]
Post subject:  Re: Terrain extension / checkIntersection

Although I could hardly reproduce the problem, it's true that there would be a problem for not only perpendicular rays but also for those which are parallel to the Z-Axis. So I think the following patch should solve this issue. Could anyone confirm this?

Code:
Index: terrain.cpp
===================================================================
--- terrain.cpp   (revision 20)
+++ terrain.cpp   (working copy)
@@ -676,8 +676,21 @@
       float height1 = _heightData[y * _hmapSize + x] / 65535.0f, height2;
 
       Vec3f pos;
-      Vec3f prevPos( startX, (dir.y * (startY - orig.z) + dir.z * orig.y) / dir.z, startY );
-
+      Vec3f prevPos;
+      
+      // Check for perpendicular ray
+      if( abs(dir.z) < 0.00001f && abs(dir.x) < 0.00001f )
+      {
+         if( (height1 < orig.y && height1 > dir.y) || (height1 > orig.y && height1 < dir.y) )
+            return true;
+         else
+            return false;
+      }
+      else if( abs(dir.z) < 0.00001f)
+         prevPos = Vec3f( startX, (dir.y * (startX - orig.x) + dir.x * orig.y) / dir.x, startY );
+      else
+         prevPos = Vec3f( startX, (dir.y * (startY - orig.z) + dir.z * orig.y) / dir.z, startY );
+            
       for( t=0; t < err_step_slow; ++t ) // error_step_slow is equal to the number of pixels to be checked
       {
          // Update error
@@ -699,7 +712,11 @@
 
          pos.x = x / (float)_hmapSize;
          pos.z = y / (float)_hmapSize;
-         pos.y = (dir.y * (pos.z - orig.z) + dir.z * orig.y) / dir.z;
+         // Calculate y value based on the fraction of the current position on the direction vector                  
+         if( abs(dir.z) < 0.00001f)
+            pos.y = (dir.y * (pos.x - orig.x) + dir.x * orig.y) / dir.x;
+         else
+            pos.y = (dir.y * (pos.z - orig.z) + dir.z * orig.y) / dir.z;
 
          if( prevPos.y >= pos.y && prevPos.y >= height1 && pos.y <= height2 )
          {

Author:  doublue [ 29.05.2008, 09:58 ]
Post subject:  Re: Terrain extension / checkIntersection

In my case when abs(dir.z) below something like 0.01f error would occur, so I need to calculate pos.y along longer axis. Codes like:

Code:
if (abs(dir.z) < abs(dir.x))
    pos.y = (dir.y * (pos.x - orig.x) + dir.x * orig.y) / dir.x;
else
    pos.y = (dir.y * (pos.z - orig.z) + dir.z * orig.y) / dir.z;


Above codes work fine with rays parallel to the x-axis or z-axis but not with rays perpendicular to the terrain. Did anyone solve the problem?

Author:  Volker [ 29.05.2008, 17:40 ]
Post subject:  Re: Terrain extension / checkIntersection

It should work fine with perpendicular rays too, since this case is handled with the
Code:
if( abs(dir.z) < 0.00001f && abs(dir.x) < 0.00001f )

statement. Maybe the threshold of 0.00001f is to low. You may try 0.01 but this seems to me a little bit high. Does anyone have a better solution?

Author:  Codepoet [ 29.05.2008, 17:44 ]
Post subject:  Re: Terrain extension / checkIntersection

I'm currently refactoring my own code and can't test it. After that I'll do some tests.

Author:  Codepoet [ 30.05.2008, 21:54 ]
Post subject:  Re: Terrain extension / checkIntersection

Edit: Ignore post, contains bad ideas.

Volker wrote:
Although I could hardly reproduce the problem, it's true that there would be a problem for not only perpendicular rays but also for those which are parallel to the Z-Axis. So I think the following patch should solve this issue. Could anyone confirm this?

So, refactoring is sufficiently completed :)
Test results:
I had to change all abs calls with fabs calls for gcc otherwise it would not compile (abs is only defined for int and long long).
Further I had to comment out the Liang-Barsky algorithm and use t1 = 0, t2 = 1. That's bad for performance but shouldn't be any problem, or am I missing something?

Then it worked even for test vectors like (0, -10000, 0). :)
Direction vectors like (10000, 0, 0) or (0, 0, 10000) work, too.

Another change in "check for perpendicular ray": the intersection Position is not returned. I added the line
Code:
intsPos = _absTrans * Vec3f(orig.x, height1, orig.z);

Author:  Volker [ 30.05.2008, 22:27 ]
Post subject:  Re: Terrain extension / checkIntersection

Sorry I can't follow you :-)

How do you get the start and end point for the bresenham algorithm if you comment out the Liang Barsky algorithm?

Author:  Codepoet [ 30.05.2008, 22:46 ]
Post subject:  Re: Terrain extension / checkIntersection

Maybe I'm completely wrong.
I thought that I could omit the line clipping, but now that you mention it and thinking a bit more about the code I don't think that it works.

Author:  Codepoet [ 31.05.2008, 18:24 ]
Post subject:  Re: Terrain extension / checkIntersection

I've tested your latest fix in svn - for the test vector (0, -10000, 0) it does not work :(
Setting the x and z component to small values like 0.0001 makes it work. Maybe that's still a problem with Liang-Barsky / the t1 > t2 check?

Author:  Volker [ 06.06.2008, 16:12 ]
Post subject:  Re: Terrain extension / checkIntersection

You were right, it was a problem with Liang Barsky. I changed the
Code:
if( orig.x < orig.x + dir.x )
...
if (orig.z < orig.z + dir.z)

to
Code:
if( orig.x <= orig.x + dir.x )
...
if (orig.z <= orig.z + dir.z)

and it seems to be fixed

I also integrated the patch for the castRay and fixed the parallel projection in Horde3DUtils::pickNode.

Page 1 of 1 All times are UTC + 1 hour
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/