فهرست منبع

Merge branch 'master' into device-class-and-flags

TheOnlyJoey 7 سال پیش
والد
کامیت
cf42f05a1b

+ 3 - 3
cmake/FindSDL2.cmake

@@ -4,12 +4,12 @@
 # SDL2_FOUND, if false, do not try to link to SDL2
 # SDL2_INCLUDE_DIR, where to find SDL.h
 #
-# This module responds to the the flag:
+# This module responds to the flag:
 # SDL2_BUILDING_LIBRARY
 # If this is defined, then no SDL2_main will be linked in because
 # only applications need main().
 # Otherwise, it is assumed you are building an application and this
-# module will attempt to locate and set the the proper link flags
+# module will attempt to locate and set the proper link flags
 # as part of the returned SDL2_LIBRARY variable.
 #
 # Don't forget to include SDL2main.h and SDL2main.m your project for the
@@ -130,7 +130,7 @@ IF(NOT APPLE)
 ENDIF(NOT APPLE)
 
 # MinGW needs an additional library, mwindows
-# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows
+# Its total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows
 # (Actually on second look, I think it only needs one of the m* libraries.)
 IF(MINGW)
   SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW")

+ 1 - 1
examples/opengl/gl.c

@@ -52,7 +52,7 @@ void init_gl(gl_ctx* ctx, int w, int h)
 
 	SDL_GL_SetSwapInterval(1);
 
-	// Disable ctrl-c catching on linux (and OS X?) 
+	// Disable ctrl-c catching on Linux (and OS X?)
 #ifdef __unix
 	signal(SIGINT, SIG_DFL);
 #endif

+ 3 - 3
examples/opengl/main.c

@@ -148,13 +148,13 @@ int main(int argc, char** argv)
 	//distortion coefficients
 	ohmd_device_getf(hmd, OHMD_UNIVERSAL_DISTORTION_K, &(distortion_coeffs[0]));
 	ohmd_device_getf(hmd, OHMD_UNIVERSAL_ABERRATION_K, &(aberr_scale[0]));
-	//calculate lens centers (assuming the eye separation is the distance betweenteh lense centers)
+	//calculate lens centers (assuming the eye separation is the distance between the lens centers)
 	ohmd_device_getf(hmd, OHMD_LENS_HORIZONTAL_SEPARATION, &sep);
 	ohmd_device_getf(hmd, OHMD_LENS_VERTICAL_POSITION, &(left_lens_center[1]));
 	ohmd_device_getf(hmd, OHMD_LENS_VERTICAL_POSITION, &(right_lens_center[1]));
 	left_lens_center[0] = viewport_scale[0] - sep/2.0f;
 	right_lens_center[0] = sep/2.0f;
-	//asume calibration was for lens view to which ever edge of screen is further away from lens center
+	//assume calibration was for lens view to which ever edge of screen is further away from lens center
 	float warp_scale = (left_lens_center[0] > right_lens_center[0]) ? left_lens_center[0] : right_lens_center[0];
 	float warp_adj = 1.0f;
 
@@ -238,7 +238,7 @@ int main(int argc, char** argv)
 						printf("lens separation: %04f\n", sep);
 						printf("IPD: %0.4f\n", ipd);
 						printf("warp_scale: %0.4f\r\n", warp_scale);
-						printf("distoriton coeffs: [%0.4f, %0.4f, %0.4f, %0.4f]\n", distortion_coeffs[0], distortion_coeffs[1], distortion_coeffs[2], distortion_coeffs[3]);
+						printf("distortion coeffs: [%0.4f, %0.4f, %0.4f, %0.4f]\n", distortion_coeffs[0], distortion_coeffs[1], distortion_coeffs[2], distortion_coeffs[3]);
 						printf("aberration coeffs: [%0.4f, %0.4f, %0.4f]\n", aberr_scale[0], aberr_scale[1], aberr_scale[2]);
 						printf("left_lens_center: [%0.4f, %0.4f]\n", left_lens_center[0], left_lens_center[1]);
 						printf("right_lens_center: [%0.4f, %0.4f]\n", right_lens_center[0], right_lens_center[1]);

+ 2 - 2
src/drv_deepoon/deepoon.c

