Scene Hierarchies

Last Time: Composition

If objects consist of multiple other objects, we can use composition (has-a) to simplify programs and make them easier to reason about.

class Bicycle{
  Frame frame;
  Wheel frontW;
  Wheel backW;
  float x, y;
  float wheelDist;
  
  Bicycle(Frame f, Wheel w){  }
  
  void displayBike(){ }
  
  void moveBike(float dx){  }
}

Last Time: Inheritance

If some classes (objects) are more specific instances of other classes (objects), we can use inheritance to model this. This is an example of an is-a relation

Motorized Vehicle

Car

Bus

class MotorizedVehicle {
  float fuel, speed;
  void addFuel(float amount){ /* */ }
  void accelerate(float rate){ /* */ }
}

class Car extends MotorizedVehicle {
  color color;
}

class Bus extends MotorizedVehicle {
  int numSeats;
}

Recap: Rules of Inheritance

  • Use inheritance only if your derived class can be thought of as a more specific instance of the base class.
     
  • Child classes retain all the members (fields + methods) of their parent, and can add more.
     
  • Use extends keyword to declare a subclass relation.
     
  • Child class constructors should call super() to access their parent constructor.
     
  • Methods that are redefined in the child override the ones in the parent.

Hands-On Review

Another View on Transforms

Another Way of thinking of Transforms

World Coordinate System

Camera Coordinate System

Object Coordinate System

Transforms modify the current coordinate system!

Screen Coordinates

"Object Coordinates"

translate(100, 100);

Screen Coordinates

"Object Coordinates"

translate(100, 100);

rect(0, 0, 50, 50);

Screen Coordinates

"Object Coordinates"

translate(100, 100);

rect(0, 0, 50, 50);

pushMatrix();

Screen Coordinates

"Object Coordinates"

translate(100, 100);

rect(0, 0, 50, 50);

pushMatrix();

rotate(PI/4);

Screen Coordinates

"Object Coordinates"

translate(100, 100);

rect(0, 0, 50, 50);

pushMatrix();

rotate(PI/4);

translate(100, 0);

x

y

Screen Coordinates

"Object Coordinates"

translate(100, 100);

rect(0, 0, 50, 50);

pushMatrix();

rotate(PI/4);

translate(100, 0);

rect(0, 0, 50, 100);

x

y

Screen Coordinates

"Object Coordinates"

translate(100, 100);

rect(0, 0, 50, 50);

pushMatrix();

rotate(PI/4);

translate(100, 0);

rect(0, 0, 50, 100);

popMatrix();

x

y

Screen Coordinates

"Object Coordinates"

translate(100, 100);

rect(0, 0, 50, 50);

pushMatrix();

rotate(PI/4);

translate(100, 0);

rect(0, 0, 50, 100);

popMatrix();

rect(100, 0, 100, 50);

Screen Coordinates

"Object Coordinates"

translate(100, 100);

rect(0, 0, 50, 50);

pushMatrix();

rotate(PI/4);

translate(100, 0);

rect(0, 0, 50, 100);

popMatrix();

rect(100, 0, 100, 50);

Screen Coordinates

"Object Coordinates"

translate(100, 100);

rect(0, 0, 50, 50);

pushMatrix();

rotate(PI/4);

translate(100, 0);

rect(0, 0, 50, 100);

popMatrix();

rect(100, 0, 100, 50);

Questions

Why make a ColorSpot class instead of just adding a color to Spot?

Is there any way to override class rules within our code?

Can you call the super function from a class several steps up the hierarchy?

No, you can't.

Part of the goal with OOP is to enforce predictability. This is naturally at-odds with "let me do what I want."

In small codebases, flexibility wins. In large codebases, predictability is paramount.

Is there a way to prevent a child class from overriding a method in its parent?

class ParentClass {
  // Cannot be overridden
  final void doAThing(){ }
  
  // Can be overridden
  void wompWompWomp(){ }
}


class ChildClass {
  // Okay!
  void wompWompWomp()
  
  // Compile error
  void doAThing(){ }
}

Why write class methods if we're going to override them later?

We might not override them later!

 

Methods in parent classes can be thought of as "default implementation" the same way we have default arguments.

Are pushing and popping the best ways to modify the transform?

Yes, and they're how I'm going to recommend you do them for this class.

....that being said......

Can we directly modify or access the transformation matrix?

I take no responsibility for any abuse of the following functions.

PMatrix curMat = getMatrix();

// stuff stuff stuff

applyMatrix(curMat);

PMatrix documentation is available as a JavaDoc, while getMatrix() and applyMatrix() appear to be intentionally undocumented (hint hint).

Rapid-Fire Round!

How much do transformations affect the speed/memory usage of the program?

  • Right now: basically zero.
  • When we switch to 3D: basically zero, but even smaller.

