j00ey Posted November 2, 2015 Share Posted November 2, 2015 (edited) Hi I'm trying to make an asset that will generate some curved lines with corners so I've written a sort of curving raytracer. It works with most settings but changing some variables I quickly come across settings where houdini just gets stuck. I can ESC out of it without difficulty and I can generate the geometry I need but I'd like to understand what's causing the problem. Attached is the hip. WIth the settings I've left it set at, it's quite happy to do 18 bounces but if you turn it up to 19 it sticks... Thanks for reading. * edit * Maybe I should explain quickly what it's actually supposed to do - for input points : while bounces is less than max bounce : using point normal, find intersection with second input geometry calculate distance between start position and intersection If distance is greater than step size, create a new point at step length away and rotate normal direction. If distance is less than step size, create a point at intersection position and set the normal to the reflection vector between normal and intersection normal curvetracer_v01.hip Edited November 2, 2015 by j00ey Quote Link to comment Share on other sites More sharing options...
fsimerey Posted November 2, 2015 Share Posted November 2, 2015 (edited) Hi, your problem is in your while loop, hit_prim = -1 when you bounce 19 times and you haven't any statement in this case. So the loop run over and over....and over. You can check this with adding these lines just after your else if statement: else { printf("hit_dist: %s | hit_prim: %s\n", hit_dist, hit_prim); break; // STOP the loop } Edited November 2, 2015 by fsim Quote Link to comment Share on other sites More sharing options...
j00ey Posted November 2, 2015 Author Share Posted November 2, 2015 Ah! Great, thanks Francois, you're right. I thought as the point is inside watertight geometry, it would never actually return -1. Do you know why it might be doing that? Quote Link to comment Share on other sites More sharing options...
fsimerey Posted November 2, 2015 Share Posted November 2, 2015 I think the curr_dir is tangent to geometry at this time. You can verify that, display N in viewport. Quote Link to comment Share on other sites More sharing options...
fsimerey Posted November 2, 2015 Share Posted November 2, 2015 Here the solution. I store the last hit_prim, hit_pos, hit_uv, and if hit_dist < steplength, i check if hitprim == -1. In this case, i reflect curr_dir from the last_hitprim. float steplength = chf("steplength"); float angle = radians(chf("angle")); float bias = chf("bias"); int maxbounces = chi("bounces"); float bounce , hit_dist; int newpoint , newprim , hit_prim; vector start_pos , curr_pos , new_pos , curr_dir , new_dir , prim_uv , hit_pos , hit_n , reflect_dir, bend_dir , bitangent; vector4 q; newprim = addprim(0,"polyline"); addvertex(0,newprim,0); start_pos = v@P; curr_dir = normalize(v@N); bounce = 0; // printf("-S-\n\n"); int last_hitprim; vector last_hitpos; vector last_primuv; while(bounce < maxbounces){ curr_pos = start_pos + (curr_dir * bias);//offset ray start in case of self intersection hit_prim = intersect(1 , curr_pos , curr_dir * 10000 , hit_pos , prim_uv );//store hit details hit_dist = length(start_pos - hit_pos);//calc distance to hit // printf("Bou: %s | Cur.P: %s | curr_dir: %s ", bounce, curr_pos, curr_dir); if ( ( hit_dist > steplength ) && ( hit_prim != -1 ) ){//if hit a prim and it is further away than step size new_pos = start_pos + (curr_dir * steplength); newpoint = addpoint(0,new_pos); addvertex(0,newprim,newpoint); start_pos = new_pos; bitangent = set(-curr_dir.z , 0 , curr_dir.x); q = quaternion( angle , bitangent); bend_dir = qrotate( q , curr_dir); bend_dir = normalize(bend_dir); setpointattrib(0,"N",newpoint,bend_dir,"set"); curr_dir = bend_dir; // printf("I'm in if...\n"); last_hitprim = hit_prim; last_hitpos = hit_pos; last_primuv = prim_uv; } else if ( ( hit_dist < steplength ) ){//if hit a prim and it is within step size if (hit_prim == -1) { hit_pos = last_hitpos; hit_prim = last_hitprim; prim_uv = last_primuv; } new_pos = hit_pos; newpoint = addpoint(0,new_pos); addvertex(0,newprim,newpoint); hit_n = primuv(1,"N",hit_prim,prim_uv); reflect_dir = normalize(reflect(curr_dir , hit_n)); setpointattrib(0,"N",newpoint,reflect_dir,"set"); setpointattrib(0,"corner",newpoint,1,"set"); start_pos = hit_pos; curr_dir = reflect_dir; bounce += 1; // printf("I'm in else...\n"); last_hitprim = hit_prim; last_hitpos = hit_pos; last_primuv = prim_uv; } else { printf("hit_dist: %s | hit_prim: %s\n", hit_dist, hit_prim); break; } } Quote Link to comment Share on other sites More sharing options...
j00ey Posted November 2, 2015 Author Share Posted November 2, 2015 (edited) Thanks very much for that Francois, I'll try it. After your initial I put in a statement to say : if hit_prim == -1 then break which fixed the problem but this is good for debugging... Edited November 2, 2015 by j00ey Quote Link to comment Share on other sites More sharing options...
fsimerey Posted November 2, 2015 Share Posted November 2, 2015 (edited) You're welcome. In fact, the real problem is you add an offset to your curr_pos. And when hit_dist is close to your bias, the curr_pos is out of geometry, and you check 'if hit_dist < steplength', the solution is to check 'if hit_dist < (steplength + bias)'. Edited November 2, 2015 by fsim Quote Link to comment Share on other sites More sharing options...
j00ey Posted November 2, 2015 Author Share Posted November 2, 2015 Ah yes, I never thought I needed to compensate for the bias. Good thinking!Thanks again Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.