How do you create an instance of an object and reference it eg. to rotate an object at a later time?

Hi,
I’ve loaded in a 3d model and I looked at the p5 docs for rotating the model and one of the functions is:

function draw() {
  background(200);
  rotateX(frameCount * 0.01);
  rotateY(frameCount * 0.01);
  model(octahedron);
}

That works - but how do you keep a reference to that model so you can change the position, rotation, etc at a later time eg. with a button press.

Thanks.

Hi @jmg007,

Welcome to the forum! :wink:

Do you mean rotating the octahedron alone and not the whole scene?

For that you might want to use translate() and the rotate functions in conjunction with push() and pop() to only affect your model.

Everything drawn in p5.js is drawn in “immediate mode”, which means that shapes drawn to the canvas don’t have any persistent representation that can be moved around. Instead you have to manage clearing the canvas and redrawing your various shapes when parameters change such as there position or rotation.

Technically in your example the octahedron variable is a reference to the “model” but that only includes the raw geometry data, not the rotation, materials, or an other parameters used to draw it.

1 Like

Hi @jmg007, welcome!

The answer you’re probably looking for is classes. What you can do is create an “Octahedron” class, which has its own properties that it stores. You create instances of this class that each have their own set of parameters (like position, rotation, colour, and can store its own set of data, like a 3d model)

Below an example of a cube class, that just stores data. You can also add actual functions to the class, like a “rotate()” method that adds a few degrees to its rotation variable, or a “display()” method that actually draws the cube (or in your case, octahedron).

class Cube
{
  float posX, posY;
  float size;
  float rot;
  
  color col;
  
  Cube(float _posX, float _posY, float _size, float _rot)
  {
    posX = _posX;
    posY = _posY;
    size = _size;
    rot = _rot;
    
    col = color(255);
  }
}


Cube cubeA, cubeB, cubeC;

void setup()
{
  size(1200, 800, P3D);
  
  cubeA = new Cube(300, 400, 100, 0);
  cubeB = new Cube(600, 400, 200, 0);
  cubeC = new Cube(900, 400, 100, 0);
  
  frameRate(60);
  
}

void draw()
{
  // update
  
  cubeA.rot += 0.01;
  cubeB.rot += 0.02;
  cubeC.rot += 0.03;
  
  // draw
  
  background(0);
  noFill();
  
  // cube A
  pushMatrix();
  translate(cubeA.posX, cubeA.posY, 0);
  rotateZ(cubeA.rot);
  stroke(cubeA.col);
  box(cubeA.size);
  popMatrix();
  
  // cube B
  pushMatrix();
  translate(cubeB.posX, cubeB.posY, 0);
  rotateZ(cubeB.rot);
  stroke(cubeB.col);
  box(cubeB.size);
  popMatrix();
  
  // cube C
  pushMatrix();
  translate(cubeC.posX, cubeC.posY, 0);
  rotateZ(cubeC.rot);
  stroke(cubeC.col);
  box(cubeC.size);
  popMatrix();
  
  
}

While this is one solution, writing reusable code does not require the use of Object Oriented Programming. That said, it is a valid approach, but perhaps an example that is in the dialect that the original poster is using (p5.js) would be more helpful:

class Cube {
  constructor(pos, size, delta, col) {
    this.pos = pos;
    this.size = size;
    this.rot = 0;
    this.delta = delta;
    
    this.col = color(col || 255);
  }
  
  update() {
    this.rot += this.delta;
  }
  
  display() {
    push();
    translate(this.pos.x, this.pos.y, 0);
    rotateZ(this.rot);
    stroke(this.col);
    box(this.size);
    pop();
  }
}


let cubeA, cubeB, cubeC;

function setup() {
  createCanvas(windowWidth, windowHeight, WEBGL);
  
  cubeA = new Cube(createVector(-200, 50), 100, -0.02, 'red');
  cubeB = new Cube(createVector(50, -100), 150, 0.01, 'lime');
  cubeC = new Cube(createVector(200, 150), 75, -0.03, 'blue');
}

function draw() {
  // draw
  background(0);
  noFill();
  
  // update cubes
  cubeA.update();
  cubeB.update();
  cubeC.update();
  
  // display cubes
  cubeA.display();
  cubeB.display();
  cubeC.display();
}
1 Like

Haha thanks Paul. Appreciated!