Skip to content

Instantly share code, notes, and snippets.

@GoToLoop
Last active August 23, 2020 02:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save GoToLoop/e35ac69e9bd4dbbcce557218c3b20588 to your computer and use it in GitHub Desktop.
Save GoToLoop/e35ac69e9bd4dbbcce557218c3b20588 to your computer and use it in GitHub Desktop.
Push/Pop Limit Workaround (Java Mode)
/**
* Push/Pop Limit Workaround (v1.0.1)
* GoToLoop (2020/Aug/22)
*
* Discourse.Processing.org/t/too-many-calls-to-pushmatrix/23411/8
* Gist.GitHub.com/GoToLoop/e35ac69e9bd4dbbcce557218c3b20588
*/
// Comment out the package statement below if it's inside a ".java" file:
package processing.core;
import processing.opengl.PGraphicsOpenGL;
//static // Comment the keyword static if it's inside a ".java" file!
public class MatrixFrameGL implements Cloneable
{
public PMatrix modelview, modelviewInv, camera, cameraInv;
public MatrixFrameGL() {
}
public MatrixFrameGL(final PGraphics pg) {
pushMatrix(pg);
}
public MatrixFrameGL pushMatrix(final PGraphics pg) {
return pushMatrix((PGraphicsOpenGL) pg);
}
public MatrixFrameGL pushMatrix(final PGraphicsOpenGL pg) {
modelview = pg.modelview.get();
modelviewInv = pg.modelviewInv.get();
camera = pg.camera.get();
cameraInv = pg.cameraInv.get();
return this;
}
public MatrixFrameGL popMatrix(final PGraphics pg) {
return popMatrix((PGraphicsOpenGL) pg);
}
public MatrixFrameGL popMatrix(final PGraphicsOpenGL pg) {
pg.modelview.set(modelview);
pg.modelviewInv.set(modelviewInv);
pg.camera.set(camera);
pg.cameraInv.set(cameraInv);
return this;
}
@Override public MatrixFrameGL clone() {
try {
final MatrixFrameGL frame = (MatrixFrameGL) super.clone();
frame.modelview = modelview.get();
frame.modelviewInv = modelviewInv.get();
frame.camera = camera.get();
frame.cameraInv = cameraInv.get();
return frame;
}
catch (final CloneNotSupportedException e) {
throw new RuntimeException(e);
}
}
}
/**
* Push/Pop Limit Workaround (v1.0.1)
* GoToLoop (2020/Aug/22)
*
* Discourse.Processing.org/t/too-many-calls-to-pushmatrix/23411/8
* Gist.GitHub.com/GoToLoop/e35ac69e9bd4dbbcce557218c3b20588
*/
import java.util.Queue;
import java.util.ArrayDeque;
final Queue<MatrixFrameGL> frames = new ArrayDeque<MatrixFrameGL>();
static final int BOXES = 32, SIZE = 6, MOV = SIZE << 2;
static final float ROT = TAU / BOXES;
void setup() {
size(1200, 200, P3D);
noLoop();
stroke(#FFFF00); // yellow
}
void draw() {
clear();
translate(0, height >> 2);
fill(#FF0000); // red
recursiveBoxes(BOXES, SIZE, MOV, ROT, g, null); // 32 boxes
translate(0, height >> 1);
fill(#0000FF); // blue
recursiveBoxes(BOXES * 3 >> 1, SIZE, MOV, ROT, g, frames); // 48 boxes
}
static final void recursiveBoxes(
final int qty, final int size, final int moveX, final float rot,
final PGraphics pg,
final Queue<MatrixFrameGL> frames // pass null to use regular push/pop
)
{
if (qty <= 0) return;
if (frames != null) frames.add(new MatrixFrameGL(pg));
else pg.pushMatrix();
pg.translate(moveX, 0);
pg.rotateX(rot);
pg.box(size);
recursiveBoxes(qty - 1, size, moveX, rot, pg, frames);
if (frames != null) frames.remove().popMatrix(pg);
else pg.popMatrix();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment