I've just been messing with this code from Pitaru and the old forum. I'm having a problem with the modelX, modelY, modelZ and screenX, screenY matrix calcs.
Can anyone see how to solve the problem of the long Z addition that occurs after the transformXYX();
It may have something to do with the mouse position. What I'd like to be able to do is always draw from the last position and not have the line draw from the last position to the post-rotated mouse coords.
It seems to require a separate cursor that follows the model transform and starts drawing again from the last position without the leap to mouseX and Y shift caused by using rotate. Is there a way of locking the mouse, or a cursor to the model, yet still allows for mouse movement ?
Sorry for the waffle!!
Code:
int pointCount = 255; // max number of vertexes to save in the shape
// 3 arrays for 3 dimensions...
float[] xpoints = new float[pointCount];
float[] ypoints = new float[pointCount];
float[] zpoints = new float[pointCount];
float x,y,z,ax,ay,az;
int first, last;
float angleX, angleY;
int lastMouseX = 0;
int lastMouseY = 0;
boolean doOnce = false;
void setup()
{
size(400, 400, OPENGL);
first = 0;
last = pointCount - 1;
//smooth();
}
void draw() {
background(255);
applyRotation();
// If mouse btn is pressed, start rotating the stage ...
if (mousePressed){
doOnce = true;
setRotation();
drawShape();
// When mouse btn is not pressed, continue drawing the 'wire'...
} else {
// If mouse btn was just release, do this once...
if ( doOnce){
doOnce = false;
drawShape();
transformXYZ();
// Otherwise, continue drawing the 'wire' ...
} else {
evolveShape();
captureMouse();
drawShape();
}
}
}
// This is Ben Fry's algorythm for re-calculating all existing vertexes, after the stage has been rotated.
void transformXYZ(){
// for every existing vertex in the array...
for(int i = 0; i < pointCount; i++){
x = xpoints[i];
y = ypoints[i];
z = zpoints[i];
// The guts of the algorythm, which uses the 'model matrix' (m00, m01 ..).
// This 'model matrix' is affected by all stage transformations/rotations.
/*
ax = (g.m00*x + g.m01*y + g.m02*z + g.m03);
ay = (g.m10*x + g.m11*y + g.m12*z + g.m13);
az = (g.m20*x + g.m21*y + g.m22*z + g.m23);
*/
ax = modelX(x, y, z);
ax+= screenX(x,y,z);
ay = modelY(x, y, z);
ay+= screenY(x,y,z);
az = modelZ(x, y,z);
az+= screenZ(x,y,z);
xpoints[i] = ax;
ypoints[i] = ay;
zpoints[i] = az;
}
angleX = 0;
angleY = 0;
}
// Draw the 'wire' onto the stage...
void drawShape(){
stroke(100);
beginShape(LINE_STRIP);
for(int j = 0; j < pointCount; j++) {
int i = (first + j) % pointCount;
// stroke( 100 + 155 -(int)((j*100/pointCount) *1.55f) );
curveVertex(xpoints[i], ypoints[i], zpoints[i]);
}
endShape();
}
// We maitain cpu performance by limitting the number of vertices in the 'wire'.
// The size of wire is set by the variable 'pointCount'.
void evolveShape(){
last++;
if (last == pointCount) last = 0;
first++;
if (first == pointCount) first = 0;
}
// Rotate the stage according to the mouse-drag.
void setRotation(){
// If the mouse was dragged more than 3 pixels...
if ( abs(mouseX- lastMouseX) > 1){
angleX += (mouseX- lastMouseX - 1)*0.0008f ;
if(angleX > TWO_PI) { angleX = 0; }
}
// same for Y..
if ( abs(mouseY- lastMouseY) > 1){
angleY += (mouseY- lastMouseY - 1)*0.0008f ;
if(angleY > TWO_PI) { angleY = 0; }
}
}
// Do the actual rotation/transformation of the stage.
void applyRotation(){
translate(width/2, height/2, 0);
rotateY(angleX);
rotateX(-angleY);
translate(-width/2, -height/2, 0);
}
// Capture the mouse coordinates.
void captureMouse(){
xpoints[last] = mouseX;
ypoints[last] = mouseY;
zpoints[last] = 0;
// Buffer the latest coordinates.
lastMouseX = mouseX;
lastMouseY = mouseY;
}