#define PLANET_ELIPSE 1.17
#define EXPLOSION_VERTICES 16
#define EXPLOSION_ELIPSE 1.17
+#define SIGHT_DIST 78.74 /* distanc of sights in inch */
+#define FIX_OBJECT_SCALE 16
/*
* render item definition and structures
}
/* rendering starts, initialize variables */
-void render_capture_start(double _fov, int _extend_roads, int debug)
+void render_capture_start(double _fov, int _extend_roads, int _smooth_planets, int debug)
{
#if defined(DEBUG_COLOR) || defined(DEBUG_VERTEX)
printf("start rendering a new frame...\n");
mercenary_get_orientation(&motion_new.orientation_roll, &motion_new.orientation_pitch, &motion_new.orientation_yaw);
mercenary_get_orientation_raw(&motion_new.orientation_raw_pitch, &motion_new.orientation_raw_yaw);
motion_new.planet_rotation = motion_old.planet_rotation;
- mercenary_get_orientation_planet(&motion_new.planet_inclination, &motion_new.planet_azimuth);
+ mercenary_get_orientation_planet(&motion_new.planet_inclination, &motion_new.planet_azimuth, _smooth_planets);
render_item_object_info = NULL;
render_item_vertices_0 = render_item_vertices_1 = render_item_vertices_2 = NULL;
return value;
}
-static void store_coord(const char __attribute__((unused)) *what, uint32_t vertex, int32_t x, int32_t y, int32_t z)
+static void store_coord(const char __attribute__((unused)) *what, uint32_t vertex, int32_t x, int32_t y, int32_t z, double scale)
{
if ((vertex & 3)) {
print_info("Vertex %d is not a multiple of four!\n", vertex);
printf("storing %s coordinates: vertex=%d, x=%d, y=%d, z=%d\n", what, vertex, x, y, z);
#endif
/* use absolute position */
- x += motion_new.position_east;
- y += motion_new.position_height;
- z += motion_new.position_north;
- render_item->u.vertices.x[vertex] = x;
- render_item->u.vertices.y[vertex] = y;
- render_item->u.vertices.z[vertex] = z;
+ render_item->u.vertices.x[vertex] = (double)x * scale + motion_new.position_east;
+ render_item->u.vertices.y[vertex] = (double)y * scale + motion_new.position_height;
+ render_item->u.vertices.z[vertex] = (double)z * scale + motion_new.position_north;
}
static void store_planets_coord(const char __attribute__((unused)) *what, uint32_t vertex, int32_t x, int32_t y, int32_t z)
y += (int32_t)REG_A[2];
z = (int16_t)REG_D[5];
z += (int32_t)REG_A[3];
- store_coord("object", REG_A[0], x, y, z);
+ store_coord("object", REG_A[0], x, y, z, 1.0);
}
/* polygon of object */
x = (int32_t)(REG_D[3] << 4) / 16;
y = (int32_t)(REG_D[4] << 4) / 16;
z = (int32_t)(REG_D[5] << 4) / 16;
- store_coord("beacon", 0, x, y, z);
+ store_coord("beacon", 0, x, y, z, 1.0);
}
/* point of beacon */
x = (int32_t)REG_D[3];
y = (int32_t)REG_D[4];
z = (int32_t)REG_D[5];
- store_coord("building exterior", REG_A[0], x, y, z);
+ store_coord("building exterior", REG_A[0], x, y, z, 1.0);
}
/* polygon of building (exterior) */
x = REG_D[3];
y = -motion_new.position_height;
z = REG_D[5];
- store_coord("road", REG_A[0], x, y, z);
+ store_coord("road", REG_A[0], x, y, z, 1.0);
}
/* line of road */
y = -motion_new.position_height;
z = m68k_read_memory_32(576 + REG_A[0]);
z -= REG_A[3];
- store_coord("road/place", REG_A[0], x, y, z);
+ store_coord("road/place", REG_A[0], x, y, z, 1.0);
}
/* polygon of road */
y += (int32_t)REG_A[2];
z = (int16_t)REG_D[5];
z += (int32_t)REG_A[3];
- store_coord("tags", REG_A[0], x, y, z);
+ store_coord("tags", REG_A[0], x, y, z, 1.0);
}
/* coordinates ready for large tags */
y += 2 * (int32_t)REG_A[2];
z = (int16_t)REG_D[5];
z += 2 * (int32_t)REG_A[3];
- store_coord("large tags", REG_A[0], x, y, z);
+ /* note that large tags have double distance, so the resolution is vitrually doubled.
+ * since we use interpolation and VR, we need to scale the vertex back to normal distance.
+ */
+ store_coord("large tags", REG_A[0], x, y, z, 0.5);
}
/* line of tag */
y = -motion_new.position_height;
z = ((int16_t)m68k_read_memory_16(REG_A[4]) * 65536);
z += (int32_t)REG_A[3];
- store_coord("island", REG_A[0], x, y, z);
+ store_coord("island", REG_A[0], x, y, z, 1.0);
}
/* polygon of island */
break;
case STOP_AT_POINT_BEACON:
point_beacon();
+ /* note: we may not call the point-renderer, because projected coordinates are invalid */
+ mercenary_patch_render();
break;
case STOP_AT_COORD_BUILDING_EXTERIOR:
coord_building_exterior();
case STOP_AT_EXPLOSION:
draw_explosion();
break;
+ case STOP_AT_PATCH_RENDER:
+ mercenary_patch_render();
+ break;
}
}
#endif
/* get color */
opengl_render_color(render_item->u.sky.red, render_item->u.sky.green, render_item->u.sky.blue, 1.0);
- /* create plane to fill view */
- x[0] = x[1] = y[1] = y[2] = -1000000;
- x[2] = x[3] = y[0] = y[3] = 1000000;
- z[0] = z[1] = z[2] = z[3] = 10;
- /* render */
- opengl_render_polygon(x, y, z, 4, 0); /* no culling, because sky (background) is always visible! */
+ /* create box to fill view */
+ x[0] = x[1] = y[1] = y[2] = -1000;
+ x[2] = x[3] = y[0] = y[3] = 1000;
+ z[0] = z[1] = z[2] = z[3] = 1000;
+ opengl_render_polygon_and_line(x, y, z, 4);
+ z[0] = z[1] = z[2] = z[3] = -1000;
+ opengl_render_polygon_and_line(x, y, z, 4);
+ x[0] = x[1] = z[1] = z[2] = -1000;
+ x[2] = x[3] = z[0] = z[3] = 1000;
+ y[0] = y[1] = y[2] = y[3] = 1000;
+ opengl_render_polygon_and_line(x, y, z, 4);
+ y[0] = y[1] = y[2] = y[3] = -1000;
+ opengl_render_polygon_and_line(x, y, z, 4);
+ y[0] = y[1] = z[1] = z[2] = -1000;
+ y[2] = y[3] = z[0] = z[3] = 1000;
+ x[0] = x[1] = x[2] = x[3] = 1000;
+ opengl_render_polygon_and_line(x, y, z, 4);
+ x[0] = x[1] = x[2] = x[3] = -1000;
+ opengl_render_polygon_and_line(x, y, z, 4);
break;
}
case RENDER_ITEM_GROUND:
opengl_render_color(render_item->u.ground.red, render_item->u.ground.green, render_item->u.ground.blue, 1.0);
yaw = 0.0; /* no need to rotate x-z plane, we don't want look at a corner of the 'ground-square' */
/* create huge square */
- x[0] = x[1] = z[1] = z[2] = -1000000;
- x[2] = x[3] = z[0] = z[3] = 1000000;
- y[0] = y[1] = y[2] = y[3] = -10;
+ x[0] = x[1] = z[1] = z[2] = -1000000000;
+ x[2] = x[3] = z[0] = z[3] = 1000000000;
+ y[0] = y[1] = y[2] = y[3] = -1000;
/* rotate vertex */
for (i = 0; i < 4; i++)
rotate_coordinate(roll, pitch, yaw, &x[i], &y[i], &z[i]);
rc = use_coord("object", render_item->u.polygon.vertex[i], &x[i], &y[i], &z[i], fix);
if (rc < 0)
break;
+ /* fixed objects are pre-scaled by 16, so we correct this */
+ if (fix) {
+ x[i] /= FIX_OBJECT_SCALE;
+ y[i] /= FIX_OBJECT_SCALE;
+ z[i] /= FIX_OBJECT_SCALE;
+ }
/* interpolate motion, if object is moving */
if ((render_item->type == RENDER_ITEM_OBJECT_POLYGON || render_item->type == RENDER_ITEM_TAG_POLYGON_OBJECT) && render_item_object_info && render_item_object_info->u.info.moving) {
for (o = 0; o < interpolation.object_count; o++) {
rc = use_coord("object", render_item->u.line.vertex[i], &x[i], &y[i], &z[i], fix);
if (rc < 0)
break;
+ /* fixed objects are pre-scaled by 16, so we correct this */
+ if (fix) {
+ x[i] /= FIX_OBJECT_SCALE;
+ y[i] /= FIX_OBJECT_SCALE;
+ z[i] /= FIX_OBJECT_SCALE;
+ }
/* interpolate motion, if object is moving */
if ((render_item->type == RENDER_ITEM_OBJECT_LINE || render_item->type == RENDER_ITEM_TAG_LINE_OBJECT) && render_item_object_info && render_item_object_info->u.info.moving) {
for (o = 0; o < interpolation.object_count; o++) {
double circle_x[PLANET_VERTICES], circle_y[PLANET_VERTICES], circle_z[PLANET_VERTICES];
double crescent_x[PLANET_VERTICES], crescent_y[PLANET_VERTICES], crescent_z[PLANET_VERTICES];
double x[PLANET_VERTICES], y[PLANET_VERTICES], z[PLANET_VERTICES];
- double size, angle, fabs_angle, crescent;
+ double dist, size, angle, fabs_angle, crescent;
double _sin, _cos;
int i;
int rc;
rotate_coordinate(roll, pitch, yaw, &sun_x, &sun_y, &sun_z);
rotate_coordinate(roll, pitch, yaw, &loc_x, &loc_y, &loc_z);
+ /* distance to planet */
+ dist = sqrt(loc_x * loc_x + loc_y * loc_y + loc_z * loc_z);
+
/* calculate direction of the sun */
angle_sun_h = atan2(sun_x, sun_z);
angle_loc_h = atan2(loc_x, loc_z);
}
}
for (i = 0; i < PLANET_VERTICES; i++) {
- x[i] = loc_x + circle_x[i];
- y[i] = loc_y + circle_y[i];
- z[i] = loc_z + circle_z[i];
+ x[i] = (loc_x + circle_x[i]) / dist * 1000000.0;
+ y[i] = (loc_y + circle_y[i]) / dist * 1000000.0;
+ z[i] = (loc_z + circle_z[i]) / dist * 1000000.0;
}
opengl_render_polygon_and_line(x, y, z, PLANET_VERTICES); /* no culling, its a planet! */
if (angle > M_PI / 2.0 || (angle < 0.0 && angle > -M_PI / 2.0)) {
/* to the right */
for (i = 0; i < PLANET_VERTICES / 2 + 1; i++) {
- x[i] = loc_x + circle_x[i];
- y[i] = loc_y + circle_y[i];
- z[i] = loc_z + circle_z[i];
+ x[i] = (loc_x + circle_x[i]) / dist * 1000000.0;
+ y[i] = (loc_y + circle_y[i]) / dist * 1000000.0;
+ z[i] = (loc_z + circle_z[i]) / dist * 1000000.0;
}
_sin = sin((1.0 - angle / (M_PI / 2)) * (M_PI / 2.0));
for (; i < PLANET_VERTICES; i++) {
- x[i] = loc_x + crescent_x[i];
- y[i] = loc_y + crescent_y[i];
- z[i] = loc_z + crescent_z[i];
+ x[i] = (loc_x + crescent_x[i]) / dist * 1000000.0;
+ y[i] = (loc_y + crescent_y[i]) / dist * 1000000.0;
+ z[i] = (loc_z + crescent_z[i]) / dist * 1000000.0;
}
} else {
/* to the left */
for (i = 0; i < PLANET_VERTICES / 2 + 1; i++) {
- x[i] = loc_x + crescent_x[i];
- y[i] = loc_y + crescent_y[i];
- z[i] = loc_z + crescent_z[i];
+ x[i] = (loc_x + crescent_x[i]) / dist * 1000000.0;
+ y[i] = (loc_y + crescent_y[i]) / dist * 1000000.0;
+ z[i] = (loc_z + crescent_z[i]) / dist * 1000000.0;
}
for (; i < PLANET_VERTICES; i++) {
- x[i] = loc_x + circle_x[i];
- y[i] = loc_y + circle_y[i];
- z[i] = loc_z + circle_z[i];
+ x[i] = (loc_x + circle_x[i]) / dist * 1000000.0;
+ y[i] = (loc_y + circle_y[i]) / dist * 1000000.0;
+ z[i] = (loc_z + circle_z[i]) / dist * 1000000.0;
}
}
opengl_render_polygon_and_line(x, y, z, PLANET_VERTICES); /* no culling, its a planet! */
double view_width, yaw = interpolation.orientation_raw_yaw;
double pitch = interpolation.orientation_raw_pitch;
uint32_t table, table_start;
- double x, y;
- double z;
+ double x, y, z;
int i;
double red, green, blue;
for (i = 0; i < 16; i++)
color[i] = m68k_read_memory_16(mercenary_palette_stars() + (i << 2));
- /* table offset is 91, so we substract it and add it back with different FOV, so table begins at later
- * full turn is 1024, we have default of 64 degrees: 1024 / 360 * 64 = 182
- * then we half it, so we get to the center via 91
- */
-
- if (render_item->u.stars.above_zenith)
- yaw = 0x200 + yaw;
- yaw = fmod(yaw + 91.0 - (91.0 * (frustum_slope_fov / frustum_slope_64)) + 65536.0, 0x400);
- yaw *= 2.0;
- table = mercenary_star_table();
- table_start = table + m68k_read_memory_16(table);
- table += m68k_read_memory_16(table + ((uint32_t)yaw & 0x7fe));
- yaw = yaw / (double)0x800 * 1800.0;
-
- if (render_item->u.stars.above_zenith)
- pitch = 0x200 - pitch;
- pitch = fmod(pitch + 65536.0, 0x400);
- pitch -= render_item->u.stars.v_offset;
- pitch *= 4;
- pitch = pitch * (double)0x6ccc / 65536.0;
-
- while (1) {
- x = m68k_read_memory_16(table);
- if (x >= 1800.0) {
- x_offset += 1800.0;
- table = table_start;
+ if (!vr) {
+ /* render legacy stars (as with the original game) */
+
+ /* table offset is 91, so we substract it and add it back with different FOV, so table begins at later
+ * full turn is 1024, we have default of 64 degrees: 1024 / 360 * 64 = 182
+ * then we half it, so we get to the center via 91
+ */
+
+ if (render_item->u.stars.above_zenith)
+ yaw = 0x200 + yaw;
+ yaw = fmod(yaw + 91.0 - (91.0 * (frustum_slope_fov / frustum_slope_64)) + 65536.0, 0x400);
+ yaw *= 2.0;
+ table = mercenary_star_table();
+ table_start = table + m68k_read_memory_16(table);
+ table += m68k_read_memory_16(table + ((uint32_t)yaw & 0x7fe));
+ yaw = yaw / (double)0x800 * 1800.0;
+
+ if (render_item->u.stars.above_zenith)
+ pitch = 0x200 - pitch;
+ pitch = fmod(pitch + 65536.0, 0x400);
+ pitch -= render_item->u.stars.v_offset;
+ pitch *= 4;
+ pitch = pitch * (double)0x6ccc / 65536.0;
+
+ while (1) {
+ x = m68k_read_memory_16(table);
+ if (x >= 1800.0) {
+ x_offset += 1800.0;
+ table = table_start;
+ }
+ x = (view_width - 1) - m68k_read_memory_16(table) - x_offset + yaw;
+ table += 2;
+ if (x < 0.0)
+ break;
+ /* special case where we tilt the view when flying on the planet */
+ if (render_item->u.stars.tilt) {
+ /* use offset as given by game: 160 is half of the screen width
+ * we extend the width to the actual FOV, so it fits
+ */
+ tilt_offset = ((x - (160.0 / frustum_slope_64 * frustum_slope_fov)) * render_item->u.stars.tilt_value) / 65536.0;
+ }
+ y = (double)((m68k_read_memory_16(table)) & 0x1ff) - pitch + tilt_offset;
+ table += 2;
+ if (render_item->u.stars.above_zenith) {
+ x = (double)(view_width - 1) - x;
+ y = -1 - y + 136;
+ }
+ /* get color */
+ gamecolor2gl(&red, &green, &blue, color[(m68k_read_memory_8(table - 2) & 0x3c) >> 2]);
+ opengl_render_color(red, green, blue, debug_opacity);
+ /* render point */
+ opengl_render_point(160.0 / frustum_slope_64 * frustum_slope_fov - x, 68.0 - y, z, 0.0);
}
- x = (view_width - 1) - m68k_read_memory_16(table) - x_offset + yaw;
- table += 2;
- if (x < 0.0)
+ } else {
+ /* render ovr stars, render star table as a sphere */
+
+ double h, v1, v2;
+ GET_ORIENTATION;
+ double inclination = interpolation.planet_inclination, azimuth = interpolation.planet_azimuth;
+
+ if (render_item->u.stars.above_zenith)
break;
- /* special case where we tilt the view when flying on the planet */
- if (render_item->u.stars.tilt) {
- /* use offset as given by game: 160 is half of the screen width
- * we extend the width to the actual FOV, so it fits
- */
- tilt_offset = ((x - (160.0 / frustum_slope_64 * frustum_slope_fov)) * render_item->u.stars.tilt_value) / 65536.0;
- }
- y = (double)((m68k_read_memory_16(table)) & 0x1ff) - pitch + tilt_offset;
- table += 2;
- if (render_item->u.stars.above_zenith) {
- x = (double)(view_width - 1) - x;
- y = -1 - y + 136;
+
+ table = mercenary_star_table();
+ table += m68k_read_memory_16(table);
+
+ while (1) {
+ x = m68k_read_memory_16(table);
+ if (x >= 1800.0)
+ break;
+ table += 2;
+ y = (double)((m68k_read_memory_16(table)) & 0x1ff) - 108.796875;
+ table += 2;
+ /* get color */
+ gamecolor2gl(&red, &green, &blue, color[(m68k_read_memory_8(table - 2) & 0x3c) >> 2]);
+ opengl_render_color(red, green, blue, debug_opacity);
+ /* render point */
+ h = (900.0 - x + 160) / 900.0 * M_PI;
+ v1 = (68.0 - y) / 900.0 * M_PI;
+ /* wrap star field (is actually 86.2 degrees high) */
+ if (v1 <= 0.0)
+ v2 = v1 + (86.2 / 180.0 * M_PI);
+ else
+ v2 = v1 - (86.2 / 180.0 * M_PI);
+ if (v1 < 0.934 && v1 > -0.934) {
+ /* be sure that v1 will not exceed PI/2 */
+ v1 = v1 / cos(v1); /* FIXME: there should be a better way to distribute stars equally */
+ x = -sin(h) * cos(v1);
+ y = sin(v1);
+ z = cos(h) * cos(v1);
+ if (motion_new.planet_rotation)
+ rotate_coordinate(0.0, inclination, azimuth, &x, &y, &z);
+ rotate_coordinate(roll, pitch, yaw, &x, &y, &z);
+ opengl_render_point(1000000.0 * x, 1000000.0 * y, 1000000.0 * z, 0.0);
+ }
+ if (v2 < 0.934 && v2 > -0.934) {
+ /* be sure that v2 will not exceed PI/2 */
+ v2 = v2 / cos(v2) /* FIXME: there should be a better way to distribute stars equally */;
+ x = -sin(h) * cos(v2);
+ y = sin(v2);
+ z = cos(h) * cos(v2);
+ if (motion_new.planet_rotation)
+ rotate_coordinate(0.0, inclination, azimuth, &x, &y, &z);
+ rotate_coordinate(roll, pitch, yaw, &x, &y, &z);
+ opengl_render_point(1000000.0 * x, 1000000.0 * y, 1000000.0 * z, 0.0);
+ }
}
- /* get color */
- gamecolor2gl(&red, &green, &blue, color[(m68k_read_memory_8(table - 2) & 0x3c) >> 2]);
- opengl_render_color(red, green, blue, debug_opacity);
- /* render point */
- opengl_render_point(160.0 / frustum_slope_64 * frustum_slope_fov - x, 68.0 - y, z, 0.0);
}
break;
}
gamecolor2gl(&red, &green, &blue, color[render_item->u.interstars.color[i]]);
opengl_render_color(red, green, blue, debug_opacity);
/* render point */
- opengl_render_point(160.0 - (double)render_item->u.interstars.x[i], 68.0 - (double)render_item->u.interstars.y[i], z, 0.0);
+ opengl_render_point((160.0 - (double)render_item->u.interstars.x[i]) * 100, (68.0 - (double)render_item->u.interstars.y[i]) * 100, z * 100, 0.0);
}
break;
}
gamecolor2gl(&red, &green, &blue, 0x777);
opengl_render_color(red, green, blue, debug_opacity);
/* render point */
- opengl_render_point(0.0, 0.0, 100.0, 0.0);
+ opengl_render_point(0.0, 0.0, 1000000.0, 0.0);
break;
}
case RENDER_ITEM_SIGHTS:
printf("RENDER_ITEM_SIGHTS\n");
#endif
/* use default fov of 64 to calculate z distance */
- z[0] = z[1] = z[2] = z[3] = 160.0 / frustum_slope_64;
+ z[0] = z[1] = z[2] = z[3] = SIGHT_DIST;
/* white */
gamecolor2gl(&red, &green, &blue, 0x777);
opengl_render_color(red, green, blue, debug_opacity);
- y[0] = y[3] = -1.0;
- y[1] = y[2] = 1.0;
- x[0] = x[1] = -16.0;
- x[2] = x[3] = -8.0;
+ y[0] = y[3] = -1.0 / 160.0 * SIGHT_DIST * frustum_slope_64;
+ y[1] = y[2] = 1.0 / 160.0 * SIGHT_DIST * frustum_slope_64;
+ x[0] = x[1] = -16.0 / 160.0 * SIGHT_DIST * frustum_slope_64;
+ x[2] = x[3] = -8.0 / 160.0 * SIGHT_DIST * frustum_slope_64;
opengl_render_polygon(x, y, z, 4, 0); /* no culling, because sights are always visible! */
- x[0] = x[1] = 8.0;
- x[2] = x[3] = 16.0;
+ x[0] = x[1] = 8.0 / 160.0 * SIGHT_DIST * frustum_slope_64;
+ x[2] = x[3] = 16.0 / 160.0 * SIGHT_DIST * frustum_slope_64;
opengl_render_polygon(x, y, z, 4, 0); /* no culling, because sights are always visible! */
break;
}
{
static render_item_t interpolated;
render_item_t *old_vertices = render_list_old, *new_vertices = render_list_new;
- int nomatch_x_count = 0;
- int nomatch_z_count = 0;
- int nomatch_x[4], nomatch_z[4];
int i, ii;
/* find old and new vertices */
if (!old_vertices || !new_vertices)
return NULL;
- /* all verices must match except four */
+ memcpy(&interpolated, new_vertices, sizeof(interpolated));
ii = MAX_INTERIOR_VERTEX >> 2;
for (i = 0; i < ii; i++) {
+ /* vertex must exist in both frames */
if (!old_vertices->u.vertices_interior.set[i] || !new_vertices->u.vertices_interior.set[i])
continue;
- if (old_vertices->u.vertices_interior.x[i] != new_vertices->u.vertices_interior.x[i]) {
- if (nomatch_x_count == 4)
- return NULL;
- nomatch_x[nomatch_x_count++] = i;
- }
+ /* all verices must not have be too far away */
+ if (fabs(old_vertices->u.vertices_interior.x[i] - new_vertices->u.vertices_interior.x[i]) > 100.0)
+ return NULL;
+ if (fabs(old_vertices->u.vertices_interior.z[i] - new_vertices->u.vertices_interior.z[i]) > 100.0)
+ return NULL;
+ /* interpolate */
+ interpolated.u.vertices_interior.x[i] =
+ (double)old_vertices->u.vertices_interior.x[i] * (1.0 - inter) +
+ (double)new_vertices->u.vertices_interior.x[i] * inter;
+ interpolated.u.vertices_interior.z[i] =
+ (double)old_vertices->u.vertices_interior.z[i] * (1.0 - inter) +
+ (double)new_vertices->u.vertices_interior.z[i] * inter;
}
for (i = 0; i < 4; i++) {
if (old_vertices->u.vertices_interior.y[i] != new_vertices->u.vertices_interior.y[i])
return NULL;
}
- for (i = 0; i < ii; i++) {
- if (!old_vertices->u.vertices_interior.set[i] || !new_vertices->u.vertices_interior.set[i])
- continue;
- if (old_vertices->u.vertices_interior.z[i] != new_vertices->u.vertices_interior.z[i]) {
- if (nomatch_z_count == 4)
- return NULL;
- nomatch_z[nomatch_z_count++] = i;
- }
- }
-
- /* copy, even if not interpolated */
- memcpy(&interpolated, new_vertices, sizeof(interpolated));
-
- /* only four x missmatch */
- if (nomatch_x_count == 4 || nomatch_x_count == 2) {
- for (i = 0; i < nomatch_x_count; i++) {
- interpolated.u.vertices_interior.x[nomatch_x[i]] =
- (double)old_vertices->u.vertices_interior.x[nomatch_x[i]] * (1.0 - inter) +
- (double)new_vertices->u.vertices_interior.x[nomatch_x[i]] * inter;
- }
- }
-
- /* only four z missmatch */
- if (nomatch_z_count == 4 || nomatch_z_count == 2) {
- for (i = 0; i < nomatch_z_count; i++) {
- interpolated.u.vertices_interior.z[nomatch_z[i]] =
- (double)old_vertices->u.vertices_interior.z[nomatch_z[i]] * (1.0 - inter) +
- (double)new_vertices->u.vertices_interior.z[nomatch_z[i]] * inter;
- }
- }
return &interpolated;
}