The Abyss – Graphics, animation and interaction with Processing [Tutorial]

The Abyss is a 3d space where custom programs (creatures) can be built and released. By creating one or more creatures, this tutorial aims to provide an introduction into graphics, animation, interaction with Processing and expand the boundaries and the variety of the Abyss. Basic creatures just floating their existence away can coexist with more sophisticated ones which may implement an aggregating or even a hunting behaviour.

The Abyss was born as a workshop by Andreas Gysin for design students with different programming skills: beginners but also third graders with good programming knowledge. Andreas wanted a common result for the whole class but also a system where everbody could contribute with an indiviudal part. The first workshop took place in 2011 at supsi and most recent at Resonate during BELEF festival in Belgrade.

For beginners it should be easy enough to contribute with a basic creature, just concentrating on the graphical output; more advanced users can train their animation skills or even build creatures which interacted with other creatures. Some flocking and hunting behaviours can emerge, food particles added to make the Abyss alive.

A few rules come with it:
• Extend the supercreature class and build your own creature.
• Allowed colors are white with alpha shades. Not a strict rule.
• Each creature must implement the move() and draw() methods (see the SuperCreature class for details).
• Transforms should use the pos, rot, sca vectors as those are used to track creatures in space.
• Animations can be timed with frames or actual time.
• The name of the new creature class is built with the authors initals and the creature name. This is not an optimal naming convention but it works with 10-20 people as each class name must be unique (Steve Zissou + Cubus = SZCubus).
• The .PDE file should have the same name of the class (for example: SZCubus.pde).
• Insert your name, the creature name, the version and the build date in the constructor.
• Break all rules and build something new.

The Processing IDE makes it easy enough to store each creaure in a separated .PDE file. To add it to the Abyss it’s enough to copy it to the main project (usually stored in a shared folder). The program will take care to instatiate the creature classes without any extra code.

As an example let’s rebuild the Cubus creature from scratch.

1. Download Processing and The Abyss code (github master)
Note: the current version uses an OpenGL fog to blend out far away creatures. This works only until Processing 1.5.1. It can still be adapted for Processing 2.0 with a fog shader or by just getting rid of the whole Fog class and its few references.

2. Launch processing and load the Abyss sketch.
Create a new tab and name it as you want or by following the naming convention explained above.

3. Each creature needs at least a move() and draw() method.
But we start with just a static cube.
In the constructor add some basic creature information, like author, name, version and birthday.

class SZCubus extends SuperCreature {

  float cSize; // size of the body

  public SZCubus() {
    creatureAuthor  = "Steve Zissou";  // your name here, Steve
    creatureName    = "Cubus";         // the creature’s one goes here 
    creatureVersion = "1.0";           // a string of your choice
    setDate(2012, 9, 24); //Y,M,D      // just to keep track

    cSize = random(6, 30);             // each creature will have a slightly different size

  void move() {
    // doesn’t move at all. Just stays in place for now…

  void draw() {    
    // this shortcut function just translates, rotates and scales the model matrix
    // by the values contained in the superclass PVectors pos, rot and sca
    // it could also be done by hand, 
    // for example in a case where the creature is based on a particle system
    // and drawing has to be in world coordinates.

    // let’s draw the creature body: a box to hounour the creature’s name

Run the sketch, press the right or left cursors until you see the ‘Cubus’ creature in the red box.
Press space several times to release them in the Abyss.

4. Now let’s add a bit of movement.
We need two fields to store a pair of PVectors:

PVector fPos, fAng;

…which are initialized and randomised in the constructor:

fPos = new PVector(random(-0.002, 0.002), random(-0.002, 0.002), random(-0.002, 0.002));
fAng = new PVector(random(-0.005, 0.005), random(-0.005, 0.005), random(-0.005, 0.005));

In the move() method we use those values to modify the creature’s pos and rot vectors.

void move() {
  pos.x += sin(frameCount * fPos.x);
  pos.y += sin(frameCount * fPos.y);
  pos.z += cos(frameCount * fPos.y);

  rot.x = sin(frameCount * fAng.x) * TWO_PI;
  rot.y = sin(frameCount * fAng.y) * TWO_PI;
  rot.z = sin(frameCount * fAng.z) * TWO_PI;

Run the sketch again and release a few creatures. Hit the ‘a’ key to visualize the creature’s origin.

5. We can also add custom methods to our creature:
this one will just take a PVector and an angle and return a new rotated PVector. In 2d.

PVector rotateVec(PVector v, float angle) {
  float c = cos(angle);
  float s = sin(angle);
  return new PVector(v.x*c - v.y*s, v.x*s + v.y*c);

6. So for the final step let’s add a few more fields to describe the tentacles and their movement

int segments;    // the number of segments for each tentacle
float bLen;      // start length of each segment
float aFreq;     // frequency
float bOffs;     // offset for the tentacle pairs
float angRange;  // min and max angle for the tentacles

Again, in the constructor we assign random values to those fields to create some difference between each creature instance.

segments = int(random(5,9));
bLen = random(4, 10);
aFreq = random(0.01, 0.1);
bOffs = random(5);
angRange = random(0.3, 0.6);

7. Finally in the draw() method, after the box we display four tentacles.

for (int j=0; j<4; j++) { //we draw four of them, on a 2d plane
  PVector p = new PVector(bLen, 0); 
  PVector pos = new PVector(cSize/2, 0); 
  float ang = sin(frameCount*aFreq + j%2 * bOffs) * angRange;
  float l = bLen;
  beginShape(); // we draw just connected segments
    for (int i=0; i<segments+1; i++)="" {="" vertex(pos.x,="" pos.y);="" pos.x="" +="p.x;" pos.y="" p="rotateVec(p," ang);="" p.limit(l);="" l="" *="0.93;" scale="" a="" bit="" the="" length="" of="" each="" segment,="" this="" factor="" could="" also="" be="" randomized="" }="" endshape();="" rotatey(half_pi);="" rotate="" about="" 90="" degrees="" and="" draw="" next="" tentacle="" <="" pre="">

And now make your own.

Pictures from the workshop are available here.

Born in Zürich, Andreas Gysin lives and works as graphic designer between Berlin and Lugano. Writing custom programs is part of his design process independently of the output medium. When not busy on projects he teaches interaction design and programming at ECAL, Lausanne and in SUPSI, Lugano and in workshops worldwide.

Resonate is a platform for networking, information, knowledge sharing and education. It brings together distinguished, world class artists with an opportunity of participating in a forward-looking debate on the position of technology in art and culture.

In 2012, Resonate featured Nicholas Feltron, Josh Nimoy, Jer Thorp, Regine Debatty, Champagne Valentine, Niklas Roy, Benjamin Gaulon, Karsten Schmidt, FIELD, LAb[au], Rafaël Rozendaal, United Visual Artists, Jürg Lehni, WARP, onedotzero, Kim Gordon + Ikue Mori, Alva Noto + Blixa Bargeld, DJ Spooky and many more..

Resonate is Magnetic Field B production in collaboration with CreativeApplications.Net and Dom Omladine Belgrade.

Next Resonate takes place 21-13rd March 2013 in Belgrade and will include around 30 talks, 15 workshops and night performances. For more information and details when they are available see or follow on Twitter / like on Facebook.

Andreas Gysin – Resonate at Belef from Resonate Festival on Vimeo.




5 comments on “The Abyss – Graphics, animation and interaction with Processing [Tutorial]