Massive Poly Rendering in Processing
Following up on Basic Rendering, I added some 100,000 spheres to my render scene for the sweetWire music video. I am controlling camera with scripted camera animations and beautiful easing functions by Roger Antonsen, who co-authored this code overall. The code is a bit longer here, but it’s nothing compared to the trouble I get trying to do the same thing in Maya. Of course this will only run if you feed it lots of pointCloud data.
int startFrame = 1;
int currFrame = startFrame;
int endFrame = 294; //last frame plus one
int radius = -3000;
int close = 0;
float sphereSize = 2.3;
boolean render = false ;
Table table;
ArrayList<PVector> vectors;
String filename = "2020_1_19_13_7_11";
int frameWidth = 1920;
int frameHeight = 1080;
void settings() {
size(frameWidth, frameHeight, P3D);
smooth(8);
}
void setup() {
perspective(PI/4.0, 1.75, 1, 100000);
//data
table = loadTable("../3D/captures/"+filename+"/frame"+startFrame+".csv");
vectors = new ArrayList<PVector>();
for (int i = 0; i< table.getRowCount(); i++) {
float xPos = table.getFloat(i, 0);
float yPos = table.getFloat(i, 1);
float zPos = table.getFloat(i, 2);
if (mag(xPos, yPos, zPos) > 0) {
vectors.add(new PVector(xPos, yPos, zPos - 2000));
}
}
}
float ease(float p, float g) {
p = constrain(p, 0, 1);
if (p < 0.5)
return 0.5 * pow(2*p, g);
else
return 1 - 0.5 * pow(2*(1 - p), g);
}
void draw() {
background(255);
if (currFrame <= endFrame) {
loadStrip(currFrame);
}
lights();
clear();
noStroke();
for (PVector P : vectors) {
pushMatrix();
translate(P.x, P.y, P.z);
sphereDetail(6);
noStroke();
ambient(255);
emissive(255);
sphere(sphereSize);
popMatrix();
}
//linear number
float centerX = 0 + 0.0 * width/2.0;
float centerY = 0 + 0.0 * height/2.0;
float centerZ = 0 + 0;
float currLinear = (currFrame % endFrame) / float(endFrame);
float currCubic = ease(currLinear, 2.1);
float angle = TWO_PI * currCubic+1.3;
radius = int(radius + (12.5*currCubic));
float eyeX = radius * cos(angle)+300;
float eyeY = 500;//height, remember higher number is lower
float eyeZ = radius * sin(angle);
//float currCubic = TWO_PI * ease(currLinear, 2.1);
float spin = sin(currCubic*TWO_PI)/3.0;
float upX = 1 * cos(spin + HALF_PI);
float upY = 1 * sin(spin + HALF_PI);
float upZ = 0;
camera(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
if (render == true && currFrame <= endFrame) {
saveFrame(filename+"_preview/"+filename+"_frame_"+currFrame+".png");
println ("saved" + filename+"_frame_"+currFrame+".png");
}
if (currFrame <= endFrame) {
currFrame++;
}
}
void keyPressed() {
if (key == 'a') {
//render out the whole thing, the GO button
currFrame = 1;
render = true;
}
if (keyCode == RIGHT) {
//forward
if (currFrame <= endFrame) {
currFrame++;
println("now at "+currFrame);
} else {
currFrame = 1;
};
table = loadTable("../3D/captures/"+filename+"/frame"+currFrame+".csv");
}
if (keyCode == LEFT) {
//back
if (currFrame > 1) {
currFrame--;
println("now at "+currFrame);
} else {
currFrame = endFrame;
}
table = loadTable("../3D/captures/"+filename+"/frame"+currFrame+".csv");
}
if (key == 'f') {
//fast forward
if (currFrame <= endFrame) {
currFrame = currFrame + 10;
println("now at "+currFrame);
} else {
currFrame = 1;
}
table = loadTable("../3D/captures/"+filename+"/frame"+currFrame+".csv");
}
if (key == 's') {
//save a frame
saveFrame("screenCapture"+currFrame+".png");
println("saved frame at "+currFrame);
}
}
void loadStrip(int l) {
table = loadTable("../3D/captures/"+filename+"/frame"+l+".csv");
vectors = new ArrayList<PVector>();
for (int i = 0; i< table.getRowCount(); i++) {
float xPos = table.getFloat(i, 0);
float yPos = table.getFloat(i, 1);
float zPos = table.getFloat(i, 2);
if (mag(xPos, yPos, zPos) > 0) {
vectors.add(new PVector(xPos, yPos, zPos - 2000));
}
}
}