Jump to content

Facetrack NOIR


sacapuces

Recommended Posts

probibly can be made to work. might require a mod though.

e:

seems the api for the 3d mice is some proprietary hardware locked crap, so going through an emulation layer to provide a fake 3d mouse might be difficult (not that it hasn't been done before with trackir). joystick emulation doesn't work either because there is no absolute look axes you can bind them to (this is why trackir works in mechwarrior 2). we do have relative axes but if you look left for example, the camera will keep turning left, and if we center, it will just stop turning left, it wont go back to center. so thats not an option (unless you enjoy sore necks and nausea).

to get data out of the face tracking program, ftnoir has the option of using the freetrak api which is incredibly easy to use (you just need to export 4 functions and a struct from a dll), among other options (joystick emulation, its own api). but if you go with the freetrack api it also supports freetrack and trackir users (sort of, natural point made them take down that version, but you can still get it) out of the box.

you still need to get the data into the game though, and apply it to the in game camera. you could do this with a plugin. i actually attempted this a long time ago. unfortunately i didnt have any experience with c# or unity so what i did was a dirty hack involving the hull cam source and this cs file that i wrote (im calling it public domain):


using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
using System.Runtime.InteropServices;
using UnityEngine;

namespace FreeTrack
{
public class FreeTrackClient
{
//a struct for the freetrack data to go
[StructLayout(LayoutKind.Sequential)]
private struct FTData
{
public int dataid;
public int camwidth, camheight;
public Single Yaw, Pitch, Roll, X, Y, Z;
public Single RawYaw, RawPitch, RawRoll;
public Single RawX, RawY, RawZ;
public Single x1, y1, x2, y2, x3, y3, x4, y4;
}
//do imports
[DllImport("FreeTrackClient.dll")]
private static extern bool FTGetData(ref FTData data);
[DllImport("FreeTrackClient.dll")]
private static extern string FTGetDllVersion();
[DllImport("FreeTrackClient.dll")]
private static extern void FTReportName(Int32 name);
[DllImport("FreeTrackClient.dll")]
private static extern string FTProvider();

//a bool to check if were inited
private static bool ftInited;
//a place to count consecutive update failures (for reset)
private static int ftBadUpdates;
public static int maxBadUpdates; //this is pulbic for tweaking purposes
//data frame from the dll goes here
private static FTData ftData;
//a place to store output values
private static Vector3 ftOffset;
private static Quaternion ftRotate;

//the following vars and the four functions that follow are the external interface
//you must init the code somewhere with initFreeTrack(), this returns a bool which wen true indicates a successful init, fail otherwise
//you may then set the constraint variables and scalers (you can do this at any time)
//then you must call updateFreeTrack() to update local position and rotation. its return is the same as initFreeTrack(). note that if the update fails it will still return true.
//after that you can get the local camera rotation with getRotation(), which returns a quaternion
//and you can get the local camera offset with getOffset(), which returns a vector

//constraints/scalers. can be changed at any time
public static Vector3 minOffset, maxOffset;
public static Vector3 minEuler, maxEuler;
public static float transFactor, rotFactor;

//init function (call before using the class)
public static bool init(){
//tell the console what were doing
UnityEngine.MonoBehaviour.print("Attempting to init FreeTrack");
ftBadUpdates = 0;
maxBadUpdates = 5;

//set things to zero
ftOffset = new Vector3(0.0f, 0.0f, 0.0f);
ftRotate = Quaternion.Euler(0.0f, 0.0f, 0.0f);
//default constraints and scalers
minOffset = new Vector3(-0.4f, -0.4f, 0.0f);
maxOffset = new Vector3(0.4f, 0.4f, 0.4f);
minEuler = new Vector3(-180.0f, -180.0f, -180.0f);
maxEuler = new Vector3(180.0f, 180.0f, 180.0f);
transFactor = 0.02f;
rotFactor = 50.0f;

//output create output struct
ftData = new FTData();

//handel no dll scenario
try
{
ftInited = FTGetData(ref ftData);
}
catch (DllNotFoundException e)
{
UnityEngine.MonoBehaviour.print(" Error: "+e);
ftInited = false;
}

if (!ftInited)
{
UnityEngine.MonoBehaviour.print(" Cannot init. No FreeTrack client or error.");
}
else
{
UnityEngine.MonoBehaviour.print(" Init successful!");
UnityEngine.MonoBehaviour.print(" Provider: " + FTProvider());
UnityEngine.MonoBehaviour.print(" DLL Version: " + FTGetDllVersion());
//report the game's id to freetrack (this doesnt work and causes an exception)
FTReportName(3431); //escape velocity of kerbin, lol
}
return ftInited;
}

//update function call it to refresh ftOffset and ftRotate. the return indicates if the interface has been inited, not if there was an update
public static bool update() {
//dont call a bunch of null functions
if (ftInited)
{
//load data into the struct
if (FTGetData(ref ftData))
{
ftBadUpdates = 0;
//constrain eulers to within set constraints
Vector3 ftEuler = new Vector3(-ftData.Pitch, -ftData.Yaw, ftData.Roll);
ftEuler *= rotFactor;
if (ftEuler.x > maxEuler.x) ftEuler.x = maxEuler.x; else if (ftEuler.x < minEuler.x) ftEuler.x = minEuler.x;
if (ftEuler.y > maxEuler.y) ftEuler.y = maxEuler.y; else if (ftEuler.y < minEuler.y) ftEuler.y = minEuler.y;
if (ftEuler.z > maxEuler.z) ftEuler.z = maxEuler.z; else if (ftEuler.z < minEuler.z) ftEuler.z = minEuler.z;
//convert to quat
ftRotate = Quaternion.Euler(ftEuler);

//constrain offset so it stays within a unit box (this box should probibly be defined in the part)
ftOffset = new Vector3(-ftData.X, ftData.Y, -ftData.Z);
ftOffset *= transFactor; //scale it, it seems way over sensitive
if (ftOffset.x > maxOffset.x) ftOffset.x = maxOffset.x; else if (ftOffset.x < minOffset.x) ftOffset.x = minOffset.x;
if (ftOffset.y > maxOffset.y) ftOffset.y = maxOffset.y; else if (ftOffset.y < minOffset.y) ftOffset.y = minOffset.y;
if (ftOffset.z > maxOffset.z) ftOffset.z = maxOffset.z; else if (ftOffset.z < minOffset.z) ftOffset.z = minOffset.z;
}
else
{
ftBadUpdates++;
//if this fails too many times assume the markers are off the camera and center everything
if (maxBadUpdates >= 0 && ftBadUpdates > maxBadUpdates)
{
ftOffset = new Vector3(0.0f, 0.0f, 0.0f);
ftRotate = Quaternion.Euler(0.0f, 0.0f, 0.0f);
}
}
}
return ftInited;
}
//get rotation
public static Quaternion getRotation() {
return ftRotate;
}
//get offset
public static Vector3 getOffset() {
return ftOffset;
}
}
}

unfortunately my hack didnt age well and it stopped working as soon as the next ksp version came out. others have tried to make it work but no success. i presume that squad added some kind of security patch to the plugin loader that prevents loading external binaries but i dont know.

Edited by Nuke
Link to comment
Share on other sites

This thread is quite old. Please consider starting a new thread rather than reviving this one.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...