Are there more transformation matrices that weren't covered?

We actually covered most of the 2D transforms. In 3D, things get a little hairer.

Will we ever need to implement the linear algebra discussed?

No. Processing handles this all for us. It's one reason why we use this language in the first place.

How do quaternions relate to what was covered in class?

Ask me again once we get to 3D :)

How do we incorporate transformations into our objects?

Today: Other Hierarchies

Hierarchy: Taxonomic

Animal

Mammal

Insect

Squirrel

Deer

Ant

Termite

Hierarchy: Location

Forest

West of River

East of River

Squirrel

Termites

Ants

Deer

Different organization, same entities!

We can organize things hierarchically using different criteria, which naturally leads to different organizations.

Today we're going to talk about spatial organization.

Shapes

An Aside

How do we define shapes?

  1. Define a set of points in space.
  2. Connect the points to form edges.
  3. Combine the edges to form faces.
  4. Combine the faces to form meshes.
v 3.045715 -0.767786 -0.261741
v 3.065544 -0.788768 0.000000
v 3.107533 -0.691019 -0.264602
v 3.118124 -0.703925 0.000000
v 3.053144 -0.609681 -0.326931
f 3 4 2
f 1 2 4
f 5 6 3

World Coordinate System

Camera Coordinate System

Object Coordinate System

Screen Coordinate System

v 3.045715 -0.767786 -0.261741
v 3.065544 -0.788768 0.000000
v 3.107533 -0.691019 -0.264602
v 3.118124 -0.703925 0.000000
v 3.053144 -0.609681 -0.326931
f 3 4 2
f 1 2 4
f 5 6 3

Vertices

A vertex is a point that provides geometric information (and is the corner of a mesh).

 

Multiple vertices define a polygon or shape.

 

Conventionally, vertex data is given in the world space as opposed to the screen space.

Polygons

The default representation for objects in graphics.

In some cases, we even use only triangles---this is often called a "trimesh".

Scenes

What is a Scene?

  • A space we want to render (draw) on our screen
  • Can be 2D or 3D
  • What can a scene include?
    • Objects
    • Lights
    • Camera
  • What types of scenes have we drawn so far in this class?

Scenes in Animation

Often like a movie set:

  • Agents (actors)
    • Scripted
    • Player-Controlled
  • Props for interaction
  • Lights for shading
  • Camera for rendering

 

Scenes in Visualization

Surprisingly similar to animation/games!

 

Not something often thought about, even by people who make these visualizations.

Scene Hierarchies

Organizing Things Is Good!

How do polygons relate to each other?

How do objects relate to each other?

Scene Graphs

Tree hierarchy representing the relationship between objects in a scene.

Scene graph example (JMonkeyEngine)

