Example #1
0
GimpRGB
get_ray_color_box (GimpVector3 *pos)
{
  GimpVector3        lvp, ldir, vp, p, dir, ns, nn;
  GimpRGB             color, color2;
  gfloat             m[16];
  gint               i;
  FaceIntersectInfo  face_intersect[2];

  color = background;
  vp = mapvals.viewpoint;
  p = *pos;

  /* Translate viewpoint so that the box has its origin */
  /* at its lower left corner.                          */
  /* ================================================== */

  vp.x = vp.x - mapvals.position.x;
  vp.y = vp.y - mapvals.position.y;
  vp.z = vp.z - mapvals.position.z;

  p.x = p.x - mapvals.position.x;
  p.y = p.y - mapvals.position.y;
  p.z = p.z - mapvals.position.z;

  /* Compute direction */
  /* ================= */

  gimp_vector3_sub (&dir, &p, &vp);
  gimp_vector3_normalize (&dir);

  /* Compute inverse of rotation matrix and apply it to   */
  /* the viewpoint and direction. This transforms the     */
  /* observer into the local coordinate system of the box */
  /* ==================================================== */

  memcpy (m, rotmat, sizeof (gfloat) * 16);

  transpose_mat (m);

  vecmulmat (&lvp, &vp, m);
  vecmulmat (&ldir, &dir, m);

  /* Ok. Now the observer is in the space where the box is located */
  /* with its lower left corner at the origin and its axis aligned */
  /* to the cartesian basis. Check if the transformed ray hits it. */
  /* ============================================================= */

  face_intersect[0].t = 1000000.0;
  face_intersect[1].t = 1000000.0;

  if (intersect_box (mapvals.scale, lvp, ldir, face_intersect) == TRUE)
    {
      /* We've hit the box. Transform the hit points and */
      /* normals back into the world coordinate system   */
      /* =============================================== */

      for (i = 0; i < 2; i++)
        {
          vecmulmat (&ns, &face_intersect[i].s, rotmat);
          vecmulmat (&nn, &face_intersect[i].n, rotmat);

          ns.x = ns.x + mapvals.position.x;
          ns.y = ns.y + mapvals.position.y;
          ns.z = ns.z + mapvals.position.z;

          face_intersect[i].s = ns;
          face_intersect[i].n = nn;
        }

      color = get_box_image_color (face_intersect[0].face,
				   face_intersect[0].u,
				   face_intersect[0].v);

      /* Check for total transparency... */
      /* =============================== */

      if (color.a < 1.0)
        {
          /* Hey, we can see  through here!      */
          /* Lets see what's on the other side.. */
          /* =================================== */

          color = phong_shade (&face_intersect[0].s,
			       &mapvals.viewpoint,
			       &face_intersect[0].n,
			       &mapvals.lightsource.position,
			       &color,
			       &mapvals.lightsource.color,
			       mapvals.lightsource.type);

          gimp_rgb_clamp (&color);

          color2 = get_box_image_color (face_intersect[1].face,
					face_intersect[1].u,
					face_intersect[1].v);

          /* Make the normal point inwards */
          /* ============================= */

          gimp_vector3_mul (&face_intersect[1].n, -1.0);

          color2 = phong_shade (&face_intersect[1].s,
				&mapvals.viewpoint,
				&face_intersect[1].n,
				&mapvals.lightsource.position,
				&color2,
				&mapvals.lightsource.color,
				mapvals.lightsource.type);

          gimp_rgb_clamp (&color2);

          if (mapvals.transparent_background == FALSE && color2.a < 1.0)
            {
	      gimp_rgb_composite (&color2, &background,
				  GIMP_RGB_COMPOSITE_BEHIND);
	    }

          /* Compute a mix of the first and second colors */
          /* ============================================ */

	  gimp_rgb_composite (&color, &color2, GIMP_RGB_COMPOSITE_NORMAL);
          gimp_rgb_clamp (&color);
        }
      else if (color.a != 0.0 && mapvals.lightsource.type != NO_LIGHT)
        {
	  color = phong_shade (&face_intersect[0].s,
			       &mapvals.viewpoint,
			       &face_intersect[0].n,
			       &mapvals.lightsource.position,
			       &color,
			       &mapvals.lightsource.color,
			       mapvals.lightsource.type);

	  gimp_rgb_clamp (&color);
        }
    }
  else
    {
      if (mapvals.transparent_background == TRUE)
	gimp_rgb_set_alpha (&color, 0.0);
    }

  return color;
}
Example #2
0
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;
}
Example #3
0
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;
}
Example #4
0
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;
}