@@ -254,13 +254,13 @@ static ohmd_device* open_device(ohmd_driver* driver, ohmd_device_desc* desc)
 	ohmd_set_default_device_properties(&priv->base.properties);
 
 	// Set device properties
-	//NOTE: These values are estimations, no one has taken one appart to check
+	//NOTE: These values are estimations, no one has taken one apart to check
 	priv->base.properties.hsize = 0.1698f;
 	priv->base.properties.vsize = 0.0936f;
 	priv->base.properties.hres = 1920;
 	priv->base.properties.vres = 1080;
 	priv->base.properties.lens_sep = 0.0849f;
-	priv->base.properties.lens_vpos = 0.0468f;;
+	priv->base.properties.lens_vpos = 0.0468f;
 	priv->base.properties.fov = DEG_TO_RAD(110.0); // TODO calculate.
 	priv->base.properties.ratio = ((float)1920 / (float)1080) / 2.0f;
 

+ 35 - 5
src/drv_oculus_rift/packet.c

@@ -10,6 +10,7 @@
 #include <stdio.h>
 #include "rift.h"
 
+#define SKIP8 (buffer++)
 #define SKIP_CMD (buffer++)
 #define READ8 *(buffer++);
 #define READ16 *buffer | (*(buffer + 1) << 8); buffer += 2;
@@ -21,6 +22,34 @@
 #define WRITE16(_val) WRITE8((_val) & 0xff); WRITE8(((_val) >> 8) & 0xff);
 #define WRITE32(_val) WRITE16((_val) & 0xffff) *buffer; WRITE16(((_val) >> 16) & 0xffff);
 
