pebble / cube / src / camera.c

#include <stdint.h>
#include <math.h>
#include <pebble_os.h>
#include "draw.h"
#include "camera.h"

/* sin_lookup() takes deg * 32768 / 90.
 * returns -65536 to 65536
 */
static const int scale = 65536;

void
camera_setup(
	camera_t * c,
	int32_t eye_z,
	int32_t a[3]
)
{
	int32_t sx = sin_lookup(a[0]);
	int32_t cx = cos_lookup(a[0]);
	int32_t sy = sin_lookup(a[1]);
	int32_t cy = cos_lookup(a[1]);
	int32_t sz = sin_lookup(a[2]);
	int32_t cz = cos_lookup(a[2]);

	c->r[0][0] = ( cy * cz) / scale;
	c->r[0][1] = ((-cy * sz) + (sx * sy * cz) / scale) / scale;
	c->r[0][2] = (( sx * sz) + (cx * sy * cz) / scale) / scale;

	c->r[1][0] = ( cx * sz) / scale;
	c->r[1][1] = (( cx * cz) + (sx * sy * sz) / scale) / scale;
	c->r[1][2] = ((-sx * cz) + (cx * sy * sz) / scale) / scale;

	c->r[2][0] = (-sy);
	c->r[2][1] = ( sx * cy) / scale;
	c->r[2][2] = ( cx * cy) / scale;

	c->eye_z = eye_z;
}


int
camera_project(
	const camera_t * c,
	const vertex_t * const v,
	pixel_t * const pixel
)
{
	int32_t p[3] = { 0, 0, c->eye_z * scale };
	for (int i = 0 ; i < 3 ; i++)
		for (int j = 0 ; j < 3 ; j++)
			p[i] += c->r[i][j] * v->x[j];

	if (p[2] <= 0)
	{
		// The point is behind us
		pixel->x = pixel->y = -1;
		return 0;
	}

	// Smaller == wider angle view
	const int32_t zoom = 1;

	// Transform to screen coordinate frame,
	// limiting to the actual boundaries
	int32_t px = (p[1] * c->eye_z * zoom) / p[2] + VSCREEN_WIDTH / 2;
	if (px < 0)
		px = 0;
	if (px >= VSCREEN_WIDTH-1)
		px = VSCREEN_WIDTH-1;
	pixel->x = px;

	int32_t py = (p[0] * c->eye_z * zoom) / p[2] + VSCREEN_HEIGHT / 2;
	if (py < 0)
		py = 0;
	if (py >= VSCREEN_HEIGHT-1)
		py = VSCREEN_HEIGHT-1;
	pixel->y = py;

	return 1;
}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.