void precompute_init (gint w, gint h) { gint n; gint bpp=1; xstep = 1.0 / (gdouble) width; ystep = 1.0 / (gdouble) height; pre_w = w; pre_h = h; for (n = 0; n < 3; n++) { if (vertex_normals[n] != NULL) g_free (vertex_normals[n]); if (heights[n] != NULL) g_free (heights[n]); heights[n] = g_new (gdouble, w); vertex_normals[n] = g_new (GimpVector3, w); } for (n = 0; n < 2; n++) if (triangle_normals[n] != NULL) g_free (triangle_normals[n]); if (bumprow != NULL) { g_free (bumprow); bumprow = NULL; } if (mapvals.bumpmap_id != -1) { bpp = gimp_drawable_bpp(mapvals.bumpmap_id); } bumprow = g_new (guchar, w * bpp); triangle_normals[0] = g_new (GimpVector3, (w << 1) + 2); triangle_normals[1] = g_new (GimpVector3, (w << 1) + 2); for (n = 0; n < (w << 1) + 1; n++) { gimp_vector3_set (&triangle_normals[0][n], 0.0, 0.0, 1.0); gimp_vector3_set (&triangle_normals[1][n], 0.0, 0.0, 1.0); } for (n = 0; n < w; n++) { gimp_vector3_set (&vertex_normals[0][n], 0.0, 0.0, 1.0); gimp_vector3_set (&vertex_normals[1][n], 0.0, 0.0, 1.0); gimp_vector3_set (&vertex_normals[2][n], 0.0, 0.0, 1.0); heights[0][n] = 0.0; heights[1][n] = 0.0; heights[2][n] = 0.0; } }
static void set_default_settings (void) { gint i; gimp_vector3_set (&mapvals.viewpoint, 0.5, 0.5, 2.0); gimp_vector3_set (&mapvals.firstaxis, 1.0, 0.0, 0.0); gimp_vector3_set (&mapvals.secondaxis, 0.0, 1.0, 0.0); gimp_vector3_set (&mapvals.normal, 0.0, 0.0, 1.0); gimp_vector3_set (&mapvals.position, 0.5, 0.5, 0.0); gimp_vector3_set (&mapvals.lightsource.position, -0.5, -0.5, 2.0); gimp_vector3_set (&mapvals.lightsource.direction, -1.0, -1.0, 1.0); gimp_vector3_set (&mapvals.scale, 0.5, 0.5, 0.5); mapvals.maptype = MAP_PLANE; mapvals.pixeltreshold = 0.25; mapvals.alpha = 0.0; mapvals.beta = 0.0; mapvals.gamma = 0.0; mapvals.maxdepth = 3.0; mapvals.radius = 0.25; mapvals.cylinder_radius = 0.25; mapvals.cylinder_length = 1.0; mapvals.zoom = 1.0; mapvals.lightsource.type = POINT_LIGHT; mapvals.antialiasing = TRUE; mapvals.create_new_image = FALSE; mapvals.create_new_layer = FALSE; mapvals.transparent_background = FALSE; mapvals.tiled = FALSE; mapvals.livepreview = FALSE; mapvals.showgrid = TRUE; mapvals.lightsource.intensity = 1.0; gimp_rgba_set (&mapvals.lightsource.color, 1.0, 1.0, 1.0, 1.0); mapvals.material.ambient_int = 0.3; mapvals.material.diffuse_int = 1.0; mapvals.material.diffuse_ref = 0.5; mapvals.material.specular_ref = 0.5; mapvals.material.highlight = 27.0; for (i = 0; i < 6; i++) mapvals.boxmap_id[i] = -1; for (i = 0; i < 2; i++) mapvals.cylindermap_id[i] = -1; }
static gboolean intersect_box (GimpVector3 scale, GimpVector3 viewp, GimpVector3 dir, FaceIntersectInfo *face_intersect) { GimpVector3 v, d, tmp, axis[3]; FaceIntersectInfo face_tmp; gboolean result = FALSE; gfloat m[16]; gint i = 0; gimp_vector3_set (&axis[0], 1.0, 0.0, 0.0); gimp_vector3_set (&axis[1], 0.0, 1.0, 0.0); gimp_vector3_set (&axis[2], 0.0, 0.0, 1.0); /* Front side */ /* ========== */ if (intersect_rect (scale.x, scale.y, scale.z / 2.0, viewp, dir, &face_intersect[i]) == TRUE) { face_intersect[i].face = 0; gimp_vector3_set (&face_intersect[i++].n, 0.0, 0.0, 1.0); result = TRUE; } /* Back side */ /* ========= */ if (intersect_rect (scale.x, scale.y, -scale.z / 2.0, viewp, dir, &face_intersect[i]) == TRUE) { face_intersect[i].face = 1; face_intersect[i].u = 1.0 - face_intersect[i].u; gimp_vector3_set (&face_intersect[i++].n, 0.0, 0.0, -1.0); result = TRUE; } /* Check if we've found the two possible intersection points */ /* ========================================================= */ if (i < 2) { /* Top: Rotate viewpoint and direction into rectangle's local coordinate system */ /* ============================================================================ */ rotatemat (90, &axis[0], m); vecmulmat (&v, &viewp, m); vecmulmat (&d, &dir, m); if (intersect_rect (scale.x, scale.z, scale.y / 2.0, v, d, &face_intersect[i]) == TRUE) { face_intersect[i].face = 2; transpose_mat (m); vecmulmat(&tmp, &face_intersect[i].s, m); face_intersect[i].s = tmp; gimp_vector3_set (&face_intersect[i++].n, 0.0, -1.0, 0.0); result = TRUE; } } /* Check if we've found the two possible intersection points */ /* ========================================================= */ if (i < 2) { /* Bottom: Rotate viewpoint and direction into rectangle's local coordinate system */ /* =============================================================================== */ rotatemat (90, &axis[0], m); vecmulmat (&v, &viewp, m); vecmulmat (&d, &dir, m); if (intersect_rect (scale.x, scale.z, -scale.y / 2.0, v, d, &face_intersect[i]) == TRUE) { face_intersect[i].face = 3; transpose_mat (m); vecmulmat (&tmp, &face_intersect[i].s, m); face_intersect[i].s = tmp; face_intersect[i].v = 1.0 - face_intersect[i].v; gimp_vector3_set (&face_intersect[i++].n, 0.0, 1.0, 0.0); result = TRUE; } } /* Check if we've found the two possible intersection points */ /* ========================================================= */ if (i < 2) { /* Left side: Rotate viewpoint and direction into rectangle's local coordinate system */ /* ================================================================================== */ rotatemat (90, &axis[1], m); vecmulmat (&v, &viewp, m); vecmulmat (&d, &dir, m); if (intersect_rect (scale.z, scale.y, scale.x / 2.0, v, d, &face_intersect[i]) == TRUE) { face_intersect[i].face = 4; transpose_mat (m); vecmulmat (&tmp, &face_intersect[i].s, m); face_intersect[i].s = tmp; gimp_vector3_set (&face_intersect[i++].n, 1.0, 0.0, 0.0); result = TRUE; } } /* Check if we've found the two possible intersection points */ /* ========================================================= */ if (i < 2) { /* Right side: Rotate viewpoint and direction into rectangle's local coordinate system */ /* =================================================================================== */ rotatemat (90, &axis[1], m); vecmulmat (&v, &viewp, m); vecmulmat (&d, &dir, m); if (intersect_rect (scale.z, scale.y, -scale.x / 2.0, v, d, &face_intersect[i]) == TRUE) { face_intersect[i].face = 5; transpose_mat (m); vecmulmat (&tmp, &face_intersect[i].s, m); face_intersect[i].u = 1.0 - face_intersect[i].u; gimp_vector3_set (&face_intersect[i++].n, -1.0, 0.0, 0.0); result = TRUE; } } /* Sort intersection points */ /* ======================== */ if (face_intersect[0].t > face_intersect[1].t) { face_tmp = face_intersect[0]; face_intersect[0] = face_intersect[1]; face_intersect[1] = face_tmp; } return result; }
static gboolean intersect_cylinder (GimpVector3 vp, GimpVector3 dir, FaceIntersectInfo *face_intersect) { gdouble a, b, c, d, e, f, tmp, l; gboolean result = FALSE; gint i; #define sqr(a) (a*a) a = sqr (dir.x) + sqr (dir.z); b = 2.0 * (vp.x * dir.x + vp.z * dir.z); c = sqr (vp.x) + sqr (vp.z) - sqr (mapvals.cylinder_radius); d = sqr (b) - 4.0 * a * c; if (d >= 0.0) { e = sqrt (d); f = 2.0 * a; if (f != 0.0) { result = TRUE; face_intersect[0].t = (-b+e)/f; face_intersect[1].t = (-b-e)/f; if (face_intersect[0].t>face_intersect[1].t) { tmp = face_intersect[0].t; face_intersect[0].t = face_intersect[1].t; face_intersect[1].t = tmp; } for (i = 0; i < 2; i++) { face_intersect[i].s.x = vp.x + face_intersect[i].t * dir.x; face_intersect[i].s.y = vp.y + face_intersect[i].t * dir.y; face_intersect[i].s.z = vp.z + face_intersect[i].t * dir.z; face_intersect[i].n = face_intersect[i].s; face_intersect[i].n.y = 0.0; gimp_vector3_normalize(&face_intersect[i].n); l = mapvals.cylinder_length/2.0; face_intersect[i].u = (atan2(face_intersect[i].s.x,face_intersect[i].s.z)+G_PI)/(2.0*G_PI); face_intersect[i].v = (face_intersect[i].s.y+l)/mapvals.cylinder_length; /* Mark hitpoint as on the cylinder hull */ /* ===================================== */ face_intersect[i].face = 0; /* Check if we're completely off the cylinder axis */ /* =============================================== */ if (face_intersect[i].s.y>l || face_intersect[i].s.y<-l) { /* Check if we've hit a cap */ /* ======================== */ if (face_intersect[i].s.y>l) { if (intersect_circle(vp,dir,l,&face_intersect[i])==FALSE) result = FALSE; else { face_intersect[i].face = 2; face_intersect[i].v = 1 - face_intersect[i].v; gimp_vector3_set(&face_intersect[i].n, 0.0, 1.0, 0.0); } } else { if (intersect_circle(vp,dir,-l,&face_intersect[i])==FALSE) result = FALSE; else { face_intersect[i].face = 1; gimp_vector3_set(&face_intersect[i].n, 0.0, -1.0, 0.0); } } } } } } #undef sqr return result; }
static void set_default_settings (void) { gint k; mapvals.update_enabled = TRUE; mapvals.light_selected = 0; mapvals.light_isolated = FALSE; gimp_vector3_set (&mapvals.viewpoint, 0.5, 0.5, 0.25); gimp_vector3_set (&mapvals.planenormal, 0.0, 0.0, 1.0); gimp_vector3_set (&mapvals.lightsource[0].position, -1.0, -1.0, 1.0); gimp_vector3_set (&mapvals.lightsource[0].direction, -1.0, -1.0, 1.0); gimp_rgba_set (&mapvals.lightsource[0].color, 1.0, 1.0, 1.0, 1.0); mapvals.lightsource[0].intensity = 1.0; mapvals.lightsource[0].type = POINT_LIGHT; mapvals.lightsource[0].active = TRUE; /* init lights 2 and 3 pos to upper left and below */ gimp_vector3_set (&mapvals.lightsource[1].position, 2.0, -1.0, 1.0); gimp_vector3_set (&mapvals.lightsource[1].direction, 1.0, -1.0, 1.0); gimp_vector3_set (&mapvals.lightsource[2].position, 1.0, 2.0, 1.0); gimp_vector3_set (&mapvals.lightsource[2].direction, 0.0, 1.0, 1.0); /* init any remaining lights to directly overhead */ for (k = 3; k < NUM_LIGHTS; k++) { gimp_vector3_set (&mapvals.lightsource[k].position, 0.0, 0.0, 1.0); gimp_vector3_set (&mapvals.lightsource[k].direction, 0.0, 0.0, 1.0); } for (k = 1; k < NUM_LIGHTS; k++) { gimp_rgba_set (&mapvals.lightsource[k].color, 1.0, 1.0, 1.0, 1.0); mapvals.lightsource[k].intensity = 1.0; mapvals.lightsource[k].type = NO_LIGHT; mapvals.lightsource[k].active = TRUE; } mapvals.material.ambient_int = 0.2; mapvals.material.diffuse_int = 0.5; mapvals.material.diffuse_ref = 0.4; mapvals.material.specular_ref = 0.5; mapvals.material.highlight = 27.0; mapvals.material.metallic = FALSE; mapvals.pixel_treshold = 0.25; mapvals.max_depth = 3.0; mapvals.preview_zoom_factor = 1.0; mapvals.bumpmaptype = 0; mapvals.bumpmin = 0.0; mapvals.bumpmax = 0.1; mapvals.antialiasing = FALSE; mapvals.create_new_image = FALSE; mapvals.transparent_background = FALSE; mapvals.bump_mapped = FALSE; mapvals.env_mapped = FALSE; mapvals.ref_mapped = FALSE; mapvals.previewquality = FALSE; mapvals.interactive_preview = TRUE; mapvals.bumpmap_id = -1; mapvals.envmap_id = -1; }
static void draw_wireframe_cylinder (gint startx, gint starty, gint pw, gint ph) { GimpVector3 p[2*8], a, axis, scale; gint n = 0, i; gdouble cx1, cy1, cx2, cy2; gfloat m[16], l, angle; /* Compute wireframe points */ /* ======================== */ init_compute (); scale = mapvals.scale; gimp_vector3_mul (&scale, 0.5); l = mapvals.cylinder_length / 2.0; angle = 0; gimp_vector3_set (&axis, 0.0, 1.0, 0.0); for (i = 0; i < 8; i++) { rotatemat (angle, &axis, m); gimp_vector3_set (&a, mapvals.cylinder_radius, 0.0, 0.0); vecmulmat (&p[i], &a, m); p[i+8] = p[i]; p[i].y += l; p[i+8].y -= l; angle += 360.0 / 8.0; } /* Rotate and translate points */ /* =========================== */ for (i = 0; i < 16; i++) { vecmulmat (&a, &p[i], rotmat); gimp_vector3_add (&p[i], &a, &mapvals.position); } /* Draw the box */ /* ============ */ cx1 = (gdouble) startx; cy1 = (gdouble) starty; cx2 = cx1 + (gdouble) pw; cy2 = cy1 + (gdouble) ph; for (i = 0; i < 7; i++) { n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[i],p[i+1]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[i+8],p[i+9]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[i],p[i+8]); } n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[7],p[0]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[15],p[8]); /* Mark end of lines */ /* ================= */ linetab[n].x1 = -1; }
static void draw_wireframe_box (gint startx, gint starty, gint pw, gint ph) { GimpVector3 p[8], tmp, scale; gint n = 0, i; gdouble cx1, cy1, cx2, cy2; /* Compute wireframe points */ /* ======================== */ init_compute (); scale = mapvals.scale; gimp_vector3_mul (&scale, 0.5); gimp_vector3_set (&p[0], -scale.x, -scale.y, scale.z); gimp_vector3_set (&p[1], scale.x, -scale.y, scale.z); gimp_vector3_set (&p[2], scale.x, scale.y, scale.z); gimp_vector3_set (&p[3], -scale.x, scale.y, scale.z); gimp_vector3_set (&p[4], -scale.x, -scale.y, -scale.z); gimp_vector3_set (&p[5], scale.x, -scale.y, -scale.z); gimp_vector3_set (&p[6], scale.x, scale.y, -scale.z); gimp_vector3_set (&p[7], -scale.x, scale.y, -scale.z); /* Rotate and translate points */ /* =========================== */ for (i = 0; i < 8; i++) { vecmulmat (&tmp, &p[i], rotmat); gimp_vector3_add (&p[i], &tmp, &mapvals.position); } /* Draw the box */ /* ============ */ cx1 = (gdouble) startx; cy1 = (gdouble) starty; cx2 = cx1 + (gdouble) pw; cy2 = cy1 + (gdouble) ph; n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[0],p[1]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[1],p[2]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[2],p[3]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[3],p[0]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[4],p[5]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[5],p[6]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[6],p[7]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[7],p[4]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[0],p[4]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[1],p[5]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[2],p[6]); n = draw_line (n, startx,starty,pw,ph, cx1,cy1,cx2,cy2, p[3],p[7]); /* Mark end of lines */ /* ================= */ linetab[n].x1 = -1; }
static void draw_wireframe_sphere (gint startx, gint starty, gint pw, gint ph) { GimpVector3 p[2 * (WIRESIZE + 5)]; gint cnt, cnt2, n = 0; gdouble x1, y1, x2, y2, twopifac, cx1, cy1, cx2, cy2; /* Compute wireframe points */ /* ======================== */ twopifac = (2.0 * G_PI) / WIRESIZE; for (cnt = 0; cnt < WIRESIZE; cnt++) { p[cnt].x = mapvals.radius * cos ((gdouble) cnt * twopifac); p[cnt].y = 0.0; p[cnt].z = mapvals.radius * sin ((gdouble) cnt * twopifac); gimp_vector3_rotate (&p[cnt], gimp_deg_to_rad (mapvals.alpha), gimp_deg_to_rad (mapvals.beta), gimp_deg_to_rad (mapvals.gamma)); gimp_vector3_add (&p[cnt], &p[cnt], &mapvals.position); } p[cnt] = p[0]; for (cnt = WIRESIZE + 1; cnt < 2 * WIRESIZE + 1; cnt++) { p[cnt].x = mapvals.radius * cos ((gdouble) (cnt-(WIRESIZE+1))*twopifac); p[cnt].y = mapvals.radius * sin ((gdouble) (cnt-(WIRESIZE+1))*twopifac); p[cnt].z = 0.0; gimp_vector3_rotate (&p[cnt], gimp_deg_to_rad (mapvals.alpha), gimp_deg_to_rad (mapvals.beta), gimp_deg_to_rad (mapvals.gamma)); gimp_vector3_add (&p[cnt], &p[cnt], &mapvals.position); } p[cnt] = p[WIRESIZE+1]; cnt++; cnt2 = cnt; /* Find rotated axis */ /* ================= */ gimp_vector3_set (&p[cnt], 0.0, -0.35, 0.0); gimp_vector3_rotate (&p[cnt], gimp_deg_to_rad (mapvals.alpha), gimp_deg_to_rad (mapvals.beta), gimp_deg_to_rad (mapvals.gamma)); p[cnt+1] = mapvals.position; gimp_vector3_set (&p[cnt+2], 0.0, 0.0, -0.35); gimp_vector3_rotate (&p[cnt+2], gimp_deg_to_rad (mapvals.alpha), gimp_deg_to_rad (mapvals.beta), gimp_deg_to_rad (mapvals.gamma)); p[cnt+3] = mapvals.position; p[cnt + 4] = p[cnt]; gimp_vector3_mul (&p[cnt + 4], -1.0); p[cnt + 5] = p[cnt + 1]; gimp_vector3_add (&p[cnt], &p[cnt], &mapvals.position); gimp_vector3_add (&p[cnt + 2], &p[cnt + 2], &mapvals.position); gimp_vector3_add (&p[cnt + 4], &p[cnt + 4], &mapvals.position); /* Draw the circles (equator and zero meridian) */ /* ============================================ */ cx1 = (gdouble) startx; cy1 = (gdouble) starty; cx2 = cx1 + (gdouble) pw; cy2 = cy1 + (gdouble) ph; for (cnt = 0; cnt < cnt2 - 1; cnt++) { if (p[cnt].z > mapvals.position.z && p[cnt + 1].z > mapvals.position.z) { gimp_vector_3d_to_2d (startx, starty, pw, ph, &x1, &y1, &mapvals.viewpoint, &p[cnt]); gimp_vector_3d_to_2d (startx, starty, pw, ph, &x2, &y2, &mapvals.viewpoint, &p[cnt + 1]); if (clip_line (&x1, &y1, &x2, &y2, cx1, cy1, cx2, cy2) == TRUE) { linetab[n].x1 = (gint) (x1 + 0.5); linetab[n].y1 = (gint) (y1 + 0.5); linetab[n].x2 = (gint) (x2 + 0.5); linetab[n].y2 = (gint) (y2 + 0.5); linetab[n].linewidth = 3; linetab[n].linestyle = GDK_LINE_SOLID; gdk_gc_set_line_attributes (gc, linetab[n].linewidth, linetab[n].linestyle, GDK_CAP_NOT_LAST, GDK_JOIN_MITER); gdk_draw_line (previewarea->window, gc, linetab[n].x1, linetab[n].y1, linetab[n].x2, linetab[n].y2); n++; } } } /* Draw the axis (pole to pole and center to zero meridian) */ /* ======================================================== */ for (cnt = 0; cnt < 3; cnt++) { gimp_vector_3d_to_2d (startx, starty, pw, ph, &x1, &y1, &mapvals.viewpoint, &p[cnt2]); gimp_vector_3d_to_2d (startx, starty, pw, ph, &x2, &y2, &mapvals.viewpoint, &p[cnt2 + 1]); if (clip_line (&x1, &y1, &x2, &y2, cx1, cy1, cx2, cy2) == TRUE) { linetab[n].x1 = RINT (x1); linetab[n].y1 = RINT (y1); linetab[n].x2 = RINT (x2); linetab[n].y2 = RINT (y2); if (p[cnt2].z < mapvals.position.z || p[cnt2+1].z < mapvals.position.z) { linetab[n].linewidth = 1; linetab[n].linestyle = GDK_LINE_DOUBLE_DASH; } else { linetab[n].linewidth = 3; linetab[n].linestyle = GDK_LINE_SOLID; } gdk_gc_set_line_attributes (gc, linetab[n].linewidth, linetab[n].linestyle, GDK_CAP_NOT_LAST, GDK_JOIN_MITER); gdk_draw_line (previewarea->window, gc, linetab[n].x1, linetab[n].y1, linetab[n].x2, linetab[n].y2); n++; } cnt2 += 2; } /* Mark end of lines */ /* ================= */ linetab[n].x1 = -1; }
static void draw_wireframe_plane (gint startx, gint starty, gint pw, gint ph) { GimpVector3 v1, v2, a, b, c, d, dir1, dir2; gint cnt, n = 0; gdouble x1, y1, x2, y2, cx1, cy1, cx2, cy2, fac; /* Find rotated box corners */ /* ======================== */ gimp_vector3_set (&v1, 0.5, 0.0, 0.0); gimp_vector3_set (&v2, 0.0, 0.5, 0.0); gimp_vector3_rotate (&v1, gimp_deg_to_rad (mapvals.alpha), gimp_deg_to_rad (mapvals.beta), gimp_deg_to_rad (mapvals.gamma)); gimp_vector3_rotate (&v2, gimp_deg_to_rad (mapvals.alpha), gimp_deg_to_rad (mapvals.beta), gimp_deg_to_rad (mapvals.gamma)); dir1 = v1; gimp_vector3_normalize (&dir1); dir2 = v2; gimp_vector3_normalize (&dir2); fac = 1.0 / (gdouble) WIRESIZE; gimp_vector3_mul (&dir1, fac); gimp_vector3_mul (&dir2, fac); gimp_vector3_add (&a, &mapvals.position, &v1); gimp_vector3_sub (&b, &a, &v2); gimp_vector3_add (&a, &a, &v2); gimp_vector3_sub (&d, &mapvals.position, &v1); gimp_vector3_sub (&d, &d, &v2); c = b; cx1 = (gdouble) startx; cy1 = (gdouble) starty; cx2 = cx1 + (gdouble) pw; cy2 = cy1 + (gdouble) ph; for (cnt = 0; cnt <= WIRESIZE; cnt++) { gimp_vector_3d_to_2d (startx, starty, pw, ph, &x1, &y1, &mapvals.viewpoint, &a); gimp_vector_3d_to_2d (startx, starty, pw, ph, &x2, &y2, &mapvals.viewpoint, &b); if (clip_line (&x1, &y1, &x2, &y2, cx1, cy1, cx2, cy2) == TRUE) { linetab[n].x1 = RINT (x1); linetab[n].y1 = RINT (y1); linetab[n].x2 = RINT (x2); linetab[n].y2 = RINT (y2); linetab[n].linewidth = 1; linetab[n].linestyle = GDK_LINE_SOLID; gdk_gc_set_line_attributes (gc, linetab[n].linewidth, linetab[n].linestyle, GDK_CAP_NOT_LAST, GDK_JOIN_MITER); gdk_draw_line (previewarea->window, gc, linetab[n].x1, linetab[n].y1, linetab[n].x2, linetab[n].y2); n++; } gimp_vector_3d_to_2d (startx, starty, pw, ph, &x1, &y1, &mapvals.viewpoint, &c); gimp_vector_3d_to_2d (startx, starty, pw, ph, &x2, &y2, &mapvals.viewpoint, &d); if (clip_line (&x1, &y1, &x2, &y2, cx1, cy1, cx2, cy2) == TRUE) { linetab[n].x1 = RINT (x1); linetab[n].y1 = RINT (y1); linetab[n].x2 = RINT (x2); linetab[n].y2 = RINT (y2); linetab[n].linewidth = 1; linetab[n].linestyle = GDK_LINE_SOLID; gdk_gc_set_line_attributes (gc, linetab[n].linewidth, linetab[n].linestyle, GDK_CAP_NOT_LAST, GDK_JOIN_MITER); gdk_draw_line (previewarea->window, gc, linetab[n].x1, linetab[n].y1, linetab[n].x2, linetab[n].y2); n++; } gimp_vector3_sub (&a, &a, &dir1); gimp_vector3_sub (&b, &b, &dir1); gimp_vector3_add (&c, &c, &dir2); gimp_vector3_add (&d, &d, &dir2); } /* Mark end of lines */ /* ================= */ linetab[n].x1 = -1; }
void compute_preview (gint x, gint y, gint w, gint h, gint pw, gint ph) { gdouble xpostab[PREVIEW_WIDTH]; gdouble ypostab[PREVIEW_HEIGHT]; gdouble realw; gdouble realh; GimpVector3 p1, p2; GimpRGB color; GimpRGB lightcheck, darkcheck; gint xcnt, ycnt, f1, f2; glong index = 0; init_compute (); p1 = int_to_pos (x, y); p2 = int_to_pos (x + w, y + h); /* First, compute the linear mapping (x,y,x+w,y+h) to (0,0,pw,ph) */ /* ============================================================== */ realw = (p2.x - p1.x); realh = (p2.y - p1.y); for (xcnt = 0; xcnt < pw; xcnt++) xpostab[xcnt] = p1.x + realw * ((gdouble) xcnt / (gdouble) pw); for (ycnt = 0; ycnt < ph; ycnt++) ypostab[ycnt] = p1.y + realh * ((gdouble) ycnt / (gdouble) ph); /* Compute preview using the offset tables */ /* ======================================= */ if (mapvals.transparent_background == TRUE) { gimp_rgba_set (&background, 0.0, 0.0, 0.0, 0.0); } else { gimp_context_get_background (&background); gimp_rgb_set_alpha (&background, 1.0); } gimp_rgba_set (&lightcheck, GIMP_CHECK_LIGHT, GIMP_CHECK_LIGHT, GIMP_CHECK_LIGHT, 1.0); gimp_rgba_set (&darkcheck, GIMP_CHECK_DARK, GIMP_CHECK_DARK, GIMP_CHECK_DARK, 1.0); gimp_vector3_set (&p2, -1.0, -1.0, 0.0); for (ycnt = 0; ycnt < ph; ycnt++) { for (xcnt = 0; xcnt < pw; xcnt++) { p1.x = xpostab[xcnt]; p1.y = ypostab[ycnt]; p2 = p1; color = (* get_ray_color) (&p1); if (color.a < 1.0) { f1 = ((xcnt % 32) < 16); f2 = ((ycnt % 32) < 16); f1 = f1 ^ f2; if (f1) { if (color.a == 0.0) color = lightcheck; else gimp_rgb_composite (&color, &lightcheck, GIMP_RGB_COMPOSITE_BEHIND); } else { if (color.a == 0.0) color = darkcheck; else gimp_rgb_composite (&color, &darkcheck, GIMP_RGB_COMPOSITE_BEHIND); } } gimp_rgb_get_uchar (&color, preview_rgb_data + index, preview_rgb_data + index + 1, preview_rgb_data + index + 2); index += 3; } } }
void precompute_normals (gint x1, gint x2, gint y) { GimpVector3 *tmpv, p1, p2, p3, normal; gdouble *tmpd; gint n, i, nv; guchar *map = NULL; gint bpp = 1; guchar mapval; /* First, compute the heights */ /* ========================== */ tmpv = triangle_normals[0]; triangle_normals[0] = triangle_normals[1]; triangle_normals[1] = tmpv; tmpv = vertex_normals[0]; vertex_normals[0] = vertex_normals[1]; vertex_normals[1] = vertex_normals[2]; vertex_normals[2] = tmpv; tmpd = heights[0]; heights[0] = heights[1]; heights[1] = heights[2]; heights[2] = tmpd; if (mapvals.bumpmap_id != -1) { bpp = gimp_drawable_bpp(mapvals.bumpmap_id); } gimp_pixel_rgn_get_row (&bump_region, bumprow, x1, y, x2 - x1); if (mapvals.bumpmaptype > 0) { switch (mapvals.bumpmaptype) { case 1: map = logmap; break; case 2: map = sinemap; break; default: map = spheremap; break; } for (n = 0; n < (x2 - x1); n++) { if (bpp>1) { mapval = (guchar)((float)((bumprow[n * bpp] +bumprow[n * bpp +1] + bumprow[n * bpp + 2])/3.0 )) ; } else { mapval = bumprow[n * bpp]; } heights[2][n] = (gdouble) mapvals.bumpmax * (gdouble) map[mapval] / 255.0; } } else { for (n = 0; n < (x2 - x1); n++) { if (bpp>1) { mapval = (guchar)((float)((bumprow[n * bpp] +bumprow[n * bpp +1] + bumprow[n * bpp + 2])/3.0 )) ; } else { mapval = bumprow[n * bpp]; } heights[2][n] = (gdouble) mapvals.bumpmax * (gdouble) mapval / 255.0; } } /* Compute triangle normals */ /* ======================== */ i = 0; for (n = 0; n < (x2 - x1 - 1); n++) { p1.x = 0.0; p1.y = ystep; p1.z = heights[2][n] - heights[1][n]; p2.x = xstep; p2.y = ystep; p2.z = heights[2][n+1] - heights[1][n]; p3.x = xstep; p3.y = 0.0; p3.z = heights[1][n+1] - heights[1][n]; triangle_normals[1][i] = gimp_vector3_cross_product (&p2, &p1); triangle_normals[1][i+1] = gimp_vector3_cross_product (&p3, &p2); gimp_vector3_normalize (&triangle_normals[1][i]); gimp_vector3_normalize (&triangle_normals[1][i+1]); i += 2; } /* Compute vertex normals */ /* ====================== */ i = 0; gimp_vector3_set (&normal, 0.0, 0.0, 0.0); for (n = 0; n < (x2 - x1 - 1); n++) { nv = 0; if (n > 0) { if (y > 0) { gimp_vector3_add (&normal, &normal, &triangle_normals[0][i-1]); gimp_vector3_add (&normal, &normal, &triangle_normals[0][i-2]); nv += 2; } if (y < pre_h) { gimp_vector3_add (&normal, &normal, &triangle_normals[1][i-1]); nv++; } } if (n <pre_w) { if (y > 0) { gimp_vector3_add (&normal, &normal, &triangle_normals[0][i]); gimp_vector3_add (&normal, &normal, &triangle_normals[0][i+1]); nv += 2; } if (y < pre_h) { gimp_vector3_add (&normal, &normal, &triangle_normals[1][i]); gimp_vector3_add (&normal, &normal, &triangle_normals[1][i+1]); nv += 2; } } gimp_vector3_mul (&normal, 1.0 / (gdouble) nv); gimp_vector3_normalize (&normal); vertex_normals[1][n] = normal; i += 2; } }