+static int bvh_scene_sample_node_h( scene *s, u32 inode, v3f pos, v3f norm )
+{
+ bvh_node *node = &s->bvh.nodes[ inode ];
+
+ if( (pos[0] >= node->bbx[0][0] && pos[0] <= node->bbx[1][0]) &&
+ (pos[2] >= node->bbx[0][2] && pos[2] <= node->bbx[1][2]) )
+ {
+ if( !node->count )
+ {
+ if( bvh_scene_sample_node_h( s, node->il, pos, norm )) return 1;
+ if( bvh_scene_sample_node_h( s, node->ir, pos, norm )) return 1;
+ }
+ else
+ {
+ for( u32 i=0; i<node->count; i++ )
+ {
+ u32 idx = (node->start+i)*3;
+ model_vert *pa = &s->verts[ s->indices[ idx+0 ] ],
+ *pb = &s->verts[ s->indices[ idx+1 ] ],
+ *pc = &s->verts[ s->indices[ idx+2 ] ];
+
+ float height;
+ if( triangle_raycast2d( pa->co, pb->co, pc->co, pos, &height ))
+ {
+ pos[1] = height;
+
+ if( norm )
+ {
+ v3f v0, v1;
+ v3_sub( pa->co, pb->co, v0 );
+ v3_sub( pc->co, pb->co, v1 );
+ v3_cross( v1, v0, norm );
+ v3_normalize( norm );
+ }
+
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int bvh_scene_sample_h( scene *s, v3f pos, v3f norm)
+{
+ return bvh_scene_sample_node_h( s, 0, pos, norm );
+}
+
+static int bvh_scene_sample( scene *s, v3f pos, ray_hit *hit )
+{
+ hit->dist = INFINITY;
+
+ v3f ray_pos;
+ v3_add( pos, (v3f){0.0f,4.0f,0.0f}, ray_pos );
+
+ if( bvh_raycast( s, ray_pos, (v3f){0.0f,-1.0f,0.0f}, hit ))
+ {
+ pos[1] = hit->pos[1];
+ return 1;
+ }
+
+ return 0;
+}
+