├── Config └── FilterPlugin.ini ├── Content ├── CranesData.uasset ├── Supertechno15 │ ├── ST15_FBX_with_texture.uasset │ ├── ST15_FBX_with_texture_PhysicsAsset.uasset │ ├── ST15_FBX_with_texture_Skeleton.uasset │ ├── StingrayPBS1.uasset │ ├── ibl_brdf_lut.uasset │ ├── lambert2SG_Alpha.uasset │ ├── lambert2SG_BaseColor.uasset │ ├── lambert2SG_Metallic.uasset │ ├── lambert2SG_Normal.uasset │ └── lambert2SG_Roughness.uasset ├── Supertechno30Plus │ ├── ST050Plus_mat.uasset │ ├── ST30_FBX.uasset │ ├── ST30_FBX_PhysicsAsset.uasset │ ├── ST30_FBX_Skeleton.uasset │ ├── lambert2SG_Alpha.uasset │ ├── lambert2SG_BaseColor.uasset │ ├── lambert2SG_Displacement.uasset │ ├── lambert2SG_Metallic.uasset │ ├── lambert2SG_Normal.uasset │ └── lambert2SG_Roughness.uasset ├── Supertechno50Plus │ ├── ST050PlusModel_ST050Plus_mat_BaseColor.uasset │ ├── ST050PlusModel_ST050Plus_mat_Normal.uasset │ ├── ST050PlusModel_ST050Plus_mat_OcclusionRoughnessMetallic.uasset │ ├── ST050Plus_mat.uasset │ ├── ST50Plus_Rigged.uasset │ ├── ST50Plus_Rigged_PhysicsAsset.uasset │ └── ST50Plus_Rigged_Skeleton.uasset ├── Supertechno75Plus │ ├── ST75_FBX.uasset │ ├── ST75_FBX_PhysicsAsset.uasset │ ├── ST75_FBX_Skeleton.uasset │ ├── lambert2.uasset │ ├── lambert2SG_Alpha.uasset │ ├── lambert2SG_BaseColor.uasset │ ├── lambert2SG_Displacement.uasset │ ├── lambert2SG_Metallic.uasset │ ├── lambert2SG_Normal.uasset │ └── lambert2SG_Roughness.uasset ├── Technocrane10 │ ├── TC10_FBX.uasset │ ├── TC10_FBX_CtrlRig.uasset │ ├── TC10_FBX_PhysicsAsset.uasset │ ├── TC10_FBX_Skeleton.uasset │ ├── TC10_mat.uasset │ ├── lambert2SG_Alpha.uasset │ ├── lambert2SG_BaseColor.uasset │ ├── lambert2SG_Displacement.uasset │ ├── lambert2SG_Metallic.uasset │ ├── lambert2SG_Normal.uasset │ └── lambert2SG_Roughness.uasset ├── Technocrane22 │ ├── TC22_Rigged.uasset │ ├── TC22_Rigged_PhysicsAsset.uasset │ ├── TC22_Rigged_Skeleton.uasset │ ├── TC22_TC22_mat_BaseColor.uasset │ ├── TC22_TC22_mat_Normal.uasset │ ├── TC22_TC22_mat_OcclusionRoughnessMetallic.uasset │ └── TC22_mat.uasset ├── Technodolly10 │ ├── SKM_TD10_FBX.uasset │ ├── SKM_TD10_FBX_CtrlRig.uasset │ ├── SK_TD10_FBX.uasset │ ├── TD10_FBX.uasset │ ├── TD10_mat.uasset │ ├── geomTD25SG_Alpha.uasset │ ├── geomTD25SG_BaseColor.uasset │ ├── geomTD25SG_Displacement.uasset │ ├── geomTD25SG_Metallic.uasset │ ├── geomTD25SG_Normal.uasset │ └── geomTD25SG_Roughness.uasset ├── Technodolly15 │ ├── SKM_TD15_FBX.uasset │ ├── SK_TD15_FBX.uasset │ ├── TD15_FBX.uasset │ ├── TD15_mat.uasset │ ├── lambert2SG_Alpha.uasset │ ├── lambert2SG_BaseColor.uasset │ ├── lambert2SG_Displacement.uasset │ ├── lambert2SG_Metallic.uasset │ ├── lambert2SG_Normal.uasset │ └── lambert2SG_Roughness.uasset ├── Technodolly25 │ ├── TD25_Rigged.uasset │ ├── TD25_Rigged_PhysicsAsset.uasset │ ├── TD25_Rigged_Skeleton.uasset │ ├── TD25_mat.uasset │ ├── TD25_mat_BaseColor.uasset │ ├── TD25_mat_Normal.uasset │ └── TD25_mat_OcclusionRoughnessMetallic.uasset ├── lambertTrack.uasset └── tracks.uasset ├── Images ├── TechnocranePlugin.JPG ├── frame_data_print.jpg ├── setup_1.jpg ├── setup_2.jpg ├── setup_3.jpg ├── setup_4.jpg ├── setup_5.jpg └── setup_6.jpg ├── LICENSE ├── README.md ├── Resources └── Icon128.png ├── Source ├── TechnocraneEditor │ ├── Private │ │ ├── CameraAssetTypeActions.cpp │ │ ├── CameraAssetTypeActions.h │ │ ├── CameraDetailsCustomization.cpp │ │ ├── CameraDetailsCustomization.h │ │ ├── TechnocraneEditorModule.cpp │ │ ├── TechnocraneEditorPCH.h │ │ └── TechnocraneEditorStyle.cpp │ ├── Public │ │ ├── TechnocraneEditorCommands.cpp │ │ ├── TechnocraneEditorCommands.h │ │ ├── TechnocraneEditorModule.h │ │ └── TechnocraneEditorStyle.h │ └── TechnocraneEditor.Build.cs ├── TechnocranePlugin │ ├── Private │ │ ├── LiveLinkTechnocraneSource.cpp │ │ ├── LiveLinkTechnocraneSource.h │ │ ├── LiveLinkTechnocraneSourceFactory.cpp │ │ ├── LiveLinkTechnocraneSourceFactory.h │ │ ├── LiveLinkTechnocraneTypes.h │ │ ├── SLiveLinkTechnocraneSourceFactory.cpp │ │ ├── SLiveLinkTechnocraneSourceFactory.h │ │ ├── TechnocraneCamera.cpp │ │ ├── TechnocraneCameraComponent.cpp │ │ ├── TechnocranePlugin.cpp │ │ ├── TechnocranePrivatePCH.h │ │ ├── TechnocraneRig.cpp │ │ ├── TechnocraneRuntimeSettings.cpp │ │ └── TechnocraneShared.cpp │ ├── Public │ │ ├── ITechnocranePlugin.h │ │ ├── TechnocraneCamera.h │ │ ├── TechnocraneCameraComponent.h │ │ ├── TechnocraneRig.h │ │ ├── TechnocraneRuntimeSettings.h │ │ └── TechnocraneShared.h │ └── TechnocranePlugin.Build.cs └── ThirdParty │ └── TechnocraneSDK │ ├── LICENSE.txt │ ├── README.md │ ├── include │ ├── technocrane_hardware.h │ └── technocrane_types.h │ └── lib │ ├── Win32 │ ├── TechnocraneLib.dll │ └── TechnocraneLib.lib │ └── Win64 │ ├── TechnocraneLib.dll │ └── TechnocraneLib.lib └── TechnocranePlugin.uplugin /Config/FilterPlugin.ini: -------------------------------------------------------------------------------- 1 | [FilterPlugin] 2 | /Config/ 3 | /Content/ 4 | -/Intermediate/* 5 | /Resources/ 6 | /Source 7 | /LICENSE.txt 8 | /README.txt -------------------------------------------------------------------------------- /Content/CranesData.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/CranesData.uasset -------------------------------------------------------------------------------- /Content/Supertechno15/ST15_FBX_with_texture.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno15/ST15_FBX_with_texture.uasset -------------------------------------------------------------------------------- /Content/Supertechno15/ST15_FBX_with_texture_PhysicsAsset.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno15/ST15_FBX_with_texture_PhysicsAsset.uasset -------------------------------------------------------------------------------- /Content/Supertechno15/ST15_FBX_with_texture_Skeleton.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno15/ST15_FBX_with_texture_Skeleton.uasset -------------------------------------------------------------------------------- /Content/Supertechno15/StingrayPBS1.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno15/StingrayPBS1.uasset -------------------------------------------------------------------------------- /Content/Supertechno15/ibl_brdf_lut.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno15/ibl_brdf_lut.uasset -------------------------------------------------------------------------------- /Content/Supertechno15/lambert2SG_Alpha.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno15/lambert2SG_Alpha.uasset -------------------------------------------------------------------------------- /Content/Supertechno15/lambert2SG_BaseColor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno15/lambert2SG_BaseColor.uasset -------------------------------------------------------------------------------- /Content/Supertechno15/lambert2SG_Metallic.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno15/lambert2SG_Metallic.uasset -------------------------------------------------------------------------------- /Content/Supertechno15/lambert2SG_Normal.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno15/lambert2SG_Normal.uasset -------------------------------------------------------------------------------- /Content/Supertechno15/lambert2SG_Roughness.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno15/lambert2SG_Roughness.uasset -------------------------------------------------------------------------------- /Content/Supertechno30Plus/ST050Plus_mat.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno30Plus/ST050Plus_mat.uasset -------------------------------------------------------------------------------- /Content/Supertechno30Plus/ST30_FBX.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno30Plus/ST30_FBX.uasset -------------------------------------------------------------------------------- /Content/Supertechno30Plus/ST30_FBX_PhysicsAsset.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno30Plus/ST30_FBX_PhysicsAsset.uasset -------------------------------------------------------------------------------- /Content/Supertechno30Plus/ST30_FBX_Skeleton.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno30Plus/ST30_FBX_Skeleton.uasset -------------------------------------------------------------------------------- /Content/Supertechno30Plus/lambert2SG_Alpha.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno30Plus/lambert2SG_Alpha.uasset -------------------------------------------------------------------------------- /Content/Supertechno30Plus/lambert2SG_BaseColor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno30Plus/lambert2SG_BaseColor.uasset -------------------------------------------------------------------------------- /Content/Supertechno30Plus/lambert2SG_Displacement.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno30Plus/lambert2SG_Displacement.uasset -------------------------------------------------------------------------------- /Content/Supertechno30Plus/lambert2SG_Metallic.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno30Plus/lambert2SG_Metallic.uasset -------------------------------------------------------------------------------- /Content/Supertechno30Plus/lambert2SG_Normal.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno30Plus/lambert2SG_Normal.uasset -------------------------------------------------------------------------------- /Content/Supertechno30Plus/lambert2SG_Roughness.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno30Plus/lambert2SG_Roughness.uasset -------------------------------------------------------------------------------- /Content/Supertechno50Plus/ST050PlusModel_ST050Plus_mat_BaseColor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno50Plus/ST050PlusModel_ST050Plus_mat_BaseColor.uasset -------------------------------------------------------------------------------- /Content/Supertechno50Plus/ST050PlusModel_ST050Plus_mat_Normal.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno50Plus/ST050PlusModel_ST050Plus_mat_Normal.uasset -------------------------------------------------------------------------------- /Content/Supertechno50Plus/ST050PlusModel_ST050Plus_mat_OcclusionRoughnessMetallic.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno50Plus/ST050PlusModel_ST050Plus_mat_OcclusionRoughnessMetallic.uasset -------------------------------------------------------------------------------- /Content/Supertechno50Plus/ST050Plus_mat.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno50Plus/ST050Plus_mat.uasset -------------------------------------------------------------------------------- /Content/Supertechno50Plus/ST50Plus_Rigged.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno50Plus/ST50Plus_Rigged.uasset -------------------------------------------------------------------------------- /Content/Supertechno50Plus/ST50Plus_Rigged_PhysicsAsset.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno50Plus/ST50Plus_Rigged_PhysicsAsset.uasset -------------------------------------------------------------------------------- /Content/Supertechno50Plus/ST50Plus_Rigged_Skeleton.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno50Plus/ST50Plus_Rigged_Skeleton.uasset -------------------------------------------------------------------------------- /Content/Supertechno75Plus/ST75_FBX.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno75Plus/ST75_FBX.uasset -------------------------------------------------------------------------------- /Content/Supertechno75Plus/ST75_FBX_PhysicsAsset.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno75Plus/ST75_FBX_PhysicsAsset.uasset -------------------------------------------------------------------------------- /Content/Supertechno75Plus/ST75_FBX_Skeleton.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno75Plus/ST75_FBX_Skeleton.uasset -------------------------------------------------------------------------------- /Content/Supertechno75Plus/lambert2.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno75Plus/lambert2.uasset -------------------------------------------------------------------------------- /Content/Supertechno75Plus/lambert2SG_Alpha.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno75Plus/lambert2SG_Alpha.uasset -------------------------------------------------------------------------------- /Content/Supertechno75Plus/lambert2SG_BaseColor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno75Plus/lambert2SG_BaseColor.uasset -------------------------------------------------------------------------------- /Content/Supertechno75Plus/lambert2SG_Displacement.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno75Plus/lambert2SG_Displacement.uasset -------------------------------------------------------------------------------- /Content/Supertechno75Plus/lambert2SG_Metallic.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno75Plus/lambert2SG_Metallic.uasset -------------------------------------------------------------------------------- /Content/Supertechno75Plus/lambert2SG_Normal.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno75Plus/lambert2SG_Normal.uasset -------------------------------------------------------------------------------- /Content/Supertechno75Plus/lambert2SG_Roughness.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Supertechno75Plus/lambert2SG_Roughness.uasset -------------------------------------------------------------------------------- /Content/Technocrane10/TC10_FBX.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane10/TC10_FBX.uasset -------------------------------------------------------------------------------- /Content/Technocrane10/TC10_FBX_CtrlRig.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane10/TC10_FBX_CtrlRig.uasset -------------------------------------------------------------------------------- /Content/Technocrane10/TC10_FBX_PhysicsAsset.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane10/TC10_FBX_PhysicsAsset.uasset -------------------------------------------------------------------------------- /Content/Technocrane10/TC10_FBX_Skeleton.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane10/TC10_FBX_Skeleton.uasset -------------------------------------------------------------------------------- /Content/Technocrane10/TC10_mat.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane10/TC10_mat.uasset -------------------------------------------------------------------------------- /Content/Technocrane10/lambert2SG_Alpha.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane10/lambert2SG_Alpha.uasset -------------------------------------------------------------------------------- /Content/Technocrane10/lambert2SG_BaseColor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane10/lambert2SG_BaseColor.uasset -------------------------------------------------------------------------------- /Content/Technocrane10/lambert2SG_Displacement.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane10/lambert2SG_Displacement.uasset -------------------------------------------------------------------------------- /Content/Technocrane10/lambert2SG_Metallic.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane10/lambert2SG_Metallic.uasset -------------------------------------------------------------------------------- /Content/Technocrane10/lambert2SG_Normal.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane10/lambert2SG_Normal.uasset -------------------------------------------------------------------------------- /Content/Technocrane10/lambert2SG_Roughness.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane10/lambert2SG_Roughness.uasset -------------------------------------------------------------------------------- /Content/Technocrane22/TC22_Rigged.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane22/TC22_Rigged.uasset -------------------------------------------------------------------------------- /Content/Technocrane22/TC22_Rigged_PhysicsAsset.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane22/TC22_Rigged_PhysicsAsset.uasset -------------------------------------------------------------------------------- /Content/Technocrane22/TC22_Rigged_Skeleton.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane22/TC22_Rigged_Skeleton.uasset -------------------------------------------------------------------------------- /Content/Technocrane22/TC22_TC22_mat_BaseColor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane22/TC22_TC22_mat_BaseColor.uasset -------------------------------------------------------------------------------- /Content/Technocrane22/TC22_TC22_mat_Normal.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane22/TC22_TC22_mat_Normal.uasset -------------------------------------------------------------------------------- /Content/Technocrane22/TC22_TC22_mat_OcclusionRoughnessMetallic.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane22/TC22_TC22_mat_OcclusionRoughnessMetallic.uasset -------------------------------------------------------------------------------- /Content/Technocrane22/TC22_mat.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technocrane22/TC22_mat.uasset -------------------------------------------------------------------------------- /Content/Technodolly10/SKM_TD10_FBX.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly10/SKM_TD10_FBX.uasset -------------------------------------------------------------------------------- /Content/Technodolly10/SKM_TD10_FBX_CtrlRig.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly10/SKM_TD10_FBX_CtrlRig.uasset -------------------------------------------------------------------------------- /Content/Technodolly10/SK_TD10_FBX.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly10/SK_TD10_FBX.uasset -------------------------------------------------------------------------------- /Content/Technodolly10/TD10_FBX.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly10/TD10_FBX.uasset -------------------------------------------------------------------------------- /Content/Technodolly10/TD10_mat.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly10/TD10_mat.uasset -------------------------------------------------------------------------------- /Content/Technodolly10/geomTD25SG_Alpha.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly10/geomTD25SG_Alpha.uasset -------------------------------------------------------------------------------- /Content/Technodolly10/geomTD25SG_BaseColor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly10/geomTD25SG_BaseColor.uasset -------------------------------------------------------------------------------- /Content/Technodolly10/geomTD25SG_Displacement.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly10/geomTD25SG_Displacement.uasset -------------------------------------------------------------------------------- /Content/Technodolly10/geomTD25SG_Metallic.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly10/geomTD25SG_Metallic.uasset -------------------------------------------------------------------------------- /Content/Technodolly10/geomTD25SG_Normal.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly10/geomTD25SG_Normal.uasset -------------------------------------------------------------------------------- /Content/Technodolly10/geomTD25SG_Roughness.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly10/geomTD25SG_Roughness.uasset -------------------------------------------------------------------------------- /Content/Technodolly15/SKM_TD15_FBX.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly15/SKM_TD15_FBX.uasset -------------------------------------------------------------------------------- /Content/Technodolly15/SK_TD15_FBX.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly15/SK_TD15_FBX.uasset -------------------------------------------------------------------------------- /Content/Technodolly15/TD15_FBX.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly15/TD15_FBX.uasset -------------------------------------------------------------------------------- /Content/Technodolly15/TD15_mat.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly15/TD15_mat.uasset -------------------------------------------------------------------------------- /Content/Technodolly15/lambert2SG_Alpha.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly15/lambert2SG_Alpha.uasset -------------------------------------------------------------------------------- /Content/Technodolly15/lambert2SG_BaseColor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly15/lambert2SG_BaseColor.uasset -------------------------------------------------------------------------------- /Content/Technodolly15/lambert2SG_Displacement.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly15/lambert2SG_Displacement.uasset -------------------------------------------------------------------------------- /Content/Technodolly15/lambert2SG_Metallic.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly15/lambert2SG_Metallic.uasset -------------------------------------------------------------------------------- /Content/Technodolly15/lambert2SG_Normal.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly15/lambert2SG_Normal.uasset -------------------------------------------------------------------------------- /Content/Technodolly15/lambert2SG_Roughness.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly15/lambert2SG_Roughness.uasset -------------------------------------------------------------------------------- /Content/Technodolly25/TD25_Rigged.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly25/TD25_Rigged.uasset -------------------------------------------------------------------------------- /Content/Technodolly25/TD25_Rigged_PhysicsAsset.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly25/TD25_Rigged_PhysicsAsset.uasset -------------------------------------------------------------------------------- /Content/Technodolly25/TD25_Rigged_Skeleton.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly25/TD25_Rigged_Skeleton.uasset -------------------------------------------------------------------------------- /Content/Technodolly25/TD25_mat.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly25/TD25_mat.uasset -------------------------------------------------------------------------------- /Content/Technodolly25/TD25_mat_BaseColor.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly25/TD25_mat_BaseColor.uasset -------------------------------------------------------------------------------- /Content/Technodolly25/TD25_mat_Normal.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly25/TD25_mat_Normal.uasset -------------------------------------------------------------------------------- /Content/Technodolly25/TD25_mat_OcclusionRoughnessMetallic.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/Technodolly25/TD25_mat_OcclusionRoughnessMetallic.uasset -------------------------------------------------------------------------------- /Content/lambertTrack.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/lambertTrack.uasset -------------------------------------------------------------------------------- /Content/tracks.uasset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Content/tracks.uasset -------------------------------------------------------------------------------- /Images/TechnocranePlugin.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Images/TechnocranePlugin.JPG -------------------------------------------------------------------------------- /Images/frame_data_print.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Images/frame_data_print.jpg -------------------------------------------------------------------------------- /Images/setup_1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Images/setup_1.jpg -------------------------------------------------------------------------------- /Images/setup_2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Images/setup_2.jpg -------------------------------------------------------------------------------- /Images/setup_3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Images/setup_3.jpg -------------------------------------------------------------------------------- /Images/setup_4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Images/setup_4.jpg -------------------------------------------------------------------------------- /Images/setup_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Images/setup_5.jpg -------------------------------------------------------------------------------- /Images/setup_6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Images/setup_6.jpg -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018-2021 Technocrane s.r.o. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Technocrane Unreal Engine Plugin 2 | 3 | [Technocrane Tracker Plugin on an official marketplace](https://unrealengine.com/marketplace/en-US/slug/technocrane-tracker?fbclid=IwAR0Fj0Ma3GsJ5hbG-oYZzfJeObZsdd8iSZKVrDtZPjCpr2IUWdOS83wVVsA) 4 | 5 | [Introduction Video](https://youtu.be/VPmdLAun9WQ) 6 | 7 | [](https://discord.gg/qw7QxSR) 8 | 9 | # Technocrane Trimmer 10 | 11 | Technocrane trimmer is a service that converts raw stream information (*.cgi) into fbx files. Its main feature is the ability to export a defined range of time to fbx. This allows for the splitting of large daily streams into smaller fbx files, which can be imported into DCC applications like Maya, MotionBuilder, and Unreal Engine for further processing. The service can be particularly helpful for importing camera animations longer than 2 minutes into Unreal Engine, which can be a challenge without splitting the animation into smaller parts. 12 | 13 | [Technocrane Trimmer](https://technocranes.github.io/) 14 | 15 | [Introduction Video To Technocrane Trimmer](https://youtu.be/JjMQ8ErkjWE) 16 | 17 | [Import fbx into Sequencer](https://youtu.be/vHJZ4-C5B0s) 18 | 19 | The UE Plugin has a special camera actor - TechnocraneCamera, derived from cinematic camera. The main feature is in its camera component which contains variables of zoom, iris, focus, track position, time code in order to be seamlessly imported from a trimmer fbx into UE Sequencer clip. 20 | 21 | # How to Install Manually 22 | 23 | * Create a "Plugins" directory in the project root (near the "Content" directory) 24 | * Create there sub-folder "TechnocranePlugin". 25 | * Put the repository folders into the "TechnocranePlugin" folder. (e.g. "/MyProject/Plugins/TechnocranePlugin") 26 | * For binaries you can build the plugin together with the project in case you have a c++ based project and Visual Studio 27 | * If you don't have development environment to compile the plugin, you can download precompiled binaries from a release section of the repository. 28 | * In case of downloaded binaries, put them into /Plugins/TechnocranePlugin/Binaries/Win64 29 | 30 | In Unreal Editor first of all you should activate Live Link plugin if you don't have that done yet. 31 | [![Step1](https://github.com/technocranes/technocrane-unreal/blob/master/Images/setup_1.jpg)]() 32 | 33 | When you are opening project for a first time, you have to go to Settings->Plugins, find there Technocrane Plugin and Enable it. 34 | [![TechnocranePlugin](https://github.com/technocranes/technocrane-unreal/blob/master/Images/TechnocranePlugin.JPG)]() 35 | 36 | Next step will be to open a live link hub 37 | [![Step2](https://github.com/technocranes/technocrane-unreal/blob/master/Images/setup_2.jpg)]() 38 | 39 | In the Live Link window you should add a new source. Should it be a network connection or connection by using a serial port? You should specify some connection settings there. The values are based on default settings for Technocrane plugin. 40 | [![Setup3](https://github.com/technocranes/technocrane-unreal/blob/master/Images/setup_3.jpg)]() 41 | 42 | Then Source has been added and you see Camera subject with green status of receving data, then you can connect that to any cinematic camera in the scene. Add Live Link Component Controller to a cinematic camera. 43 | [![Step4](https://github.com/technocranes/technocrane-unreal/blob/master/Images/setup_4.jpg)]() 44 | 45 | Default settings and camera frames rate are presented in project settings under technocrane tracker group 46 | [![Settings](https://github.com/technocranes/technocrane-unreal/blob/master/Images/setup_6.jpg)]() 47 | 48 | # Live Link Frame Meta Data and Properties 49 | 50 | Every Frame Data constains additional meta data 51 | * CameraOn - 1/0 values 52 | * Running - 1/0 values 53 | * IsZoomCalibrated - 1/0 values 54 | * IsFocusCalibrated - 1/0 values 55 | * IsIrisCalibrated - 1/0 values 56 | * PacketNumber - number of a packet 57 | * HasTimeCode - packet data recevies time code, 1/0 58 | * RawTimeCode - raw packet timecode value 59 | * FrameRate - string of camera frame rate (according to technocrane project settings) 60 | 61 | Every Frame Data contains property values 62 | * TrackPosition 63 | * PacketNumber 64 | * raw x 65 | * raw y 66 | * raw z 67 | * raw pan 68 | * raw tilt 69 | * raw roll 70 | * CameraOn 71 | * Running 72 | 73 | [![FrameDataPrint](https://github.com/technocranes/technocrane-unreal/blob/master/Images/frame_data_print.jpg)]() 74 | 75 | 76 | # Video Tutorial 77 | 78 | [![plugin_introduction](https://youtu.be/Nxp08jvDGdk)](https://youtu.be/Nxp08jvDGdk) 79 | 80 | # Contact 81 | 82 | Please post issues and feature requests to this [github repository issues section](https://github.com/technocranes/technocrane-unreal/issues) 83 | -------------------------------------------------------------------------------- /Resources/Icon128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Resources/Icon128.png -------------------------------------------------------------------------------- /Source/TechnocraneEditor/Private/CameraAssetTypeActions.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // CameraAssetTypeActions.cpp 6 | // Sergei Solokhin 7 | 8 | #include "CameraAssetTypeActions.h" 9 | #include "TechnocraneEditorPCH.h" 10 | 11 | #include "TechnocraneCamera.h" 12 | 13 | #include "UObject/ObjectMacros.h" 14 | #include "UObject/Object.h" 15 | 16 | #define LOCTEXT_NAMESPACE "TechnocraneCamera" 17 | 18 | ////////////////////////////////////////////////////////////////////////// 19 | // FFlipbookAssetTypeActions 20 | 21 | FAssetTypeActions_TechnocraneCamera::FAssetTypeActions_TechnocraneCamera(EAssetTypeCategories::Type InAssetCategory) 22 | : MyAssetCategory(InAssetCategory) 23 | { 24 | } 25 | 26 | FText FAssetTypeActions_TechnocraneCamera::GetName() const 27 | { 28 | return LOCTEXT("FCameraAssetTypeActionsName", "Technocrane Camera"); 29 | } 30 | 31 | FColor FAssetTypeActions_TechnocraneCamera::GetTypeColor() const 32 | { 33 | return FColor(129, 196, 115); 34 | } 35 | 36 | UClass* FAssetTypeActions_TechnocraneCamera::GetSupportedClass() const 37 | { 38 | return ATDCamera::StaticClass(); 39 | } 40 | 41 | uint32 FAssetTypeActions_TechnocraneCamera::GetCategories() 42 | { 43 | return MyAssetCategory; // EAssetTypeCategories::Animation | 44 | } 45 | 46 | ////////////////////////////////////////////////////////////////////////// 47 | 48 | UTechnocraneCameraFactory::UTechnocraneCameraFactory(const FObjectInitializer& ObjectInitializer) 49 | : Super(ObjectInitializer) 50 | { 51 | SupportedClass = ATDCamera::StaticClass(); 52 | 53 | bCreateNew = true; 54 | bEditorImport = false; 55 | bEditAfterNew = true; 56 | } 57 | 58 | UObject* UTechnocraneCameraFactory::FactoryCreateNew(UClass* Class, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) 59 | { 60 | ATDCamera* NewPreset = NewObject(InParent, InName, Flags); 61 | return NewPreset; 62 | } 63 | 64 | #undef LOCTEXT_NAMESPACE 65 | -------------------------------------------------------------------------------- /Source/TechnocraneEditor/Private/CameraAssetTypeActions.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // CameraAssetTypeActions.h 6 | // Sergei Solokhin 7 | 8 | #pragma once 9 | 10 | #include "CoreMinimal.h" 11 | #include "Stats/Stats.h" 12 | #include "AssetToolsModule.h" 13 | #include "Factories/Factory.h" 14 | #include "AssetTypeActions_Base.h" 15 | 16 | #include "CameraAssetTypeActions.generated.h" 17 | 18 | class FAssetTypeActions_TechnocraneCamera : public FAssetTypeActions_Base 19 | { 20 | public: 21 | FAssetTypeActions_TechnocraneCamera(EAssetTypeCategories::Type InAssetCategory); 22 | 23 | // IAssetTypeActions interface 24 | virtual FText GetName() const override; 25 | virtual FColor GetTypeColor() const override; 26 | virtual UClass* GetSupportedClass() const override; 27 | virtual uint32 GetCategories() override; 28 | virtual void OpenAssetEditor(const TArray& InObjects, TSharedPtr EditWithinLevelEditor = TSharedPtr()) override 29 | {} 30 | // End of IAssetTypeActions interface 31 | 32 | private: 33 | EAssetTypeCategories::Type MyAssetCategory; 34 | }; 35 | 36 | UCLASS(MinimalAPI, hidecategories = Object) 37 | class UTechnocraneCameraFactory : public UFactory 38 | { 39 | GENERATED_UCLASS_BODY() 40 | 41 | //~ Begin UFactory Interface 42 | virtual UObject* FactoryCreateNew(UClass* Class, UObject* InParent, FName Name, EObjectFlags Flags, UObject* Context, FFeedbackContext* Warn) override; 43 | //~ Begin UFactory Interface 44 | }; -------------------------------------------------------------------------------- /Source/TechnocraneEditor/Private/CameraDetailsCustomization.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // CameraDetailsCustomization.cpp 6 | // Sergei Solokhin 7 | 8 | #include "CameraDetailsCustomization.h" 9 | #include "TechnocraneEditorPCH.h" 10 | 11 | #include "DetailLayoutBuilder.h" 12 | #include "IDetailChildrenBuilder.h" 13 | #include "IDetailPropertyRow.h" 14 | #include "DetailCategoryBuilder.h" 15 | #include "PropertyCustomizationHelpers.h" 16 | 17 | #include "Widgets/Text/STextBlock.h" 18 | #include "Widgets/Images/SImage.h" 19 | #include "Widgets/Layout/SBox.h" 20 | #include "Widgets/SToolTip.h" 21 | 22 | #include "TechnocraneCamera.h" 23 | #include 24 | 25 | #define LOCTEXT_NAMESPACE "TechnocraneCamera" 26 | 27 | ////////////////////////////////////////////////////////////////////////// 28 | // FFlipbookComponentDetailsCustomization 29 | 30 | TSharedRef FCameraDetailsCustomization::MakeInstance() 31 | { 32 | return MakeShareable(new FCameraDetailsCustomization); 33 | } 34 | 35 | void FCameraDetailsCustomization::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder) 36 | { 37 | // Create a category so this is displayed early in the properties 38 | DetailBuilder.EditCategory("Tracking Raw Data", FText::GetEmpty(), ECategoryPriority::Important); 39 | DetailBuilder.EditCategory("Tracking Calibrated", FText::GetEmpty(), ECategoryPriority::Important); 40 | DetailBuilder.EditCategory("Tracking Options", FText::GetEmpty(), ECategoryPriority::Important); 41 | } 42 | 43 | 44 | ////////////////////////////////////////////////////////////////////////// 45 | 46 | #undef LOCTEXT_NAMESPACE 47 | -------------------------------------------------------------------------------- /Source/TechnocraneEditor/Private/CameraDetailsCustomization.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // CameraDetailsCustomization.h 6 | // Sergei Solokhin 7 | 8 | #pragma once 9 | 10 | #include "CoreMinimal.h" 11 | #include "IDetailCustomization.h" 12 | 13 | class IDetailCategoryBuilder; 14 | class IDetailLayoutBuilder; 15 | class ATechnocraneCamera; 16 | 17 | ////////////////////////////////////////////////////////////////////////// 18 | // FFlipbookComponentDetailsCustomization 19 | 20 | class FCameraDetailsCustomization : public IDetailCustomization 21 | { 22 | public: 23 | /** Makes a new instance of this detail layout class for a specific detail view requesting it */ 24 | static TSharedRef MakeInstance(); 25 | 26 | // IDetailCustomization interface 27 | virtual void CustomizeDetails(IDetailLayoutBuilder& DetailLayout) override; 28 | // End of IDetailCustomization interface 29 | }; 30 | -------------------------------------------------------------------------------- /Source/TechnocraneEditor/Private/TechnocraneEditorModule.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // TechnocraneEditorModule.cpp 4 | // Sergei Solokhin 5 | 6 | #include "TechnocraneEditorModule.h" 7 | #include "TechnocraneEditorPCH.h" 8 | 9 | #include "Stats/Stats.h" 10 | #include "Modules/ModuleInterface.h" 11 | #include "Modules/ModuleManager.h" 12 | //#include "LevelEditor/Public/LevelEditor.h" 13 | //#include "LevelEditor/Private/SLevelEditor.h" 14 | //#include "LevelEditor/Public/SLevelViewport.h" 15 | #include "AssetToolsModule.h" 16 | #include "Factories/Factory.h" 17 | #include "AssetTypeActions_Base.h" 18 | 19 | #include "AssetToolsModule.h" 20 | #include "PropertyEditorModule.h" 21 | #include "IAssetTypeActions.h" 22 | 23 | #include "CameraAssetTypeActions.h" 24 | #include "CameraDetailsCustomization.h" 25 | 26 | #include "TechnocraneCamera.h" 27 | #include "TechnocraneEditorCommands.h" 28 | #include "TechnocraneEditorStyle.h" 29 | 30 | // Settings 31 | #include "TechnocraneRuntimeSettings.h" 32 | #include "ISettingsModule.h" 33 | 34 | #define LOCTEXT_NAMESPACE "TechnocraneCamera" 35 | 36 | IMPLEMENT_MODULE(FTechnocraneEditorModule, TechnocraneEditor) 37 | 38 | static EAssetTypeCategories::Type TechnocraneAssetCategoryBit; 39 | 40 | /** All created asset type actions. Cached here so that we can unregister them during shutdown. */ 41 | TArray< TSharedPtr > CreatedAssetTypeActions; 42 | 43 | void RegisterAssetTypeAction(IAssetTools& AssetTools, TSharedRef Action) 44 | { 45 | AssetTools.RegisterAssetTypeActions(Action); 46 | CreatedAssetTypeActions.Add(Action); 47 | } 48 | 49 | void RegisterSettings() 50 | { 51 | if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings")) 52 | { 53 | SettingsModule->RegisterSettings("Project", "Plugins", "TechnocranePlugin", 54 | LOCTEXT("RuntimeSettingsName", "Technocrane Tracker"), 55 | LOCTEXT("RuntimeSettingsDescription", "Configure the Technocrane plugin"), 56 | GetMutableDefault()); 57 | } 58 | } 59 | 60 | void UnregisterSettings() 61 | { 62 | if (ISettingsModule* SettingsModule = FModuleManager::GetModulePtr("Settings")) 63 | { 64 | SettingsModule->UnregisterSettings("Project", "Plugins", "TechnocranePlugin"); 65 | } 66 | } 67 | 68 | void FTechnocraneEditorModule::StartupModule() 69 | { 70 | // Register the new assets 71 | { 72 | IAssetTools& AssetTools = FModuleManager::LoadModuleChecked("AssetTools").Get(); 73 | 74 | TechnocraneAssetCategoryBit = AssetTools.RegisterAdvancedAssetCategory(FName(TEXT("Technocrane")), LOCTEXT("TechnocraneAssetCategory", "Technocrane")); 75 | 76 | RegisterAssetTypeAction(AssetTools, MakeShareable(new FAssetTypeActions_TechnocraneCamera(TechnocraneAssetCategoryBit))); 77 | 78 | } 79 | 80 | // Register the details customizations 81 | { 82 | FPropertyEditorModule& PropertyModule = FModuleManager::LoadModuleChecked("PropertyEditor"); 83 | PropertyModule.RegisterCustomClassLayout(ATDCamera::StaticClass()->GetFName(), FOnGetDetailCustomizationInstance::CreateStatic(&FCameraDetailsCustomization::MakeInstance)); 84 | 85 | PropertyModule.NotifyCustomizationModuleChanged(); 86 | } 87 | 88 | // Settings 89 | RegisterSettings(); 90 | 91 | // 92 | FTechnocraneEditorStyle::Initialize(); 93 | FTechnocraneEditorStyle::ReloadTextures(); 94 | 95 | FTechnocraneEditorCommands::Register(); 96 | 97 | // Toolbar 98 | PluginCommands = MakeShareable(new FUICommandList); 99 | 100 | // Dummy action for main toolbar button 101 | PluginCommands->MapAction( 102 | FTechnocraneEditorCommands::Get().PluginAction, 103 | FExecuteAction::CreateRaw(this, &FTechnocraneEditorModule::PluginButtonClicked), 104 | FCanExecuteAction()); 105 | 106 | // TODO: add functionality and activate the toolbar button 107 | // Only add the toolbar if TechnocranePlugin is the currently active 108 | //static FName SystemName(TEXT("Technocrane")); 109 | //if (FModuleManager::Get().IsModuleLoaded("TechnocranePlugin")) 110 | //{ 111 | // TSharedPtr ToolbarExtender = MakeShareable(new FExtender); 112 | // ToolbarExtender->AddToolBarExtension("Settings", EExtensionHook::After, PluginCommands, FToolBarExtensionDelegate::CreateRaw(this, &FTechnocraneEditorModule::AddToolbarExtension)); 113 | // 114 | // FLevelEditorModule& LevelEditorModule = FModuleManager::LoadModuleChecked("LevelEditor"); 115 | // LevelEditorModule.GetToolBarExtensibilityManager()->AddExtender(ToolbarExtender); 116 | //} 117 | } 118 | 119 | void FTechnocraneEditorModule::PluginButtonClicked() 120 | { 121 | // Empty on purpose 122 | } 123 | 124 | void FTechnocraneEditorModule::AddToolbarExtension(FToolBarBuilder& Builder) 125 | { 126 | Builder.AddComboButton( 127 | FUIAction(FExecuteAction::CreateRaw(this, &FTechnocraneEditorModule::PluginButtonClicked)), 128 | FOnGetContent::CreateRaw(this, &FTechnocraneEditorModule::FillComboButton, PluginCommands), 129 | LOCTEXT("TechnocraneInputBtn", "Technocrane"), 130 | LOCTEXT("TechnocraneInputBtnTootlip", "Technocrane"), 131 | FSlateIcon(FTechnocraneEditorStyle::GetStyleSetName(), "TechnocraneEditor.PluginAction") 132 | ); 133 | } 134 | 135 | TSharedRef FTechnocraneEditorModule::FillComboButton(TSharedPtr Commands) 136 | { 137 | FMenuBuilder MenuBuilder(true, Commands); 138 | 139 | return MenuBuilder.MakeWidget(); 140 | } 141 | 142 | void FTechnocraneEditorModule::ShutdownModule() 143 | { 144 | UnregisterSettings(); 145 | 146 | // Unregister all the asset types that we registered 147 | if (FModuleManager::Get().IsModuleLoaded("AssetTools")) 148 | { 149 | IAssetTools& AssetTools = FModuleManager::GetModuleChecked("AssetTools").Get(); 150 | for (int32 Index = 0; Index < CreatedAssetTypeActions.Num(); ++Index) 151 | { 152 | AssetTools.UnregisterAssetTypeActions(CreatedAssetTypeActions[Index].ToSharedRef()); 153 | } 154 | } 155 | CreatedAssetTypeActions.Empty(); 156 | } 157 | 158 | 159 | -------------------------------------------------------------------------------- /Source/TechnocraneEditor/Private/TechnocraneEditorPCH.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // TechnocraneEditorPCH.h 4 | // Sergei Solokhin 5 | 6 | #pragma once 7 | 8 | #include "CoreMinimal.h" 9 | -------------------------------------------------------------------------------- /Source/TechnocraneEditor/Private/TechnocraneEditorStyle.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneEditorStyle.cpp 6 | // Sergei Solokhin 7 | 8 | #include "TechnocraneEditorStyle.h" 9 | #include "Runtime/Projects/Public/Interfaces/IPluginManager.h" 10 | 11 | TSharedPtr< FSlateStyleSet > FTechnocraneEditorStyle::StyleInstance = nullptr; 12 | 13 | void FTechnocraneEditorStyle::Initialize() 14 | { 15 | if (!StyleInstance.IsValid()) 16 | { 17 | StyleInstance = Create(); 18 | FSlateStyleRegistry::RegisterSlateStyle(*StyleInstance); 19 | } 20 | } 21 | 22 | void FTechnocraneEditorStyle::Shutdown() 23 | { 24 | FSlateStyleRegistry::UnRegisterSlateStyle(*StyleInstance); 25 | ensure(StyleInstance.IsUnique()); 26 | StyleInstance.Reset(); 27 | } 28 | 29 | FName FTechnocraneEditorStyle::GetStyleSetName() 30 | { 31 | static FName StyleSetName(TEXT("TechnocraneEditorStyle")); 32 | return StyleSetName; 33 | } 34 | 35 | #define IMAGE_BRUSH( RelativePath, ... ) FSlateImageBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) 36 | #define BOX_BRUSH( RelativePath, ... ) FSlateBoxBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) 37 | #define BORDER_BRUSH( RelativePath, ... ) FSlateBorderBrush( Style->RootToContentDir( RelativePath, TEXT(".png") ), __VA_ARGS__ ) 38 | #define TTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".ttf") ), __VA_ARGS__ ) 39 | #define OTF_FONT( RelativePath, ... ) FSlateFontInfo( Style->RootToContentDir( RelativePath, TEXT(".otf") ), __VA_ARGS__ ) 40 | 41 | const FVector2D Icon16x16(16.0f, 16.0f); 42 | const FVector2D Icon20x20(20.0f, 20.0f); 43 | const FVector2D Icon40x40(40.0f, 40.0f); 44 | 45 | TSharedRef< FSlateStyleSet > FTechnocraneEditorStyle::Create() 46 | { 47 | TSharedRef< FSlateStyleSet > Style = MakeShareable(new FSlateStyleSet("TechnocraneEditorStyle")); 48 | FString base_dir{ IPluginManager::Get().FindPlugin("TechnocranePlugin")->GetBaseDir() / TEXT("Resources") }; 49 | Style->SetContentRoot(base_dir); 50 | 51 | Style->Set("TechnocraneEditor.PluginAction", new IMAGE_BRUSH(TEXT("Icon40"), Icon40x40)); 52 | 53 | return Style; 54 | } 55 | 56 | #undef IMAGE_BRUSH 57 | #undef BOX_BRUSH 58 | #undef BORDER_BRUSH 59 | #undef TTF_FONT 60 | #undef OTF_FONT 61 | 62 | void FTechnocraneEditorStyle::ReloadTextures() 63 | { 64 | if (FSlateApplication::IsInitialized()) 65 | { 66 | FSlateApplication::Get().GetRenderer()->ReloadTextureResources(); 67 | } 68 | } 69 | 70 | const ISlateStyle& FTechnocraneEditorStyle::Get() 71 | { 72 | return *StyleInstance; 73 | } 74 | -------------------------------------------------------------------------------- /Source/TechnocraneEditor/Public/TechnocraneEditorCommands.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneEditorCommands.cpp 6 | // Sergei Solokhin 2020 7 | 8 | #include "TechnocraneEditorCommands.h" 9 | 10 | #define LOCTEXT_NAMESPACE "TechnocraneCamera" 11 | 12 | void FTechnocraneEditorCommands::RegisterCommands() 13 | { 14 | UI_COMMAND(PluginAction, "TechnocraneEditor", "Add Tracker to a camera", EUserInterfaceActionType::Button, FInputGesture()); 15 | } 16 | 17 | #undef LOCTEXT_NAMESPACE // "TechnocraneEditor" -------------------------------------------------------------------------------- /Source/TechnocraneEditor/Public/TechnocraneEditorCommands.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneEditorCommands.h 6 | // Sergei Solokhin 7 | 8 | #pragma once 9 | 10 | class FTechnocraneEditorCommands : public TCommands 11 | { 12 | public: 13 | 14 | FTechnocraneEditorCommands() 15 | : TCommands(TEXT("TechnocraneEditor"), NSLOCTEXT("Contexts", "TechncraneEditor", "TechnocraneEditor Plugin"), NAME_None, TEXT("TechnocraneEditor.Common.Icon")) 16 | { 17 | } 18 | 19 | // TCommands<> interface 20 | virtual void RegisterCommands() override; 21 | 22 | public: 23 | TSharedPtr PluginAction; 24 | }; 25 | -------------------------------------------------------------------------------- /Source/TechnocraneEditor/Public/TechnocraneEditorModule.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneEditorModule.h 6 | // Sergei Solokhin 7 | 8 | #pragma once 9 | 10 | #include "CoreMinimal.h" 11 | #include "Modules/ModuleInterface.h" 12 | #include "Modules/ModuleManager.h" 13 | 14 | class FToolBarBuilder; 15 | class SWidget; 16 | 17 | class FTechnocraneEditorModule : public IModuleInterface 18 | { 19 | public: 20 | 21 | // IModuleInterface interface 22 | virtual void StartupModule() override; 23 | virtual void ShutdownModule() override; 24 | 25 | protected: 26 | 27 | void PluginButtonClicked(); 28 | 29 | void AddToolbarExtension(FToolBarBuilder& Builder); 30 | 31 | TSharedPtr PluginCommands; 32 | TSharedRef FillComboButton(TSharedPtr Commands); 33 | }; 34 | -------------------------------------------------------------------------------- /Source/TechnocraneEditor/Public/TechnocraneEditorStyle.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneEditorStyle.h 6 | // Sergei Solokhin 7 | 8 | #pragma once 9 | 10 | #include "Styling/SlateStyle.h" 11 | #include "Styling/SlateStyleRegistry.h" 12 | #include "Framework/Application/SlateApplication.h" 13 | #include "Framework/MultiBox/MultiBoxBuilder.h" 14 | #include "Framework/Commands/Commands.h" 15 | #include "Framework/Commands/UIAction.h" 16 | #include "Framework/Commands/UICommandInfo.h" 17 | 18 | 19 | class FTechnocraneEditorStyle 20 | { 21 | public: 22 | static void Initialize(); 23 | 24 | static void Shutdown(); 25 | 26 | /** reloads textures used by slate renderer */ 27 | static void ReloadTextures(); 28 | 29 | /** @return The Slate style set */ 30 | static const ISlateStyle& Get(); 31 | 32 | static FName GetStyleSetName(); 33 | 34 | private: 35 | 36 | static TSharedRef< class FSlateStyleSet > Create(); 37 | static TSharedPtr< class FSlateStyleSet > StyleInstance; 38 | }; -------------------------------------------------------------------------------- /Source/TechnocraneEditor/TechnocraneEditor.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneEditor.Build.cs 6 | // Sergei Solokhin 7 | 8 | using Path = System.IO.Path; 9 | 10 | namespace UnrealBuildTool.Rules 11 | { 12 | public class TechnocraneEditor : ModuleRules 13 | { 14 | public TechnocraneEditor(ReadOnlyTargetRules Target) : base(Target) 15 | { 16 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 17 | 18 | bLegacyPublicIncludePaths = false; 19 | 20 | PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Public")); 21 | PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Private")); 22 | 23 | // NOTE: for debug purpose 24 | //OptimizeCode = CodeOptimization.Never; 25 | 26 | PublicDependencyModuleNames.AddRange( 27 | new string[] { 28 | "Core", 29 | "CoreUObject", 30 | "Slate", 31 | "SlateCore", 32 | "Engine", 33 | "EditorStyle", 34 | "UnrealEd", 35 | "MainFrame", 36 | "RHI", 37 | "LevelEditor", 38 | } 39 | ); 40 | 41 | PrivateIncludePathModuleNames.AddRange( 42 | new string[] { 43 | "Settings", 44 | "AssetTools", 45 | }); 46 | 47 | PrivateDependencyModuleNames.AddRange( 48 | new string[] { 49 | "Projects", 50 | "InputCore", 51 | "UnrealEd", 52 | "LevelEditor", 53 | "CoreUObject", 54 | "Engine", 55 | "Slate", 56 | "SlateCore", 57 | "TechnocranePlugin" 58 | } 59 | ); 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/LiveLinkTechnocraneSource.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // LiveLinkTechnocraneSource.cpp 6 | // Sergei Solokhin 7 | 8 | #include "LiveLinkTechnocraneSource.h" 9 | 10 | #include "ILiveLinkClient.h" 11 | #include "LiveLinkTypes.h" 12 | 13 | #include "Roles/LiveLinkCameraRole.h" 14 | #include "Roles/LiveLinkCameraTypes.h" 15 | #include "Roles/LiveLinkTransformRole.h" 16 | #include "Roles/LiveLinkTransformTypes.h" 17 | 18 | #include "Async/Async.h" 19 | #include "HAL/RunnableThread.h" 20 | #include "Json.h" 21 | 22 | #include "TechnocraneRuntimeSettings.h" 23 | #include "LiveLinkTechnocraneTypes.h" 24 | 25 | #include "Windows/WindowsPlatformTime.h" 26 | 27 | #define LOCTEXT_NAMESPACE "TechnocraneLiveLinkSource" 28 | 29 | //////////////////////////////////////////////////////////////////////////////////////////// 30 | // FLiveLinkTechnocraneSource 31 | 32 | FLiveLinkTechnocraneSource::FLiveLinkTechnocraneSource(bool use_network, int serial_port, FIPv4Endpoint address, bool bind_any_address, bool broadcast) 33 | : m_Stopping(false) 34 | , m_CreateStaticSubject(true) 35 | , m_Thread(nullptr) 36 | { 37 | // defaults 38 | m_UseNetwork = use_network; 39 | m_NetworkAddress = address; 40 | m_NetworkBindAnyAddress = bind_any_address; 41 | m_NetworkBroadcast = broadcast; 42 | m_SerialPort = serial_port; 43 | 44 | // Live link params 45 | m_SourceStatus = LOCTEXT("SourceStatus_Waiting", "Waiting"); 46 | m_SourceType = LOCTEXT("TechnocraneLiveLinkSourceType", "Technocrane"); 47 | 48 | if (use_network) 49 | { 50 | m_SourceMachineName = address.ToText(); 51 | } 52 | else 53 | { 54 | m_SourceMachineName = FText::FromString(TEXT("COM ") + FString::FromInt(serial_port)); 55 | } 56 | 57 | m_Hardware = new NTechnocrane::CTechnocrane_Hardware(); 58 | m_Hardware->Init(false, false, false); 59 | 60 | Start(); 61 | } 62 | 63 | FLiveLinkTechnocraneSource::~FLiveLinkTechnocraneSource() 64 | { 65 | Stop(); 66 | if (m_Thread != nullptr) 67 | { 68 | m_Thread->WaitForCompletion(); 69 | delete m_Thread; 70 | m_Thread = nullptr; 71 | } 72 | 73 | if (m_Hardware) 74 | { 75 | delete m_Hardware; 76 | m_Hardware = nullptr; 77 | } 78 | } 79 | 80 | void FLiveLinkTechnocraneSource::ReceiveClient(ILiveLinkClient* InClient, FGuid InSourceGuid) 81 | { 82 | m_Client = InClient; 83 | m_SourceGuid = InSourceGuid; 84 | } 85 | 86 | bool FLiveLinkTechnocraneSource::IsSourceStillValid() const 87 | { 88 | // Source is valid if we have a valid thread and socket 89 | bool is_source_valid = (!m_Stopping && m_Thread != nullptr && m_Hardware != nullptr); 90 | return is_source_valid; 91 | } 92 | 93 | bool FLiveLinkTechnocraneSource::RequestSourceShutdown() 94 | { 95 | Stop(); 96 | return true; 97 | } 98 | 99 | // FRunnable interface 100 | 101 | void FLiveLinkTechnocraneSource::Start() 102 | { 103 | m_ThreadName = "Technocrane Receiver "; 104 | m_ThreadName.AppendInt(FAsyncThreadIndex::GetNext()); 105 | 106 | m_Thread = FRunnableThread::Create(this, *m_ThreadName, 128 * 1024, TPri_AboveNormal, FPlatformAffinity::GetPoolThreadMask()); 107 | } 108 | 109 | void FLiveLinkTechnocraneSource::Stop() 110 | { 111 | m_Stopping = true; 112 | } 113 | 114 | void FLiveLinkTechnocraneSource::UpdateStatus(const NTechnocrane::STechnocrane_Packet& packet, const bool force_update, const float rate) 115 | { 116 | const bool flags[4] = { packet.HasTimeCode(), packet.IsZoomCalibrated, packet.IsIrisCalibrated, packet.IsFocusCalibrated }; 117 | const bool updated_rate = std::abs(rate - m_LastRate) > 1.0f; 118 | 119 | if (updated_rate || force_update || flags[0] != m_LastStatusFlags[0] || flags[1] != m_LastStatusFlags[1] || flags[2] != m_LastStatusFlags[2] || flags[3] != m_LastStatusFlags[3]) 120 | { 121 | FString text; 122 | text = FString::Format(TEXT("Receiving {0} [T:{1}, Z:{2}, F:{3}, I:{4}]"), 123 | { 124 | FString::SanitizeFloat(floorf(rate), 2), 125 | (packet.HasTimeCode()) ? TEXT("Y") : TEXT("N"), 126 | (packet.IsZoomCalibrated) ? TEXT("Y") : TEXT("N"), 127 | (packet.IsFocusCalibrated) ? TEXT("Y") : TEXT("N"), 128 | (packet.IsIrisCalibrated) ? TEXT("Y") : TEXT("N") 129 | } 130 | ); 131 | 132 | m_SourceStatus = FText::FromString(text); 133 | 134 | memcpy(m_LastStatusFlags, flags, sizeof(bool) * 4); 135 | m_LastRate = rate; 136 | } 137 | } 138 | 139 | uint32 FLiveLinkTechnocraneSource::Run() 140 | { 141 | bool first_enter{ true }; 142 | float last_timestamp = FPlatformTime::Seconds(); 143 | constexpr float reset_time{ 3.0f }; 144 | 145 | while (!m_Stopping) 146 | { 147 | if (!m_Hardware) 148 | break; 149 | 150 | const float curr_time = FPlatformTime::Seconds(); 151 | 152 | if (KeepLive(first_enter)) 153 | { 154 | memset(m_LastStatusFlags, 0, sizeof(m_LastStatusFlags)); 155 | m_LastRate = 0.0f; 156 | last_timestamp = curr_time; 157 | } 158 | 159 | if (m_Hardware->IsReady()) 160 | { 161 | const bool packed_data = GetDefault()->bPacketContainsRawAndCalibratedData; 162 | 163 | size_t index = 0; 164 | NTechnocrane::STechnocrane_Packet packet; 165 | 166 | if (m_Hardware->FetchDataPacket(packet, 1, index, packed_data) > 0) 167 | { 168 | const float rate = m_Hardware->GetTimeCodeRate(); 169 | UpdateStatus(packet, first_enter, rate); 170 | AsyncTask(ENamedThreads::GameThread, [this, packet]() { HandleReceivedData(packet); }); 171 | 172 | last_timestamp = curr_time; 173 | } 174 | } 175 | 176 | first_enter = ((curr_time - last_timestamp) > reset_time); 177 | } 178 | 179 | if (m_Hardware->IsReady()) 180 | { 181 | m_Hardware->StopDataStream(); 182 | m_Hardware->Close(); 183 | } 184 | 185 | return 0; 186 | } 187 | 188 | 189 | void FLiveLinkTechnocraneSource::HandleReceivedData(const NTechnocrane::STechnocrane_Packet& packet) 190 | { 191 | if (m_Stopping) 192 | return; 193 | 194 | const UTechnocraneRuntimeSettings* settings = GetDefault(); 195 | 196 | if (!settings) 197 | return; 198 | 199 | const float x = packet.Position[2]; 200 | const float y = packet.Position[0]; 201 | const float z = packet.Position[1]; 202 | 203 | const float space_scale = settings->SpaceScaleByDefault; 204 | 205 | FVector v(space_scale * y, space_scale * x, space_scale * z); 206 | FRotator rot(packet.Tilt, 90.0f + packet.Pan, packet.Roll); 207 | 208 | const float track_position = space_scale * packet.TrackPos; 209 | 210 | float zoom = 1.0; 211 | bool IsZoomCalibrated = NTechnocrane::ComputeZoomf(zoom, packet.Zoom, settings->ZoomRange.Min, settings->ZoomRange.Max); 212 | 213 | float iris = 1.0; 214 | bool IsIrisCalibrated = false; 215 | 216 | const bool packed_data = settings->bPacketContainsRawAndCalibratedData; 217 | if (!packed_data) 218 | { 219 | IsIrisCalibrated = NTechnocrane::ComputeIrisf(iris, packet.Iris, settings->IrisRange.Min, settings->IrisRange.Max); 220 | } 221 | 222 | float focus = 1.0; 223 | bool IsFocusCalibrated = NTechnocrane::ComputeFocusf(focus, packet.Focus, settings->FocusRange.Min, settings->FocusRange.Max); 224 | 225 | // 226 | // static data 227 | 228 | FName subject_name("CameraSubject"); 229 | 230 | if (m_CreateStaticSubject) 231 | { 232 | FLiveLinkStaticDataStruct StaticDataStruct = FLiveLinkStaticDataStruct(FLiveLinkCameraStaticData::StaticStruct()); 233 | FLiveLinkCameraStaticData& StaticData = *StaticDataStruct.Cast(); 234 | 235 | StaticData.bIsFieldOfViewSupported = false; 236 | StaticData.bIsFocalLengthSupported = true; 237 | StaticData.bIsFocusDistanceSupported = true; 238 | StaticData.bIsApertureSupported = true; 239 | 240 | StaticData.PropertyNames.Reset(static_cast(EPacketProperties::Total)); 241 | 242 | const char* property_names[static_cast(EPacketProperties::Total)] = { 243 | "TrackPosition", 244 | "PacketNumber", 245 | "X", 246 | "Y", 247 | "Z", 248 | "Pan", 249 | "Tilt", 250 | "Roll", 251 | "CameraOn", 252 | "Running" 253 | }; 254 | 255 | for (const char* name : property_names) 256 | { 257 | StaticData.PropertyNames.Add(name); 258 | } 259 | 260 | m_Client->PushSubjectStaticData_AnyThread({ m_SourceGuid, subject_name }, ULiveLinkCameraRole::StaticClass(), MoveTemp(StaticDataStruct)); 261 | 262 | m_CreateStaticSubject = false; 263 | } 264 | 265 | 266 | // 267 | // dynamic data 268 | 269 | FLiveLinkFrameDataStruct FrameDataStruct = FLiveLinkFrameDataStruct(FLiveLinkCameraFrameData::StaticStruct()); 270 | FLiveLinkCameraFrameData& FrameData = *FrameDataStruct.Cast(); 271 | 272 | FrameData.FocalLength = zoom; 273 | FrameData.FocusDistance = space_scale * focus; 274 | FrameData.Aperture = iris; 275 | 276 | const bool has_timecode = packet.HasTimeCode(); 277 | const int32 packet_number = packet.PacketNumber; 278 | 279 | FTimecode TimeCode; 280 | FFrameRate FrameRate(settings->CameraFrameRate); 281 | 282 | if (has_timecode) 283 | { 284 | TimeCode.Hours = packet.hours; 285 | TimeCode.Minutes = packet.minutes; 286 | TimeCode.Seconds = packet.seconds; 287 | TimeCode.Frames = packet.frames; 288 | } 289 | else 290 | { 291 | TimeCode.FromFrameNumber(FFrameNumber(static_cast(packet.frames)), 292 | FrameRate, false); 293 | } 294 | 295 | FrameData.Transform.SetTranslation(v); 296 | FrameData.Transform.SetRotation(rot.Quaternion()); 297 | FrameData.MetaData.SceneTime.Time = TimeCode.ToFrameNumber(FrameRate); 298 | 299 | FrameData.MetaData.StringMetaData.Add("CameraOn", (packet.CameraOn) ? "1" : "0"); 300 | FrameData.MetaData.StringMetaData.Add("Running", (packet.Running) ? "1" : "0"); 301 | 302 | FrameData.MetaData.StringMetaData.Add("IsZoomCalibrated", (IsZoomCalibrated) ? "1" : "0"); 303 | FrameData.MetaData.StringMetaData.Add("IsFocusCalibrated", (IsFocusCalibrated) ? "1" : "0"); 304 | FrameData.MetaData.StringMetaData.Add("IsIrisCalibrated", (IsIrisCalibrated) ? "1" : "0"); 305 | 306 | FrameData.MetaData.StringMetaData.Add("PacketNumber", FString::FromInt(packet_number)); 307 | 308 | FrameData.MetaData.StringMetaData.Add("HasTimeCode", (has_timecode) ? "1" : "0"); 309 | FrameData.MetaData.StringMetaData.Add("RawTimeCode", TimeCode.ToString()); 310 | 311 | FrameData.MetaData.StringMetaData.Add("FrameRate", FrameRate.ToPrettyText().ToString()); 312 | 313 | const float property_values[static_cast(EPacketProperties::Total)] = { 314 | track_position, 315 | static_cast(packet_number), 316 | packet.Position[0], 317 | packet.Position[1], 318 | packet.Position[2], 319 | packet.Pan, 320 | packet.Tilt, 321 | packet.Roll, 322 | static_cast(packet.CameraOn), 323 | static_cast(packet.Running) 324 | }; 325 | 326 | FrameData.PropertyValues.Reserve(static_cast(EPacketProperties::Total)); 327 | for (const float prop : property_values) 328 | { 329 | FrameData.PropertyValues.Add(prop); 330 | } 331 | 332 | FrameData.WorldTime = FPlatformTime::Seconds(); 333 | m_Client->PushSubjectFrameData_AnyThread({ m_SourceGuid, subject_name }, MoveTemp(FrameDataStruct)); 334 | } 335 | 336 | bool FLiveLinkTechnocraneSource::KeepLive(const bool compare_options) 337 | { 338 | bool need_restart = false; 339 | 340 | if (m_Hardware->IsReady() && compare_options) 341 | { 342 | NTechnocrane::SOptions options; 343 | options = m_Hardware->GetOptions(); 344 | 345 | NTechnocrane::SOptions camera_options(options); 346 | PrepareOptions(camera_options); 347 | 348 | if (!CompareOptions(options, camera_options)) 349 | { 350 | need_restart = true; 351 | } 352 | } 353 | 354 | if (need_restart) 355 | { 356 | m_Hardware->StopDataStream(); 357 | m_Hardware->Close(); 358 | } 359 | 360 | if (!m_Hardware->IsReady() ) 361 | { 362 | m_SourceStatus = LOCTEXT("SourceStatus_Waiting", "Waiting"); 363 | 364 | const double curr_time{ FPlatformTime::Seconds() }; 365 | constexpr double eps_time{ 7.0 }; 366 | 367 | if (curr_time - m_CooldownTimer > eps_time) 368 | { 369 | m_CooldownTimer = curr_time; 370 | 371 | NTechnocrane::SOptions options; 372 | options = m_Hardware->GetOptions(); 373 | PrepareOptions(options); 374 | m_Hardware->ClearLastError(); 375 | 376 | if (m_Hardware->Open(options)) 377 | { 378 | m_Hardware->StartDataStream(); 379 | return true; 380 | } 381 | else 382 | { 383 | UE_LOG(LogTemp, Log, TEXT("Failed to connect to a hardware on a specified port")); 384 | m_SourceStatus = LOCTEXT("SourceStatus_Failed", "Failed to Connect"); 385 | } 386 | } 387 | } 388 | return false; 389 | } 390 | 391 | void FLiveLinkTechnocraneSource::PrepareOptions(NTechnocrane::SOptions& options) 392 | { 393 | options.m_UseNetworkConnection = m_UseNetwork; 394 | 395 | options.m_BindAnyAddress = m_NetworkBindAnyAddress; 396 | options.m_Broadcast = m_NetworkBroadcast; 397 | options.m_NetworkPort = m_NetworkAddress.Port; // server port 398 | 399 | options.m_SerialPort = m_SerialPort; 400 | } 401 | 402 | bool FLiveLinkTechnocraneSource::CompareOptions(const NTechnocrane::SOptions& a, const NTechnocrane::SOptions& b) 403 | { 404 | if (a.m_UseNetworkConnection != b.m_UseNetworkConnection) 405 | { 406 | return false; 407 | } 408 | 409 | if (a.m_NetworkPort != b.m_NetworkPort) 410 | { 411 | return false; 412 | } 413 | 414 | if (a.m_SerialPort != b.m_SerialPort) 415 | { 416 | return false; 417 | } 418 | 419 | return true; 420 | } 421 | 422 | #undef LOCTEXT_NAMESPACE -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/LiveLinkTechnocraneSource.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // LiveLinkTechnocraneSource.h 6 | // Sergei Solokhin 7 | 8 | #pragma once 9 | 10 | #include "ILiveLinkSource.h" 11 | #include "HAL/Runnable.h" 12 | #include "HAL/ThreadSafeBool.h" 13 | #include "IMessageContext.h" 14 | #include "Interfaces/IPv4/IPv4Endpoint.h" 15 | 16 | #include 17 | 18 | class FRunnableThread; 19 | class FSocket; 20 | class ILiveLinkClient; 21 | class ISocketSubsystem; 22 | 23 | class TECHNOCRANEPLUGIN_API FLiveLinkTechnocraneSource : public ILiveLinkSource, public FRunnable 24 | { 25 | public: 26 | //! a constructor 27 | FLiveLinkTechnocraneSource(bool use_network, int serial_port, FIPv4Endpoint endpoint, bool bind_any_address, bool broadcast); 28 | //! a destructor 29 | virtual ~FLiveLinkTechnocraneSource(); 30 | 31 | // ILiveLinkSource interface 32 | 33 | void ReceiveClient(ILiveLinkClient* InClient, FGuid InSourceGuid) override; 34 | 35 | bool IsSourceStillValid() const override; 36 | bool RequestSourceShutdown() override; 37 | 38 | FText GetSourceType() const override { return m_SourceType; } 39 | FText GetSourceMachineName() const override { return m_SourceMachineName; } 40 | FText GetSourceStatus() const override { return m_SourceStatus; } 41 | 42 | // Begin FRunnable Interface 43 | 44 | virtual bool Init() override { return true; } 45 | virtual uint32 Run() override; 46 | void Start(); 47 | virtual void Stop() override; 48 | virtual void Exit() override { } 49 | 50 | // End FRunnable Interface 51 | 52 | void HandleReceivedData(const NTechnocrane::STechnocrane_Packet& packet); 53 | 54 | private: 55 | 56 | ILiveLinkClient* m_Client{ nullptr }; 57 | 58 | // Our identifier in LiveLink 59 | FGuid m_SourceGuid; 60 | 61 | FText m_SourceType; 62 | FText m_SourceMachineName; 63 | FText m_SourceStatus; 64 | 65 | bool m_LastStatusFlags[4]{ false }; 66 | float m_LastRate{ 0.0 }; 67 | 68 | bool m_UseNetwork; 69 | FIPv4Endpoint m_NetworkAddress; 70 | bool m_NetworkBindAnyAddress; 71 | bool m_NetworkBroadcast; 72 | 73 | int32 m_SerialPort; 74 | 75 | 76 | // Threadsafe Bool for terminating the main thread loop 77 | FThreadSafeBool m_Stopping; 78 | FThreadSafeBool m_CreateStaticSubject; 79 | 80 | // Thread to run socket operations on 81 | FRunnableThread* m_Thread; 82 | 83 | // Name of the sockets thread 84 | FString m_ThreadName; 85 | 86 | 87 | double m_CooldownTimer{ 0.0 }; 88 | 89 | NTechnocrane::CTechnocrane_Hardware* m_Hardware{ nullptr }; 90 | 91 | void PrepareOptions(NTechnocrane::SOptions& options); 92 | bool CompareOptions(const NTechnocrane::SOptions& a, const NTechnocrane::SOptions& b); 93 | 94 | bool KeepLive(const bool compare_options=false); 95 | void UpdateStatus(const NTechnocrane::STechnocrane_Packet& packet, const bool force_update, const float rate); 96 | }; -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/LiveLinkTechnocraneSourceFactory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // LiveLinkTechnocraneSourceFactory.cpp 6 | // Sergei Solokhin 7 | 8 | #include "LiveLinkTechnocraneSourceFactory.h" 9 | 10 | #include "LiveLinkTechnocraneSource.h" 11 | #include "SLiveLinkTechnocraneSourceFactory.h" 12 | 13 | #define LOCTEXT_NAMESPACE "LiveLinkTechnocraneSourceFactory" 14 | 15 | FText ULiveLinkTechnocraneSourceFactory::GetSourceDisplayName() const 16 | { 17 | return LOCTEXT("SourceDisplayName", "Technocrane LiveLink"); 18 | } 19 | 20 | FText ULiveLinkTechnocraneSourceFactory::GetSourceTooltip() const 21 | { 22 | return LOCTEXT("SourceTooltip", "Creates a connection to a Technocrane UDP Stream"); 23 | } 24 | 25 | TSharedPtr ULiveLinkTechnocraneSourceFactory::BuildCreationPanel(FOnLiveLinkSourceCreated InOnLiveLinkSourceCreated) const 26 | { 27 | return SNew(SLiveLinkTechnocraneSourceFactory) 28 | .OnOkClicked(SLiveLinkTechnocraneSourceFactory::FOnOkClicked::CreateUObject(this, &ULiveLinkTechnocraneSourceFactory::OnOkClicked, InOnLiveLinkSourceCreated)); 29 | } 30 | 31 | TSharedPtr ULiveLinkTechnocraneSourceFactory::CreateSource(const FString& InConnectionString) const 32 | { 33 | FIPv4Endpoint DeviceEndPoint; 34 | if (!FIPv4Endpoint::Parse(InConnectionString, DeviceEndPoint)) 35 | { 36 | return TSharedPtr(); 37 | } 38 | 39 | return MakeShared(true, 1, DeviceEndPoint, true, false); 40 | } 41 | 42 | void ULiveLinkTechnocraneSourceFactory::OnOkClicked(SCreationInfo info, FOnLiveLinkSourceCreated InOnLiveLinkSourceCreated) const 43 | { 44 | InOnLiveLinkSourceCreated.ExecuteIfBound(MakeShared( 45 | info.m_UseNetwork, 46 | info.m_SerialPort, 47 | info.m_Address, 48 | info.m_NetworkBindAny, 49 | info.m_NetworkBroadcast), 50 | info.m_Address.ToString()); 51 | } 52 | 53 | #undef LOCTEXT_NAMESPACE -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/LiveLinkTechnocraneSourceFactory.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // LiveLinkTechnocraneSourceFactory.h 6 | // Sergei Solokhin 7 | 8 | #pragma once 9 | 10 | #include "LiveLinkSourceFactory.h" 11 | #include "SLiveLinkTechnocraneSourceFactory.h" 12 | #include "LiveLinkTechnocraneSourceFactory.generated.h" 13 | 14 | 15 | class SLiveLinkTechnocraneSourceEditor; 16 | 17 | UCLASS() 18 | class ULiveLinkTechnocraneSourceFactory : public ULiveLinkSourceFactory 19 | { 20 | public: 21 | GENERATED_BODY() 22 | 23 | virtual FText GetSourceDisplayName() const; 24 | virtual FText GetSourceTooltip() const; 25 | 26 | virtual EMenuType GetMenuType() const override { return EMenuType::SubPanel; } 27 | virtual TSharedPtr BuildCreationPanel(FOnLiveLinkSourceCreated OnLiveLinkSourceCreated) const override; 28 | virtual TSharedPtr CreateSource(const FString& ConnectionString) const override; 29 | 30 | private: 31 | void OnOkClicked(SCreationInfo info, FOnLiveLinkSourceCreated OnLiveLinkSourceCreated) const; 32 | }; 33 | -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/LiveLinkTechnocraneTypes.h: -------------------------------------------------------------------------------- 1 | 2 | #pragma once 3 | 4 | enum class EPacketProperties : uint8 5 | { 6 | TrackPosition, 7 | PacketNumber, 8 | X, 9 | Y, 10 | Z, 11 | Pan, 12 | Tilt, 13 | Roll, 14 | CameraOn, 15 | Running, 16 | Total 17 | }; -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/SLiveLinkTechnocraneSourceFactory.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // SLiveLinkTechnocraneSourceFactory.cpp 6 | // Sergei Solokhin 7 | 8 | #include "SLiveLinkTechnocraneSourceFactory.h" 9 | 10 | #include "Interfaces/IPv4/IPv4Endpoint.h" 11 | #include "Widgets/SBoxPanel.h" 12 | #include "Widgets/Input/SButton.h" 13 | #include "Widgets/Input/SCheckBox.h" 14 | #include "Widgets/Input/SEditableTextBox.h" 15 | #include "Widgets/Input/SNumericEntryBox.h" 16 | #include "Widgets/Layout/SBox.h" 17 | #include "Widgets/Text/STextBlock.h" 18 | 19 | #include "TechnocraneRuntimeSettings.h" 20 | 21 | #define LOCTEXT_NAMESPACE "SLiveLinkTechnocraneSourceFactory" 22 | 23 | void SLiveLinkTechnocraneSourceFactory::Construct(const FArguments& Args) 24 | { 25 | OkClicked = Args._OnOkClicked; 26 | 27 | // default values 28 | 29 | const UTechnocraneRuntimeSettings* settings = GetDefault(); 30 | 31 | FIPv4Address address(FIPv4Address::Any); 32 | FIPv4Address::Parse(settings->NetworkServerAddressByDefault, address); 33 | 34 | FIPv4Endpoint Endpoint; 35 | Endpoint.Address = address; 36 | Endpoint.Port = settings->NetworkPortIdByDefault; 37 | 38 | const int serial_port = settings->SerialPortIdByDefault; 39 | m_SerialPortIndex = serial_port; 40 | 41 | auto GetNetworkVisibility = [&]() 42 | { 43 | TSharedPtr checkbox = m_UseNetworkConnection.Pin(); 44 | if (checkbox.IsValid()) 45 | { 46 | return checkbox->IsChecked() ? EVisibility::Visible : EVisibility::Collapsed; 47 | } 48 | return EVisibility::Collapsed; 49 | }; 50 | 51 | auto GetSerialVisibility = [&]() 52 | { 53 | TSharedPtr checkbox = m_UseNetworkConnection.Pin(); 54 | if (checkbox.IsValid()) 55 | { 56 | return checkbox->IsChecked() ? EVisibility::Collapsed : EVisibility::Visible; 57 | } 58 | return EVisibility::Collapsed; 59 | }; 60 | 61 | ChildSlot 62 | [ 63 | SNew(SBox) 64 | .WidthOverride(250) 65 | [ 66 | SNew(SVerticalBox) 67 | + SVerticalBox::Slot() 68 | .AutoHeight() 69 | [ 70 | SNew(SHorizontalBox) 71 | + SHorizontalBox::Slot() 72 | .HAlign(HAlign_Left) 73 | .FillWidth(0.5f) 74 | [ 75 | SNew(STextBlock) 76 | .Text(LOCTEXT("UseNetworkConnection", "Use Network Connection")) 77 | ] 78 | + SHorizontalBox::Slot() 79 | .HAlign(HAlign_Fill) 80 | .FillWidth(0.5f) 81 | [ 82 | SAssignNew(m_UseNetworkConnection, SCheckBox) 83 | ] 84 | ] 85 | + SVerticalBox::Slot() 86 | .AutoHeight() 87 | [ 88 | SNew(SHorizontalBox) 89 | + SHorizontalBox::Slot() 90 | .HAlign(HAlign_Left) 91 | .FillWidth(0.5f) 92 | [ 93 | SNew(STextBlock) 94 | .Text(LOCTEXT("NetworkBindAnyAddress", "Network Bind Any Address")) 95 | .Visibility_Lambda(GetNetworkVisibility) 96 | ] 97 | + SHorizontalBox::Slot() 98 | .HAlign(HAlign_Fill) 99 | .FillWidth(0.5f) 100 | [ 101 | SAssignNew(m_NetworkBindAnyAddress, SCheckBox) 102 | .Visibility_Lambda(GetNetworkVisibility) 103 | ] 104 | ] 105 | + SVerticalBox::Slot() 106 | .AutoHeight() 107 | [ 108 | SNew(SHorizontalBox) 109 | + SHorizontalBox::Slot() 110 | .HAlign(HAlign_Left) 111 | .FillWidth(0.5f) 112 | [ 113 | SNew(STextBlock) 114 | .Text(LOCTEXT("NetworkBroadcast", "Network Broadcast")) 115 | .Visibility_Lambda(GetNetworkVisibility) 116 | ] 117 | + SHorizontalBox::Slot() 118 | .HAlign(HAlign_Fill) 119 | .FillWidth(0.5f) 120 | [ 121 | SAssignNew(m_NetworkBroadcast, SCheckBox) 122 | .Visibility_Lambda(GetNetworkVisibility) 123 | ] 124 | ] 125 | + SVerticalBox::Slot() 126 | .AutoHeight() 127 | [ 128 | SNew(SHorizontalBox) 129 | + SHorizontalBox::Slot() 130 | .HAlign(HAlign_Left) 131 | .FillWidth(0.5f) 132 | [ 133 | SNew(STextBlock) 134 | .Text(LOCTEXT("UDPAddress", "Network Address:Port")) 135 | .Visibility_Lambda(GetNetworkVisibility) 136 | ] 137 | + SHorizontalBox::Slot() 138 | .HAlign(HAlign_Fill) 139 | .FillWidth(0.5f) 140 | [ 141 | SAssignNew(m_NetworkAddress, SEditableTextBox) 142 | .Text(FText::FromString(Endpoint.ToString())) 143 | .OnTextCommitted(this, &SLiveLinkTechnocraneSourceFactory::OnEndpointChanged) 144 | .Visibility_Lambda(GetNetworkVisibility) 145 | ] 146 | ] 147 | + SVerticalBox::Slot() 148 | .AutoHeight() 149 | [ 150 | SNew(SHorizontalBox) 151 | + SHorizontalBox::Slot() 152 | .HAlign(HAlign_Left) 153 | .FillWidth(0.5f) 154 | [ 155 | SNew(STextBlock) 156 | .Text(LOCTEXT("SerialPort", "Serial Port")) 157 | .Visibility_Lambda(GetSerialVisibility) 158 | ] 159 | + SHorizontalBox::Slot() 160 | .HAlign(HAlign_Fill) 161 | .FillWidth(0.5f) 162 | [ 163 | SAssignNew(m_SerialPortBox, SNumericEntryBox) 164 | .MinValue(0) 165 | .MaxValue(100) 166 | .Value(serial_port) 167 | .OnValueChanged(this, &SLiveLinkTechnocraneSourceFactory::NewSerialPortIndex) 168 | .Visibility_Lambda(GetSerialVisibility) 169 | ] 170 | ] 171 | + SVerticalBox::Slot() 172 | .HAlign(HAlign_Right) 173 | .AutoHeight() 174 | [ 175 | SNew(SButton) 176 | .OnClicked(this, &SLiveLinkTechnocraneSourceFactory::OnOkClicked) 177 | [ 178 | SNew(STextBlock) 179 | .Text(LOCTEXT("Ok", "Ok")) 180 | ] 181 | ] 182 | ] 183 | ]; 184 | 185 | // some default values 186 | const bool use_network = settings->bNetworkConnection; 187 | const bool broadcast = settings->bNetworkBroadcast; 188 | const bool bind_any_address = settings->bNetworkBindAnyAddress; 189 | 190 | { 191 | TSharedPtr checkbox = m_UseNetworkConnection.Pin(); 192 | if (checkbox.IsValid()) 193 | { 194 | return checkbox->SetIsChecked(use_network ? ECheckBoxState::Checked : ECheckBoxState::Unchecked); 195 | } 196 | } 197 | 198 | { 199 | TSharedPtr checkbox = m_NetworkBindAnyAddress.Pin(); 200 | if (checkbox.IsValid()) 201 | { 202 | return checkbox->SetIsChecked(bind_any_address ? ECheckBoxState::Checked : ECheckBoxState::Unchecked); 203 | } 204 | } 205 | 206 | { 207 | TSharedPtr checkbox = m_NetworkBroadcast.Pin(); 208 | if (checkbox.IsValid()) 209 | { 210 | return checkbox->SetIsChecked(broadcast ? ECheckBoxState::Checked : ECheckBoxState::Unchecked); 211 | } 212 | } 213 | } 214 | 215 | void SLiveLinkTechnocraneSourceFactory::OnEndpointChanged(const FText& NewValue, ETextCommit::Type) 216 | { 217 | TSharedPtr address = m_NetworkAddress.Pin(); 218 | if (address.IsValid()) 219 | { 220 | FIPv4Endpoint Endpoint; 221 | if (!FIPv4Endpoint::Parse(NewValue.ToString(), Endpoint)) 222 | { 223 | Endpoint.Address = FIPv4Address::Any; 224 | Endpoint.Port = 15246; 225 | address->SetText(FText::FromString(Endpoint.ToString())); 226 | } 227 | } 228 | } 229 | 230 | FReply SLiveLinkTechnocraneSourceFactory::OnOkClicked() 231 | { 232 | TSharedPtr use_network = m_UseNetworkConnection.Pin(); 233 | TSharedPtr bind_any_address = m_NetworkBindAnyAddress.Pin(); 234 | TSharedPtr broadcast = m_NetworkBroadcast.Pin(); 235 | TSharedPtr address = m_NetworkAddress.Pin(); 236 | TSharedPtr> serial_port = m_SerialPortBox.Pin(); 237 | 238 | if (use_network.IsValid() && serial_port.IsValid() && address.IsValid() 239 | && bind_any_address.IsValid() && broadcast.IsValid()) 240 | { 241 | FIPv4Endpoint Endpoint; 242 | if (FIPv4Endpoint::Parse(address->GetText().ToString(), Endpoint)) 243 | { 244 | SCreationInfo info{ 245 | use_network->IsChecked(), 246 | m_SerialPortIndex, 247 | Endpoint, 248 | bind_any_address->IsChecked(), 249 | broadcast->IsChecked() 250 | }; 251 | 252 | OkClicked.ExecuteIfBound(info); 253 | } 254 | } 255 | return FReply::Handled(); 256 | } 257 | 258 | #undef LOCTEXT_NAMESPACE 259 | -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/SLiveLinkTechnocraneSourceFactory.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // SLiveLinkTechnocraneSourceFactory.h 6 | // Sergei Solokhin 7 | 8 | #pragma once 9 | 10 | #include "CoreMinimal.h" 11 | #include "UObject/ObjectMacros.h" 12 | #include "Widgets/SCompoundWidget.h" 13 | #include "Widgets/Input/SNumericEntryBox.h" 14 | #include "Input/Reply.h" 15 | #include "Types/SlateEnums.h" 16 | #include "Widgets/DeclarativeSyntaxSupport.h" 17 | #include "Interfaces/IPv4/IPv4Endpoint.h" 18 | 19 | class SEditableTextBox; 20 | class SCheckBox; 21 | class STextBlock; 22 | 23 | struct SCreationInfo 24 | { 25 | bool m_UseNetwork; 26 | int32 m_SerialPort; 27 | FIPv4Endpoint m_Address; 28 | bool m_NetworkBindAny; 29 | bool m_NetworkBroadcast; 30 | }; 31 | 32 | class SLiveLinkTechnocraneSourceFactory : public SCompoundWidget 33 | { 34 | public: 35 | // use network, serial port, address, bind any, broadcast 36 | DECLARE_DELEGATE_OneParam(FOnOkClicked, SCreationInfo); 37 | 38 | SLATE_BEGIN_ARGS(SLiveLinkTechnocraneSourceFactory) {} 39 | SLATE_EVENT(FOnOkClicked, OnOkClicked) 40 | SLATE_END_ARGS() 41 | 42 | void Construct(const FArguments& Args); 43 | 44 | private: 45 | void OnEndpointChanged(const FText& NewValue, ETextCommit::Type); 46 | 47 | FReply OnOkClicked(); 48 | 49 | TWeakPtr m_UseNetworkConnection; 50 | TWeakPtr m_NetworkBindAnyAddress; 51 | TWeakPtr m_NetworkBroadcast; 52 | 53 | TWeakPtr m_NetworkAddress; 54 | TWeakPtr> m_SerialPortBox; 55 | 56 | int32 m_SerialPortIndex{ 1 }; 57 | 58 | FOnOkClicked OkClicked; 59 | 60 | void NewSerialPortIndex(int new_value) { m_SerialPortIndex = new_value; } 61 | }; -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/TechnocraneCamera.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2024 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneCamera.cpp 6 | // Sergei Solokhin 7 | 8 | #include "TechnocraneCamera.h" 9 | #include "TechnocraneCameraComponent.h" 10 | #include "TechnocranePrivatePCH.h" 11 | #include "TechnocraneRuntimeSettings.h" 12 | #include "ITechnocranePlugin.h" 13 | #include 14 | #include 15 | 16 | // Sets default values 17 | ATDCamera::ATDCamera(const FObjectInitializer& ObjectInitializer) 18 | : Super(ObjectInitializer 19 | .SetDefaultSubobjectClass(TEXT("CameraComponent"))) 20 | 21 | { 22 | TechnocraneCameraComponent = Cast(GetCameraComponent()); 23 | 24 | // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. 25 | PrimaryActorTick.bCanEverTick = true; 26 | 27 | } 28 | 29 | // Called when the game starts or when spawned 30 | void ATDCamera::BeginPlay() 31 | { 32 | Super::BeginPlay(); 33 | 34 | } 35 | 36 | // Called every frame 37 | void ATDCamera::Tick(float DeltaTime) 38 | { 39 | Super::Tick(DeltaTime); 40 | } 41 | 42 | -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/TechnocraneCameraComponent.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-24 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneCameraComponent.cpp 6 | // Sergei Solokhin 7 | 8 | #include "TechnocraneCameraComponent.h" 9 | #include "TechnocranePrivatePCH.h" 10 | #include "TechnocraneRuntimeSettings.h" 11 | #include "ITechnocranePlugin.h" 12 | #include 13 | 14 | // Sets default values 15 | UTechnocraneCameraComponent::UTechnocraneCameraComponent() 16 | : Super() 17 | , FrameRate(25, 1) 18 | { 19 | #if (ENGINE_MAJOR_VERSION > 4 || ENGINE_MINOR_VERSION >= 25) 20 | FocusSettings.FocusMethod = ECameraFocusMethod::Tracking; 21 | #else 22 | FocusSettings.FocusMethod = ECameraFocusMethod::None; 23 | #endif 24 | SetFilmbackPresetByName("35mm Full Aperture"); 25 | 26 | SpaceScale = GetDefault()->SpaceScaleByDefault; 27 | TrackPos = 0.0f; 28 | 29 | // 30 | ZoomRange = FVector2D(0.0f, 100.0f); 31 | IrisRange = FVector2D(0.0f, 100.0f); 32 | FocusRange = FVector2D(0.0f, 100.0f); 33 | } 34 | 35 | UTechnocraneCameraComponent::~UTechnocraneCameraComponent() 36 | { 37 | } 38 | 39 | // Called every frame 40 | void UTechnocraneCameraComponent::TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) 41 | { 42 | IsZoomCalibrated = NTechnocrane::ComputeZoomf(CalibratedZoom, Zoom, ZoomRange.X, ZoomRange.Y); 43 | IsIrisCalibrated = NTechnocrane::ComputeIrisf(CalibratedIris, Iris, IrisRange.X, IrisRange.Y); 44 | IsFocusCalibrated = NTechnocrane::ComputeFocusf(CalibratedFocus, Focus, FocusRange.X, FocusRange.Y); 45 | 46 | if (ApplyCalibratedValues) 47 | { 48 | CurrentFocalLength = CalibratedZoom; 49 | CurrentAperture = CalibratedIris; 50 | FocusSettings.ManualFocusDistance = SpaceScale * CalibratedFocus; 51 | } 52 | 53 | Super::TickComponent(DeltaTime, TickType, ThisTickFunction); 54 | } 55 | 56 | -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/TechnocranePlugin.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocranePlugin.cpp 6 | // Sergei Solokhin 7 | 8 | #include "TechnocranePrivatePCH.h" 9 | #include "CoreMinimal.h" 10 | #include "Modules/ModuleManager.h" 11 | #include "ITechnocranePlugin.h" 12 | #include "technocrane_hardware.h" 13 | 14 | #include "Interfaces/IPluginManager.h" 15 | 16 | class FTechnocranePlugin : public ITechnocranePlugin 17 | { 18 | /** IModuleInterface implementation */ 19 | virtual void StartupModule() override; 20 | virtual void ShutdownModule() override; 21 | 22 | private: 23 | 24 | /** Handle to the delay-loaded library. */ 25 | void* TechnocraneLibHandle; 26 | 27 | }; 28 | 29 | IMPLEMENT_MODULE(FTechnocranePlugin, TechnocranePlugin ) 30 | 31 | void TechnocraneLogCallback(const char* text, const int level) 32 | { 33 | FString str_text(text); 34 | switch (level) 35 | { 36 | case 0x02: 37 | UE_LOG(LogTechnocrane, Warning, TEXT("%s"), *str_text); 38 | break; 39 | case 0x03: 40 | UE_LOG(LogTechnocrane, Error, TEXT("%s"), *str_text); 41 | break; 42 | default: 43 | UE_LOG(LogTechnocrane, Log, TEXT("%s"), *str_text); 44 | } 45 | } 46 | 47 | void FTechnocranePlugin::StartupModule() 48 | { 49 | // This code will execute after your module is loaded into memory (but after global variables are initialized, of course.) 50 | check(TechnocraneLibHandle == nullptr); 51 | 52 | // Note: These paths correspond to the RuntimeDependency specified in the .Build.cs script. 53 | const FString PluginBaseDir = IPluginManager::Get().FindPlugin("TechnocranePlugin")->GetBaseDir(); 54 | const FString TechnocraneDll = TEXT("TechnocraneLib.dll"); 55 | 56 | #if PLATFORM_WINDOWS && PLATFORM_64BITS 57 | FString LibraryPath = FPaths::Combine(*PluginBaseDir, TEXT("/Source/ThirdParty/TechnocraneSDK/lib/Win64")); 58 | #elif PLATFORM_WINDOWS && PLATFORM_32BITS 59 | FString LibraryPath = FPaths::Combine(*PluginBaseDir, TEXT("/Source/ThirdParty/TechnocraneSDK/lib/Win32")); 60 | #else 61 | # error Path to Technocrane shared library not specified for this platform! 62 | #endif 63 | FPlatformProcess::PushDllDirectory(*LibraryPath); 64 | LibraryPath = FPaths::Combine(LibraryPath, TechnocraneDll); 65 | 66 | if (!FPaths::FileExists(LibraryPath)) 67 | { 68 | UE_LOG(LogTechnocrane, Error, TEXT("Failed to find the binary folder for the dll. Plug-in will not be functional.")); 69 | return; 70 | } 71 | 72 | TechnocraneLibHandle = FPlatformProcess::GetDllHandle(*LibraryPath); 73 | 74 | if (TechnocraneLibHandle == nullptr) 75 | { 76 | printf("error loading a library\n"); 77 | UE_LOG(LogTechnocrane, Error, TEXT("Failed to load required library %s. Plug-in will not be functional."), *TechnocraneDll); 78 | return; 79 | } 80 | 81 | #if defined(TECHNOCRANESDK) 82 | NTechnocrane::SetLogCallback(TechnocraneLogCallback); 83 | #endif 84 | } 85 | 86 | 87 | void FTechnocranePlugin::ShutdownModule() 88 | { 89 | // This function may be called during shutdown to clean up your module. For modules that support dynamic reloading, 90 | // we call this function before unloading the module. 91 | 92 | // Unload the DLL. 93 | if (nullptr != TechnocraneLibHandle) 94 | { 95 | FPlatformProcess::FreeDllHandle(TechnocraneLibHandle); 96 | TechnocraneLibHandle = nullptr; 97 | } 98 | } 99 | 100 | 101 | DEFINE_LOG_CATEGORY(LogTechnocrane); 102 | 103 | -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/TechnocranePrivatePCH.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocranePrivatePCH.h 6 | // Sergei Solokhin 7 | 8 | #pragma once 9 | 10 | #include 11 | 12 | DECLARE_LOG_CATEGORY_EXTERN(LogTechnocrane, Log, All); -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/TechnocraneRig.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneRig.cpp 6 | // Sergei Solokhin 7 | 8 | #include "TechnocraneRig.h" 9 | #include "TechnocranePrivatePCH.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include "Engine/CollisionProfile.h" 15 | #include "DrawDebugHelpers.h" 16 | 17 | #include 18 | #include 19 | 20 | #include "Interfaces/IPluginManager.h" 21 | 22 | #include "TechnocraneShared.h" 23 | #include 24 | #include 25 | 26 | #include "LiveLinkComponentController.h" 27 | #include "ILiveLinkClient.h" 28 | #include "LiveLinkTypes.h" 29 | 30 | #include "Roles/LiveLinkCameraRole.h" 31 | #include "Roles/LiveLinkCameraTypes.h" 32 | #include "LiveLinkTechnocraneTypes.h" 33 | 34 | #define LOCTEXT_NAMESPACE "TechnocraneCamera" 35 | 36 | 37 | /////////////////////////////////////////////////////////////////////////////////// 38 | // FTechnocraneRigImpl 39 | 40 | class FTechnocraneRigImpl 41 | { 42 | public: 43 | 44 | //! a constructor 45 | FTechnocraneRigImpl() 46 | {} 47 | 48 | UPoseableMeshComponent* mComponent{ nullptr }; 49 | FCraneData* CraneData{ nullptr }; 50 | 51 | void SetPoseableMeshComponent(UPoseableMeshComponent* component) 52 | { 53 | mComponent = component; 54 | } 55 | 56 | void SetCranePresetData(FCraneData* data) 57 | { 58 | CraneData = data; 59 | } 60 | 61 | FVector ComputeHeadTransform() const 62 | { 63 | const FName BoneName = GetCraneJointName(ECraneJoints::Head); 64 | return mComponent->GetBoneLocation(BoneName, EBoneSpaces::WorldSpace); 65 | } 66 | 67 | bool Reset() 68 | { 69 | mComponent->ResetBoneTransformByName(GetCraneJointName(ECraneJoints::Columns)); 70 | mComponent->ResetBoneTransformByName(GetCraneJointName(ECraneJoints::Beams)); 71 | return true; 72 | } 73 | 74 | // recompute transform of crane elements in order to fit a target camera position and orientation 75 | bool Compute(UWorld* World, const FVector& Target, const float TrackPosition, const FVector& RawRotation, const FQuat& NeckRotation) 76 | { 77 | if (!CraneData) 78 | { 79 | return false; 80 | } 81 | 82 | const FTransform& BaseTransform = mComponent->GetComponentTransform(); 83 | 84 | const float ZOffset = CraneData->ZOffsetOnGround; // make it appear in the right place 85 | FVector const NewLoc(0.0f, TrackPosition, ZOffset); 86 | 87 | const FTransform RelativeTM = BaseTransform.GetRelativeTransformReverse(FTransform(Target)); 88 | FVector vTarget3 = Target; // relativeTM.GetLocation(); 89 | 90 | const FName RootBoneName(GetCraneJointName(ECraneJoints::Base)); 91 | const FName ColumnsBoneName(GetCraneJointName(ECraneJoints::Columns)); 92 | const FName ColumnRotationBoneName(!CraneData->ColumnRotationBone.IsNone() ? CraneData->ColumnRotationBone : ColumnsBoneName); 93 | const FName BeamsBoneName(GetCraneJointName(ECraneJoints::Beams)); 94 | const FName GravityBoneName(GetCraneJointName(ECraneJoints::Gravity)); 95 | const FName Beam1BoneName(GetCraneJointName(ECraneJoints::Beam1)); 96 | const FName Beam2BoneName(GetCraneJointName(ECraneJoints::Beam2)); 97 | const FName Beam4BoneName(GetCraneJointName(ECraneJoints::Beam4)); 98 | const FName NeckBoneName(GetCraneJointName(ECraneJoints::Neck)); 99 | const FName HeadBoneName(GetCraneJointName(ECraneJoints::Head)); 100 | 101 | mComponent->SetBoneLocationByName(RootBoneName, NewLoc, EBoneSpaces::ComponentSpace); 102 | 103 | FVector HeadPos; 104 | FVector ColumnPos, BeamsPos, ProjPos; 105 | 106 | FQuat DeltaQuat; 107 | FVector DeltaAxis(0.f); 108 | float DeltaAngle = 0.f; 109 | 110 | ColumnPos = mComponent->GetBoneLocation(ColumnsBoneName); 111 | BeamsPos = mComponent->GetBoneLocation(BeamsBoneName); 112 | 113 | { 114 | FRotator rot = mComponent->GetBoneRotationByName(ColumnRotationBoneName, EBoneSpaces::ComponentSpace); 115 | 116 | FVector DirInPlane = vTarget3 - BeamsPos; 117 | DirInPlane.Z = 0.0; 118 | DirInPlane.Normalize(); 119 | 120 | double AngleRad = FMath::Atan2(FVector::DotProduct(FVector::CrossProduct(FVector::ForwardVector, DirInPlane), FVector::UpVector), 121 | FVector::DotProduct(DirInPlane, FVector::ForwardVector)); 122 | double Angle = FMath::RadiansToDegrees(AngleRad); 123 | 124 | rot.Yaw = 90.0 + Angle; 125 | mComponent->SetBoneRotationByName(ColumnRotationBoneName, rot, EBoneSpaces::ComponentSpace); 126 | 127 | HeadPos = FVector::ForwardVector; 128 | FVector HeadDir = HeadPos.RotateAngleAxisRad(AngleRad, FVector::UpVector); 129 | HeadDir.Normalize(); 130 | 131 | constexpr double DistCamHeadAndNeck{ 50.0 }; 132 | FVector DirToCam = FVector(vTarget3.X, vTarget3.Y, vTarget3.Z + DistCamHeadAndNeck) - BeamsPos; 133 | DirToCam.Normalize(); 134 | 135 | AngleRad = FMath::Acos(FVector::DotProduct(DirToCam, HeadDir)); 136 | Angle = FMath::RadiansToDegrees( ((vTarget3.Z + DistCamHeadAndNeck) > BeamsPos.Z) ? AngleRad : -AngleRad); 137 | 138 | rot = mComponent->GetBoneRotationByName(BeamsBoneName, EBoneSpaces::ComponentSpace); 139 | rot.Roll = 90.0 + Angle; 140 | mComponent->SetBoneRotationByName(BeamsBoneName, rot, EBoneSpaces::ComponentSpace); 141 | } 142 | 143 | ColumnPos = mComponent->GetBoneLocation(ColumnsBoneName); 144 | BeamsPos = mComponent->GetBoneLocation(BeamsBoneName); 145 | HeadPos = ComputeHeadTransform(); 146 | 147 | // 148 | // rotate gravity point 149 | FTransform TM, ParentTM; 150 | FVector angles; 151 | 152 | TM = mComponent->GetBoneTransformByName(BeamsBoneName, EBoneSpaces::ComponentSpace); 153 | ParentTM = mComponent->GetBoneTransformByName(mComponent->GetParentBone(BeamsBoneName), EBoneSpaces::ComponentSpace); 154 | 155 | TM.SetToRelativeTransform(ParentTM); 156 | angles = TM.GetRotation().Euler(); 157 | 158 | TM = mComponent->GetBoneTransformByName(GravityBoneName, EBoneSpaces::ComponentSpace); 159 | ParentTM = mComponent->GetBoneTransformByName(mComponent->GetParentBone(GravityBoneName), EBoneSpaces::ComponentSpace); 160 | 161 | TM.SetToRelativeTransform(ParentTM); 162 | TM.SetRotation(FQuat::MakeFromEuler(-angles)); 163 | 164 | TM = TM * ParentTM; 165 | mComponent->SetBoneTransformByName(GravityBoneName, TM, EBoneSpaces::ComponentSpace); 166 | 167 | // 168 | // beams length 169 | 170 | HeadPos = ComputeHeadTransform(); 171 | 172 | DeltaQuat = FQuat::FindBetween(HeadPos - BeamsPos, ProjPos - BeamsPos); 173 | DeltaQuat.ToAxisAndAngle(DeltaAxis, DeltaAngle); 174 | 175 | if (DeltaAngle < 60.0f) 176 | { 177 | const float l1 = (HeadPos - BeamsPos).Size(); 178 | const float l2 = (vTarget3 - BeamsPos).Size(); 179 | const float l = 0.15f * (l1 - l2); 180 | 181 | if (abs(l) > 0.1f) 182 | { 183 | ParentTM = mComponent->GetBoneTransformByName(Beam1BoneName, EBoneSpaces::ComponentSpace); 184 | 185 | const int32 Beam2 = static_cast(ECraneJoints::Beam2); 186 | const int32 Beam5 = static_cast(ECraneJoints::Beam5); 187 | 188 | for (int32 i = Beam2; i <= Beam5; ++i) 189 | { 190 | const FName BoneName(GetCraneJointName(static_cast(i))); 191 | 192 | if (INDEX_NONE == mComponent->GetBoneIndex(BoneName)) 193 | continue; 194 | 195 | TM = mComponent->GetBoneTransformByName(BoneName, EBoneSpaces::ComponentSpace); 196 | TM.SetToRelativeTransform(ParentTM); 197 | 198 | FVector tr = TM.GetLocation(); 199 | tr.Z += l; 200 | 201 | const float MaxLength = mComponent->GetRefPoseTransform(mComponent->GetBoneIndex(BoneName)).GetLocation().Z; 202 | 203 | if (tr.Z > -2.0f) tr.Z = -2.0f; 204 | else if (tr.Z < MaxLength) tr.Z = MaxLength; 205 | 206 | TM.SetLocation(tr); 207 | TM = TM * ParentTM; 208 | 209 | mComponent->SetBoneTransformByName(BoneName, TM, EBoneSpaces::ComponentSpace); 210 | 211 | ParentTM = TM; 212 | } 213 | } 214 | } 215 | 216 | // 217 | // crane head and neck 218 | 219 | TM = mComponent->GetBoneTransformByName(NeckBoneName, EBoneSpaces::ComponentSpace); 220 | ParentTM = mComponent->GetBoneTransformByName(mComponent->GetParentBone(NeckBoneName), EBoneSpaces::ComponentSpace); 221 | 222 | TM.SetToRelativeTransform(ParentTM); 223 | 224 | TM = TM * ParentTM; 225 | TM.SetRotation(NeckRotation); 226 | 227 | mComponent->SetBoneTransformByName(NeckBoneName, TM, EBoneSpaces::ComponentSpace); 228 | 229 | // 230 | 231 | TM = mComponent->GetBoneTransformByName(HeadBoneName, EBoneSpaces::ComponentSpace); 232 | ParentTM = mComponent->GetBoneTransformByName(mComponent->GetParentBone(HeadBoneName), EBoneSpaces::ComponentSpace); 233 | 234 | TM.SetToRelativeTransform(ParentTM); 235 | TM.SetRotation(FQuat::MakeFromEuler(FVector(RawRotation.Y, 0.0f, 0.0f))); 236 | 237 | TM = TM * ParentTM; 238 | mComponent->SetBoneTransformByName(HeadBoneName, TM, EBoneSpaces::ComponentSpace); 239 | 240 | return true; 241 | } 242 | }; 243 | 244 | FTechnocraneRig::FTechnocraneRig() 245 | { 246 | // allocate memory for a private data 247 | Impl = CreateImpl(); 248 | } 249 | FTechnocraneRig::~FTechnocraneRig() 250 | { 251 | } 252 | 253 | TUniquePtr FTechnocraneRig::CreateImpl() 254 | { 255 | return TUniquePtr(new FTechnocraneRigImpl()); 256 | } 257 | 258 | /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 259 | // Sets default values 260 | ATechnocraneRig::ATechnocraneRig() 261 | : LastPreviewModel(ECranePreviewModelsEnum::ECranePreview_Count) 262 | { 263 | // Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it. 264 | PrimaryActorTick.bCanEverTick = true; 265 | PrimaryActorTick.TickInterval = 0; 266 | 267 | // default control values 268 | TrackPosition = 0.0f; 269 | AmountOfTracks = 1; 270 | 271 | CameraPivotOffset = FVector(-70.0f, 0.0f, 0.0f); 272 | 273 | // create the root component 274 | TransformComponent = CreateDefaultSubobject(TEXT("TransformComponent")); 275 | RootComponent = TransformComponent; 276 | 277 | #if WITH_EDITORONLY_DATA 278 | 279 | MeshComponent = nullptr; 280 | 281 | // create preview meshes 282 | if (!IsRunningDedicatedServer()) 283 | { 284 | const FString DataPath = TEXT("/TechnocranePlugin/CranesData"); 285 | static ConstructorHelpers::FObjectFinder CraneDataAsset(*DataPath); 286 | if (CraneDataAsset.Succeeded()) 287 | { 288 | CranesData = CraneDataAsset.Object; 289 | PreloadPreviewMeshes(); 290 | PreloadTracksMesh(); 291 | } 292 | else 293 | { 294 | CranesData = nullptr; 295 | } 296 | } 297 | #endif 298 | } 299 | 300 | #if WITH_EDITORONLY_DATA 301 | 302 | bool ATechnocraneRig::PreloadPreviewMeshes() 303 | { 304 | if (!CranesData) 305 | { 306 | return false; 307 | } 308 | 309 | const TArray RowNames = CranesData->GetRowNames(); 310 | 311 | for (const FName RawName : RowNames) 312 | { 313 | FString ModelPath(""); 314 | 315 | if (FCraneData* Data = CranesData->FindRow(RawName, "", false)) 316 | { 317 | ModelPath = Data->CraneModelPath; 318 | } 319 | 320 | ConstructorHelpers::FObjectFinder CraneBaseMesh(*ModelPath); 321 | 322 | if (CraneBaseMesh.Succeeded()) 323 | { 324 | PreviewMeshes.Add(CraneBaseMesh.Object); 325 | } 326 | } 327 | 328 | // 329 | 330 | MeshComponent = CreateOptionalDefaultSubobject(TEXT("preview_mesh")); 331 | if (MeshComponent) 332 | { 333 | MeshComponent->bIsEditorOnly = true; 334 | MeshComponent->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName); 335 | MeshComponent->bHiddenInGame = false; 336 | MeshComponent->CastShadow = true; 337 | MeshComponent->SetupAttachment(TransformComponent); // sibling of yawcontrol 338 | 339 | TechnocraneRig.Impl->SetPoseableMeshComponent(MeshComponent); 340 | } 341 | 342 | return (PreviewMeshes.Num() > 0); 343 | } 344 | 345 | bool ATechnocraneRig::PreloadTracksMesh() 346 | { 347 | const FString ModelPath("/TechnocranePlugin/tracks"); 348 | 349 | ConstructorHelpers::FObjectFinder CraneTracksBaseMesh(*ModelPath); 350 | 351 | if (CraneTracksBaseMesh.Succeeded()) 352 | { 353 | CraneTracksMesh = CraneTracksBaseMesh.Object; 354 | CraneTracksMeshComponent = CreateOptionalDefaultSubobject(TEXT("tracks_mesh")); 355 | 356 | if (CraneTracksMeshComponent) 357 | { 358 | CraneTracksMeshComponent->bIsEditorOnly = true; 359 | CraneTracksMeshComponent->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName); 360 | CraneTracksMeshComponent->bHiddenInGame = false; 361 | CraneTracksMeshComponent->CastShadow = true; 362 | CraneTracksMeshComponent->SetupAttachment(TransformComponent); // sibling of yawcontrol 363 | 364 | CraneTracksMeshComponent->SetStaticMesh(CraneTracksMesh); 365 | return true; 366 | } 367 | } 368 | return false; 369 | } 370 | 371 | void ATechnocraneRig::UpdateTracksMesh() 372 | { 373 | if (!CraneTracksMeshComponent) 374 | return; 375 | 376 | bool bShowTracks = bLastSupportTracks && bShowTracksIfSupported; 377 | 378 | if (CraneTracksMeshComponent->IsVisible() != bShowTracks) 379 | { 380 | CraneTracksMeshComponent->SetVisibility(bShowTracks); 381 | } 382 | } 383 | 384 | void ATechnocraneRig::UpdatePreviewMeshes() 385 | { 386 | 387 | if (PreviewMeshes.Num() > 0 && MeshComponent) 388 | { 389 | if (LastPreviewModel != CraneModel) 390 | { 391 | // attach another crane 392 | USkeletalMesh* PreviewMesh = PreviewMeshes[static_cast(CraneModel)]; 393 | 394 | // crane preset data 395 | const FString PresetName(FString::FromInt(static_cast(CraneModel) + 1)); 396 | FCraneData* Data = CranesData->FindRow(FName(*PresetName), "", false); 397 | TechnocraneRig.Impl->SetCranePresetData(Data); 398 | 399 | MeshComponent->SetSkinnedAssetAndUpdate(PreviewMesh); 400 | 401 | LastPreviewModel = CraneModel; 402 | bLastSupportTracks = Data->TracksSupport > 0; 403 | LastTracksOffset = Data->ZOffsetOnTracks; 404 | 405 | if (CraneTracksMeshComponent) 406 | { 407 | CraneTracksMeshComponent->SetRelativeLocation(FVector(0.0f, 0.0f, LastTracksOffset)); 408 | } 409 | } 410 | 411 | // Perform kinematic updates 412 | 413 | FTransform Target = FTransform::Identity; 414 | Target.SetLocation(FVector(0.0f, 0.0f, 100.0f)); 415 | FVector RawRotation = FVector::ZeroVector; 416 | FQuat NeckQ(FQuat::Identity); 417 | 418 | if (ACineCameraActor* CineCamera = Cast(TargetComponent.OtherActor)) 419 | { 420 | // get transform and track position / raw rotation if live link is presented 421 | 422 | FTransform CameraTransform = CineCamera->GetTransform(); 423 | 424 | if (UCineCameraComponent* comp = Cast(CineCamera->GetCameraComponent())) 425 | { 426 | CameraTransform = comp->GetRelativeTransform() * CameraTransform; 427 | } 428 | if (UTechnocraneCameraComponent* Comp = Cast< UTechnocraneCameraComponent>(CineCamera->GetCameraComponent())) 429 | { 430 | TrackPosition = Comp->TrackPos; 431 | } 432 | 433 | // add some camera pivot offset 434 | FTransform NewPivotOffset; 435 | NewPivotOffset.SetLocation(CameraPivotOffset); 436 | 437 | Target = NewPivotOffset * CameraTransform; 438 | RawRotation = CineCamera->GetActorRotation().Euler(); 439 | NeckQ = FQuat::MakeFromEuler(FVector(90.0, 0.0, 180.0 + RawRotation.X)); 440 | 441 | if (!CameraPivotOffset.IsNearlyZero(0.0001)) 442 | { 443 | FVector DirToCam = (CameraTransform.GetLocation() - Target.GetLocation()); 444 | DirToCam.Normalize(); 445 | FVector DirInPlane = DirToCam; 446 | DirInPlane.Z = 0.0; 447 | DirInPlane.Normalize(); 448 | 449 | double AngleRad = FMath::Atan2(FVector::DotProduct(FVector::CrossProduct(FVector::ForwardVector, DirInPlane), FVector::UpVector), 450 | FVector::DotProduct(DirInPlane, FVector::ForwardVector)); 451 | 452 | const double Angle = FMath::RadiansToDegrees( AngleRad ); 453 | 454 | NeckQ = FQuat::MakeFromEuler(FVector(90.0, 0.0, 90.0 + Angle)); 455 | } 456 | 457 | // track position / raw rotation 458 | 459 | ULiveLinkComponentController* LiveLinkComponent = Cast(CineCamera->GetComponentByClass(ULiveLinkComponentController::StaticClass())); 460 | if (LiveLinkComponent && LiveLinkComponent->SubjectRepresentation.Role) 461 | { 462 | //if Subjects role direct controller is us, set the component to control to what we had 463 | 464 | if (ULiveLinkCameraRole* LiveLinkRole = Cast(LiveLinkComponent->SubjectRepresentation.Role->GetDefaultObject())) 465 | { 466 | //Create the struct holder and make it point to the output data 467 | 468 | IModularFeatures& ModularFeatures = IModularFeatures::Get(); 469 | if (ModularFeatures.IsModularFeatureAvailable(ILiveLinkClient::ModularFeatureName)) 470 | { 471 | ILiveLinkClient& LiveLinkClient = ModularFeatures.GetModularFeature(ILiveLinkClient::ModularFeatureName); 472 | 473 | FLiveLinkSubjectFrameData CurrentFrameData; 474 | bool bSuccess = LiveLinkClient.EvaluateFrame_AnyThread(LiveLinkComponent->SubjectRepresentation.Subject, LiveLinkComponent->SubjectRepresentation.Role, CurrentFrameData); 475 | 476 | if (bSuccess) 477 | { 478 | FLiveLinkCameraFrameData* FrameData = CurrentFrameData.FrameData.Cast(); 479 | 480 | if (FrameData->PropertyValues.Num() > 8) 481 | { 482 | TrackPosition = FrameData->PropertyValues[static_cast(EPacketProperties::TrackPosition)]; 483 | RawRotation = FVector( 484 | FrameData->PropertyValues[static_cast(EPacketProperties::Pan)], 485 | FrameData->PropertyValues[static_cast(EPacketProperties::Tilt)], 486 | FrameData->PropertyValues[static_cast(EPacketProperties::Roll)] 487 | ); 488 | 489 | NeckQ = FQuat::MakeFromEuler(FVector(90.0f, 0.0f, 180.0f + RawRotation.X)); 490 | } 491 | } 492 | } 493 | } 494 | } 495 | 496 | } 497 | 498 | TechnocraneRig.Impl->Compute(GetWorld(), Target.GetLocation(), TrackPosition, RawRotation, NeckQ); 499 | } 500 | } 501 | #endif 502 | 503 | void ATechnocraneRig::UpdateCraneComponents() 504 | { 505 | #if WITH_EDITORONLY_DATA 506 | UpdatePreviewMeshes(); 507 | UpdateTracksMesh(); 508 | #endif 509 | } 510 | 511 | // Called when the game starts or when spawned 512 | void ATechnocraneRig::BeginPlay() 513 | { 514 | Super::BeginPlay(); 515 | 516 | } 517 | 518 | // Called every frame 519 | void ATechnocraneRig::Tick(float DeltaTime) 520 | { 521 | Super::Tick(DeltaTime); 522 | 523 | // feed exposed API into underlying components 524 | UpdateCraneComponents(); 525 | } 526 | 527 | #if WITH_EDITOR 528 | void ATechnocraneRig::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) 529 | { 530 | Super::PostEditChangeProperty(PropertyChangedEvent); 531 | 532 | if (PropertyChangedEvent.MemberProperty && PropertyChangedEvent.MemberProperty->GetFName() == "TargetComponent") 533 | { 534 | TechnocraneRig.Impl->Reset(); 535 | } 536 | 537 | UpdateCraneComponents(); 538 | } 539 | 540 | void ATechnocraneRig::PostEditUndo() 541 | { 542 | Super::PostEditUndo(); 543 | 544 | UpdateCraneComponents(); 545 | } 546 | 547 | void ATechnocraneRig::EditorApplyTranslation(const FVector& DeltaTranslation, bool bAltDown, bool bShiftDown, bool bCtrlDown) 548 | { 549 | Super::EditorApplyTranslation(DeltaTranslation, bAltDown, bShiftDown, bCtrlDown); 550 | 551 | UpdateCraneComponents(); 552 | } 553 | 554 | #endif // WITH_EDITOR 555 | 556 | bool ATechnocraneRig::ShouldTickIfViewportsOnly() const 557 | { 558 | return true; 559 | } 560 | 561 | #undef LOCTEXT_NAMESPACE 562 | -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/TechnocraneRuntimeSettings.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneRuntimeSettings.cpp 6 | // Sergei Solokhin 7 | 8 | #include "TechnocraneRuntimeSettings.h" 9 | #include "TechnocranePrivatePCH.h" 10 | 11 | #include "Math\Interval.h" 12 | 13 | UTechnocraneRuntimeSettings::UTechnocraneRuntimeSettings() 14 | : CameraFrameRate(25, 1) 15 | { 16 | bLiveByDefault = false; 17 | bNetworkConnection = false; 18 | SerialPortIdByDefault = 1; 19 | bNetworkBindAnyAddress = true; 20 | bNetworkBroadcast = false; 21 | NetworkServerAddressByDefault = "127.0.0.1"; // localhost 22 | NetworkPortIdByDefault = 15246; 23 | SpaceScaleByDefault = 100.0f; 24 | bPacketContainsRawAndCalibratedData = false; 25 | 26 | ZoomRange = FFloatInterval(0.0f, 100.0f); 27 | FocusRange = FFloatInterval(0.0f, 100.0f); 28 | IrisRange = FFloatInterval(0.0f, 100.0f); 29 | } -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Private/TechnocraneShared.cpp: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneShared.cpp 6 | // Sergei Solokhin 7 | 8 | #include "TechnocraneShared.h" 9 | #include "TechnocranePrivatePCH.h" 10 | 11 | 12 | const char* g_CraneJointNames[static_cast(ECraneJoints::JointCount)] = { 13 | "jointRoot", 14 | "jointColumns", 15 | "jointColumn1", 16 | "jointColumn2", 17 | "jointColumn3", 18 | "jointBeams", 19 | "jointBeam1", 20 | "jointBeam2", 21 | "jointBeam3", 22 | "jointBeam4", 23 | "jointBeam5", 24 | "jointGravity", 25 | "jointNeck", 26 | "jointHead", 27 | 28 | "jointWheelFR", 29 | "jointWheelFL", 30 | "jointWheelRR", 31 | "jointWheelRL", 32 | }; 33 | 34 | const FName GetCraneJointName(const ECraneJoints enum_index) 35 | { 36 | const int32 index = static_cast(enum_index); 37 | return g_CraneJointNames[index]; 38 | } -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Public/ITechnocranePlugin.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // ITechnocranePlugin.h 6 | // Sergei Solokhins 7 | 8 | #pragma once 9 | 10 | #include "CoreMinimal.h" 11 | #include "Modules/ModuleInterface.h" 12 | #include "Modules/ModuleManager.h" 13 | 14 | 15 | /** 16 | * The public interface to this module. In most cases, this interface is only public to sibling modules 17 | * within this plugin. 18 | */ 19 | class ITechnocranePlugin : public IModuleInterface 20 | { 21 | 22 | public: 23 | 24 | /** 25 | * Singleton-like access to this module's interface. This is just for convenience! 26 | * Beware of calling this during the shutdown phase, though. Your module might have been unloaded already. 27 | * 28 | * @return Returns singleton instance, loading the module on demand if needed 29 | */ 30 | static inline ITechnocranePlugin& Get() 31 | { 32 | return FModuleManager::LoadModuleChecked< ITechnocranePlugin >( "TechnocranePlugin" ); 33 | } 34 | 35 | /** 36 | * Checks to see if this module is loaded and ready. It is only valid to call Get() if IsAvailable() returns true. 37 | * 38 | * @return True if the module is loaded and ready to use 39 | */ 40 | static inline bool IsAvailable() 41 | { 42 | return FModuleManager::Get().IsModuleLoaded( "TechnocranePlugin" ); 43 | } 44 | 45 | }; 46 | 47 | -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Public/TechnocraneCamera.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2024 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneCamera.h 6 | // Sergei Solokhin 7 | 8 | #pragma once 9 | 10 | #include "CoreMinimal.h" 11 | #include "GameFramework/Actor.h" 12 | #include 13 | #include "Misc/Timecode.h" 14 | 15 | #include "TechnocraneCamera.generated.h" 16 | 17 | // forward 18 | class UTechnocraneCameraComponent; 19 | 20 | /// 21 | /// A version of CineCamera that is using a @sa TechnocraneCameraComponent 22 | /// The component exposes properties that match those stored in Technocrane Trimmer FBX with camera data export. 23 | /// 24 | UCLASS(Blueprintable, ClassGroup = Technocrane, Category = "Technocrane", meta = (DisplayName = "Technocrane Camera", BlueprintSpawnableComponent)) 25 | class TECHNOCRANEPLUGIN_API ATDCamera : public ACineCameraActor 26 | { 27 | GENERATED_BODY() 28 | 29 | public: 30 | // Sets default values for this actor's properties 31 | ATDCamera(const FObjectInitializer& ObjectInitializer); 32 | 33 | UTechnocraneCameraComponent* GetTechnocraneCameraComponent() const { return TechnocraneCameraComponent; } 34 | 35 | protected: 36 | // Called when the game starts or when spawned 37 | virtual void BeginPlay() override; 38 | 39 | public: 40 | // Called every frame 41 | virtual void Tick(float DeltaTime) override; 42 | 43 | private: 44 | /** Returns TechnocraneCameraComponent subobject **/ 45 | class UTechnocraneCameraComponent* TechnocraneCameraComponent; 46 | }; 47 | -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Public/TechnocraneCameraComponent.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2024 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneCameraComponent.h 6 | // Sergei Solokhin 7 | 8 | #pragma once 9 | 10 | #include "CoreMinimal.h" 11 | #include "GameFramework/Actor.h" 12 | #include "CineCameraActor.h" 13 | #include "CineCameraComponent.h" 14 | #include "Misc/Timecode.h" 15 | 16 | #include "TechnocraneCameraComponent.generated.h" 17 | 18 | /// 19 | /// A camera component class that exposes additional variables to align with Technocrane Trimmer exported camera data. 20 | /// @sa ATDCamera 21 | /// 22 | UCLASS(ClassGroup = (Technocrane), meta = (DisplayName = "TDCamera Component")) 23 | class TECHNOCRANEPLUGIN_API UTechnocraneCameraComponent : public UCineCameraComponent 24 | { 25 | GENERATED_BODY() 26 | 27 | public: 28 | // Sets default values for this actor's properties 29 | UTechnocraneCameraComponent(); 30 | virtual ~UTechnocraneCameraComponent(); 31 | 32 | public: 33 | // Called every frame 34 | virtual void TickComponent(float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction) override; 35 | 36 | // 37 | 38 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking Raw Data") 39 | float Zoom; 40 | 41 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking Raw Data") 42 | float Iris; 43 | 44 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking Raw Data") 45 | float Focus; 46 | 47 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking Raw Data") 48 | float TrackPos; 49 | 50 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking Raw Data") 51 | float PacketNumber; 52 | 53 | // 54 | 55 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Tracking Calibrated") 56 | bool ApplyCalibratedValues = true; 57 | 58 | UPROPERTY(VisibleAnywhere, SkipSerialization, BlueprintReadOnly, Category = "Tracking Calibrated") 59 | bool IsZoomCalibrated; 60 | 61 | UPROPERTY(VisibleAnywhere, SkipSerialization, BlueprintReadOnly, Category = "Tracking Calibrated") 62 | bool IsIrisCalibrated; 63 | 64 | UPROPERTY(VisibleAnywhere, SkipSerialization, BlueprintReadOnly, Category = "Tracking Calibrated") 65 | bool IsFocusCalibrated; 66 | 67 | UPROPERTY(VisibleAnywhere, SkipSerialization, BlueprintReadOnly, Category = "Tracking Calibrated") 68 | float CalibratedZoom; 69 | 70 | UPROPERTY(VisibleAnywhere, SkipSerialization, BlueprintReadOnly, Category = "Tracking Calibrated") 71 | float CalibratedIris; 72 | 73 | UPROPERTY(VisibleAnywhere, SkipSerialization, BlueprintReadOnly, Category = "Tracking Calibrated") 74 | float CalibratedFocus; 75 | 76 | // 77 | 78 | UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Tracking Options") 79 | float SpaceScale; 80 | 81 | UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Tracking Options") 82 | FFrameRate FrameRate; 83 | 84 | UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Tracking Options") 85 | FVector2D ZoomRange; 86 | 87 | UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Tracking Options") 88 | FVector2D IrisRange; 89 | 90 | UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Tracking Options") 91 | FVector2D FocusRange; 92 | }; 93 | -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Public/TechnocraneRig.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneRig.h 6 | // Sergei Solokhin 7 | 8 | #pragma once 9 | 10 | #include "CoreMinimal.h" 11 | #include "GameFramework/Actor.h" 12 | #include "Engine/DataTable.h" 13 | #include "TechnocraneRig.generated.h" 14 | 15 | class USkeletalMeshComponent; 16 | class UPoseableMeshComponent; 17 | 18 | /** Structure that defines a level up table entry */ 19 | USTRUCT(BlueprintType) 20 | struct FCraneData : public FTableRowBase 21 | { 22 | GENERATED_USTRUCT_BODY() 23 | 24 | public: 25 | 26 | FCraneData() 27 | : Name("TechnoDolly") 28 | , ZOffsetOnGround(36.0f) 29 | , ZOffsetOnTracks(20.0f) 30 | , TracksSupport(0) 31 | , BeamsCount(3) 32 | , ColumnCount(0) 33 | , TiltMin(55.0f) 34 | , TiltMax(55.0f) 35 | , PanMin(270.0f) 36 | , PanMax(270.0f) 37 | , CameraOffsetX(26.0f) 38 | , CraneModelPath("/TechnocranePlugin/TechnodollyModel") 39 | {} 40 | 41 | 42 | /** Name of a crane preset */ 43 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Data) 44 | FString Name; 45 | 46 | /** offset from a ground */ 47 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Data) 48 | float ZOffsetOnGround; 49 | 50 | /** offset from a tracks */ 51 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Tracks) 52 | float ZOffsetOnTracks; 53 | 54 | /** are tracks supported for the crane preset */ 55 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Tracks) 56 | int32 TracksSupport; 57 | 58 | /** number of beams in the crane */ 59 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Data) 60 | int32 BeamsCount; 61 | 62 | /** number of columns in the crane */ 63 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Data) 64 | int32 ColumnCount; 65 | 66 | /** use a specific bone to peform a horizontal rotation (column around up axis) */ 67 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Data) 68 | FName ColumnRotationBone; 69 | 70 | /** Minimum angle to tilt */ 71 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Limits) 72 | float TiltMin; 73 | 74 | /** Maximum angle to tilt */ 75 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Limits) 76 | float TiltMax; 77 | 78 | /** Minimum angle to pan */ 79 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Limits) 80 | float PanMin; 81 | 82 | /** Maximum angle to pan */ 83 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Limits) 84 | float PanMax; 85 | 86 | /** Camera Pivot Offset */ 87 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = CameraPivot) 88 | float CameraOffsetX; 89 | 90 | /** Icon to use for Achivement */ 91 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Data) 92 | FString CraneModelPath; 93 | }; 94 | 95 | /** Shake start offset parameter */ 96 | UENUM(BlueprintType) 97 | enum class ECranePreviewModelsEnum : uint8 98 | { 99 | ECranePreview_Technodolly10 = 0 UMETA(DisplayName = "Technodolly 10"), 100 | ECranePreview_Technodolly15 = 1 UMETA(DisplayName = "Technodolly 15"), 101 | ECranePreview_Technodolly25 = 2 UMETA(DisplayName = "Technodolly 25"), 102 | ECranePreview_Technocrane10 = 3 UMETA(DisplayName = "Technocrane 10"), 103 | ECranePreview_Technocrane22 = 4 UMETA(DisplayName = "Technocrane 22"), 104 | ECranePreview_Supertechno15 = 5 UMETA(DisplayName = "SuperTechno 15"), 105 | ECranePreview_Supertechno30 = 6 UMETA(DisplayName = "SuperTechno 30 Plus"), 106 | ECranePreview_Supertechno50 = 7 UMETA(DisplayName = "SuperTechno 50 Plus"), 107 | ECranePreview_Supertechno75 = 8 UMETA(DisplayName = "SuperTechno 75 Plus"), 108 | ECranePreview_Count UMETA(Hidden) 109 | }; 110 | 111 | class FTechnocraneRigImpl; 112 | 113 | class FTechnocraneRig 114 | { 115 | public: 116 | FTechnocraneRig(); 117 | ~FTechnocraneRig(); 118 | 119 | public: 120 | /** This is a private data **/ 121 | TUniquePtr CreateImpl(); 122 | TUniquePtr Impl; 123 | }; 124 | 125 | /** 126 | * an actor that simulates a Technocrane Crane Rig to follow a target camera position 127 | * in case tracks are used, the position on track could be received from live or exported tecnocrane data 128 | */ 129 | UCLASS(Blueprintable, ClassGroup = "Technocrane", meta = (BlueprintSpawnableComponent)) 130 | class TECHNOCRANEPLUGIN_API ATechnocraneRig : public AActor 131 | { 132 | GENERATED_BODY() 133 | 134 | public: 135 | // Sets default values for this actor's properties 136 | ATechnocraneRig(); 137 | 138 | protected: 139 | // Called when the game starts or when spawned 140 | virtual void BeginPlay() override; 141 | 142 | public: 143 | // Called every frame 144 | virtual void Tick(float DeltaTime) override; 145 | virtual bool ShouldTickIfViewportsOnly() const override; 146 | 147 | /** Defines how to begin (either at zero, or at a randomized value. */ 148 | UPROPERTY(EditAnywhere, Category = "Crane Controls") 149 | ECranePreviewModelsEnum CraneModel{ ECranePreviewModelsEnum::ECranePreview_Technodolly25 }; 150 | 151 | /** Crane position on tracks, reads from Camera Component or from Live Data */ 152 | UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Crane Controls", meta = (Units = cm)) 153 | float TrackPosition{ 0.0f }; 154 | 155 | /** Controls if we would like to show a preview of tracks (only when crane supports tracks preview) */ 156 | UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Crane Controls") 157 | bool bShowTracksIfSupported{ true }; 158 | 159 | /** Controls the amount of rails for the crane rig. */ 160 | UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Crane Controls", meta = (ClampMin = 0, ClampMax = 6)) 161 | int AmountOfTracks{ 0 }; 162 | 163 | /** Controls the attaced camera pivot offset. */ 164 | UPROPERTY(Interp, EditAnywhere, BlueprintReadWrite, Category = "Crane Controls", meta = (Units = cm)) 165 | FVector CameraPivotOffset; 166 | 167 | #if WITH_EDITOR 168 | virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override; 169 | virtual void PostEditUndo() override; 170 | virtual void EditorApplyTranslation(const FVector& DeltaTranslation, bool bAltDown, bool bShiftDown, bool bCtrlDown) override; 171 | #endif 172 | 173 | private: 174 | #if WITH_EDITORONLY_DATA 175 | bool PreloadPreviewMeshes(); 176 | void UpdatePreviewMeshes(); 177 | bool PreloadTracksMesh(); 178 | void UpdateTracksMesh(); 179 | #endif 180 | void UpdateCraneComponents(); 181 | 182 | /** Root component to give the whole actor a transform. */ 183 | UPROPERTY(EditDefaultsOnly, Category = "Crane Components") 184 | USceneComponent* TransformComponent{ nullptr }; 185 | 186 | /** Camera component to use as a crane target. */ 187 | UPROPERTY(EditAnywhere, Category = "Crane Components") 188 | FComponentReference TargetComponent; 189 | 190 | #if WITH_EDITORONLY_DATA 191 | /** Preview meshes for visualization */ 192 | UPROPERTY() 193 | TArray PreviewMeshes; 194 | 195 | UPROPERTY() 196 | UPoseableMeshComponent* MeshComponent{ nullptr }; 197 | 198 | /** Preview mesh of crane tracks */ 199 | UPROPERTY() 200 | UStaticMesh* CraneTracksMesh{ nullptr }; 201 | 202 | /** mesh component for tracks */ 203 | UPROPERTY() 204 | UStaticMeshComponent* CraneTracksMeshComponent{ nullptr }; 205 | 206 | /** Data table with crane presets, the asset is part of technocrane plugin content */ 207 | UPROPERTY() 208 | UDataTable* CranesData{ nullptr }; 209 | #endif 210 | 211 | private: 212 | FTechnocraneRig TechnocraneRig; 213 | ECranePreviewModelsEnum LastPreviewModel; 214 | bool bLastSupportTracks{ false }; 215 | float LastTracksOffset{ 0.0f }; 216 | }; 217 | -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Public/TechnocraneRuntimeSettings.h: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocraneRuntimeSettings.h 6 | // Sergei Solokhin 7 | 8 | #pragma once 9 | 10 | #include "CoreMinimal.h" 11 | #include "UObject/ObjectMacros.h" 12 | #include "UObject/Object.h" 13 | #include "Misc/FrameRate.h" 14 | #include "TechnocraneRuntimeSettings.generated.h" 15 | 16 | /** 17 | * Implements the settings for the Paper2D plugin. 18 | */ 19 | UCLASS(config=Engine, defaultconfig) 20 | class TECHNOCRANEPLUGIN_API UTechnocraneRuntimeSettings : public UObject 21 | { 22 | GENERATED_BODY() 23 | public: 24 | //! a constructor 25 | UTechnocraneRuntimeSettings(); 26 | 27 | // Specify a default state of live mode for a Technocrane Camera Connection 28 | UPROPERTY(EditAnywhere, config, Category=Settings) 29 | bool bLiveByDefault; 30 | 31 | // switch between serial or network connections 32 | UPROPERTY(EditAnywhere, config, Category = Settings) 33 | bool bNetworkConnection; 34 | 35 | // Specify a default serial port index for a Technocrane Camera 36 | UPROPERTY(EditAnywhere, config, Category = Settings) 37 | int SerialPortIdByDefault; 38 | 39 | // try to catch packets from a specified udp port broadcasted into a local network 40 | UPROPERTY(EditAnywhere, config, Category = NetworkSettings) 41 | bool bNetworkBindAnyAddress; 42 | 43 | UPROPERTY(EditAnywhere, config, Category = NetworkSettings) 44 | bool bNetworkBroadcast; 45 | 46 | // Specify a default network server address 47 | UPROPERTY(EditAnywhere, config, Category = NetworkSettings) 48 | FString NetworkServerAddressByDefault; 49 | 50 | // Specify a default network port index for a Technocrane Camera 51 | UPROPERTY(EditAnywhere, config, Category = NetworkSettings) 52 | int NetworkPortIdByDefault; 53 | 54 | // Specify a default packet raw data space scale 55 | UPROPERTY(EditAnywhere, config, Category=Settings) 56 | float SpaceScaleByDefault; 57 | 58 | // Convert uncalibrated percentage into a range 59 | UPROPERTY(EditAnywhere, config, Category = UncalibratedRanges) 60 | FFloatInterval ZoomRange; 61 | 62 | UPROPERTY(EditAnywhere, config, Category = UncalibratedRanges) 63 | FFloatInterval FocusRange; 64 | 65 | UPROPERTY(EditAnywhere, config, Category = UncalibratedRanges) 66 | FFloatInterval IrisRange; 67 | 68 | // Specify a default packet raw data space scale 69 | UPROPERTY(EditAnywhere, config, Category = Settings) 70 | bool bPacketContainsRawAndCalibratedData; 71 | 72 | // Default camera frame rate 73 | UPROPERTY(EditAnywhere, config, Category = Settings) 74 | FFrameRate CameraFrameRate; 75 | }; 76 | -------------------------------------------------------------------------------- /Source/TechnocranePlugin/Public/TechnocraneShared.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // Copyright (c) 2020 Technocrane s.r.o. 4 | // 5 | // https://github.com/technocranes/technocrane-unreal 6 | // 7 | // TechnocraneShared.h 8 | // Sergei Solokhin 9 | 10 | #include "CoreMinimal.h" 11 | #include "UObject/ObjectMacros.h" 12 | 13 | #define TECHNOCRANE_MAX_COLUMNS_COUNT 3 14 | #define TECHNOCRANE_MAX_BEAMS_COUNT 5 15 | 16 | UENUM( BlueprintType ) 17 | enum class ECraneJoints : uint8 18 | { 19 | Base = 0, 20 | Columns, 21 | Column1, 22 | Column2, 23 | Column3, 24 | Beams, 25 | Beam1, 26 | Beam2, 27 | Beam3, 28 | Beam4, 29 | Beam5, 30 | Gravity, 31 | Neck, 32 | Head, 33 | 34 | WheelFR, 35 | WheelFL, 36 | WheelRR, 37 | WheelRL, 38 | 39 | JointCount 40 | }; 41 | 42 | const FName GetCraneJointName(const ECraneJoints index); -------------------------------------------------------------------------------- /Source/TechnocranePlugin/TechnocranePlugin.Build.cs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2020-2023 Technocrane s.r.o. 2 | // 3 | // https://github.com/technocranes/technocrane-unreal 4 | // 5 | // TechnocranePlugin.Build.cs 6 | // Sergei Solokhin 7 | 8 | using System.IO; 9 | 10 | using Path = System.IO.Path; 11 | using Microsoft.Extensions.Logging; 12 | 13 | namespace UnrealBuildTool.Rules 14 | { 15 | public class TechnocranePlugin : ModuleRules 16 | { 17 | 18 | public TechnocranePlugin(ReadOnlyTargetRules Target) : base(Target) 19 | { 20 | PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; 21 | 22 | bLegacyPublicIncludePaths = false; 23 | 24 | if (!Target.bUseUnityBuild) 25 | { 26 | PrivatePCHHeaderFile = "Private/TechnocranePrivatePCH.h"; 27 | #if UE_4_22_OR_LATER 28 | #else 29 | PrivateDependencyModuleNames.Add("LivePP"); 30 | #endif 31 | } 32 | 33 | if (Target.Platform == UnrealTargetPlatform.Win64) 34 | { 35 | PublicDefinitions.Add("TECHNOCRANESDK"); 36 | PublicDefinitions.Add("TECHNOCRANESDK_IMPORTS"); 37 | } 38 | 39 | PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Public")); 40 | PublicIncludePaths.Add(Path.Combine(ModuleDirectory, "Private")); 41 | 42 | PublicDependencyModuleNames.AddRange( 43 | new string[] 44 | { 45 | "Core", 46 | "Projects", 47 | "CoreUObject", 48 | "Engine", 49 | "InputCore", 50 | "CinematicCamera", 51 | "LiveLink", 52 | "LiveLinkInterface", 53 | "LiveLinkComponents", 54 | "Messaging", 55 | "Networking" 56 | } 57 | ); 58 | 59 | PrivateDependencyModuleNames.AddRange( 60 | new string[] 61 | { 62 | "Messaging", 63 | "LiveLink", 64 | "LiveLinkInterface", 65 | "LiveLinkMessageBusFramework", 66 | "Networking", 67 | "TimeManagement", 68 | "SlateCore", 69 | "Slate", 70 | "Sockets" 71 | } 72 | ); 73 | 74 | PrivateIncludePathModuleNames.AddRange( 75 | new string[] { 76 | "Messaging", 77 | "MessagingCommon", 78 | }); 79 | 80 | /****************************************/ 81 | 82 | // If you update this path, ensure the DLL runtime delay load path in TechnocraneModule::StartupModule stays in sync. 83 | string TechnocranePath = Path.GetFullPath(Path.Combine(ModuleDirectory, "..", "ThirdParty", "TechnocraneSDK")); 84 | 85 | if (Directory.Exists(TechnocranePath)) 86 | { 87 | Logger.LogInformation("TechnocranePath: " + Path.Combine(TechnocranePath, "include")); 88 | 89 | PublicSystemIncludePaths.Add(Path.Combine(TechnocranePath, "include")); 90 | 91 | if (Target.Platform == UnrealTargetPlatform.Win64) 92 | { 93 | string TechnocraneLibBinPath = Path.Combine(TechnocranePath, "lib", "Win64"); 94 | PublicAdditionalLibraries.Add(Path.Combine(TechnocraneLibBinPath, "TechnocraneLib.lib")); 95 | 96 | PublicDelayLoadDLLs.Add("TechnocraneLib.dll"); 97 | // Add API for Runtime too 98 | RuntimeDependencies.Add(Path.Combine(TechnocraneLibBinPath, "TechnocraneLib.lib")); 99 | RuntimeDependencies.Add(Path.Combine(TechnocraneLibBinPath, "TechnocraneLib.dll")); 100 | } 101 | } 102 | else 103 | { 104 | Logger.LogError("TechnocranePath Not Found: " + TechnocranePath); 105 | } 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /Source/ThirdParty/TechnocraneSDK/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The "New" BSD License: 2 | ---------------------- 3 | 4 | Copyright (c) 2018-2021, Technocrane s.r.o. 5 | All rights reserved. 6 | 7 | Redistribution and use in source and binary forms, with or without 8 | modification, are permitted provided that the following conditions are met: 9 | 10 | * Redistributions of source code must retain the above copyright notice, this 11 | list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | * Neither the name of the Technocrane s.r.o. nor the names of its contributors 16 | may be used to endorse or promote products derived from this software 17 | without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 23 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 25 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | -------------------------------------------------------------------------------- /Source/ThirdParty/TechnocraneSDK/README.md: -------------------------------------------------------------------------------- 1 | 2 | # Technocrane SDK 3 | 4 | This is an API to read data from a robotic crane produced by Technocrane s.r.o 5 | 6 | For more information, please visit 7 | 8 | Technocrane s.r.o website - https://www.supertechno.com 9 | GitHub repositories - https://github.com/technocranes 10 | 11 | -------------------------------------------------------------------------------- /Source/ThirdParty/TechnocraneSDK/include/technocrane_hardware.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | ////////////////////////////////////////////////////////////////// 4 | // Copyright (c) 2018-2020 Technocrane s.r.o. 5 | // 6 | // Technocrane SDK hardware device, communication class 7 | // Sergei Solokhin 2018-2020 8 | ////////////////////////////////////////////////////////////////// 9 | 10 | #include "technocrane_types.h" 11 | 12 | namespace NTechnocrane 13 | { 14 | // helper function for a manual calibration 15 | bool TECHNOCRANESDK_API ComputeFocusf(float &value, const float src, const float rangeMin, const float rangeMax); 16 | bool TECHNOCRANESDK_API ComputeZoomf(float &value, const float src, const float rangeMin, const float rangeMax); 17 | bool TECHNOCRANESDK_API ComputeIrisf(float &value, const float src, const float rangeMin, const float rangeMax); 18 | 19 | float TECHNOCRANESDK_API ComputeHorizontalFOVf(const float height, const float aspect, const float focal_length); 20 | 21 | bool TECHNOCRANESDK_API ComputeFocusd(double &value, const double src, const double rangeMin, const double rangeMax); 22 | bool TECHNOCRANESDK_API ComputeZoomd(double &value, const double src, const double rangeMin, const double rangeMax); 23 | bool TECHNOCRANESDK_API ComputeIrisd(double &value, const double src, const double rangeMin, const double rangeMax); 24 | 25 | double TECHNOCRANESDK_API ComputeHorizontalFOVd(const double height, const double aspect, const double focal_length); 26 | 27 | bool TECHNOCRANESDK_API UnPackData(STechnocrane_Packet& packet, const double framerate, 28 | const void* raw_data, const bool packed_data, const bool mobu_rotation); 29 | 30 | 31 | // Log output 32 | typedef void(*LOG_CALLBACK)(const char* message, const int level); 33 | void TECHNOCRANESDK_API SetLogCallback(LOG_CALLBACK log_callback); 34 | 35 | ///////////////////////////////////////////////////////////////////////////////////////////// 36 | //! Technocrane hardware. 37 | class TECHNOCRANESDK_API CTechnocrane_Hardware 38 | { 39 | public: 40 | //! Constructor. 41 | CTechnocrane_Hardware(); 42 | 43 | //! Destructor. 44 | virtual ~CTechnocrane_Hardware(); 45 | 46 | // set options 47 | 48 | const SAvaliablePortList GetAvaliablePortList(); 49 | const SOptions GetOptions() const; 50 | 51 | // run-time status info 52 | const SStatusInfo GetStatusInfo() const; 53 | 54 | // communication info 55 | const dataReceptionStatus &GetDataReceptionStatus() const; 56 | 57 | //--- Opens and closes connection with data server. returns true if successful 58 | bool Init(bool enable_comm_log, bool enable_packets_log, bool mobu_rotation); //!< Initialize hardware. 59 | bool Open(const SOptions& options); //!< Open the connection. 60 | bool Close(); //!< Close connection. 61 | bool Done(); //!< Close down hardware. 62 | 63 | // Streaming functions 64 | // Once connection is established and information packets have been received 65 | // these functions start and stops the data streaming 66 | bool StartDataStream(); //!< Start data streaming. 67 | bool StopDataStream(); //!< Stop data streaming. 68 | 69 | bool IsReady() const; 70 | 71 | //--- Packet query 72 | 73 | // packet contains 74 | int FetchDataPacket(STechnocrane_Packet& packet, size_t localReadIndex, size_t &localReadCount, const bool packed_data); 75 | 76 | void SetHardwareRate(const float rate); 77 | float GetHardwareRate() const; 78 | 79 | void GetRawRotation(float& pan, float& tilt, float& roll); 80 | void GetRotation(float* r, const ERotationOrder order, const float* mult); 81 | void GetPosition(float* p, const float scale, const bool righthanded); 82 | 83 | bool GetFocus(float &value, const float rangeMin, const float rangeMax); 84 | bool GetZoom(float &value, const float rangeMin, const float rangeMax); 85 | bool GetIris(float &value, const float rangeMin, const float rangeMax); 86 | 87 | float GetTimeCodeRate() const; 88 | 89 | bool HasTimeCode() const; 90 | bool GetCameraOn() const; 91 | bool GetRunning() const; 92 | bool IsZoomCalibrated() const; 93 | bool IsFocusCalibrated() const; 94 | bool IsIrisCalibrated() const; 95 | 96 | // 97 | // track last error 98 | 99 | const int GetLastError() const; 100 | void ClearLastError(); 101 | 102 | // IO 103 | 104 | bool StartDataRecording(); 105 | bool StopDataRecording(); 106 | 107 | bool SaveRecordedData(const char *filename); 108 | 109 | int GetNumberOfRecordedPackets() const; 110 | const void* GetRawPacketData(const int index) const; 111 | 112 | protected: 113 | void* impl; 114 | }; 115 | 116 | }; 117 | 118 | // 119 | // 120 | 121 | TECHNOCRANESDK_CAPI int32_t StartStream(const bool use_network_connection, const int32_t port_id); 122 | TECHNOCRANESDK_CAPI int32_t StopStream(); 123 | 124 | TECHNOCRANESDK_CAPI void* MapPacket(); 125 | TECHNOCRANESDK_CAPI void UnMapPacket(); 126 | 127 | -------------------------------------------------------------------------------- /Source/ThirdParty/TechnocraneSDK/include/technocrane_types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /////////////////////////////////////////////////////////////////// 4 | // Copyright (c) 2020 Technocrane s.r.o. 5 | // 6 | // Technocrane SDK Types declaration 7 | // Sergei Solokhin 2018-2020 8 | /////////////////////////////////////////////////////////////////// 9 | 10 | #include 11 | #include 12 | 13 | #ifdef TECHNOCRANESDK_EXPORTS 14 | #define TECHNOCRANESDK_API __declspec(dllexport) 15 | #define TECHNOCRANESDK_CAPI extern "C" __declspec(dllexport) 16 | #else 17 | #define TECHNOCRANESDK_API __declspec(dllimport) 18 | #define TECHNOCRANESDK_CAPI __declspec(dllimport) 19 | #endif 20 | 21 | namespace NTechnocrane 22 | { 23 | 24 | typedef std::pair port_pair; 25 | 26 | #define TECHNOCRANE_HELP "Please visit Technocrane homepage - http://www.supertechno.com/" 27 | #define TECHNOCRANE_ABOUT "TECHNOCRANE s.r.o.\n Developed by Sergei Solokhin 2018-2020" 28 | 29 | #define TECHNOCRANE_NO_ERROR 0 30 | #define TECHNOCRANE_NO_PORTS 1 31 | #define TECHNOCRANE_NO_PORTS_MSG "Is Data Cabel Connected? Do you want to try again ?" 32 | #define TECHNOCRANE_SERIAL_FAILED 2 33 | #define TECHNOCRANE_SERIAL_FAILED_MSG "Failed to Activate Serial Port" 34 | #define TECHNOCRANE_NETWORK_FAILED 3 35 | #define TECHNOCRANE_NETWORK_FAILED_MSG "Failed to Start A Network Communication" 36 | 37 | #define default_port 1 38 | #define default_fps 25.0f // PAL 39 | 40 | //////////////////////////////////////////////////////////////////////////////// 41 | // SAvaliablePortList 42 | 43 | struct TECHNOCRANESDK_API SAvaliablePortList 44 | { 45 | SAvaliablePortList(const void* _impl); 46 | 47 | const int GetCount() const; 48 | 49 | const char* GetPortName(const int index) const; 50 | const int GetPort(const int index) const; 51 | 52 | protected: 53 | const void* impl; 54 | }; 55 | 56 | //////////////////////////////////////////////////////////////////////////////// 57 | // SOptions 58 | struct SOptions 59 | { 60 | float m_CameraFPS; 61 | bool m_UseNetworkConnection; 62 | 63 | // network options 64 | bool m_BindAnyAddress; 65 | bool m_Broadcast; 66 | unsigned long m_NetworkAddress; 67 | int m_NetworkPort; 68 | 69 | // serial options 70 | int m_SerialPort; 71 | int m_BaudRate; 72 | }; 73 | 74 | void TECHNOCRANESDK_API SetDefaultOptions(SOptions& options); 75 | 76 | /////////////////////////////////////////////////////////////////////////////// 77 | // SStatusInfo 78 | struct SStatusInfo 79 | { 80 | double timecode_rate; // rate extracted from received packets 81 | bool has_timecode; 82 | bool is_camera_on; 83 | bool is_running; 84 | bool is_zoom_calibrated; 85 | bool is_focus_calibrated; 86 | bool is_iris_calibrated; 87 | }; 88 | 89 | // DONE: 90 | enum ETimeRatePreset 91 | { 92 | eTimeRateCustom, 93 | eNTSC_DROP, //!< 29.97f 94 | eNTSC_FULL, //!< -29.97f 95 | ePAL_25, //!< -25.0f 96 | eMPAL_30, //!< -29.971f Currently not supported : "1" is added just to differentiate from NTSC_FULL(-29.97f) 97 | eFILM_24, //!< -24.0f 98 | eFILM_23976, //!< -23.976f 99 | eFRAMES_30, //!< -30.0f 100 | eFRAMES_5994 //!< -59.94f 101 | }; 102 | 103 | float TECHNOCRANESDK_API ETimeRatePresetToFloat(const ETimeRatePreset preset); 104 | 105 | enum ERotationOrder 106 | { 107 | eXYZ, //!< XYZ 108 | eXZY, //!< XZY 109 | eYXZ, //!< YXZ 110 | eYZX, //!< YZX 111 | eZXY, //!< ZXY 112 | eZYX, //!< ZYX 113 | }; 114 | 115 | /* 116 | * This class holds informations about reception history. 117 | */ 118 | class dataReceptionStatus 119 | { 120 | public: 121 | dataReceptionStatus(); 122 | 123 | void IncTotalCharsRead(); 124 | void IncCompletePackets(); 125 | void IncTotalCheckSumErrors(); 126 | void IncTotalMissedSyncs(); 127 | 128 | int totalCharsRead; 129 | int nextSync; 130 | int totalCheckSumErrors; 131 | int totalMissedSyncs; 132 | int completePackets; 133 | double startTime, endTime, totalTime; 134 | }; 135 | 136 | ////////////////////////////////////////////////////////////////////////////////////////// 137 | //! Camera packet class. 138 | struct TECHNOCRANESDK_API STechnocrane_Packet 139 | { 140 | //! a constructor 141 | STechnocrane_Packet() 142 | { 143 | Pan = 0.0f; 144 | Tilt = 0.0f; 145 | Roll = 0.0f; 146 | 147 | memset(Position, 0, sizeof(float) * 3); 148 | memset(Rotation, 0, sizeof(float) * 3); 149 | 150 | Iris = 0.0f; 151 | TrackPos = 0.0f; 152 | PacketNumber = 0.0f; 153 | 154 | CameraOn = false; 155 | Running = false; 156 | IsZoomCalibrated = false; // calibrated zoom, focus, iris ?! 157 | IsFocusCalibrated = false; 158 | IsIrisCalibrated = false; 159 | PacketHasTimeCode = false; 160 | 161 | hours = 0; 162 | minutes = 0; 163 | seconds = 0; 164 | frames = 0; 165 | field = 0; 166 | } 167 | 168 | 169 | float Focus; //!< Property: Focus encoder value (relative). 170 | float Zoom; //!< Property: Zoom encoder value. 171 | 172 | float Position[3]; //!< Property: Position of camera. 173 | float Rotation[3]; //!< Property: Orientation of camera. 174 | float Offset[3]; //!< Property: Camera offset. 175 | float FieldOfView[2]; //!< Property: Field of View (X,Y) of camera lens. 176 | float OpticalCenter[2]; //!< Property: Optical Center of camera lens. 177 | 178 | float Pan; 179 | float Tilt; 180 | float Roll; 181 | 182 | float Iris; 183 | float TrackPos; 184 | 185 | // manually computed FOV 186 | float ComputedFOV; 187 | 188 | float PacketNumber; 189 | 190 | unsigned int hours; 191 | unsigned int minutes; 192 | unsigned int seconds; 193 | unsigned int frames; 194 | unsigned int field; 195 | 196 | // control over a camera 197 | 198 | bool IsZoomCalibrated; // calibrated zoom, focus, iris ?! 199 | bool IsFocusCalibrated; 200 | bool IsIrisCalibrated; 201 | bool PacketHasTimeCode; 202 | 203 | bool CameraOn; 204 | bool Running; 205 | 206 | 207 | bool HasTimeCode() const 208 | { 209 | return (true == PacketHasTimeCode); 210 | } 211 | float ComputeLocalTime(const float framerate) const 212 | { 213 | return (3600.0f * hours + 60.0f * minutes + seconds + (1.0f / framerate * frames)); 214 | } 215 | }; 216 | 217 | }; 218 | 219 | -------------------------------------------------------------------------------- /Source/ThirdParty/TechnocraneSDK/lib/Win32/TechnocraneLib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Source/ThirdParty/TechnocraneSDK/lib/Win32/TechnocraneLib.dll -------------------------------------------------------------------------------- /Source/ThirdParty/TechnocraneSDK/lib/Win32/TechnocraneLib.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Source/ThirdParty/TechnocraneSDK/lib/Win32/TechnocraneLib.lib -------------------------------------------------------------------------------- /Source/ThirdParty/TechnocraneSDK/lib/Win64/TechnocraneLib.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Source/ThirdParty/TechnocraneSDK/lib/Win64/TechnocraneLib.dll -------------------------------------------------------------------------------- /Source/ThirdParty/TechnocraneSDK/lib/Win64/TechnocraneLib.lib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/technocranes/technocrane-unreal/be6f2c139425410d062b94e860eec1c34df0f21e/Source/ThirdParty/TechnocraneSDK/lib/Win64/TechnocraneLib.lib -------------------------------------------------------------------------------- /TechnocranePlugin.uplugin: -------------------------------------------------------------------------------- 1 | { 2 | "FileVersion": 3, 3 | "Version": 150, 4 | "VersionName": "1.5.0", 5 | "FriendlyName": "Technocrane Plugin", 6 | "Description": "Technocrane Tracking Plugin.", 7 | "Category": "Input Devices", 8 | "CreatedBy": "Technocrane r.s.o.", 9 | "CreatedByURL": "http://supertechno.com", 10 | "DocsURL": "https://github.com/technocranes/technocrane-unreal", 11 | "MarketplaceURL": "com.epicgames.launcher://ue/marketplace/content/7ac283e8aa09461380eaa412284d8087", 12 | "SupportURL": "https://github.com/technocranes/technocrane-unreal", 13 | "EngineVersion": [ "4.22.0", "4.23.0", "4.24.0", "4.25.0", "4.26.0", "4.27.0", "5.0", "5.1", "5.2", "5.3", "5.4", "5.5" ], 14 | "EnabledByDefault": false, 15 | "CanContainContent": true, 16 | "IsBetaVersion": false, 17 | "Installed": true, 18 | "Modules": [ 19 | { 20 | "Name": "TechnocranePlugin", 21 | "Type": "Runtime", 22 | "LoadingPhase": "Default", 23 | "WhitelistPlatforms": [ "Win64" ] 24 | }, 25 | { 26 | "Name": "TechnocraneEditor", 27 | "Type": "Editor", 28 | "LoadingPhase": "PostEngineInit", 29 | "WhitelistPlatforms": [ "Win64" ] 30 | } 31 | ], 32 | "Plugins": [ 33 | { 34 | "Name": "LiveLink", 35 | "Enabled": true 36 | } 37 | ] 38 | } --------------------------------------------------------------------------------