Sixense Truemotion: Hyrda Controllers

Not sure if I should be releasing this. glancing around HOWEVER I have gotten the inside word that Sixense will be releasing an API for Unity 3D for the use of there Hydra motion controllers. This won’t be released for a couple of months, (neither will the hardware) but it is something to look forward to! To get more info on the company and technology follow the link below!

Sixense

Or with these youtube videos

why is their website in Flash, yet not really use any of the benefits of Flash?

Also, I couldn’t even find a clear picture of whatever the product was.

They are redesigning there website, in like a week I believe. We will see what it looks like then.

Yea I was disappointed in that also, here are a few youtube videos with them demoing the hardware.
http://www.youtube.com/watch?v=K0Z6hMBTnEM
http://www.youtube.com/watch?v=1jeLjaSa0bA
http://www.youtube.com/watch?v=auHSErC6ssE
That should give you a good preview.

Bumb I think some users might find this interesting.

I’m definitely intrigued, the video looked great.

Trust me when you get these controllers in your hands, it sure feels awesome.

Any update on the Unity integration? I’d like to know more about it before buying the controllers.

http://sixense.com/forum/phpBB3/viewtopic.php?f=2&t=73

Apparently it’s integrated, but you have to email them.

I’m betting it requires Pro.

Any updates to this? I am trying to build my own plugin using their SDK documentation and .dll but I am running into some problems with their data structures.

******Edited out the code because of changes made it is no longer relevant

The errors are Cannot take the address of, get the size of, or declare a pointer to a managed type. I am sure its something stupid I am missing with the pointers that aren’t allowed in c#. Can anyone give me a hand, or point me towards someone who already has this?

Thanks guys.

I have been continuing to work on this, and I am getting somewhere. I can call the functions that don’t use pointers or reference stuff real easy.

Removed Code because it has been figured out***********

When I try to get the data from the actual controllers though it crashes(un-commenting the code above causes it to crash) . It probably has something to do with passing the references.

Any help here would be greatly appreciated.

Thanks for the code Germy, it pointed me in the right direction.

Looks like your data struct is a bit off, a couple of vars missing and also things like defining pos as float[ ] doesn’t tell unity how many floats to reserve. I’m messing with it now, but I’m not familiar with c#… I’m using a Vector3 for pos ( Vector3 is a float[3] ) will post here with any progress.

Update: I’ve got it working!
Update 2: I’ve got it working properly!!

I should probably mention some of the issues I had for others who are trying this.

First, you need Unity Pro to use plugins at all.

Put sixense.dll in your project/Assets/Plugins folder

Put DeviceDLL.dll in your project folder (its in the sixense SDK)

I’m using mostly javascript, so the c# plugin script also had to go in Project/Assets/Plugins to ensure it gets compiled first.

update 3: posted code here:
http://sixense.com/forum/vbulletin/showthread.php?3671-I-got-it-working!-Here-s-how&p=9803#post9803

Awesome I will try this out a bit later. I had to put that project on the back burner for another project I am working on. Thanks for the script.

Lol its frustrating how close I was to having this completed. Excellent job on the script. Here is the c# version for those who prefer that method. Now lets make some crazy awesome games guys!

using UnityEngine;

using System.Collections;

using System.Runtime.InteropServices;

using System.Text;



public class RazerHydraPlugin {

	

	

	public const int SIXENSE_BUTTON_BUMPER    = 128; //(0x01<<7)

	public const int SIXENSE_BUTTON_JOYSTICK  = 256; //(0x01<<8)

	public const int SIXENSE_BUTTON_1         = 32;  //(0x01<<5)

	public const int SIXENSE_BUTTON_2         = 64;  //(0x01<<6)

	public const int SIXENSE_BUTTON_3         = 8;   //(0x01<<3)

	public const int SIXENSE_BUTTON_4         = 16;  //(0x01<<4)

	public const int SIXENSE_BUTTON_START     = 1;   //(0x01<<0)

	

	//dllFile = "sixensed_x64" or "sixensed"

	//[DllImport ("sixensed_x64")]

	public struct _sixenseControllerData{

