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/ |