Another scene graph example (http://hadva.blogspot.com/)

Scene Hierarchies are not OOP!

Looks a bit like an inheritance graph, but it is not!

 

People and motorcycles are not instances of the same class (well, maybe a generic "Object" class).

But we can use composition to model these sorts of things. For example, we can have a Transform which tells us how to transform this particular node.

Scene Graphs

Modeling and Animation

If we were moving each vertex of Atlas individually, how many different movements would we need to apply?

But joint movements are related to each other!

 

Example: Bending the elbow/shoulder changes the positions of the hand.

Hierarchical structure avoids having to move each vertex individually.

 

The hierarchy is based on the object design, not haphazard or random.

 

Consider the Pixar lamp: what is a hierarchical model that captures its degrees of motion?

Modeling to Animation

  • Modeling: Set shape and form
  • Rigging: Set underlying bone structure
  • Skinning: Map skin (surface) onto bones
  • Animating: Position bones to move the shape

Animation Hierarchy Examples

Hands-On: Scene Hierarchy

  1. Design a scene hierarchy for your project 3.
     
  2. Design the individual objects and how each object will have two levels of animation.

Submit a .txt file describing your plans for the project.

0. Read the Project 3 spec if you haven't yet.

Index Cards!

  1. Your name and EID.
     
  2. One thing that you learned from class today. You are allowed to say "nothing" if you didn't learn anything.
     
  3. One question you have about something covered in class today. You may not respond "nothing".
     
  4. (Optional) Any other comments/questions/thoughts about today's class.

Old Questions

Why was there another Hands-On due yesterday?

Due dates for hands-on activities are optimistic: they assume we're covering as much material in class as possible.

The actual due date for the hands-on will be based on when we get to it in class.

Why bother with subclassing if you're just going to override the methods anyways?

class MotorVehicle {
  // blah blah blah
  void accelerate() {  }
}

class Car {
  void goFast() {  }
}
void makeThingGoFast(MotorVehicle v){
  v.accelerate();
  v.accelerate();
  v.accelerate();
  v.accelerate();
  v.accelerate();
  v.accelerate();
}

What relation between the two classes guarantees that v has an accelerate() method?

class MotorVehicle {
  // blah blah blah
  void accelerate() {  }
}

class Car extends MotorVehicle {

}

Why bother with subclassing if you're just going to override the methods anyways?

class MotorVehicle {
  void accelerate() {  }
}

class Car {
  void accelerate() {  }
}

class CS324E {
  void accelerate() {  }
}

class ProjectSchedule {
  void accelerate() {  }
}

class ParticleBeam {
  void accelerate() {  }
}

Which of these accelerate() methods do similar things?

Inheritance tells us that related objects are likely to behave similarly.

How many classes do you usually see in large programs?

Quite a few, as it turns out! It takes a while to learn the object hierarchy in these projects, but it makes it easier in the long run.

 

A few notes about this:

  • In Java (and Processing), each class can only have one parent.
  • Great pains have been taken here to have a class hierarchy that makes sense (i.e. no Cars that are actually ParkingGarages). If the hierarchy were nonsense, it would make things much harder to understand.

Can you explain a little more about super?

this can be used as a variable to access the current object.

class Cow {
  void moo(){
    println(this.name + " says Moo");
  }
}

this can be used to call methods of the current class.

class Cow {
  void beHappy(){
    this.eatGrass(field);
    this.moo();
  }
}

this can be used to call constructors of the current class.

class Cow {
  Cow(String name){
    this.name = name;
  }
  Cow(){
    this("Peanut");
  }
}

super can be used to call methods of the superclass.

class SuperCow extends Cow {
  void beHappy(){
    this.fightCrime();
    // Would infinite recurse if it was
    // this.beHappy();
    super.beHappy();
  }
}

super can be used to call other constructors of the superclass.

class SuperCow extends Cow {
  SuperCow(String name, String power){
    super(name);  // Must exist!
    this.power = power;
  }
}

These last two uses are shared by super, but refer to things in the superclass!

Why does super() have to be the first thing in a constructor if it's present?

Java said so.

There are explanations out there that you can find, but they're a little complex.

 

It boils down to:

  • Java was trying to enforce some rules about object validity
  • Forcing you to call super() first is one way to try to enforce that
  • This doesn't really accomplish what it was supposed to
  • There were probably other ways of enforcing these rules

Why bother with super()?

class BaseClass{
  int val1, val2;
  BaseClass(int x, int y){
    val1 = x;
    val2 = y;
  }
  BaseClass(){
    val1 = 0;
    val2 = 5;
  }
}

class Sub1 extends BaseClass {
  Sub1(int x, int y){
    val1 = x;
    val2 = y;
  }
  Sub1(){
    val1 = 2;
    val2 = 5;
  }
}

Uh-oh. The requirements changed! Now we need to guarantee that the values are all between 0 and 4. In the constructor, if the value is outside the range, we clamp it.

class Sub2 extends Sub1 {
  int val3;
  Sub2(int x, int y, int z){
    val1 = x;
    val2 = y;
    val3 = z;
  }
  Sub2(){
    val1 = -1;
    val2 = 5;
    val3 = 4;
  }
}

Why bother with super()?

class BaseClass{
  int val1, val2;
  BaseClass(int x, int y){
    val1 = x;
    val2 = y;
  }
  BaseClass(){
    this(0, 5);
  }
}

class Sub1 extends BaseClass {
  Sub1(int x, int y){
    super(x, y);
  }
  Sub1(){
    this(2,5)
  }
}
class Sub2 extends Sub1 {
  int val3;
  Sub2(int x, int y, int z){
    super(x, y);
    val3 = z;
  }
  Sub2(){
    this(-1, 5, 4);
  }
}

Now how many places do we need to change?

class BaseClass{
  int val1, val2;
  BaseClass(int x, int y){
    val1 = x;
    val2 = y;
  }
  BaseClass(){
    this(0, 5);
  }
}

class Sub1 extends BaseClass {
  Sub1(int x, int y){
    super(x, y);
  }
  Sub1(){
    this(2, 5);
  }
}

What happens if my class hierarchy gets too complex?

But this does touch on one of the distinct weaknesses of this type of programming.

Code Review

How can I control the number of members that the child inherits from the parent?

You can't.

By saying your child is a special type of the parent, you're saying the child can do everything the parent can and more.

Deleting members or preventing the child from inheriting them would fundamentally break this guarantee.

class MotorVehicle {
  void accelerate() {  }
}

class Car extends MotorVehicle{
  // Cast magical spell to prevent
  // method from being inherited
  // ABLOOGY WOOGY WOO
  // void accelerate() {  }
}

[07b]: Scene Hierarchies

By Kevin Song

[07b]: Scene Hierarchies

  • 74