		public Vector3 pos; 

		public Vector3 rot_mat_x;

		public Vector3 rot_mat_y;

		public Vector3 rot_mat_z;

		public byte joystick_x;

		public byte joystick_y;

		public byte trigger;

		public int buttons;

		public byte sequence_number;

		public Quaternion rotQuat;

		public short firmware_revision;

		public short hardware_revision;

		public short packet_type;

		public short magnetic_frequency;

		public int enabled;

		public int controller_index;

		public byte is_docked;

		public byte which_hand;	

	};

	

	public _sixenseControllerData data;

	public _sixenseAllControllerData all_data;

	

	//[DllImport ("sixensed_x64")]

	public struct _sixenseAllControllerData{

		_sixenseControllerData[] controllers;	

	};

	

	[DllImport ("sixense")]

	private static extern int sixenseInit( );

	[DllImport ("sixense")]

	private static extern int sixenseExit( );

	[DllImport ("sixense")]

	private static extern int sixenseGetMaxBases( );

	[DllImport ("sixense")]

	private static extern int sixenseSetActiveBase( int base_num);

	[DllImport ("sixense")]

	private static extern int sixenseIsBaseConnected(int base_num );

	[DllImport ("sixense")]

	private static extern int sixenseGetMaxControllers( );

	[DllImport ("sixense")]

	private static extern int sixenseGetNumActiveControllers( );

	[DllImport ("sixense")]

	private static extern int sixenseIsControllerEnabled(int which);

	[DllImport ("sixense")]

	private static extern int sixenseGetAllNewestData(out _sixenseAllControllerData all_data);

	[DllImport ("sixense")]

	private static extern int sixenseGetAllData(int index_back,out _sixenseAllControllerData all_data);

	[DllImport ("sixense")]

	private static extern int sixenseGetNewestData(int which,out _sixenseControllerData data);

	[DllImport ("sixense")]

	private static extern int sixenseGetData(int which, int index_data,out _sixenseControllerData data);

	[DllImport ("sixense")]

	private static extern int sixenseGetHistorySize( );

	[DllImport ("sixense")]

	private static extern int sixenseSetFilterEnabled(int on_or_off);

	[DllImport ("sixense")]

	private static extern int sixenseGetFilterEnabled(out int on_or_off);

	[DllImport ("sixense")]

	private static extern int sixenseSetFilterParams(float near_range, float near_val, float far_range, float far_val);

	[DllImport ("sixense")]

	private static extern int sixenseGetFilterParams(out float near_range,out float near_val,out float far_range,out float far_val);

	[DllImport ("sixense")]

	private static extern int sixenseTriggerVibration(int controller_id, int duration_100ms, int pattern_id);

	[DllImport ("sixense")]

	private static extern int sixenseAutoEnableHemisphereTracking(int which_controller);

	[DllImport ("sixense")]

	private static extern int sixenseSetHighPriorityBindingEnabled(int on_or_off);

	[DllImport ("sixense")]

	private static extern int sixenseGetHighPriorityBindingEnabled(out int on_or_off);

	[DllImport ("sixense")]

	private static extern int sixenseSetbaseColor( char red, char green, char blue);

	[DllImport ("sixense")]

	private static extern int sixenseGetBaseColor(out char red,out char green,out char blue);



    public int _sixenseInit(){

        return sixenseInit();

    }

    public int _sixenseExit(){

        return sixenseExit();

	}

    public int _sixenseGetMaxBases(){

        return sixenseGetMaxBases();

    }

    public int _sixenseSetActiveBase(int base_num){

        return sixenseSetActiveBase(base_num);

    }

    public int _sixenseIsBaseConnected(int base_num){

        return sixenseIsBaseConnected(base_num);

    }

    public int _sixenseGetMaxControllers(){

        return sixenseGetMaxControllers();

    }

    public int _sixenseGetNumActiveControllers(){

        return sixenseGetNumActiveControllers();

    }

    public int _sixenseIsControllerEnabled(int which){

        return sixenseIsControllerEnabled(which);

    }

    public int _sixenseGetAllNewestData(){

        return sixenseGetAllNewestData(out all_data);

    }

