The Ohio State University

www.osu.edu

  1. Help
  2. Campus map
  3. Find people
  4. Webmail



CSE 682 Classwork

Role

In this project, I was primarily responsible for procedurally generating the shaking of objects and the flipping of pages. After some preliminary work it was decided that we could keyframe the guts of the page flipping and I would focus on the shaking of our main book.
To achieve this goal I produced a script that when loaded into the maya environment, that would allow you to select objects that you would like to shake and then click a shelf button to apply the attributes necessary to gain control of the shaking process.
In addition to the procedural task, I was responsible for some technical support to the group. I compressed the renders of our movie to be shown in class. I also helped with the initial creation of our group website and configured this forumn.

Journal

Week 1

  • Formation of group
  • Brain Storming of Animation Ideas
  • Decided to use web forumn as a central place for ideas

Week 2

  • Set up the forumn
  • Narrowed down brainstorm ideas
  • Read about the principles of animation

Week 3

  • Started playing with maya
  • Continued research of animation techniques

Week 4

  • Played with animating a page turn

Week 5

  • Page flipping animation enhanced with Sucheta's help
  • Started making attempts at using mel to create effects

Week 6

  • Primitive book shaking in place
  • Started work on enhancing with a spring system

Week 7

  • Completed advance shaking code manipulating the power of randomness

Week 8

  • Discarded advance shaking code manipulating the power of randomness
  • Re-engineered algorithm to use sin waves to generate the shaking motiion

Week 9

  • Added function to control the flapping of the book binding
  • Merged randomness back into shaking code for added realism

Week 10

  • Assisted in adding final touches to scenes

Source Code

Final Source

/*
 * New "Better" Version of createShaker()
 */
global proc createShaker() {
  string $nodes[] = selectedNodes("-do");
  string $node;

  for($node in $nodes) {
    string $type[] = {"rotate", "translate"};
    string $param[] = {"Weight", "Origin", "Amplitude", "Frequency"};
    string $axis[] = {"X", "Y", "Z"};
    string $t, $p, $a;

    /*
     * Add Attributes that allow for the modification of a node's rotations and
     * translations.
     */
    for($t in $type) {
      for($p in $param) {
        for($a in $axis) {
          string $attr = $t + $p + $a;

          /*
           * Only add attribute if necessary.
           */
          if(!attributeExists($attr, $node)) addAttr -ln $attr -dv 0 $node;

          /*
           * Make origin attributes equal to the current transformation
           * attributes.
           */
          if($p == "Origin") {
            setAttr($node + "." + $attr, getAttr($node + "." + $t + $a));
          }

          /*
           * Make frequency default to something reasonable.
           */
          else if($p == "Frequency") {
            setAttr($node + "." + $attr, 1);
          }
        }
      }
    }

    /*
     * Add expression to control object.
     *
     * Note: There needs to be a check to make sure an object isn't "shaked"
     * twice.
     */
    expression("-s", "updateShaker(\"" + $node + "\", frame);", "-ae", 1);
  }
}

/*
 * New "Even Better" Version of updateShaker(string, int)
 */
global proc int updateShaker(string $node, int $frame) {
  string $type[] = {"rotate", "translate"};
  string $axis[] = {"X", "Y", "Z"};
  string $t, $p, $a;
  float $factor = deg_to_rad(360) / 24;

  for($t in $type) {
    for($a in $axis) {
      string $val_str = $node + "." + $t + $a;
      string $org_str = $node + "." + $t + "Origin" + $a;
      string $amp_str = $node + "." + $t + "Amplitude" + $a;
      string $frq_str = $node + "." + $t + "Frequency" + $a;
      string $weight_str = $node + "." + $t + "Weight" + $a;

      float $val = getAttr($val_str);
      float $org = getAttr($org_str);
      float $amp = getAttr($amp_str);
      float $frq = getAttr($frq_str);
      float $off = $amp * sin($frame * $factor * $frq);
      float $weight = getAttr($weight_str);

      if($amp != 0) {
        // Add Jitter to break oscillations
        $off = (1 - $weight) * $off + $weight * rand(-$amp, $amp);
      }

      setAttr($val_str, $org + $off);
    }
  }

  return 1;
}

global proc extraShake(int $frame) {
  if($frame > 1684 && $frame < 1804) {
    float $intensity = 1 - abs($frame - 1744)/60;
    float $rotate1 = $intensity * rand(0, 5);
    float $rotate2 = $intensity * rand(0, 5) + $rotate1;

    setAttr("joint2.rotateZ", $rotate2);
    setAttr("joint1.rotateZ", -$rotate1);
    setAttr("joint1.translateY", 1.65 * sin(deg_to_rad($rotate1)) + 6.231);
  }

  else if($frame = 1804) {
    setAttr("joint1.translateY", 6.231);
    setAttr("joint1.rotateZ", 0);
  }
}

Early Attempt [Randomness]

/*
 * New "Better" Version of createShaker()
 */
global proc createShaker() {
  string $nodes[] = selectedNodes("-do");
  string $node;

  for($node in $nodes) {
    string $type[] = {"rotate", "translate"};
    string $param[] = {"Origin", "Offset", "Intensity", "Frequency"};
    string $axis[] = {"X", "Y", "Z"};
    string $t, $p, $a;

    /*
     * Add Attributes that allow for the modification of a node's rotations and
     * translations.
     */
    for($t in $type) {
      for($p in $param) {
	for($a in $axis) {
	  string $attr = $t + $p + $a;

	  /*
	   * Only add attribute if necessary.
	   */
	  if(!attributeExists($attr, $node)) addAttr -ln $attr -dv 0 $node;

	  /*
	   * Make origin attributes equal to the current transformation
	   * attributes.
	   */
	  if($p == "Origin") {
	    setAttr($node + "." + $attr, getAttr($node + "." + $t + $a));
	  }
	}
      }
    }

    /*
     * Add expression to control object.
     *
     * Note: There needs to be a check to make sure an object isn't "shaked"
     * twice.
     */
    expression("-s", "updateShaker(\"" + $node + "\");", "-ae", 1);
  }
}

/*
 * New "Better" Version of updateShaker(string)
 */
global proc int updateShaker(string $node) {
  string $type[] = {"rotate", "translate"};
  string $axis[] = {"X", "Y", "Z"};
  string $t, $p, $a;

  for($t in $type) {
    for($a in $axis) {
      string $val_str = $node + "." + $t + $a;
      string $off_str = $node + "." + $t + "Offset" + $a;
      string $org_str = $node + "." + $t + "Origin" + $a;
      string $int_str = $node + "." + $t + "Intensity" + $a;
      string $frq_str = $node + "." + $t + "Frequency" + $a;

      float $val = getAttr($val_str);
      float $off = getAttr($off_str);
      float $org = getAttr($org_str);
      float $int = getAttr($int_str);
      float $frq = getAttr($frq_str);

      float $delta = $org + $off - $val;

      if($int != 0) {
	// Shaker is active since intensity != 0
	if(abs($delta) < .01) {
	  setAttr($off_str, rand(-$int, $int));
	}

	else {
	  // More than .01 from destination.  Go halfway there.
	  $val += ($delta)/2;
	}

	setAttr($val_str, $val);
      }
    }
  }

  return 1;
}
Valid XHTML 1.1! Valid CSS!