Projecting 3d points from an ofMesh using ofMatrixStack

i wrote a short function for projecting an ofMesh to 2d given a camera and viewport:

void project(ofMesh& mesh, const ofCamera& camera, const ofRectangle& viewport) {
	ofMatrix4x4 modelViewProjectionMatrix = camera.getModelViewProjectionMatrix(viewport);
	for(int i = 0; i < mesh.getNumVertices(); i++) {
		ofVec3f& cur = mesh.getVerticesPointer()[i];
		ofVec3f CameraXYZ = cur * modelViewProjectionMatrix;
		cur.x = (CameraXYZ.x + 1.0f) / 2.0f * viewport.width + viewport.x;
		cur.y = (1.0f - CameraXYZ.y) / 2.0f * viewport.height + viewport.y;
		cur.z = 0;
	}
}

but i also want to be able to do this for any arbitrary collection of transformations. i have some old code that does this with gluUnProject() but i’m trying to understand the pattern behind ofMatrixStack and use that instead. i tried this but it doesn’t do what i expect:

void project(ofMesh& mesh) {
	ofMatrixStack matrixStack(*ofGetWindowPtr());
	ofMatrix4x4 modelViewProjectionMatrix = matrixStack.getModelViewProjectionMatrix();
	ofRectangle viewport = matrixStack.getCurrentViewport();
	for(int i = 0; i < mesh.getNumVertices(); i++) {
		ofVec3f& cur = mesh.getVerticesPointer()[i];
		ofVec3f CameraXYZ = cur * modelViewProjectionMatrix;
		cur.x = (CameraXYZ.x + 1.0f) / 2.0f * viewport.width + viewport.x;
		cur.y = (1.0f - CameraXYZ.y) / 2.0f * viewport.height + viewport.y;
		cur.z = 0;
	}
}

do i need to further prepare the modelViewProjectionMatrix somehow to account for the viewport?

1 Like

matrix stack is only to be used internally, it would actually be good to hide it somehow, and it’s just an utility class to accumulate transformations, calculate orientation… so if you create a new instance the matrix information will be empty.

i’ve just merged a PR that adds an ofGetCurrentMatrix() that will give you the current modelView or projection depending on the mode set with ofSetMatrixMode()