Can't get intersection when starting position is over the map and it crashes when it's out.

/* Given a point that is on a ray, move it until it is within a given heightmap's borders. */ void MoveIntoMap(Vec3f& point, Vec3f ray, Heightmap* hmap) { // Already within map? if(point.x >= 1 && point.x < hmap->m_widthx * TILE_SIZE - 1 && point.z >= 1 && point.z < hmap->m_widthz * TILE_SIZE - 1) return; // Get x distance off the map. float xdif = 0; if(point.x < 0) // If start x is behind the map xdif = point.x - 5; // Add padding to make sure we're within the map else if(point.x > hmap->m_widthx * TILE_SIZE) // If start x is in front of the map xdif = hmap->m_widthx * TILE_SIZE - point.x + 5; // Add padding to make sure we're within the map // Ray is of unit length, so this gives us how much we travel along the ray to get x to within the map border. float x0moveratio = -xdif / ray.x; point = point + ray * x0moveratio; // Get z distance off the map. float zdif = 0; if(point.z < 0) // If start z is behind the map zdif = point.z - 5; // Add padding to make sure we're within the map else if(point.z > hmap->m_widthz * TILE_SIZE) // If start z is in front of the map zdif = hmap->m_widthz * TILE_SIZE - point.z + 5; // Add padding to make sure we're within the map // Ray is of unit length, so this gives us how much we travel along the ray to get z to within the map border. float z0moveratio = -zdif / ray.z; point = point + ray * z0moveratio; } bool TileIntersect(Heightmap* hmap, Vec3f* line, int x, int z, Vec3f* intersection) { Vec3f tri[3]; const int wx = hmap->m_widthx; const int wz = hmap->m_widthz; Vec3f* v = hmap->m_vertices; tri[0] = v[ (z * wx + x) * 3 * 2 + 0 ]; tri[1] = v[ (z * wx + x) * 3 * 2 + 1 ]; tri[2] = v[ (z * wx + x) * 3 * 2 + 2 ]; if(IntersectedPolygon(tri, line, 3, intersection)) return true; tri[0] = v[ (z * wx + x) * 3 * 2 + 3 ]; tri[1] = v[ (z * wx + x) * 3 * 2 + 4 ]; tri[2] = v[ (z * wx + x) * 3 * 2 + 5 ]; if(IntersectedPolygon(tri, line, 3, intersection)) return true; return false; } bool FastMapIntersect(Heightmap* hmap, Vec3f line[2], Vec3f* intersection) { // If both start and end are on one side of the map, we can't get an intersection, so return false. if(line[0].x < 0 && line[1].x < 0) return false; if(line[0].x >= hmap->m_widthx * TILE_SIZE && line[1].x >= hmap->m_widthx * TILE_SIZE) return false; if(line[0].z < 0 && line[1].z < 0) return false; if(line[0].z >= hmap->m_widthz * TILE_SIZE && line[1].z >= hmap->m_widthz * TILE_SIZE) return false; Vec3f ray = Normalize( line[1] - line[0] ); float lengthsqrd = Magnitude2( line[1] - line[0] ); MoveIntoMap(line[0], ray, hmap); // Move the start to within the map if it isn't already. MoveIntoMap(line[1], ray, hmap); // Move the end to within the map if it isn't already. float lengthdone = 0; Vec3f currpoint = line[0]; int currtilex = currpoint.x / TILE_SIZE; int currtilez = currpoint.z / TILE_SIZE; int nexttilex = currtilex; int nexttilez = currtilez; // The directions in which we will move to the next tile on the x and z axis int tiledx = 0; int tiledz = 0; if(ray.x > 0) tiledx = 1; else if(ray.x < 0) tiledx = -1; if(ray.z > 0) tiledz = 1; else if(ray.z < 0) tiledz = -1; // Move from tile to tile along the line until, // testing each tile's triangles for intersection. while(lengthdone*lengthdone < lengthsqrd) { float xdif = fabs( currtilex * TILE_SIZE - currpoint.x ); float zdif = fabs( currtilez * TILE_SIZE - currpoint.z ); float xmoveratio = xdif / ray.x + 1; // Add padding to make sure we get into the next tile float zmoveratio = zdif / ray.z + 1; // Add padding to make sure we get into the next tile float moveratio = 0; // Move the smallest distance to the next tile if(xmoveratio < zmoveratio) { moveratio = xmoveratio; } else { moveratio = zmoveratio; } currpoint = currpoint + ray * moveratio; if(TileIntersect(hmap, line, currtilex, currtilez, intersection)) return true; lengthdone += moveratio; // Move the smallest distance to the next tile if(xmoveratio < zmoveratio) { currtilex = nexttilex; nexttilex += tiledx; } else { currtilez = nexttilez; nexttilez += tiledz; } } return false; }

When I test each tile for intersection it works, but that's too slow, so I'm trying to get this to work.

**Edited by polyfrag, 12 January 2014 - 05:26 PM.**