World to screen coordinates

Hi all, I’ve just got a quick question relating to converting world coordinates to screen coordinates. I’ve got a code snippet below that’s written in javascript rather than java, but it should be fairly understandable. My issue is that I’m performing a 3D perspective projection, but this function allows for points that are behind the camera (off the screen) to still be rendered. I’m wondering whether there’s a check that I can perform to check whether the point in question is outside of the view. I know it’s not a very good way of doing this. :stuck_out_tongue: I’m just playing around trying to get something made. If anyone knows how I perform this check I’d appreciate your help. Thanks


var xOffset = canvas.width >> 1;
var yOffset = canvas.height >> 1;

function world_to_screen(x, y, z) {
	// Vert relative to camera position
	var rel_x = x - xCam;
	var rel_y = y - yCam;
	var rel_z = z - zCam;

	// Vert relative to camera orientation
	var c = Math.cos(yRot * (Math.PI / 180.0));
	var s = Math.sin(yRot * (Math.PI / 180.0));
	var orient_x = c * rel_x + 0 * rel_y - s * rel_z;
	var orient_y = 0 * rel_x + 1 * rel_y + 0 * rel_z;
	var orient_z = s * rel_x + 0 * rel_y + c * rel_z;

	var proj_point = persp_point(orient_x, orient_y, orient_z);
	var screen_x = ((proj_point[0] * canvas.height) | 0) + xOffset;
	var screen_y = ((proj_point[1] * canvas.height) | 0) + yOffset;

	return [screen_x, screen_y];
}

function persp_point(x, y, z) {
	return [x / z, y / z];
}

Think you can do it using PerspectiveCamera


// setup camera
float fieldOfView = 90;
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
PerspectiveCamera camera = new PerspectiveCamera(fieldOfView, w, h);
camera.rotate(yRot,0,0,1);
camera.translate(xCam,yCam,zCam);
// setup clipping
camera.far = maxDistance
camera.near = -maxDistance
camera.update();

// get screen coord
Vector3 screenCoords = camera.project(new Vector3(x,y,z))

What you ask for (testing if a point is behind the camera) can be achieved with a simple dot product. If you have a vertex, V which you are projecting, your camera position, P, and the “forward” vector of the camera (which is the vector pointing in the direction of the camera), F then the test to see if V is in front of the camera is simply:

(V - P) . F >= 0

where . means the dot product (scalar product).

However there is a test which is probably more appropriate for you. It is called frustum culling. I won’t link a tutorial because they are abundant and a there are few different implementations. Essentially you create the frustum which describes the camera’s viewing volume and test to see if the vertex is inside this volume. Simple really. In fact I think the most popular implementation is just 6 lots of the above test so…

In case you hadn’t already notice, for both of these tests you would need to test each vertex of a face and you can only not render that face if every vertex is not in the camera’s viewing volume.

Last but not least: JavaScript on JGO? Tut tut. That is all I have to say on the matter especially considering the topic (read “argument”) that was, last I checked, still raging in the General Discussions.