+bool decode_position_info(pkt_position_info* p, const unsigned char* buffer, int size)
+{
+	if(size != 30) {
+		LOGE("invalid packet size (expected 30 but got %d)", size);
+		return false;
+	}
+
+	SKIP_CMD;
+	SKIP8;
+	SKIP8;
+	p->flags = READ8;
+	p->pos_x = READ32;
+	p->pos_y = READ32;
+	p->pos_z = READ32;
+	p->dir_x = READ16;
+	p->dir_y = READ16;
+	p->dir_z = READ16;
+	SKIP8;
+	SKIP8;
+	p->index = READ8;
+	SKIP8;
+	p->num = READ8;
+	SKIP8;
+	p->type = READ8;
+
+	return true;
+}
+
 bool decode_sensor_range(pkt_sensor_range* range, const unsigned char* buffer, int size)
 {
 	if(!(size == 8 || size == 9)){
@@ -195,7 +224,7 @@ int encode_keep_alive(unsigned char* buffer, const pkt_keep_alive* keep_alive)
 	return 5; // keep alive packet size
 }
 
-int encode_enable_components(unsigned char* buffer, bool display, bool audio)
+int encode_enable_components(unsigned char* buffer, bool display, bool audio, bool leds)
 {
 	uint8_t flags = 0;
 
@@ -203,12 +232,13 @@ int encode_enable_components(unsigned char* buffer, bool display, bool audio)
 	WRITE16(0); // last command ID
 
 	if (display)
-		flags |= 1;
+		flags |= RIFT_COMPONENT_DISPLAY;
 	if (audio)
-		flags |= 2;
-//	flags |= 4; // I don't know what it is. Wireless?
+		flags |= RIFT_COMPONENT_AUDIO;
+	if (leds)
+		flags |= RIFT_COMPONENT_LEDS;
 	WRITE8(flags);
-	return 4;
+	return 4; // component flags packet size
 }
 
 void dump_packet_sensor_range(const pkt_sensor_range* range)

+ 47 - 3
src/drv_oculus_rift/rift.c

@@ -33,6 +33,12 @@ typedef struct {
 	double last_keep_alive;
 	fusion sensor_fusion;
 	vec3f raw_mag, raw_accel, raw_gyro;
+
+	struct {
+		vec3f pos;
+	} imu;
+
+	rift_led *leds;
 } rift_priv;
 
 typedef enum {
@@ -81,7 +87,7 @@ static void set_coordinate_frame(rift_priv* priv, rift_coordinate_frame coordfra
 	}
 
 	// read the state again, set the hw_coordinate_frame to match what
-	// the hardware actually is set to just incase it doesn't stick.
+	// the hardware actually is set to just in case it doesn't stick.
 	size = get_feature_report(priv, RIFT_CMD_SENSOR_CONFIG, buf);
 	if(size <= 0){
 		LOGW("could not set coordinate frame");
@@ -243,7 +249,7 @@ static ohmd_device* open_device(ohmd_driver* driver, ohmd_device_desc* desc)
 	if(!priv->handle) {
 		char* path = _hid_to_unix_path(desc->path);
 		ohmd_set_error(driver->ctx, "Could not open %s.\n"
-		                            "Check your rights: "
+		                            "Check your permissions: "
 		                            UDEV_WIKI_URL, path);
 		free(path);
 		goto cleanup;
@@ -286,9 +292,47 @@ static ohmd_device* open_device(ohmd_driver* driver, ohmd_device_desc* desc)
 	// Turn the screens on
 	if (desc->revision == REV_CV1)
 	{
-		size = encode_enable_components(buf, true, true);
+		size = encode_enable_components(buf, true, true, true);
 		if (send_feature_report(priv, buf, size) == -1)
 			LOGE("error turning the screens on");
+
+		hid_write(priv->handle, rift_enable_leds_cv1, sizeof(rift_enable_leds_cv1));
+	}
+	else if (desc->revision == REV_DK2)
+	{
+		hid_write(priv->handle, rift_enable_leds_dk2, sizeof(rift_enable_leds_dk2));
+	}
+
+	pkt_position_info pos;
+	int first_index = -1;
+
+	//Get LED positions
+	while (true) {
+		size = get_feature_report(priv, RIFT_CMD_POSITION_INFO, buf);
+		if (size <= 0 || !decode_position_info(&pos, buf, size) ||
+		    first_index == pos.index) {
+			break;
+		}
+
+		if (first_index < 0) {
+			first_index = pos.index;
+			priv->leds = calloc(pos.num, sizeof(rift_led));
+		}
+
+		if (pos.flags == 1) { //reports 0's
+			priv->imu.pos.x = (float)pos.pos_x;
+			priv->imu.pos.y = (float)pos.pos_y;
+			priv->imu.pos.z = (float)pos.pos_z;
+		} else if (pos.flags == 2) {
+			rift_led *led = &priv->leds[pos.index];
+			led->pos.x = (float)pos.pos_x;
+			led->pos.y = (float)pos.pos_y;
+			led->pos.z = (float)pos.pos_z;
+			led->dir.x = (float)pos.dir_x;
+			led->dir.y = (float)pos.dir_y;
+			led->dir.z = (float)pos.dir_z;
+			ovec3f_normalize_me(&led->dir);
+		}
 	}
 
 	// set keep alive interval to n seconds

+ 35 - 2
src/drv_oculus_rift/rift.h

@@ -19,7 +19,8 @@ typedef enum {
 	RIFT_CMD_RANGE = 4,
 	RIFT_CMD_KEEP_ALIVE = 8,
 	RIFT_CMD_DISPLAY_INFO = 9,
-	RIFT_CMD_ENABLE_COMPONENTS = 0x1d
+	RIFT_CMD_ENABLE_COMPONENTS = 0x1d,
+	RIFT_CMD_POSITION_INFO = 15,
 } rift_sensor_feature_cmd;
 
 typedef enum {
@@ -38,6 +39,12 @@ typedef enum {
 	RIFT_DT_DISTORTION
 } rift_distortion_type;
 
+typedef enum {
+	RIFT_COMPONENT_DISPLAY = 1,
+	RIFT_COMPONENT_AUDIO = 2,
+	RIFT_COMPONENT_LEDS = 4
+} rift_component_type;
+
 // Sensor config flags
 #define RIFT_SCF_RAW_MODE           0x01
 #define RIFT_SCF_CALIBRATION_TEST   0x02
@@ -47,7 +54,13 @@ typedef enum {
 #define RIFT_SCF_COMMAND_KEEP_ALIVE 0x20
 #define RIFT_SCF_SENSOR_COORDINATES 0x40
 
+static const unsigned char rift_enable_leds_dk2[17] = {
+	0x0c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x5E, 0x01, 0x1A, 0x41, 0x00, 0x00, 0x7F,
+};
 
+static const unsigned char rift_enable_leds_cv1[17] = {
+	0x0c, 0x00, 0x00, 0xFF, 0x05, 0x00, 0x8F, 0x01, 0x00, 0x4B, 0x00, 0x00, 0x7F,
+};
 
 typedef struct {
 	uint16_t command_id;
@@ -94,18 +107,38 @@ typedef struct {
 	uint16_t keep_alive_interval;
 } pkt_keep_alive;
 
+typedef struct {
+	uint8_t flags;
+	int32_t pos_x;
+	int32_t pos_y;
+	int32_t pos_z;
+	int16_t dir_x;
+	int16_t dir_y;
+	int16_t dir_z;
+	uint8_t index;
+	uint8_t num;
+	uint8_t type;
+} pkt_position_info;
+
+typedef struct {
+	// Relative position in micrometers
+	vec3f pos;
+	// Normal
+	vec3f dir;
+} rift_led;
 
 bool decode_sensor_range(pkt_sensor_range* range, const unsigned char* buffer, int size);
 bool decode_sensor_display_info(pkt_sensor_display_info* info, const unsigned char* buffer, int size);
 bool decode_sensor_config(pkt_sensor_config* config, const unsigned char* buffer, int size);
 bool decode_tracker_sensor_msg(pkt_tracker_sensor* msg, const unsigned char* buffer, int size);
 bool decode_tracker_sensor_msg_dk2(pkt_tracker_sensor* msg, const unsigned char* buffer, int size);
+bool decode_position_info(pkt_position_info* p, const unsigned char* buffer, int size);
 
 void vec3f_from_rift_vec(const int32_t* smp, vec3f* out_vec);
 
 int encode_sensor_config(unsigned char* buffer, const pkt_sensor_config* config);
 int encode_keep_alive(unsigned char* buffer, const pkt_keep_alive* keep_alive);
-int encode_enable_components(unsigned char* buffer, bool display, bool audio);
+int encode_enable_components(unsigned char* buffer, bool display, bool audio, bool leds);
 
 void dump_packet_sensor_range(const pkt_sensor_range* range);
 void dump_packet_sensor_config(const pkt_sensor_config* config);

+ 1 - 1
src/fusion.c

@@ -96,7 +96,7 @@ void ofusion_update(fusion* me, float dt, const vec3f* ang_vel, const vec3f* acc
 			}
 		}
 
-		// preform gravity tilt correction
+		// perform gravity tilt correction
 		if(me->grav_error_angle > min_tilt_error){
 			float use_angle;
 			// if less than 2000 iterations have passed, set the up axis to the correction value outright

+ 23 - 2
src/openhmd.c

@@ -5,7 +5,7 @@
  * Distributed under the Boost 1.0 licence, see LICENSE for full text.
  */
 
-/* Main Lib Implemenation */
+/* Main Lib Implementation */
 
 #include "openhmdi.h"
 #include "shaders.h"
@@ -26,6 +26,8 @@ ohmd_context* OHMD_APIENTRY ohmd_ctx_create(void)
 		return NULL;
 	}
 
+	ohmd_monotonic_init(ctx);
+
 #if DRIVER_OCULUS_RIFT
 	ctx->drivers[ctx->num_drivers++] = ohmd_create_oculus_rift_drv(ctx);
 #endif
@@ -582,7 +584,7 @@ void ohmd_calc_default_proj_matrices(ohmd_device_properties* props)
 	// same projection matrix with the exception of the offset.
 	omat4x4f_init_perspective(&proj_base, props->fov, props->ratio, props->znear, props->zfar);
 
-	// Setup the two adjusted projection matricies. Each is setup to deal
+	// Setup the two adjusted projection matrices. Each is setup to deal
 	// with the fact that the lens is not in the center of the screen.
 	// These matrices only change of the hardware changes, so static.
 	mat4x4f translate;
@@ -608,3 +610,22 @@ void ohmd_set_universal_aberration_k(ohmd_device_properties* props, float r, flo
 	props->universal_aberration_k[1] = g;
 	props->universal_aberration_k[2] = b;
 }
+
+uint64_t ohmd_monotonic_per_sec(ohmd_context* ctx)
+{
+	return ctx->monotonic_ticks_per_sec;
+}
+
+/*
+ * Grabbed from druntime, good thing it's BOOST v1.0 as well.
+ */
+uint64_t ohmd_monotonic_conv(uint64_t ticks, uint64_t srcTicksPerSecond, uint64_t dstTicksPerSecond)
+{
+	// This would be more straightforward with floating point arithmetic,
+	// but we avoid it here in order to avoid the rounding errors that that
+	// introduces. Also, by splitting out the units in this way, we're able
+	// to deal with much larger values before running into problems with
+	// integer overflow.
+	return ticks / srcTicksPerSecond * dstTicksPerSecond +
+		ticks % srcTicksPerSecond * dstTicksPerSecond / srcTicksPerSecond;
+}

+ 6 - 0
src/openhmdi.h

@@ -133,10 +133,16 @@ struct ohmd_context {
 
 	bool update_request_quit;
 
+	uint64_t monotonic_ticks_per_sec;
+
 	char error_msg[OHMD_STR_SIZE];
 };
 
 // helper functions
+void ohmd_monotonic_init(ohmd_context* ctx);
+uint64_t ohmd_monotonic_get(ohmd_context* ctx);
+uint64_t ohmd_monotonic_per_sec(ohmd_context* ctx);
+uint64_t ohmd_monotonic_conv(uint64_t ticks, uint64_t srcTicksPerSecond, uint64_t dstTicksPerSecond);
 void ohmd_set_default_device_properties(ohmd_device_properties* props);
 void ohmd_calc_default_proj_matrices(ohmd_device_properties* props);
 void ohmd_set_universal_distortion_k(ohmd_device_properties* props, float a, float b, float c, float d);

+ 47 - 0
src/platform-posix.c

@@ -41,6 +41,53 @@ double ohmd_get_tick()
 }
 #endif
 
+#ifndef CLOCK_MONOTONIC
+
+static const uint64_t NUM_1_000_000 = 1000000;
+
+void ohmd_monotonic_init(ohmd_context* ctx)
+{
+	ctx->monotonic_ticks_per_sec = NUM_1_000_000;
+}
+
+uint64_t ohmd_monotonic_get(ohmd_context* ctx)
+{
+	struct timeval now;
+	gettimeofday(&now, NULL);
+	return now.tv_sec * NUM_1_000_000 + now.tv_usec;
+}
+
+#else
+
+static const uint64_t NUM_1_000_000_000 = 1000000000;
+
+void ohmd_monotonic_init(ohmd_context* ctx)
+{
+		struct timespec ts;
+		if (clock_getres(CLOCK_MONOTONIC, &ts) !=  0) {
+			ctx->monotonic_ticks_per_sec = NUM_1_000_000_000;
+			return;
+		}
+
+		ctx->monotonic_ticks_per_sec =
+			ts.tv_nsec >= 1000 ?
+			NUM_1_000_000_000 :
+			NUM_1_000_000_000 / ts.tv_nsec;
+}
+
+uint64_t ohmd_monotonic_get(ohmd_context* ctx)
+{
+	struct timespec now;
+	clock_gettime(CLOCK_MONOTONIC, &now);
+
+	return ohmd_monotonic_conv(
+		now.tv_sec * NUM_1_000_000_000 + now.tv_nsec,
+		NUM_1_000_000_000,
+		ctx->monotonic_ticks_per_sec);
+}
+
+#endif
+
 void ohmd_sleep(double seconds)
 {
 	struct timespec sleepfor;

+ 15 - 0
src/platform-win32.c

@@ -30,6 +30,21 @@ double ohmd_get_tick()
 	return (high * 4294967296.0 + low) / 10000000;
 }
 
+static const uint64_t NUM_10_000_000 = 10000000;
+
+void ohmd_monotonic_init(ohmd_context* ctx)
+{
+	ctx->monotonic_ticks_per_sec = NUM_10_000_000;
+}
+
+uint64_t ohmd_monotonic_get(ohmd_context* ctx)
+{
+	FILETIME filetime;
+	GetSystemTimeAsFileTime(&filetime);
+
+	return ((uint64_t)filetime.dwHighDateTime << 32) | filetime.dwLowDateTime;
+}
+
 // TODO higher resolution
 void ohmd_sleep(double seconds)
 {