	public int _sixenseGetAllData(int indexBack){

		return sixenseGetAllData(indexBack,out all_data);	

	}

	public int _sixenseGetNewestData(int which){

        return sixenseGetNewestData(which,out data);

    }

    public int _sixenseGetData(int which, int indexData){

        return sixenseGetData(which, indexData,out data);

    }

    public int _sixenseGetHistorySize(){

        return sixenseGetHistorySize();

    }

    public int _sixenseSetFilterEnabled(int on_or_off){

        sixenseSetFilterEnabled(on_or_off);

		return 0;

    }

    public int _sixenseGetFilterEnabled(int on_or_off){

        return sixenseGetFilterEnabled(out on_or_off);

    }

    public int _sixenseSetFilterParams(float near_range, float near_val, float far_range, float far_val){

        return sixenseSetFilterParams(near_range, near_val, far_range, far_val);

	}

    public int _sixenseGetFilterParams(float near_range,float near_val,float far_range,float far_val ){

        return sixenseGetFilterParams(out near_range,out near_val,out far_range,out far_val);

    }

    public int _sixenseTriggerVibration(int controllerId, int duration100ms, int patternId){

        return sixenseTriggerVibration(controllerId, duration100ms, patternId);

    }

    public int _sixenseAutoEnableHemisphereTracking(int which_controller){

        return sixenseAutoEnableHemisphereTracking(which_controller);

    }

    public int _sixenseSetHighPriorityBindingEnabled(int on_or_off){

        return sixenseSetHighPriorityBindingEnabled(on_or_off);

    }

    public int _sixenseGetHighPriorityBindingEnabled(int on_or_off){

        return sixenseGetHighPriorityBindingEnabled(out on_or_off);

    }

    public int _sixenseSetbaseColor(char red, char green, char blue){

        return sixenseSetbaseColor( red, green, blue);

    }

    public int _sixenseGetBaseColor(char red, char green, char blue){

        return sixenseGetBaseColor( out red,out green,out blue);

    }

}
using UnityEngine;

using System.Collections;



public class RazerHydra : MonoBehaviour {

	

	private RazerHydraPlugin sixenseContrllrData = new RazerHydraPlugin();

	public int controllerID = 0;

	

	// Use this for initialization

	void Start () 

	{	

		sixenseContrllrData._sixenseInit();

	}

	

	// Update is called once per frame

	void Update () 

	{

		Debug.Log("Hope this works " + sixenseContrllrData._sixenseGetNumActiveControllers());

		

		if(sixenseContrllrData._sixenseIsControllerEnabled(controllerID) == 1)

		{

			sixenseContrllrData._sixenseGetNewestData(controllerID);

			Debug.Log(sixenseContrllrData.data.pos + " , " + sixenseContrllrData.data.rotQuat);

			//this.transform.Translate(sixenseContrllrData.data.pos);

			this.transform.rotation = sixenseContrllrData.data.rotQuat;

		}

	}

}

very nice. I’m playing around with this in a project and Im noticing an issue

sixenseExit() is causing crashes in the editor. I was using this with OnApplicationQuit() events. Not including this keeps things stable, but I’d imagine the device should be shut down when you are not using it anymore.

also, in the C# conversion, change to

public struct _sixenseAllControllerData
    {
        public _sixenseControllerData[] controllers;
    };

cant access the controller array otherwise.

calling _sixenseGetAllNewestData(); is causing a runtime error and unity crash.

allData needs to be an array, it contains 2 controllers for the last 10 frames.

Germy, I will continue to cherrypick chunks of your code into mine if that’s OK with you.
I’m assuming the sixense guys will come out with an official version soon.

pixelshaded, I have noticed that the device shuts itself down automatically if the handsets are left in the cradle for a couple of minutes, so I wouldn’t worry too much about doing a manual exit if it’s crashing.

Thats what it’s for, please take it all if you want.

just to confirm, anyone else getting the runtime errors with GetAllNewestData?

I haven’t tried to use it. I’ve been calling GetNewestData, so I don’t know, sorry.