예제 #1
0
파일: drawplant.c 프로젝트: transfix/cs354
/*
 * Draws the plant.
 */
void drawPlant(int i,float scale,float radscale,int string)
{  
  char *ptr = lsystem[string];
  char ch[] = { '\0','\0' };
  GLfloat c1[] = { 0.6549f,0.4901f,0.2392f }; /* light brown */
  GLfloat c2[] = { 0.3607f,0.2510f,0.2000f }; /* dark brown */
  GLfloat c3[] = { 0.1373f,0.5568f,0.1373f }; /* forest green */

  if(i==0)
    return;
  
  PushMatrix();
  while(*ptr != '\0')
    {
      switch(*ptr)
	{
	case 'F':
	  Rotate(tilt/10000,0.0,0.0,1.0); /* tilt very very slightly */
	  LoadMatrix();
	  if(do_growth && floor(growth)==i)
	    {
	      draw_branch(LENGTH*scale*(growth-1),RADIUS*radscale,BASE_TRI,c1,c2);
	      Translate(0.0,LENGTH*scale*(growth-1),0.0);
	    }
	  else
	    {
	      draw_branch(LENGTH*scale,RADIUS*radscale,BASE_TRI,c1,c2);
	      Translate(0.0,LENGTH*scale,0.0);
	    }
	  break;
	case '[':
	  PushMatrix();
	  break;
	case ']':
	  PopMatrix();
	  break;
	case 'L':
	  if(do_growth && floor(growth)==i)
	      draw_leaf(4*(growth-1)*scale,1*(growth-1)*scale,25,c3);
	  else
	    draw_leaf(4*scale,1*scale,25,c3);
	  break;
	case 'R':
	  Rotate(yrotate,0.0,1.0,0.0);
	  break;
	case 'T':
	  Rotate(tilt,0.0,0.0,1.0);
	  break;
	default:
	  if(isdigit(*ptr))
	    {
	      ch[0] = *ptr;
	      drawPlant(i-1,scale*SCALE,radscale*RADSCALE,atoi(ch));
	    }
	  break;
	}
      ptr++;
    }
  PopMatrix();
}
예제 #2
0
void fltr_herb_stems(texture *tx, void const * const fargs) {
  herb_leaves_filter_args *hlfargs = (herb_leaves_filter_args *) fargs;
  ptrdiff_t hash;
  int i = 0;
  float noise;
  int nstalks;
  float spread;
  leaf_filter_args lfargs; // stores individual leaf parameters
  curve c; // stores individual leaf shapes
  c.from.y = BLOCK_TEXTURE_SIZE;
  c.to.y = 0;
  c.from.z = 0;
  c.come_from.z = 0;
  c.go_towards.z = 0;
  c.to.z = 0;

  herb_setup(hlfargs, &hash, &noise, &nstalks, &spread, &lfargs);
  lfargs.shape = LS_LINEAR;

  float th_base = 0;
  float mid = (BLOCK_TEXTURE_SIZE / 2);

  for (i = 0; i < nstalks; ++i) {
    // generate x in [mid - spread, mid + spread]
    // for stems, we use the same top/bottom values so that they'll fit
    // together vertically.
    c.from.x = mid - spread;
    c.from.x += 2 * spread * ptrf(hash + i);
    c.to.x = c.from.x;
    hash = prng(hash + i + c.from.x);
    // pick the same starting angle that leaves use [-1, 1]
    noise = 1.0 - 2 * ptrf(hash);
    hash = prng(hash + i);
    th_base = hlfargs->angle * noise;
    // An extra hash to maintain stride with fltr_herb_leaves:
    hash = prng(hash + i);
    // stems use the same angle at the top and bottom so that they can stack.
    c.come_from.x = c.to.x - sinf(th_base) * hlfargs->length*hlfargs->shape;
    c.come_from.y = c.to.y + cosf(th_base) * hlfargs->length*hlfargs->shape;
    c.go_towards.x = c.from.x + sinf(th_base) * hlfargs->length*hlfargs->shape;
    c.go_towards.y = c.from.y - cosf(th_base) * hlfargs->length*hlfargs->shape;
    // pick a base width in [0.75, 1.25]
    noise = 0.75 + 0.5 * ptrf(hash);
    hash = prng(hash + i);
    lfargs.width = hlfargs->width * noise;

    // draw the leaf:
    draw_leaf(tx, &c, &lfargs);
  }
}
예제 #3
0
void fltr_leaf(texture *tx, void const * const fargs) {
  leaf_filter_args *lfargs = (leaf_filter_args *) fargs;
  ptrdiff_t hash = prng(lfargs->seed);
  float noise = 0;
  float angle = 0, bend = 0;
  float mid = LEAF_TEXTURE_SIZE / 2.0;
  curve c;
  c.from.x = 0; c.from.y = 0; c.from.z = 0;
  c.go_towards.x = 0; c.go_towards.y = 0; c.go_towards.z = 0;
  c.come_from.x = 0; c.come_from.y = 0; c.come_from.z = 0;
  c.to.x = 0; c.to.y = 0; c.to.z = 0;
  tx_clear(tx);
  if (lfargs->type == LT_SIMPLE) {
    // pick an angle in [-1, 1] * lfargs->angle_var (0 will be straight down)
    noise = -1 + 2.0 * ptrf(prng(hash + lfargs->seed));
    angle = lfargs->angle + lfargs->angle_var * noise;

    // the leaf starts opposite that angle:
    c.from.x = mid + (mid - 1) * sinf(angle + M_PI);
    c.from.y = mid + (mid - 1) * cosf(angle + M_PI);

    // its midpoint is in the direction of the given angle:
    c.go_towards.x = c.from.x + (lfargs->length / 2.0) * sinf(angle);
    c.go_towards.y = c.from.y + (lfargs->length / 2.0) * cosf(angle);
    // make sure we're still inside the texture:
    if (c.go_towards.x < 1) {
      c.go_towards.x = 1;
    } else if (c.go_towards.x > LEAF_TEXTURE_SIZE - 2) {
      c.go_towards.x = LEAF_TEXTURE_SIZE - 2;
    }

    // its endpoint bends:
    noise = 0.7 + 0.6 * ptrf((hash + 2)*noise); // [0.7, 1.3]
    bend = lfargs->bend * noise;
    if ((angle > 0 && angle < M_PI) || (angle < -M_PI) ) {
      bend = angle - bend;
    } else {
      bend = angle + bend;
    }
    c.to.x = c.go_towards.x + (lfargs->length / 2.0) * sinf(bend);
    c.to.y = c.go_towards.y + (lfargs->length / 2.0) * cosf(bend);
    // check bounds again:
    if (c.to.x < 1) {
      c.go_towards.x += (1 - c.to.x) / 2.0;
      c.to.x = 1;
    } else if (c.to.x > LEAF_TEXTURE_SIZE - 2) {
      c.go_towards.x -= (c.to.x - (LEAF_TEXTURE_SIZE - 2)) / 2.0;
      c.to.x = LEAF_TEXTURE_SIZE - 2;
    }

    // copy the go_towards point as the come_from point:
    vcopy_as(&c.come_from, &c.go_towards);

    // draw the leaf:
    draw_leaf(tx, &c, lfargs);
  } else if (lfargs->type == LT_TRIPARTITE) {
    // TODO: Tripartite leaves!
  } else if (lfargs->type == LT_NEEDLES) {
    // TODO: Needles!
  }
#ifdef DEBUG
  else {
    fprintf(stderr, "Bad leaf filter type %d!\n", lfargs->type);
  }
#endif
}
예제 #4
0
void fltr_herb_leaves(texture *tx, void const * const fargs) {
  herb_leaves_filter_args *hlfargs = (herb_leaves_filter_args *) fargs;
  ptrdiff_t hash;
  int i = 0;
  float noise;
  int nstalks;
  float spread;
  leaf_filter_args lfargs; // stores individual leaf parameters
  curve c; // stores individual leaf shapes
  c.from.y = BLOCK_TEXTURE_SIZE;
  c.from.z = 0;
  c.come_from.z = 0;
  c.go_towards.z = 0;
  c.to.z = 0;

  herb_setup(hlfargs, &hash, &noise, &nstalks, &spread, &lfargs);
  lfargs.shape = LS_DELTOID;

  float th_base = 0, th_mid = 0;
  float mid = (BLOCK_TEXTURE_SIZE / 2);

  for (i = 0; i < nstalks; ++i) {
    // generate x in [mid - spread, mid + spread]
    c.from.x = mid - spread;
    c.from.x += 2 * spread * ptrf(hash + i);
    hash = prng(hash + i + c.from.x);
    // pick a starting angle in [-1, 1]
    noise = 1.0 - 2 * ptrf(hash);
    hash = prng(hash + i);
    th_base = hlfargs->angle * noise;
    // pick a bend angle in [0.6, 1.4] of the specified angle
    noise = 0.6 + 0.8 * ptrf(hash);
    hash = prng(hash + i);
    th_mid = hlfargs->bend * noise * th_base / hlfargs->angle;
    th_mid += th_base;
    // compute midpiont and endpoint
    c.go_towards.x = c.from.x + sinf(th_base) * hlfargs->length*hlfargs->shape;
    c.go_towards.y = c.from.y - cosf(th_base) * hlfargs->length*hlfargs->shape;
    c.to.x = c.go_towards.x + sinf(th_mid) * hlfargs->length*(1-hlfargs->shape);
    c.to.y = c.go_towards.y - cosf(th_mid) * hlfargs->length*(1-hlfargs->shape);
    // keep things in-bounds
    /*
    if (c.to.x < 1) {
      c.go_towards.x += (1 - c.to.x) / 2.0;
      c.to.x = 1;
    } else if (c.to.x > BLOCK_TEXTURE_SIZE - 2) {
      c.go_towards.x -= (c.to.x - (BLOCK_TEXTURE_SIZE - 2)) / 2.0;
      c.to.x = BLOCK_TEXTURE_SIZE - 2;
    }
    if (c.to.y < 1) {
      c.go_towards.y += (1 - c.to.y) / 2.0;
      c.to.y = 1;
    }
    // */
    // Copy the come_from vector from the go_towards vector:
    vcopy_as(&c.come_from, &c.go_towards);
    /* DEBUG:
    printf("th_base: %.3f\n", th_base);
    printf("th_mid: %.3f\n", th_mid);
    printf("th_mid_atten: %.3f\n", th_base / hlfargs->angle);
    printf("th_mid_roll: %.3f\n", noise);
    printf("xy_mid: %.2f, %.2f\n", c.go_towards.x, c.go_towards.y);
    printf("xy_end: %.2f, %.2f\n", c.to.x, c.to.y);
    // */
    // pick a base width in [0.75, 1.25]
    noise = 0.75 + 0.5 * ptrf(hash);
    hash = prng(hash + i);
    lfargs.width = hlfargs->width * noise;

    // draw the leaf:
    draw_leaf(tx, &c, &lfargs);
  }
}
예제 #5
0
/**
 * Draws given node as a node in a tree - first draws element,
 * then calls the draw function of all children
 */
int draw_node(Control* node, Control* parent) {
	if (draw_children(node, NULL )) {
		return draw_leaf(node, parent);
	}
	return 0;
}