├── 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 | []()
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 | []()
35 |
36 | Next step will be to open a live link hub
37 | []()
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 | []()
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 | []()
44 |
45 | Default settings and camera frames rate are presented in project settings under technocrane tracker group
46 | []()
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 | []()
74 |
75 |
76 | # Video Tutorial
77 |
78 | [](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 | }
--------------------------------------------------------------------------------