Example #1
0
/** A callback function that will get called whenever the tracker
 * provides us with new data. This may be called repeatedly for each
 * record that we have missed if many records have been delivered
 * since the last call to the VRPN mainloop() function. */
static void VRPN_CALLBACK handle_tracker(void *name, vrpn_TRACKERCB t)
{
	float fps = kuhl_getfps(&fps_state);
	if(fps_state.frame == 0)
		msg(INFO, "VRPN records per second: %.1f\n", fps);

	/* Some tracking systems return large values when a point gets
	 * lost. If the tracked point seems to be lost, ignore this
	 * update. */
	float pos[3];
	vec3f_set(pos, t.pos[0], t.pos[1], t.pos[2]);
	
	long microseconds = (t.msg_time.tv_sec* 1000000L) + t.msg_time.tv_usec;

	if(0)
	{
		printf("Current time %ld; VRPN record time: %ld\n", kuhl_microseconds(), microseconds);
		printf("Received position from vrpn: ");
		vec3f_print(pos);
	}
	
	if(vec3f_norm(pos) > 100)
		return;
	
	// Store the data in our map so that someone can use it later.
	std::string s = (char*)name;
	nameToCallbackData[s] = t;
	smooth(nameToCallbackData[s]);
}
Example #2
0
/** Performs a sanity check on the IPD to ensure that it is not too small, big, or reversed.

 @param viewmatrix View matrix for the viewportID
 @param viewportID The viewportID for this particular view matrix.
*/
static void viewmat_validate_ipd(float viewmatrix[16], int viewportID)
{
	// First, if viewportID=0, save the matrix so we can do the check when we are called with viewportID=1.
	static float viewmatrix0[16];
	static long viewmatrix0time;
	if(viewportID == 0)
	{
		mat4f_copy(viewmatrix0, viewmatrix);
		viewmatrix0time = kuhl_microseconds();
		return;
	}

	// If rendering viewportID == 1, and if there are two viewports,
	// assume that we are running in a stereoscopic configuration and
	// validate the IPD value.
	if(viewportID == 1 && viewports_size == 2)
	{
		float flip = 1;
		/* In most cases, viewportID=0 is the left eye. However,
		 * Oculus may cause this to get swapped. */
		if(viewmat_viewport_to_eye(0) == VIEWMAT_EYE_RIGHT)
			flip = -1;

		// Get the position matrix information
		float pos1[4], pos2[4];
		mat4f_getColumn(pos1, viewmatrix0, 3); // get last column
		mat4f_getColumn(pos2, viewmatrix,  3); // get last column

		// Get a vector between the eyes
		float diff[4];
		vec4f_sub_new(diff, pos1, pos2);
		vec4f_scalarMult_new(diff, diff, flip); // flip vector if necessary

		/* This message may be triggered if a person is moving quickly
		 * and/or when the FPS is low. This happens because the
		 * position/orientation of the head changed between the
		 * rendering of the left and right eyes. */
		float ipd = diff[0];
		long delay = kuhl_microseconds() - viewmatrix0time;
		if(ipd > .07 || ipd < .05)
		{
			msg(MSG_WARNING, "IPD=%.4f meters, delay=%ld us (IPD validation failed; occasional messages are OK!)\n", ipd, delay);
		}
		// msg(MSG_INFO, "IPD=%.4f meters, delay=%ld us\n", ipd, delay);

	}
}
Example #3
0
/** Performs a sanity check on how long it took us to render a
 * frame. At 60fps, we have approximately 16 milliseconds or 16000
 * microseconds per frame. If the time between two subsequent
 * renderings of viewportID 0 is too large, a warning message is
 * printed.
 *
 * Even though the average FPS over a period of time may be above 60,
 * the rendering might not appear smooth if an occasional frame misses
 * the time budget.
 */
static void viewmat_validate_fps(void)
{
	/* Set the time budget. If vblank syncing is turned on, we'd
	 * expect to always get a FPS close to the monitor. Setting this
	 * to 55 (instead of 60) will prevent messages from getting
	 * printed out constantly on such machines. */
#define targetFps 55 // older compilers won't let us use a static const variable to calculate another static const variable.
	static const int timeBudget = 1000000.0f / targetFps;
	
	/* Initialize our warning message counter and the time that the
	 * last frame was rendered. */
	static int warnMsgCount = 0;
	static long lastTime = -1;
	if(lastTime < 0) // if our first time called, initialize time and return.
	{
		lastTime = kuhl_microseconds();
		return;
	}

	/* If it took too long to render the frame, print a message. */
	long delay = kuhl_microseconds() - lastTime;
	// msg(MSG_INFO, "Time to render frame %d\n", delay);
	if(delay > timeBudget)
	{
		warnMsgCount++;

		/* Don't print the message if the first few frames took too
		 * long to render. Also, eventually stop printing the
		 * message. */
		if(warnMsgCount > 5 && warnMsgCount <= 100)
			msg(MSG_WARNING, "It took %ld microseconds to render a frame. Time budget for %d fps is %d microseconds.\n", delay, targetFps, timeBudget);
		if(warnMsgCount == 100)
			msg(MSG_WARNING, "That was your last warning about the time budget per frame.\n");
	}

	lastTime = kuhl_microseconds();
}