// // Update Headpose in Game. // void FTNoIR_Protocol::sendHeadposeToGame(const double *headpose ) { DWORD result; TFSState pitch; TFSState yaw; TFSState roll; WORD FSZoom; float virtPosX; float virtPosY; float virtPosZ; float virtRotX; float virtRotY; float virtRotZ; // qDebug() << "FSUIPCServer::run() says: started!"; virtRotX = -headpose[Pitch]; // degrees virtRotY = headpose[Yaw]; virtRotZ = headpose[Roll]; virtPosX = 0.0f; // cm, X and Y are not working for FS2002/2004! virtPosY = 0.0f; virtPosZ = headpose[TZ]; // // Init. the FSUIPC offsets (derived from Free-track...) // pitch.Control = 66503; yaw.Control = 66504; roll.Control = 66505; // // Only do this when the data has changed. This way, the HAT-switch can be used when tracking is OFF. // if ((prevPosX != virtPosX) || (prevPosY != virtPosY) || (prevPosZ != virtPosZ) || (prevRotX != virtRotX) || (prevRotY != virtRotY) || (prevRotZ != virtRotZ)) { // // Open the connection // FSUIPC_Open(SIM_ANY, &result); // // Check the FS-version // if (((result == FSUIPC_ERR_OK) || (result == FSUIPC_ERR_OPEN)) && ((FSUIPC_FS_Version == SIM_FS2K2) || (FSUIPC_FS_Version == SIM_FS2K4))) { // qDebug() << "FSUIPCServer::run() says: FSUIPC opened succesfully"; // // Write the 4! DOF-data to FS. Only rotations and zoom are possible. // pitch.Value = scale2AnalogLimits(virtRotX, -180, 180); FSUIPC_Write(0x3110, 8, &pitch, &result); yaw.Value = scale2AnalogLimits(virtRotY, -180, 180); FSUIPC_Write(0x3110, 8, &yaw, &result); roll.Value = scale2AnalogLimits(virtRotZ, -180, 180); FSUIPC_Write(0x3110, 8, &roll, &result); FSZoom = (WORD) (64/50) * virtPosZ + 64; FSUIPC_Write(0x832E, 2, &FSZoom, &result); // // Write the data, in one go! // FSUIPC_Process(&result); if (result == FSUIPC_ERR_SENDMSG) { FSUIPC_Close(); //timeout (1 second) so assume FS closed } } } prevPosX = virtPosX; prevPosY = virtPosY; prevPosZ = virtPosZ; prevRotX = virtRotX; prevRotY = virtRotY; prevRotZ = virtRotZ; }
// // Update Headpose in Game. // void FTNoIR_Protocol_MOUSE::sendHeadposeToGame( T6DOF *headpose ) { float fMouse_X; // The actual value float fMouse_Y; float fMouse_Wheel; // // Determine which of the 6DOF's is used. // The rotations are from -180 to +180 and the translations from -50cm to +50cm. // Let's scale the translations to the degrees for simplicity sake... // switch (Mouse_X) { case FTN_PITCH: fMouse_X = headpose->position.pitch; break; case FTN_YAW: fMouse_X = headpose->position.yaw; break; case FTN_ROLL: fMouse_X = headpose->position.roll; break; case FTN_X: fMouse_X = headpose->position.x * 3.0f; break; case FTN_Y: fMouse_X = headpose->position.y * 3.0f; break; case FTN_Z: fMouse_X = headpose->position.z * 3.0f; break; default: break; } // // Determine which of the 6DOF's is used. // The rotations are from -180 to +180 and the translations from -50cm to +50cm. // Let's scale the translations to the degrees for simplicity sake... // switch (Mouse_Y) { case FTN_PITCH: fMouse_Y = headpose->position.pitch; break; case FTN_YAW: fMouse_Y = headpose->position.yaw; break; case FTN_ROLL: fMouse_Y = headpose->position.roll; break; case FTN_X: fMouse_Y = headpose->position.x * 3.0f; break; case FTN_Y: fMouse_Y = headpose->position.y * 3.0f; break; case FTN_Z: fMouse_Y = headpose->position.z * 3.0f; break; default: break; } // // Determine which of the 6DOF's is used. // The rotations are from -180 to +180 and the translations from -50cm to +50cm. // Let's scale the translations to the degrees for simplicity sake... // switch (Mouse_Wheel) { case FTN_PITCH: fMouse_Wheel = headpose->position.pitch; break; case FTN_YAW: fMouse_Wheel = headpose->position.yaw; break; case FTN_ROLL: fMouse_Wheel = headpose->position.roll; break; case FTN_X: fMouse_Wheel = headpose->position.x * 3.0f; break; case FTN_Y: fMouse_Wheel = headpose->position.y * 3.0f; break; case FTN_Z: fMouse_Wheel = headpose->position.z * 3.0f; break; default: break; } // // Determine which style is used. // SecureZeroMemory(&MouseStruct, sizeof(MouseStruct)); MouseStruct.type = INPUT_MOUSE; switch (Mouse_Style) { case FTN_ABSOLUTE: MouseStruct.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_WHEEL | MOUSEEVENTF_ABSOLUTE; if (useVirtualDesk) { MouseStruct.mi.dwFlags |= MOUSEEVENTF_VIRTUALDESK; } MouseStruct.mi.dx = scale2AnalogLimits(-1.0f * fMouse_X * mouse_X_factor, -150, 150); MouseStruct.mi.dy = scale2AnalogLimits(fMouse_Y * mouse_Y_factor, -150, 150); MouseStruct.mi.mouseData = mouse_Wheel_factor * (fMouse_Wheel - prev_fMouse_Wheel); frame_delay = 9999; // Seems no problem with Absolute positioning break; case FTN_RELATIVE: MouseStruct.mi.dwFlags = MOUSEEVENTF_MOVE | MOUSEEVENTF_WHEEL; MouseStruct.mi.dx = -1.0f * mouse_X_factor * (fMouse_X - prev_fMouse_X); MouseStruct.mi.dy = mouse_Y_factor * (fMouse_Y - prev_fMouse_Y); MouseStruct.mi.mouseData = - 1.0f * mouse_Wheel_factor * (fMouse_Wheel - prev_fMouse_Wheel); frame_delay += 1; // Add 1 to the counter qDebug() << "sendHeadposeToGame(): FTN_RELATIVE x = " << MouseStruct.mi.dx << ", y = " << MouseStruct.mi.dy; break; default: Mouse_Style = FTN_ABSOLUTE; // Force to a valid value... break; } // // Only send Input, when it has changed. // This releases the Mouse, when tracking is stopped (for a while). // if (frame_delay > 10) { if ((prev_fMouse_X != fMouse_X) || (prev_fMouse_Y != fMouse_Y) || (prev_fMouse_Wheel != fMouse_Wheel)) { SendInput(1, &MouseStruct, sizeof(MouseStruct)); } prev_fMouse_X = fMouse_X; prev_fMouse_Y = fMouse_Y; prev_fMouse_Wheel = fMouse_Wheel; } }